summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/map')
-rw-r--r--src/map/atcommand.cpp447
-rw-r--r--src/map/atcommand.hpp2
-rw-r--r--src/map/battle.cpp19
-rw-r--r--src/map/battle.hpp1
-rw-r--r--src/map/battle.t.hpp6
-rw-r--r--src/map/chrif.cpp33
-rw-r--r--src/map/clif.cpp296
-rw-r--r--src/map/intif.cpp56
-rw-r--r--src/map/itemdb.cpp6
-rw-r--r--src/map/itemdb.hpp8
-rw-r--r--src/map/magic-expr-eval.hpp6
-rw-r--r--src/map/magic-expr.cpp327
-rw-r--r--src/map/magic-expr.hpp22
-rw-r--r--src/map/magic-interpreter-aux.hpp6
-rw-r--r--src/map/magic-interpreter-base.cpp217
-rw-r--r--src/map/magic-interpreter-lexer.lpp23
-rw-r--r--src/map/magic-interpreter-parser.ypp506
-rw-r--r--src/map/magic-interpreter.hpp321
-rw-r--r--src/map/magic-stmt.cpp341
-rw-r--r--src/map/magic.cpp79
-rw-r--r--src/map/magic.hpp10
-rw-r--r--src/map/map.cpp435
-rw-r--r--src/map/map.hpp137
-rw-r--r--src/map/mob.cpp342
-rw-r--r--src/map/mob.hpp2
-rw-r--r--src/map/npc.cpp611
-rw-r--r--src/map/npc.hpp11
-rw-r--r--src/map/party.cpp2
-rw-r--r--src/map/party.hpp2
-rw-r--r--src/map/path.cpp17
-rw-r--r--src/map/path.hpp8
-rw-r--r--src/map/pc.cpp282
-rw-r--r--src/map/pc.hpp10
-rw-r--r--src/map/script.cpp2736
-rw-r--r--src/map/script.hpp90
-rw-r--r--src/map/skill.cpp34
-rw-r--r--src/map/skill.hpp6
-rw-r--r--src/map/storage.cpp36
-rw-r--r--src/map/tmw.cpp2
-rw-r--r--src/map/trade.cpp12
40 files changed, 3233 insertions, 4274 deletions
diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp
index 56ff2ab..c066a46 100644
--- a/src/map/atcommand.cpp
+++ b/src/map/atcommand.cpp
@@ -127,10 +127,6 @@ ATCOMMAND_FUNC(enablenpc);
ATCOMMAND_FUNC(disablenpc);
ATCOMMAND_FUNC(servertime); // by Yor
ATCOMMAND_FUNC(chardelitem); // by Yor
-ATCOMMAND_FUNC(ignorelist); // by Yor
-ATCOMMAND_FUNC(charignorelist); // by Yor
-ATCOMMAND_FUNC(inall); // by Yor
-ATCOMMAND_FUNC(exall); // by Yor
ATCOMMAND_FUNC(email); // by Yor
ATCOMMAND_FUNC(effect); //by Apple
ATCOMMAND_FUNC(character_item_list); // by Yor
@@ -293,10 +289,6 @@ AtCommandInfo atcommand_info[] =
{"@servertime", 0, atcommand_servertime}, // by Yor
{"@chardelitem", 60, atcommand_chardelitem}, // by Yor
{"@listnearby", 40, atcommand_list_nearby}, // by Yor
- {"@ignorelist", 0, atcommand_ignorelist}, // by Yor
- {"@charignorelist", 20, atcommand_charignorelist}, // by Yor
- {"@inall", 20, atcommand_inall}, // by Yor
- {"@exall", 20, atcommand_exall}, // by Yor
{"@email", 0, atcommand_email}, // by Yor
{"@effect", 40, atcommand_effect}, // by Apple
{"@charitemlist", 40, atcommand_character_item_list}, // by Yor
@@ -372,19 +364,19 @@ void log_atcommand(dumb_ptr<map_session_data> sd, const_string cmd)
stamp_time(tmpstr);
fprintf(fp, "[%s] %s(%d,%d) %s(%d) : ",
tmpstr,
- map[sd->bl_m].name, sd->bl_x, sd->bl_y,
+ sd->bl_m->name, sd->bl_x, sd->bl_y,
sd->status.name, sd->status.account_id);
fwrite(cmd.data(), 1, cmd.size(), fp);
}
-char *gm_logfile_name = NULL;
+std::string gm_logfile_name;
/*==========================================
* Log a timestamped line to GM log file
*------------------------------------------
*/
FILE *get_gm_log()
{
- if (!gm_logfile_name)
+ if (gm_logfile_name.empty())
return NULL;
struct tm ctime = TimeT::now();
@@ -410,7 +402,7 @@ FILE *get_gm_log()
if (!gm_logfile)
{
perror("GM log file");
- gm_logfile_name = NULL;
+ gm_logfile_name.clear();
}
return gm_logfile;
}
@@ -642,7 +634,6 @@ int atcommand_charwarp(const int fd, dumb_ptr<map_session_data> sd,
char character[100];
int x = 0, y = 0;
dumb_ptr<map_session_data> pl_sd;
- int m;
memset(map_name, '\0', sizeof(map_name));
memset(character, '\0', sizeof(character));
@@ -669,15 +660,15 @@ int atcommand_charwarp(const int fd, dumb_ptr<map_session_data> sd,
{ // you can rura+ only lower or same GM level
if (x > 0 && x < 800 && y > 0 && y < 800)
{
- m = map_mapname2mapid(map_name);
- if (m >= 0 && map[m].flag.nowarpto
+ map_local *m = map_mapname2mapid(map_name);
+ if (m != nullptr && m->flag.nowarpto
&& battle_config.any_warp_GM_min_level > pc_isGM(sd))
{
clif_displaymessage(fd,
"You are not authorised to warp someone to this map.");
return -1;
}
- if (pl_sd->bl_m >= 0 && map[pl_sd->bl_m].flag.nowarp
+ if (pl_sd->bl_m != nullptr && pl_sd->bl_m->flag.nowarp
&& battle_config.any_warp_GM_min_level > pc_isGM(sd))
{
clif_displaymessage(fd,
@@ -725,7 +716,6 @@ int atcommand_warp(const int fd, dumb_ptr<map_session_data> sd,
{
char map_name[100];
int x = 0, y = 0;
- int m;
memset(map_name, '\0', sizeof(map_name));
@@ -747,15 +737,15 @@ int atcommand_warp(const int fd, dumb_ptr<map_session_data> sd,
if (x > 0 && x < 800 && y > 0 && y < 800)
{
- m = map_mapname2mapid(map_name);
- if (m >= 0 && map[m].flag.nowarpto
+ map_local *m = map_mapname2mapid(map_name);
+ if (m != nullptr && m->flag.nowarpto
&& battle_config.any_warp_GM_min_level > pc_isGM(sd))
{
clif_displaymessage(fd,
"You are not authorised to warp you to this map.");
return -1;
}
- if (sd->bl_m >= 0 && map[sd->bl_m].flag.nowarp
+ if (sd->bl_m != nullptr && sd->bl_m->flag.nowarp
&& battle_config.any_warp_GM_min_level > pc_isGM(sd))
{
clif_displaymessage(fd,
@@ -834,14 +824,14 @@ int atcommand_goto(const int fd, dumb_ptr<map_session_data> sd,
if ((pl_sd = map_nick2sd(character)) != NULL)
{
- if (pl_sd->bl_m >= 0 && map[pl_sd->bl_m].flag.nowarpto
+ if (pl_sd->bl_m != nullptr && pl_sd->bl_m->flag.nowarpto
&& battle_config.any_warp_GM_min_level > pc_isGM(sd))
{
clif_displaymessage(fd,
"You are not authorised to warp you to the map of this player.");
return -1;
}
- if (sd->bl_m >= 0 && map[sd->bl_m].flag.nowarp
+ if (sd->bl_m != nullptr && sd->bl_m->flag.nowarp
&& battle_config.any_warp_GM_min_level > pc_isGM(sd))
{
clif_displaymessage(fd,
@@ -877,14 +867,14 @@ int atcommand_jump(const int fd, dumb_ptr<map_session_data> sd,
y = random_::in(1, 399);
if (x > 0 && x < 800 && y > 0 && y < 800)
{
- if (sd->bl_m >= 0 && map[sd->bl_m].flag.nowarpto
+ if (sd->bl_m != nullptr && sd->bl_m->flag.nowarpto
&& battle_config.any_warp_GM_min_level > pc_isGM(sd))
{
clif_displaymessage(fd,
"You are not authorised to warp you to your actual map.");
return -1;
}
- if (sd->bl_m >= 0 && map[sd->bl_m].flag.nowarp
+ if (sd->bl_m != nullptr && sd->bl_m->flag.nowarp
&& battle_config.any_warp_GM_min_level > pc_isGM(sd))
{
clif_displaymessage(fd,
@@ -1056,7 +1046,7 @@ int atcommand_whomap(const int fd, dumb_ptr<map_session_data> sd,
{
int count;
int pl_GM_level, GM_level;
- int map_id;
+ map_local *map_id;
char map_name[100];
memset(map_name, '\0', sizeof(map_name));
@@ -1068,7 +1058,8 @@ int atcommand_whomap(const int fd, dumb_ptr<map_session_data> sd,
sscanf(message, "%99s", map_name);
if (strstr(map_name, ".gat") == NULL && strstr(map_name, ".afm") == NULL && strlen(map_name) < 13) // 16 - 4 (.gat)
strcat(map_name, ".gat");
- if ((map_id = map_mapname2mapid(map_name)) < 0)
+ map_id = map_mapname2mapid(map_name);
+ if (map_id == nullptr)
map_id = sd->bl_m;
}
@@ -1108,7 +1099,7 @@ int atcommand_whomap(const int fd, dumb_ptr<map_session_data> sd,
}
std::string output = STRPRINTF("%d players found in map '%s'.",
- count, map[map_id].name);
+ count, map_id->name);
clif_displaymessage(fd, output);
return 0;
@@ -1123,12 +1114,12 @@ int atcommand_whomapgroup(const int fd, dumb_ptr<map_session_data> sd,
{
int count;
int pl_GM_level, GM_level;
- int map_id = 0;
char map_name[100];
struct party *p;
memset(map_name, '\0', sizeof(map_name));
+ map_local *map_id;
if (!message || !*message)
map_id = sd->bl_m;
else
@@ -1136,7 +1127,8 @@ int atcommand_whomapgroup(const int fd, dumb_ptr<map_session_data> sd,
sscanf(message, "%99s", map_name);
if (strstr(map_name, ".gat") == NULL && strstr(map_name, ".afm") == NULL && strlen(map_name) < 13) // 16 - 4 (.gat)
strcat(map_name, ".gat");
- if ((map_id = map_mapname2mapid(map_name)) < 0)
+ map_id = map_mapname2mapid(map_name);
+ if (map_id == nullptr)
map_id = sd->bl_m;
}
@@ -1176,12 +1168,12 @@ int atcommand_whomapgroup(const int fd, dumb_ptr<map_session_data> sd,
std::string output;
if (count == 0)
- output = STRPRINTF("No player found in map '%s'.", map[map_id].name);
+ output = STRPRINTF("No player found in map '%s'.", map_id->name);
else if (count == 1)
- output = STRPRINTF("1 player found in map '%s'.", map[map_id].name);
+ output = STRPRINTF("1 player found in map '%s'.", map_id->name);
else
{
- output = STRPRINTF("%d players found in map '%s'.", count, map[map_id].name);
+ output = STRPRINTF("%d players found in map '%s'.", count, map_id->name);
}
clif_displaymessage(fd, output);
@@ -1295,17 +1287,15 @@ int atcommand_save(const int fd, dumb_ptr<map_session_data> sd,
int atcommand_load(const int fd, dumb_ptr<map_session_data> sd,
const char *, const char *)
{
- int m;
-
- m = map_mapname2mapid(sd->status.save_point.map);
- if (m >= 0 && map[m].flag.nowarpto
+ map_local *m = map_mapname2mapid(sd->status.save_point.map);
+ if (m != nullptr && m->flag.nowarpto
&& battle_config.any_warp_GM_min_level > pc_isGM(sd))
{
clif_displaymessage(fd,
"You are not authorised to warp you to your save map.");
return -1;
}
- if (sd->bl_m >= 0 && map[sd->bl_m].flag.nowarp
+ if (sd->bl_m != nullptr && sd->bl_m->flag.nowarp
&& battle_config.any_warp_GM_min_level > pc_isGM(sd))
{
clif_displaymessage(fd,
@@ -1894,9 +1884,9 @@ int atcommand_pvpoff(const int fd, dumb_ptr<map_session_data> sd,
return -1;
}
- if (map[sd->bl_m].flag.pvp)
+ if (sd->bl_m->flag.pvp)
{
- map[sd->bl_m].flag.pvp = 0;
+ sd->bl_m->flag.pvp = 0;
for (int i = 0; i < fd_max; i++)
{
if (!session[i])
@@ -1934,9 +1924,9 @@ int atcommand_pvpon(const int fd, dumb_ptr<map_session_data> sd,
return -1;
}
- if (!map[sd->bl_m].flag.pvp && !map[sd->bl_m].flag.nopvp)
+ if (!sd->bl_m->flag.pvp && !sd->bl_m->flag.nopvp)
{
- map[sd->bl_m].flag.pvp = 1;
+ sd->bl_m->flag.pvp = 1;
for (int i = 0; i < fd_max; i++)
{
if (!session[i])
@@ -2210,23 +2200,27 @@ static
void atcommand_killmonster_sub(const int fd, dumb_ptr<map_session_data> sd,
const char *message, const int drop)
{
- int map_id;
char map_name[100];
memset(map_name, '\0', sizeof(map_name));
+ map_local *map_id;
if (!message || !*message || sscanf(message, "%99s", map_name) < 1)
map_id = sd->bl_m;
else
{
if (strstr(map_name, ".gat") == NULL && strstr(map_name, ".afm") == NULL && strlen(map_name) < 13) // 16 - 4 (.gat)
strcat(map_name, ".gat");
- if ((map_id = map_mapname2mapid(map_name)) < 0)
+ map_id = map_mapname2mapid(map_name);
+ if (map_id == nullptr)
map_id = sd->bl_m;
}
- map_foreachinarea(std::bind(atkillmonster_sub, ph::_1, drop), map_id, 0, 0, map[map_id].xs,
- map[map_id].ys, BL::MOB);
+ map_foreachinarea(std::bind(atkillmonster_sub, ph::_1, drop),
+ map_id,
+ 0, 0,
+ map_id->xs, map_id->ys,
+ BL::MOB);
clif_displaymessage(fd, "All monsters killed!");
@@ -2268,8 +2262,10 @@ int atcommand_list_nearby(const int fd, dumb_ptr<map_session_data> sd,
{
clif_displaymessage(fd, "Nearby players:");
map_foreachinarea(std::bind(atlist_nearby_sub, ph::_1, fd),
- sd->bl_m, sd->bl_x - 1, sd->bl_y - 1,
- sd->bl_x + 1, sd->bl_x + 1, BL::PC);
+ sd->bl_m,
+ sd->bl_x - 1, sd->bl_y - 1,
+ sd->bl_x + 1, sd->bl_x + 1,
+ BL::PC);
return 0;
}
@@ -2299,7 +2295,7 @@ int atcommand_gat(const int fd, dumb_ptr<map_session_data> sd,
{
std::string output = STRPRINTF(
"%s (x= %d, y= %d) %02X %02X %02X %02X %02X",
- map[sd->bl_m].name, sd->bl_x - 2, sd->bl_y + y,
+ 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),
map_getcell(sd->bl_m, sd->bl_x, sd->bl_y + y),
@@ -2348,15 +2344,15 @@ int atcommand_statuspoint(const int fd, dumb_ptr<map_session_data> sd,
return -1;
}
- new_status_point = (int) sd->status.status_point + point;
+ new_status_point = sd->status.status_point + point;
if (point > 0 && (point > 0x7FFF || new_status_point > 0x7FFF)) // fix positiv overflow
new_status_point = 0x7FFF;
else if (point < 0 && (point < -0x7FFF || new_status_point < 0)) // fix negativ overflow
new_status_point = 0;
- if (new_status_point != (int) sd->status.status_point)
+ if (new_status_point != sd->status.status_point)
{
- sd->status.status_point = (short) new_status_point;
+ sd->status.status_point = new_status_point;
clif_updatestatus(sd, SP::STATUSPOINT);
clif_displaymessage(fd, "Number of status points changed!");
}
@@ -2388,15 +2384,15 @@ int atcommand_skillpoint(const int fd, dumb_ptr<map_session_data> sd,
return -1;
}
- new_skill_point = (int) sd->status.skill_point + point;
+ new_skill_point = sd->status.skill_point + point;
if (point > 0 && (point > 0x7FFF || new_skill_point > 0x7FFF)) // fix positiv overflow
new_skill_point = 0x7FFF;
else if (point < 0 && (point < -0x7FFF || new_skill_point < 0)) // fix negativ overflow
new_skill_point = 0;
- if (new_skill_point != (int) sd->status.skill_point)
+ if (new_skill_point != sd->status.skill_point)
{
- sd->status.skill_point = (short) new_skill_point;
+ sd->status.skill_point = new_skill_point;
clif_updatestatus(sd, SP::SKILLPOINT);
clif_displaymessage(fd, "Number of skill points changed!");
}
@@ -2473,7 +2469,7 @@ int atcommand_param(const int fd, dumb_ptr<map_session_data> sd,
return -1;
}
- new_value = (int) sd->status.attrs[attr] + value;
+ new_value = sd->status.attrs[attr] + value;
if (value > 0 && (value > battle_config.max_parameter || new_value > battle_config.max_parameter)) // fix positiv overflow
new_value = battle_config.max_parameter;
else if (value < 0 && (value < -battle_config.max_parameter || new_value < 1)) // fix negativ overflow
@@ -2569,14 +2565,14 @@ int atcommand_recall(const int fd, dumb_ptr<map_session_data> sd,
{
if (pc_isGM(sd) >= pc_isGM(pl_sd))
{ // you can recall only lower or same level
- if (sd->bl_m >= 0 && map[sd->bl_m].flag.nowarpto
+ if (sd->bl_m != nullptr && sd->bl_m->flag.nowarpto
&& battle_config.any_warp_GM_min_level > pc_isGM(sd))
{
clif_displaymessage(fd,
"You are not authorised to warp somenone to your actual map.");
return -1;
}
- if (pl_sd->bl_m >= 0 && map[pl_sd->bl_m].flag.nowarp
+ if (pl_sd->bl_m != nullptr && pl_sd->bl_m->flag.nowarp
&& battle_config.any_warp_GM_min_level > pc_isGM(sd))
{
clif_displaymessage(fd,
@@ -3094,7 +3090,6 @@ int atcommand_character_save(const int fd, dumb_ptr<map_session_data> sd,
char character[100];
dumb_ptr<map_session_data> pl_sd;
int x = 0, y = 0;
- int m;
memset(map_name, '\0', sizeof(map_name));
memset(character, '\0', sizeof(character));
@@ -3114,16 +3109,17 @@ int atcommand_character_save(const int fd, dumb_ptr<map_session_data> sd,
if ((pl_sd = map_nick2sd(character)) != NULL)
{
if (pc_isGM(sd) >= pc_isGM(pl_sd))
- { // you can change save point only to lower or same gm level
- m = map_mapname2mapid(map_name);
- if (m < 0)
+ {
+ // you can change save point only to lower or same gm level
+ map_local *m = map_mapname2mapid(map_name);
+ if (m == nullptr)
{
clif_displaymessage(fd, "Map not found.");
return -1;
}
else
{
- if (m >= 0 && map[m].flag.nowarpto
+ if (m != nullptr && m->flag.nowarpto
&& battle_config.any_warp_GM_min_level > pc_isGM(sd))
{
clif_displaymessage(fd,
@@ -4113,12 +4109,12 @@ int atcommand_charskpoint(const int fd, dumb_ptr<map_session_data>,
if ((pl_sd = map_nick2sd(character)) != NULL)
{
- new_skill_point = (int) pl_sd->status.skill_point + point;
+ new_skill_point = pl_sd->status.skill_point + point;
if (point > 0 && (point > 0x7FFF || new_skill_point > 0x7FFF)) // fix positiv overflow
new_skill_point = 0x7FFF;
else if (point < 0 && (point < -0x7FFF || new_skill_point < 0)) // fix negativ overflow
new_skill_point = 0;
- if (new_skill_point != (int) pl_sd->status.skill_point)
+ if (new_skill_point != pl_sd->status.skill_point)
{
pl_sd->status.skill_point = new_skill_point;
clif_updatestatus(pl_sd, SP::SKILLPOINT);
@@ -4167,12 +4163,12 @@ int atcommand_charstpoint(const int fd, dumb_ptr<map_session_data>,
if ((pl_sd = map_nick2sd(character)) != NULL)
{
- new_status_point = (int) pl_sd->status.status_point + point;
+ new_status_point = pl_sd->status.status_point + point;
if (point > 0 && (point > 0x7FFF || new_status_point > 0x7FFF)) // fix positiv overflow
new_status_point = 0x7FFF;
else if (point < 0 && (point < -0x7FFF || new_status_point < 0)) // fix negativ overflow
new_status_point = 0;
- if (new_status_point != (int) pl_sd->status.status_point)
+ if (new_status_point != pl_sd->status.status_point)
{
pl_sd->status.status_point = new_status_point;
clif_updatestatus(pl_sd, SP::STATUSPOINT);
@@ -4257,7 +4253,7 @@ int atcommand_recallall(const int fd, dumb_ptr<map_session_data> sd,
{
int count;
- if (sd->bl_m >= 0 && map[sd->bl_m].flag.nowarpto
+ if (sd->bl_m != nullptr && sd->bl_m->flag.nowarpto
&& battle_config.any_warp_GM_min_level > pc_isGM(sd))
{
clif_displaymessage(fd,
@@ -4277,7 +4273,7 @@ int atcommand_recallall(const int fd, dumb_ptr<map_session_data> sd,
&& pc_isGM(sd) >= pc_isGM(pl_sd))
{
// you can recall only lower or same level
- if (pl_sd->bl_m >= 0 && map[pl_sd->bl_m].flag.nowarp
+ if (pl_sd->bl_m != nullptr && pl_sd->bl_m->flag.nowarp
&& battle_config.any_warp_GM_min_level > pc_isGM(sd))
count++;
else
@@ -4317,7 +4313,7 @@ int atcommand_partyrecall(const int fd, dumb_ptr<map_session_data> sd,
return -1;
}
- if (sd->bl_m >= 0 && map[sd->bl_m].flag.nowarpto
+ if (sd->bl_m != nullptr && sd->bl_m->flag.nowarpto
&& battle_config.any_warp_GM_min_level > pc_isGM(sd))
{
clif_displaymessage(fd,
@@ -4338,7 +4334,7 @@ int atcommand_partyrecall(const int fd, dumb_ptr<map_session_data> sd,
&& sd->status.account_id != pl_sd->status.account_id
&& pl_sd->status.party_id == p->party_id)
{
- if (pl_sd->bl_m >= 0 && map[pl_sd->bl_m].flag.nowarp
+ if (pl_sd->bl_m != nullptr && pl_sd->bl_m->flag.nowarp
&& battle_config.any_warp_GM_min_level > pc_isGM(sd))
count++;
else
@@ -4448,7 +4444,7 @@ int atcommand_mapinfo(const int fd, dumb_ptr<map_session_data> sd,
dumb_ptr<npc_data> nd = NULL;
char map_name[100];
const char *direction = NULL;
- int m_id, list = 0;
+ int list = 0;
memset(map_name, '\0', sizeof(map_name));
@@ -4466,7 +4462,8 @@ int atcommand_mapinfo(const int fd, dumb_ptr<map_session_data> sd,
if (strstr(map_name, ".gat") == NULL && strstr(map_name, ".afm") == NULL && strlen(map_name) < 13) // 16 - 4 (.gat)
strcat(map_name, ".gat");
- if ((m_id = map_mapname2mapid(map_name)) < 0)
+ map_local *m_id = map_mapname2mapid(map_name);
+ if (m_id != nullptr)
{
clif_displaymessage(fd, "Map not found.");
return -1;
@@ -4475,38 +4472,38 @@ int atcommand_mapinfo(const int fd, dumb_ptr<map_session_data> sd,
clif_displaymessage(fd, "------ Map Info ------");
std::string output = STRPRINTF("Map Name: %s", map_name);
clif_displaymessage(fd, output);
- output = STRPRINTF("Players In Map: %d", map[m_id].users);
+ output = STRPRINTF("Players In Map: %d", m_id->users);
clif_displaymessage(fd, output);
- output = STRPRINTF("NPCs In Map: %d", map[m_id].npc_num);
+ output = STRPRINTF("NPCs In Map: %d", m_id->npc_num);
clif_displaymessage(fd, output);
clif_displaymessage(fd, "------ Map Flags ------");
output = STRPRINTF("Player vs Player: %s | No Party: %s",
- (map[m_id].flag.pvp) ? "True" : "False",
- (map[m_id].flag.pvp_noparty) ? "True" : "False");
+ (m_id->flag.pvp) ? "True" : "False",
+ (m_id->flag.pvp_noparty) ? "True" : "False");
clif_displaymessage(fd, output);
output = STRPRINTF("No Dead Branch: %s",
- (map[m_id].flag.nobranch) ? "True" : "False");
+ (m_id->flag.nobranch) ? "True" : "False");
clif_displaymessage(fd, output);
output = STRPRINTF("No Memo: %s",
- (map[m_id].flag.nomemo) ? "True" : "False");
+ (m_id->flag.nomemo) ? "True" : "False");
clif_displaymessage(fd, output);
output = STRPRINTF("No Penalty: %s",
- (map[m_id].flag.nopenalty) ? "True" : "False");
+ (m_id->flag.nopenalty) ? "True" : "False");
clif_displaymessage(fd, output);
output = STRPRINTF("No Return: %s",
- (map[m_id].flag.noreturn) ? "True" : "False");
+ (m_id->flag.noreturn) ? "True" : "False");
clif_displaymessage(fd, output);
output = STRPRINTF("No Save: %s",
- (map[m_id].flag.nosave) ? "True" : "False");
+ (m_id->flag.nosave) ? "True" : "False");
clif_displaymessage(fd, output);
output = STRPRINTF("No Teleport: %s",
- (map[m_id].flag.noteleport) ? "True" : "False");
+ (m_id->flag.noteleport) ? "True" : "False");
clif_displaymessage(fd, output);
output = STRPRINTF("No Monster Teleport: %s",
- (map[m_id].flag.monster_noteleport) ? "True" : "False");
+ (m_id->flag.monster_noteleport) ? "True" : "False");
clif_displaymessage(fd, output);
output = STRPRINTF("No Zeny Penalty: %s",
- (map[m_id].flag.nozenypenalty) ? "True" : "False");
+ (m_id->flag.nozenypenalty) ? "True" : "False");
clif_displaymessage(fd, output);
switch (list)
@@ -4533,9 +4530,9 @@ int atcommand_mapinfo(const int fd, dumb_ptr<map_session_data> sd,
break;
case 2:
clif_displaymessage(fd, "----- NPCs in Map -----");
- for (int i = 0; i < map[m_id].npc_num;)
+ for (int i = 0; i < m_id->npc_num;)
{
- nd = map[m_id].npc[i];
+ nd = m_id->npc[i];
switch (nd->dir)
{
case DIR::S:
@@ -4845,249 +4842,6 @@ int atcommand_localbroadcast(const int fd, dumb_ptr<map_session_data> sd,
}
/*==========================================
- * @ignorelist by [Yor]
- *------------------------------------------
- */
-int atcommand_ignorelist(const int fd, dumb_ptr<map_session_data> sd,
- const char *, const char *)
-{
- int count;
- int i;
-
- count = 0;
- for (i = 0; i < (int)(sizeof(sd->ignore) / sizeof(sd->ignore[0])); i++)
- if (sd->ignore[i].name[0])
- count++;
-
- if (sd->ignoreAll == 0)
- if (count == 0)
- clif_displaymessage(fd, "You accept any wisp (no wisper is refused).");
- else
- {
- std::string output = STRPRINTF(
- "You accept any wisp, except thoses from %d player (s):",
- count);
- clif_displaymessage(fd, output);
- }
- else if (count == 0)
- clif_displaymessage(fd, "You refuse all wisps (no specifical wisper is refused).");
- else
- {
- std::string output = STRPRINTF(
- "You refuse all wisps, AND refuse wisps from %d player (s):",
- count);
- clif_displaymessage(fd, output);
- }
-
- if (count > 0)
- for (i = 0; i < (int)(sizeof(sd->ignore) / sizeof(sd->ignore[0]));
- i++)
- if (sd->ignore[i].name[0])
- clif_displaymessage(fd, sd->ignore[i].name);
-
- return 0;
-}
-
-/*==========================================
- * @charignorelist <player_name> by [Yor]
- *------------------------------------------
- */
-int atcommand_charignorelist(const int fd, dumb_ptr<map_session_data>,
- const char *, const char *message)
-{
- char character[100];
- dumb_ptr<map_session_data> pl_sd;
- int count;
- int i;
-
- memset(character, '\0', sizeof(character));
-
- if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1)
- {
- clif_displaymessage(fd,
- "Please, enter a player name (usage: @charignorelist <char name>).");
- return -1;
- }
-
- if ((pl_sd = map_nick2sd(character)) != NULL)
- {
- count = 0;
- for (i = 0;
- i < (int)(sizeof(pl_sd->ignore) / sizeof(pl_sd->ignore[0]));
- i++)
- if (pl_sd->ignore[i].name[0])
- count++;
-
- if (pl_sd->ignoreAll == 0)
- if (count == 0)
- {
- std::string output = STRPRINTF(
- "'%s' accept any wisp (no wisper is refused).",
- pl_sd->status.name);
- clif_displaymessage(fd, output);
- }
- else
- {
- std::string output = STRPRINTF(
- "'%s' accept any wisp, except thoses from %d player(s):",
- pl_sd->status.name, count);
- clif_displaymessage(fd, output);
- }
- else if (count == 0)
- {
- std::string output = STRPRINTF(
- "'%s' refuse all wisps (no specifical wisper is refused).",
- pl_sd->status.name);
- clif_displaymessage(fd, output);
- }
- else
- {
- std::string output = STRPRINTF(
- "'%s' refuse all wisps, AND refuse wisps from %d player(s):",
- pl_sd->status.name, count);
- clif_displaymessage(fd, output);
- }
-
- if (count > 0)
- for (i = 0;
- i < (int)(sizeof(pl_sd->ignore) / sizeof(pl_sd->ignore[0]));
- i++)
- if (pl_sd->ignore[i].name[0])
- clif_displaymessage(fd, pl_sd->ignore[i].name);
-
- }
- else
- {
- clif_displaymessage(fd, "Character not found.");
- return -1;
- }
-
- return 0;
-}
-
-/*==========================================
- * @inall <player_name> by [Yor]
- *------------------------------------------
- */
-int atcommand_inall(const int fd, dumb_ptr<map_session_data> sd,
- const char *, const char *message)
-{
- char character[100];
- dumb_ptr<map_session_data> pl_sd;
-
- memset(character, '\0', sizeof(character));
-
- if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1)
- {
- clif_displaymessage(fd,
- "Please, enter a player name (usage: @inall <char name>).");
- return -1;
- }
-
- if ((pl_sd = map_nick2sd(character)) != NULL)
- {
- if (pc_isGM(sd) >= pc_isGM(pl_sd))
- { // you can change wisp option only to lower or same level
- if (pl_sd->ignoreAll == 0)
- {
- std::string output = STRPRINTF(
- "'%s' already accepts all wispers.",
- pl_sd->status.name);
- clif_displaymessage(fd, output);
- return -1;
- }
- else
- {
- pl_sd->ignoreAll = 0;
- std::string output = STRPRINTF(
- "'%s' now accepts all wispers.",
- pl_sd->status.name);
- clif_displaymessage(fd, output);
- // message to player
- clif_displaymessage(pl_sd->fd, "A GM has authorised all wispers for you.");
- WFIFOW(pl_sd->fd, 0) = 0x0d2; // R 00d2 <type>.B <fail>.B: type: 0: deny, 1: allow, fail: 0: success, 1: fail
- WFIFOB(pl_sd->fd, 2) = 1;
- WFIFOB(pl_sd->fd, 3) = 0; // success
- WFIFOSET(pl_sd->fd, 4); // packet_len_table[0x0d2]
- }
- }
- else
- {
- clif_displaymessage(fd, "Your GM level don't authorise you to do this action on this player.");
- return -1;
- }
- }
- else
- {
- clif_displaymessage(fd, "Character not found.");
- return -1;
- }
-
- return 0;
-}
-
-/*==========================================
- * @exall <player_name> by [Yor]
- *------------------------------------------
- */
-int atcommand_exall(const int fd, dumb_ptr<map_session_data> sd,
- const char *, const char *message)
-{
- char character[100];
- dumb_ptr<map_session_data> pl_sd;
-
- memset(character, '\0', sizeof(character));
-
- if (!message || !*message || sscanf(message, "%99[^\n]", character) < 1)
- {
- clif_displaymessage(fd,
- "Please, enter a player name (usage: @exall <char name>).");
- return -1;
- }
-
- if ((pl_sd = map_nick2sd(character)) != NULL)
- {
- if (pc_isGM(sd) >= pc_isGM(pl_sd))
- { // you can change wisp option only to lower or same level
- if (pl_sd->ignoreAll == 1)
- {
- std::string output = STRPRINTF(
- "'%s' already blocks all wispers.",
- pl_sd->status.name);
- clif_displaymessage(fd, output);
- return -1;
- }
- else
- {
- pl_sd->ignoreAll = 1;
- std::string output = STRPRINTF(
- "'%s' blocks now all wispers.",
- pl_sd->status.name);
- clif_displaymessage(fd, output);
- // message to player
- clif_displaymessage(pl_sd->fd, "A GM has blocked all wispers for you.");
- WFIFOW(pl_sd->fd, 0) = 0x0d2; // R 00d2 <type>.B <fail>.B: type: 0: deny, 1: allow, fail: 0: success, 1: fail
- WFIFOB(pl_sd->fd, 2) = 0;
- WFIFOB(pl_sd->fd, 3) = 0; // success
- WFIFOSET(pl_sd->fd, 4); // packet_len_table[0x0d2]
- }
- }
- else
- {
- clif_displaymessage(fd, "Your GM level don't authorise you to do this action on this player.");
- return -1;
- }
- }
- else
- {
- clif_displaymessage(fd, "Character not found.");
- return -1;
- }
-
- return 0;
-}
-
-/*==========================================
* @email <actual@email> <new@email> by [Yor]
*------------------------------------------
*/
@@ -5901,10 +5655,10 @@ int atcommand_rain(const int, dumb_ptr<map_session_data> sd,
int effno = 0;
effno = 161;
nullpo_retr(-1, sd);
- if (effno < 0 || map[sd->bl_m].flag.rain)
+ if (effno < 0 || sd->bl_m->flag.rain)
return -1;
- map[sd->bl_m].flag.rain = 1;
+ sd->bl_m->flag.rain = 1;
clif_specialeffect(sd, effno, 2);
return 0;
}
@@ -5919,10 +5673,10 @@ int atcommand_snow(const int, dumb_ptr<map_session_data> sd,
int effno = 0;
effno = 162;
nullpo_retr(-1, sd);
- if (effno < 0 || map[sd->bl_m].flag.snow)
+ if (effno < 0 || sd->bl_m->flag.snow)
return -1;
- map[sd->bl_m].flag.snow = 1;
+ sd->bl_m->flag.snow = 1;
clif_specialeffect(sd, effno, 2);
return 0;
}
@@ -5937,10 +5691,10 @@ int atcommand_sakura(const int, dumb_ptr<map_session_data> sd,
int effno = 0;
effno = 163;
nullpo_retr(-1, sd);
- if (effno < 0 || map[sd->bl_m].flag.sakura)
+ if (effno < 0 || sd->bl_m->flag.sakura)
return -1;
- map[sd->bl_m].flag.sakura = 1;
+ sd->bl_m->flag.sakura = 1;
clif_specialeffect(sd, effno, 2);
return 0;
}
@@ -5955,10 +5709,10 @@ int atcommand_fog(const int, dumb_ptr<map_session_data> sd,
int effno = 0;
effno = 233;
nullpo_retr(-1, sd);
- if (effno < 0 || map[sd->bl_m].flag.fog)
+ if (effno < 0 || sd->bl_m->flag.fog)
return -1;
- map[sd->bl_m].flag.fog = 1;
+ sd->bl_m->flag.fog = 1;
clif_specialeffect(sd, effno, 2);
return 0;
@@ -5974,10 +5728,10 @@ int atcommand_leaves(const int, dumb_ptr<map_session_data> sd,
int effno = 0;
effno = 333;
nullpo_retr(-1, sd);
- if (effno < 0 || map[sd->bl_m].flag.leaves)
+ if (effno < 0 || sd->bl_m->flag.leaves)
return -1;
- map[sd->bl_m].flag.leaves = 1;
+ sd->bl_m->flag.leaves = 1;
clif_specialeffect(sd, effno, 2);
return 0;
}
@@ -6077,7 +5831,8 @@ int atcommand_adjgmlvl(const int fd, dumb_ptr<map_session_data>,
dumb_ptr<map_session_data> pl_sd;
if (!message || !*message
- || sscanf(message, "%d %s", &newlev, user) != 2)
+ || sscanf(message, "%d %s", &newlev, user) != 2
+ || newlev < 0 || newlev > 99)
{
clif_displaymessage(fd, "usage: @adjgmlvl <lvl> <user>.");
return -1;
@@ -6301,21 +6056,21 @@ int atcommand_jump_iterate(const int fd, dumb_ptr<map_session_data> sd,
pl_sd = get_start();
}
- if (pl_sd->bl_m >= 0 && map[pl_sd->bl_m].flag.nowarpto
+ if (pl_sd->bl_m != nullptr && pl_sd->bl_m->flag.nowarpto
&& battle_config.any_warp_GM_min_level > pc_isGM(sd))
{
clif_displaymessage(fd,
"You are not authorised to warp you to the map of this player.");
return -1;
}
- if (sd->bl_m >= 0 && map[sd->bl_m].flag.nowarp
+ if (sd->bl_m != nullptr && sd->bl_m->flag.nowarp
&& battle_config.any_warp_GM_min_level > pc_isGM(sd))
{
clif_displaymessage(fd,
"You are not authorised to warp you from your actual map.");
return -1;
}
- pc_setpos(sd, map[pl_sd->bl_m].name, pl_sd->bl_x, pl_sd->bl_y, BeingRemoveWhy::WARPED);
+ pc_setpos(sd, pl_sd->bl_m->name, pl_sd->bl_x, pl_sd->bl_y, BeingRemoveWhy::WARPED);
std::string output = STRPRINTF("Jump to %s", pl_sd->status.name);
clif_displaymessage(fd, output);
@@ -6395,7 +6150,7 @@ int atcommand_skillpool_info(const int fd, dumb_ptr<map_session_data>,
for (i = 0; i < skill_pool_skills_size; ++i)
{
- const char *name = skill_name(skill_pool_skills[i]);
+ const std::string& name = skill_name(skill_pool_skills[i]);
int lvl = pl_sd->status.skill[skill_pool_skills[i]].lv;
if (lvl)
@@ -6522,7 +6277,7 @@ int atcommand_ipcheck(const int fd, dumb_ptr<map_session_data>,
return -1;
}
- if (getpeername(pl_sd->fd, (struct sockaddr *)&sai, &sa_len))
+ if (getpeername(pl_sd->fd, reinterpret_cast<struct sockaddr *>(&sai), &sa_len))
{
clif_displaymessage(fd,
"Guru Meditation Error: getpeername() failed");
@@ -6541,7 +6296,7 @@ int atcommand_ipcheck(const int fd, dumb_ptr<map_session_data>,
pl_sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(session[i]->session_data.get()));
if (pl_sd && pl_sd->state.auth)
{
- if (getpeername(pl_sd->fd, (struct sockaddr *)&sai, &sa_len))
+ if (getpeername(pl_sd->fd, reinterpret_cast<struct sockaddr *>(&sai), &sa_len))
continue;
// Is checking GM levels really needed here?
diff --git a/src/map/atcommand.hpp b/src/map/atcommand.hpp
index 7033972..d81f04d 100644
--- a/src/map/atcommand.hpp
+++ b/src/map/atcommand.hpp
@@ -13,6 +13,6 @@ int atcommand_config_read(const char *cfgName);
void log_atcommand(dumb_ptr<map_session_data> sd, const_string cmd);
// only used by map.cpp
-extern char *gm_logfile_name;
+extern std::string gm_logfile_name;
#endif // ATCOMMAND_HPP
diff --git a/src/map/battle.cpp b/src/map/battle.cpp
index 8e7b174..81e606f 100644
--- a/src/map/battle.cpp
+++ b/src/map/battle.cpp
@@ -12,6 +12,7 @@
#include "itemdb.hpp"
#include "map.hpp"
#include "mob.hpp"
+#include "path.hpp"
#include "pc.hpp"
#include "skill.hpp"
@@ -2039,8 +2040,8 @@ ATK battle_weapon_attack(dumb_ptr<block_list> src, dumb_ptr<block_list> target,
&& bool(sd->status.inventory[weapon_index].equip & EPOS::WEAPON))
weapon = sd->inventory_data[weapon_index]->nameid;
- MAP_LOG("PC%d %d:%d,%d WPNDMG %s%d %d FOR %d WPN %d",
- sd->status.char_id, src->bl_m, src->bl_x, src->bl_y,
+ MAP_LOG("PC%d %s:%d,%d WPNDMG %s%d %d FOR %d WPN %d",
+ sd->status.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->as_player()-> status.char_id
@@ -2052,8 +2053,8 @@ ATK battle_weapon_attack(dumb_ptr<block_list> src, dumb_ptr<block_list> target,
if (target->bl_type == BL::PC)
{
dumb_ptr<map_session_data> sd2 = target->as_player();
- MAP_LOG("PC%d %d:%d,%d WPNINJURY %s%d %d FOR %d",
- sd2->status.char_id, target->bl_m, target->bl_x, target->bl_y,
+ MAP_LOG("PC%d %s:%d,%d WPNINJURY %s%d %d FOR %d",
+ sd2->status.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->as_player()->status.char_id
@@ -2226,12 +2227,12 @@ int battle_check_target(dumb_ptr<block_list> src, dumb_ptr<block_list> target,
if (ss->bl_type == BL::PC && target->bl_type == BL::PC)
{ // 両方PVPモードなら否定(敵)
- if (map[ss->bl_m].flag.pvp
+ if (ss->bl_m->flag.pvp
|| pc_iskiller(ss->as_player(), target->as_player()))
{ // [MouseJstr]
if (battle_config.pk_mode)
return 1; // prevent novice engagement in pk_mode [Valaris]
- else if (map[ss->bl_m].flag.pvp_noparty && s_p > 0 && t_p > 0
+ else if (ss->bl_m->flag.pvp_noparty && s_p > 0 && t_p > 0
&& s_p == t_p)
return 1;
return 0;
@@ -2313,7 +2314,7 @@ int battle_config_read(const char *cfgName)
battle_config.defnotenemy = 1;
battle_config.random_monster_checklv = 1;
battle_config.attr_recover = 1;
- battle_config.flooritem_lifetime = (int)std::chrono::duration_cast<std::chrono::milliseconds>(LIFETIME_FLOORITEM).count();
+ battle_config.flooritem_lifetime = std::chrono::duration_cast<std::chrono::milliseconds>(LIFETIME_FLOORITEM).count();
battle_config.item_auto_get = 0;
battle_config.drop_pickup_safety_zone = 20;
battle_config.item_first_get_time = 3000;
@@ -2341,7 +2342,6 @@ int battle_config_read(const char *cfgName)
battle_config.wp_rate = 100;
battle_config.pp_rate = 100;
battle_config.monster_active_enable = 1;
- battle_config.monster_loot_type = 0;
battle_config.mob_skill_use = 1;
battle_config.mob_count_rate = 100;
battle_config.quest_skill_learn = 0;
@@ -2524,7 +2524,6 @@ int battle_config_read(const char *cfgName)
{"weapon_produce_rate", &battle_config.wp_rate},
{"potion_produce_rate", &battle_config.pp_rate},
{"monster_active_enable", &battle_config.monster_active_enable},
- {"monster_loot_type", &battle_config.monster_loot_type},
{"mob_skill_use", &battle_config.mob_skill_use},
{"mob_count_rate", &battle_config.mob_count_rate},
{"quest_skill_learn", &battle_config.quest_skill_learn},
@@ -2666,7 +2665,7 @@ int battle_config_read(const char *cfgName)
if (--count == 0)
{
if (static_cast<interval_t>(battle_config.flooritem_lifetime) < std::chrono::seconds(1))
- battle_config.flooritem_lifetime = (int)std::chrono::duration_cast<std::chrono::milliseconds>(LIFETIME_FLOORITEM).count();
+ 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;
else if (battle_config.restart_hp_rate > 100)
diff --git a/src/map/battle.hpp b/src/map/battle.hpp
index 8b7c1bd..168cf60 100644
--- a/src/map/battle.hpp
+++ b/src/map/battle.hpp
@@ -132,7 +132,6 @@ extern struct Battle_Config
int wp_rate;
int pp_rate;
int monster_active_enable;
- int monster_loot_type;
int mob_skill_use;
int mob_count_rate;
int quest_skill_learn;
diff --git a/src/map/battle.t.hpp b/src/map/battle.t.hpp
index e374298..f730cc5 100644
--- a/src/map/battle.t.hpp
+++ b/src/map/battle.t.hpp
@@ -25,6 +25,10 @@ ENUM_BITWISE_OPERATORS(BF)
}
using e::BF;
+namespace e
+{
+// not actually an enum, but put in the namespace to hide the operators
+// from non-ADL.
struct BCT
{
// former representation:
@@ -56,6 +60,8 @@ constexpr
bool operator == (BCT l, BCT r) { return l.lo == r.lo && l.mid == r.mid && l.classic == r.classic && l.level == r.level && l.unused == r.unused; }
constexpr
bool operator != (BCT l, BCT r) { return !(l == r); }
+} // namespace e
+using e::BCT;
constexpr
BCT BCT_NOENEMY = {0x00, 0x00, 0x0, 0x0, 0x00};
diff --git a/src/map/chrif.cpp b/src/map/chrif.cpp
index aaa727e..ebed281 100644
--- a/src/map/chrif.cpp
+++ b/src/map/chrif.cpp
@@ -145,14 +145,17 @@ int chrif_connect(int fd)
static
int chrif_sendmap(int fd)
{
- int i;
+ int i = 0;
WFIFOW(fd, 0) = 0x2afa;
- for (i = 0; i < map_num; i++)
- if (map[i].alias[0] != '\0') // [MouseJstr] map aliasing
- memcpy(WFIFOP(fd, 4 + i * 16), map[i].alias, 16);
- else
- memcpy(WFIFOP(fd, 4 + i * 16), map[i].name, 16);
+ for (auto& pair : maps_db)
+ {
+ map_abstract *ma = pair.second.get();
+ if (!ma->gat)
+ continue;
+ memcpy(WFIFOP(fd, 4 + i * 16), ma->name, 16);
+ i++;
+ }
WFIFOW(fd, 2) = 4 + i * 16;
WFIFOSET(fd, WFIFOW(fd, 2));
@@ -176,7 +179,7 @@ int chrif_recvmap(int fd)
port = RFIFOW(fd, 8);
for (i = 10, j = 0; i < RFIFOW(fd, 2); i += 16, j++)
{
- map_setipport((const char *)RFIFOP(fd, i), ip, port);
+ map_setipport(static_cast<const char *>(RFIFOP(fd, i)), ip, port);
// if (battle_config.etc_log)
// PRINTF("recv map %d %s\n", j, RFIFOP(fd,i));
}
@@ -241,7 +244,7 @@ int chrif_changemapserverack(int fd)
pc_authfail(sd->fd);
return 0;
}
- clif_changemapserver(sd, (const char *)RFIFOP(fd, 18), RFIFOW(fd, 34),
+ clif_changemapserver(sd, static_cast<const char *>(RFIFOP(fd, 18)), RFIFOW(fd, 34),
RFIFOW(fd, 36), in_addr{RFIFOL(fd, 38)}, RFIFOW(fd, 42));
return 0;
@@ -989,9 +992,8 @@ void ladmin_itemfrob_c2(dumb_ptr<block_list> bl, int source_id, int dest_id)
case BL::MOB:
{
dumb_ptr<mob_data> mob = bl->as_mob();
- int i;
- for (i = 0; i < mob->lootitem_count; i++)
- FIX(mob->lootitem[i]);
+ for (struct item& itm : mob->lootitemv)
+ FIX(itm);
break;
}
@@ -1017,10 +1019,11 @@ void ladmin_itemfrob(int fd)
{
int source_id = RFIFOL(fd, 2);
int dest_id = RFIFOL(fd, 6);
- dumb_ptr<block_list> bl = (dumb_ptr<block_list>) map_get_first_session();
+ dumb_ptr<block_list> bl = map_get_first_session();
// flooritems
- map_foreachobject(std::bind(ladmin_itemfrob_c, ph::_1, source_id, dest_id), BL::NUL /* any object */);
+ map_foreachobject(std::bind(ladmin_itemfrob_c, ph::_1, source_id, dest_id),
+ BL::NUL /* any object */);
// player characters (and, hopefully, mobs)
while (bl->bl_next)
@@ -1097,7 +1100,7 @@ void chrif_parse(int fd)
case 0x2afd:
pc_authok(RFIFOL(fd, 4), RFIFOL(fd, 8),
static_cast<time_t>(RFIFOL(fd, 12)), RFIFOW(fd, 16),
- (const struct mmo_charstatus *) RFIFOP(fd, 18));
+ static_cast<const struct mmo_charstatus *>(RFIFOP(fd, 18)));
break;
case 0x2afe:
pc_authfail(RFIFOL(fd, 2));
@@ -1115,7 +1118,7 @@ void chrif_parse(int fd)
chrif_changemapserverack(fd);
break;
case 0x2b09:
- map_addchariddb(RFIFOL(fd, 2), (const char *)RFIFOP(fd, 6));
+ map_addchariddb(RFIFOL(fd, 2), static_cast<const char *>(RFIFOP(fd, 6)));
break;
case 0x2b0b:
chrif_changedgm(fd);
diff --git a/src/map/clif.cpp b/src/map/clif.cpp
index fbba044..f20c887 100644
--- a/src/map/clif.cpp
+++ b/src/map/clif.cpp
@@ -203,9 +203,16 @@ static
void clif_emotion_towards(dumb_ptr<block_list> bl,
dumb_ptr<block_list> target, int type);
+
+enum class ChatType
+{
+ Party,
+ Whisper,
+ Global,
+};
+
static
-char *clif_validate_chat(dumb_ptr<map_session_data> sd, int type,
- const char **message, size_t *message_len);
+std::string clif_validate_chat(dumb_ptr<map_session_data> sd, ChatType type);
/*==========================================
* clif_sendでSendWho::AREA*指定時用
@@ -337,13 +344,17 @@ int clif_send(const uint8_t *buf, int len, dumb_ptr<block_list> bl, SendWho type
case SendWho::AREA:
case SendWho::AREA_WOS:
map_foreachinarea(std::bind(clif_send_sub, ph::_1, buf, len, 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);
+ 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),
- 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);
+ 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::PARTY_AREA: // 同じ画面内の全パーティーメンバに送信
@@ -912,15 +923,15 @@ int clif_spawnpc(dumb_ptr<map_session_data> sd)
WBUFW(buf, 51) = 0;
clif_send(buf, clif_parse_func_table[0x1d9].len, sd, SendWho::AREA_WOS);
- if (map[sd->bl_m].flag.snow)
+ if (sd->bl_m->flag.snow)
clif_specialeffect(sd, 162, 1);
- if (map[sd->bl_m].flag.fog)
+ if (sd->bl_m->flag.fog)
clif_specialeffect(sd, 233, 1);
- if (map[sd->bl_m].flag.sakura)
+ if (sd->bl_m->flag.sakura)
clif_specialeffect(sd, 163, 1);
- if (map[sd->bl_m].flag.leaves)
+ if (sd->bl_m->flag.leaves)
clif_specialeffect(sd, 333, 1);
- if (map[sd->bl_m].flag.rain)
+ if (sd->bl_m->flag.rain)
clif_specialeffect(sd, 161, 1);
// clif_changelook_accessories(sd, NULL);
@@ -1281,7 +1292,7 @@ int clif_scriptmes(dumb_ptr<map_session_data> sd, int npcid, const char *mes)
WFIFOW(fd, 0) = 0xb4;
WFIFOW(fd, 2) = strlen(mes) + 9;
WFIFOL(fd, 4) = npcid;
- strcpy((char *)WFIFOP(fd, 8), mes);
+ strcpy(static_cast<char *>(WFIFOP(fd, 8)), mes);
WFIFOSET(fd, WFIFOW(fd, 2));
return 0;
@@ -1337,7 +1348,7 @@ int clif_scriptmenu(dumb_ptr<map_session_data> sd, int npcid, const char *mes)
WFIFOW(fd, 0) = 0xb7;
WFIFOW(fd, 2) = strlen(mes) + 8;
WFIFOL(fd, 4) = npcid;
- strcpy((char *)WFIFOP(fd, 8), mes);
+ strcpy(static_cast<char *>(WFIFOP(fd, 8)), mes);
WFIFOSET(fd, WFIFOW(fd, 2));
return 0;
@@ -1469,7 +1480,7 @@ int clif_additem(dumb_ptr<map_session_data> sd, int n, int amount, PickupFail fa
WFIFOB(fd, 10) = sd->status.inventory[n].refine;
if (sd->status.inventory[n].card[0] == 0x00ff
|| sd->status.inventory[n].card[0] == 0x00fe
- || sd->status.inventory[n].card[0] == (short) 0xff00)
+ || sd->status.inventory[n].card[0] == static_cast<short>(0xff00))
{
WFIFOW(fd, 11) = sd->status.inventory[n].card[0];
WFIFOW(fd, 13) = sd->status.inventory[n].card[1];
@@ -1617,7 +1628,7 @@ int clif_equiplist(dumb_ptr<map_session_data> sd)
WFIFOB(fd, n * 20 + 15) = sd->status.inventory[i].refine;
if (sd->status.inventory[i].card[0] == 0x00ff
|| sd->status.inventory[i].card[0] == 0x00fe
- || sd->status.inventory[i].card[0] == (short) 0xff00)
+ || sd->status.inventory[i].card[0] == static_cast<short>(0xff00))
{
WFIFOW(fd, n * 20 + 16) = sd->status.inventory[i].card[0];
WFIFOW(fd, n * 20 + 18) = sd->status.inventory[i].card[1];
@@ -1742,7 +1753,7 @@ int clif_storageequiplist(dumb_ptr<map_session_data> sd, struct storage *stor)
WFIFOB(fd, n * 20 + 15) = stor->storage_[i].refine;
if (stor->storage_[i].card[0] == 0x00ff
|| stor->storage_[i].card[0] == 0x00fe
- || stor->storage_[i].card[0] == (short) 0xff00)
+ || stor->storage_[i].card[0] == static_cast<short>(0xff00))
{
WFIFOW(fd, n * 20 + 16) = stor->storage_[i].card[0];
WFIFOW(fd, n * 20 + 18) = stor->storage_[i].card[1];
@@ -2312,7 +2323,7 @@ int clif_traderequest(dumb_ptr<map_session_data> sd, const char *name)
fd = sd->fd;
WFIFOW(fd, 0) = 0xe5;
- strcpy((char *)WFIFOP(fd, 2), name);
+ strcpy(static_cast<char *>(WFIFOP(fd, 2)), name);
WFIFOSET(fd, clif_parse_func_table[0xe5].len);
return 0;
@@ -2378,7 +2389,7 @@ int clif_tradeadditem(dumb_ptr<map_session_data> sd,
WFIFOB(fd, 10) = sd->status.inventory[index].refine; //refine
if (sd->status.inventory[index].card[0] == 0x00ff
|| sd->status.inventory[index].card[0] == 0x00fe
- || sd->status.inventory[index].card[0] == (short) 0xff00)
+ || sd->status.inventory[index].card[0] == static_cast<short>(0xff00))
{
WFIFOW(fd, 11) = sd->status.inventory[index].card[0]; //card (4w)
WFIFOW(fd, 13) = sd->status.inventory[index].card[1]; //card (4w)
@@ -2541,7 +2552,7 @@ int clif_storageitemadded(dumb_ptr<map_session_data> sd, struct storage *stor,
WFIFOB(fd, 12) = stor->storage_[index].refine; //refine
if (stor->storage_[index].card[0] == 0x00ff
|| stor->storage_[index].card[0] == 0x00fe
- || stor->storage_[index].card[0] == (short) 0xff00)
+ || stor->storage_[index].card[0] == static_cast<short>(0xff00))
{
WFIFOW(fd, 13) = stor->storage_[index].card[0]; //card (4w)
WFIFOW(fd, 15) = stor->storage_[index].card[1]; //card (4w)
@@ -3790,7 +3801,7 @@ void clif_parse_LoadEndAck(int, dumb_ptr<map_session_data> sd)
if (!battle_config.pk_mode)
sd->pvp_timer.cancel();
- if (map[sd->bl_m].flag.pvp)
+ if (sd->bl_m->flag.pvp)
{
if (!battle_config.pk_mode)
{
@@ -3832,9 +3843,11 @@ void clif_parse_LoadEndAck(int, dumb_ptr<map_session_data> sd)
// clif_changelook_accessories(sd, NULL);
- map_foreachinarea(std::bind(clif_getareachar, ph::_1, sd), sd->bl_m, sd->bl_x - AREA_SIZE,
- sd->bl_y - AREA_SIZE, sd->bl_x + AREA_SIZE,
- sd->bl_y + AREA_SIZE, BL::NUL);
+ map_foreachinarea(std::bind(clif_getareachar, ph::_1, sd),
+ sd->bl_m,
+ sd->bl_x - AREA_SIZE, sd->bl_y - AREA_SIZE,
+ sd->bl_x + AREA_SIZE, sd->bl_y + AREA_SIZE,
+ BL::NUL);
}
/*==========================================
@@ -3998,7 +4011,7 @@ void clif_parse_GetCharNameRequest(int fd, dumb_ptr<map_session_data> sd)
case BL::NPC:
memcpy(WFIFOP(fd, 6), bl->as_npc()->name, 24);
{
- char *start = (char *)WFIFOP(fd, 6);
+ char *start = static_cast<char *>(WFIFOP(fd, 6));
char *end = strchr(start, '#'); // [fate] elim hashed out/invisible names for the client
if (end)
while (*end)
@@ -4038,52 +4051,41 @@ void clif_parse_GetCharNameRequest(int fd, dumb_ptr<map_session_data> sd)
static
void clif_parse_GlobalMessage(int fd, dumb_ptr<map_session_data> sd)
{
- int msg_len = RFIFOW(fd, 2) - 4; /* Header(2) + length(2). */
- size_t message_len = 0;
- // sometimes uint8_t
- char *buf = NULL;
- const char *message = NULL; /* The message text only. */
-
nullpo_retv(sd);
- if (!(buf = clif_validate_chat(sd, 2, &message, &message_len)))
+ std::string mbuf = clif_validate_chat(sd, ChatType::Global);
+ if (mbuf.empty())
{
clif_displaymessage(fd, "Your message could not be sent.");
return;
}
- if (is_atcommand(fd, sd, message, 0)) //チャット禁止
- {
- free(buf);
+ if (is_atcommand(fd, sd, mbuf.c_str(), 0))
return;
- }
- if (!magic_message(sd, buf, msg_len))
+ if (!magic_message(sd, mbuf))
{
/* Don't send chat that results in an automatic ban. */
- if (tmw_CheckChatSpam(sd, message))
+ if (tmw_CheckChatSpam(sd, mbuf.c_str()))
{
- free(buf);
clif_displaymessage(fd, "Your message could not be sent.");
return;
}
/* It's not a spell/magic message, so send the message to others. */
- WBUFW(reinterpret_cast<uint8_t *>(buf), 0) = 0x8d;
- WBUFW(reinterpret_cast<uint8_t *>(buf), 2) = msg_len + 8; /* Header(2) + length(2) + ID(4). */
- WBUFL(reinterpret_cast<uint8_t *>(buf), 4) = sd->bl_id;
+ 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;
+ memcpy(WBUFP(sendbuf, 8), mbuf.data(), mbuf.size());
- // evil multiuse buffer!
- clif_send((const uint8_t *)buf, msg_len + 8, sd, SendWho::AREA_CHAT_WOC);
+ clif_send(sendbuf, mbuf.size() + 8, sd, SendWho::AREA_CHAT_WOC);
}
/* Send the message back to the speaker. */
memcpy(WFIFOP(fd, 0), RFIFOP(fd, 0), RFIFOW(fd, 2));
WFIFOW(fd, 0) = 0x8e;
WFIFOSET(fd, WFIFOW(fd, 2));
-
- free(buf);
- return;
}
int clif_message(dumb_ptr<block_list> bl, const char *msg)
@@ -4290,29 +4292,25 @@ void clif_parse_Restart(int fd, dumb_ptr<map_session_data> sd)
static
void clif_parse_Wis(int fd, dumb_ptr<map_session_data> sd)
{
- size_t message_len = 0;
- char *buf = NULL;
- const char *message = NULL; /* The message text only. */
dumb_ptr<map_session_data> dstsd = NULL;
nullpo_retv(sd);
- if (!(buf = clif_validate_chat(sd, 1, &message, &message_len)))
+ std::string mbuf = clif_validate_chat(sd, ChatType::Whisper);
+ if (mbuf.empty())
{
clif_displaymessage(fd, "Your message could not be sent.");
return;
}
- if (is_atcommand(fd, sd, message, 0))
+ if (is_atcommand(fd, sd, mbuf.c_str(), 0))
{
- free(buf);
return;
}
/* Don't send chat that results in an automatic ban. */
- if (tmw_CheckChatSpam(sd, message))
+ if (tmw_CheckChatSpam(sd, mbuf.c_str()))
{
- free(buf);
clif_displaymessage(fd, "Your message could not be sent.");
return;
}
@@ -4323,9 +4321,10 @@ void clif_parse_Wis(int fd, dumb_ptr<map_session_data> sd)
* conflict (for instance, "Test" versus "test"), the char-server must
* settle the discrepancy.
*/
- if (!(dstsd = map_nick2sd((const char *)RFIFOP(fd, 4)))
- || strcmp(dstsd->status.name, (const char *)RFIFOP(fd, 4)) != 0)
- intif_wis_message(sd, (const char *)RFIFOP(fd, 4), message, RFIFOW(fd, 2) - 28);
+ const char *tname = static_cast<const char *>(RFIFOP(fd, 4));
+ if (!(dstsd = map_nick2sd(tname))
+ || strcmp(dstsd->status.name, tname) != 0)
+ intif_wis_message(sd, tname, mbuf.c_str(), RFIFOW(fd, 2) - 28);
else
{
/* Refuse messages addressed to self. */
@@ -4336,28 +4335,10 @@ void clif_parse_Wis(int fd, dumb_ptr<map_session_data> sd)
}
else
{
- /* The target is ignoring all whispers. */
- if (dstsd->ignoreAll == 1)
- /* Ignored by target. */
- clif_wis_end(fd, 2);
- else
{
- int i;
- size_t end = sizeof(dstsd->ignore) / sizeof(dstsd->ignore[0]);
-
- /* See if the source player is being ignored. */
- for (i = 0; i < end; ++i)
- if (strcmp(dstsd->ignore[i].name, sd->status.name) == 0)
- {
- /* Ignored by target. */
- clif_wis_end(fd, 2);
- break;
- }
-
/* The player is not being ignored. */
- if (i == end)
{
- clif_wis_message(dstsd->fd, sd->status.name, message,
+ clif_wis_message(dstsd->fd, sd->status.name, mbuf.c_str(),
RFIFOW(fd, 2) - 28);
/* The whisper was sent successfully. */
clif_wis_end(fd, 0);
@@ -4365,8 +4346,6 @@ void clif_parse_Wis(int fd, dumb_ptr<map_session_data> sd)
}
}
}
-
- free(buf);
}
/*==========================================
@@ -4423,7 +4402,7 @@ void clif_parse_DropItem(int fd, dumb_ptr<map_session_data> sd)
clif_clearchar(sd, BeingRemoveWhy::DEAD);
return;
}
- if (map[sd->bl_m].flag.no_player_drops)
+ if (sd->bl_m->flag.no_player_drops)
{
clif_displaymessage(sd->fd, "Can't drop items here.");
return;
@@ -4765,7 +4744,7 @@ void clif_parse_NpcStringInput(int fd, dumb_ptr<map_session_data> sd)
}
if (len > 0)
- strncpy(sd->npc_str, (const char *)RFIFOP(fd, 8), len);
+ strncpy(sd->npc_str, static_cast<const char *>(RFIFOP(fd, 8)), len);
sd->npc_str[len] = '\0';
map_scriptcont(sd, RFIFOL(fd, 4));
@@ -4851,7 +4830,7 @@ void clif_parse_CreateParty(int fd, dumb_ptr<map_session_data> sd)
if (battle_config.basic_skill_check == 0
|| pc_checkskill(sd, SkillID::NV_PARTY) >= 2)
{
- party_create(sd, (const char *)RFIFOP(fd, 2));
+ party_create(sd, static_cast<const char *>(RFIFOP(fd, 2)));
}
else
clif_skill_fail(sd, SkillID::ONE, 0, 4);
@@ -4909,7 +4888,7 @@ void clif_parse_LeaveParty(int, dumb_ptr<map_session_data> sd)
static
void clif_parse_RemovePartyMember(int fd, dumb_ptr<map_session_data> sd)
{
- party_removemember(sd, RFIFOL(fd, 2), (const char *)RFIFOP(fd, 6));
+ party_removemember(sd, RFIFOL(fd, 2), static_cast<const char *>(RFIFOP(fd, 6)));
}
/*==========================================
@@ -4933,81 +4912,26 @@ void clif_parse_PartyChangeOption(int fd, dumb_ptr<map_session_data> sd)
static
void clif_parse_PartyMessage(int fd, dumb_ptr<map_session_data> sd)
{
- size_t message_len = 0;
- char *buf = NULL;
- const char *message = NULL; /* The message text only. */
-
nullpo_retv(sd);
- if (!(buf = clif_validate_chat(sd, 0, &message, &message_len)))
+ std::string mbuf = clif_validate_chat(sd, ChatType::Party);
+ if (mbuf.empty())
{
clif_displaymessage(fd, "Your message could not be sent.");
return;
}
- if (is_atcommand(fd, sd, message, 0)) //チャット禁止
- {
- free(buf);
+ if (is_atcommand(fd, sd, mbuf.c_str(), 0))
return;
- }
/* Don't send chat that results in an automatic ban. */
- if (tmw_CheckChatSpam(sd, message))
+ if (tmw_CheckChatSpam(sd, mbuf.c_str()))
{
- free(buf);
clif_displaymessage(fd, "Your message could not be sent.");
return;
}
- party_send_message(sd, message, RFIFOW(fd, 2) - 4);
- free(buf);
-}
-
-// 4144 wants this, but I don't like it ...
-static
-void clif_parse_PMIgnoreAll(int fd, dumb_ptr<map_session_data> sd)
-{ // Rewritten by [Yor]
- //PRINTF("Ignore all: state: %d\n", RFIFOB(fd,2));
- if (RFIFOB(fd, 2) == 0)
- { // S 00d0 <type>len.B: 00 (/exall) deny all speech, 01 (/inall) allow all speech
- WFIFOW(fd, 0) = 0x0d2; // R 00d2 <type>.B <fail>.B: type: 0: deny, 1: allow, fail: 0: success, 1: fail
- WFIFOB(fd, 2) = 0;
- if (sd->ignoreAll == 0)
- {
- sd->ignoreAll = 1;
- WFIFOB(fd, 3) = 0; // success
- WFIFOSET(fd, clif_parse_func_table[0x0d2].len);
- }
- else
- {
- WFIFOB(fd, 3) = 1; // fail
- WFIFOSET(fd, clif_parse_func_table[0x0d2].len);
- clif_wis_message(fd, wisp_server_name,
- "You already block everyone.",
- strlen("You already block everyone.") + 1);
- }
- }
- else
- {
- WFIFOW(fd, 0) = 0x0d2; // R 00d2 <type>.B <fail>.B: type: 0: deny, 1: allow, fail: 0: success, 1: fail
- WFIFOB(fd, 2) = 1;
- if (sd->ignoreAll == 1)
- {
- sd->ignoreAll = 0;
- WFIFOB(fd, 3) = 0; // success
- WFIFOSET(fd, clif_parse_func_table[0x0d2].len);
- }
- else
- {
- WFIFOB(fd, 3) = 1; // fail
- WFIFOSET(fd, clif_parse_func_table[0x0d2].len);
- clif_wis_message(fd, wisp_server_name,
- "You already allow everyone.",
- strlen("You already allow everyone.") + 1);
- }
- }
-
- return;
+ party_send_message(sd, mbuf.c_str(), RFIFOW(fd, 2) - 4);
}
func_table clif_parse_func_table[0x0220] =
@@ -5220,7 +5144,7 @@ func_table clif_parse_func_table[0x0220] =
{0, 6, NULL, }, // 0x00cd
{0, 2, NULL, }, // 0x00ce
{0, 27, NULL, }, // 0x00cf
- {0, 3, clif_parse_PMIgnoreAll, }, // 0x00d0
+ {0, 3, NULL, }, // 0x00d0
{0, 4, NULL, }, // 0x00d1
{0, 4, NULL, }, // 0x00d2
{0, 2, NULL, }, // 0x00d3
@@ -5653,35 +5577,22 @@ void WARN_MALFORMED_MSG(dumb_ptr<map_session_data> sd, const char *msg)
* 0 for when the sender's name is not included (party chat)
* 1 for when the target's name is included (whisper chat)
* 2 for when the sender's name is given ("sender : text", public/guild chat)
- * @param[out] message the message text (pointing within return value, or NULL)
- * @param[out] message_len the length of the actual text, excluding NUL
- * @return a dynamically allocated copy of the message, or NULL upon failure
+ * @return a dynamically allocated copy of the message, or empty string upon failure
*/
static
-char *clif_validate_chat(dumb_ptr<map_session_data> sd, int type,
- const char **message, size_t *message_len)
+std::string clif_validate_chat(dumb_ptr<map_session_data> sd, ChatType type)
{
- int fd;
- unsigned int buf_len; /* Actual message length. */
- unsigned int msg_len; /* Reported message length. */
- unsigned int min_len; /* Minimum message length. */
- size_t name_len; /* Sender's name length. */
- char *buf = NULL; /* Copy of actual message data. */
-
- *message = NULL;
- *message_len = 0;
-
- nullpo_retr(NULL, sd);
+ nullpo_retr(std::string(), sd);
/*
* Don't send chat in the period between the ban and the connection's
* closure.
*/
- if (type < 0 || type > 2 || sd->auto_ban_info.in_progress)
- return NULL;
+ if (sd->auto_ban_info.in_progress)
+ return std::string();
- fd = sd->fd;
- msg_len = RFIFOW(fd, 2) - 4;
- name_len = strlen(sd->status.name);
+ int fd = sd->fd;
+ size_t msg_len = RFIFOW(fd, 2) - 4;
+ size_t name_len = strlen(sd->status.name);
/*
* At least one character is required in all instances.
* Notes for length checks:
@@ -5692,33 +5603,42 @@ char *clif_validate_chat(dumb_ptr<map_session_data> sd, int type,
* For type 2, the message must be longer than the sender's name length
* plus the length of the separator (" : ").
*/
- min_len = (type == 1) ? 24 : (type == 2) ? name_len + 3 : 0;
+ 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 NULL;
+ return std::string();
}
/* The client sent (or claims to have sent) an empty message. */
if (msg_len == min_len)
{
WARN_MALFORMED_MSG(sd, "empty message");
- return NULL;
+ return std::string();
}
/* The protocol specifies that the target must be 24 bytes long. */
- if (type == 1 && msg_len < min_len)
+ if (type == ChatType::Whisper && msg_len < min_len)
{
/* Disallow malformed messages. */
clif_setwaitclose(fd);
WARN_MALFORMED_MSG(sd, "illegal target name");
- return NULL;
+ return std::string();
}
- const char *p = static_cast<const char *>((type != 1) ? RFIFOP(fd, 4) : RFIFOP(fd, 28));
- buf_len = (type == 1) ? msg_len - min_len: msg_len;
+ const char *p = static_cast<const char *>(RFIFOP(fd, 4));
+ size_t buf_len = msg_len;
+ if (type == ChatType::Whisper)
+ {
+ p += 24;
+ buf_len -= 24;
+ }
+ const char *pend = p + buf_len;
/*
* The client attempted to exceed the maximum message length.
@@ -5730,43 +5650,25 @@ char *clif_validate_chat(dumb_ptr<map_session_data> sd, int type,
if (buf_len >= battle_config.chat_maxline)
{
WARN_MALFORMED_MSG(sd, "exceeded maximum message length");
- return NULL;
+ return std::string();
}
- /* We're leaving an extra eight bytes for public/global chat, 1 for NUL. */
- buf_len += (type == 2) ? 8 + 1 : 1;
-
- buf = (char *) malloc(buf_len);
- memcpy((type != 2) ? buf : buf + 8, p,
- (type != 2) ? buf_len - 1 : buf_len - 8 - 1);
- buf[buf_len - 1] = '\0';
- p = (type != 2) ? buf : buf + 8;
-
- if (type != 2)
- {
- *message = buf;
- /* Don't count the NUL. */
- *message_len = buf_len - 1;
- }
- else
+ if (type == ChatType::Global)
{
- const char *pos = NULL;
- if (!(pos = strstr(p, " : "))
- || strncmp(p, sd->status.name, name_len)
- || pos - p != name_len)
+ const char *pos = strstr(p, " : ");
+ if (!pos || pos != p + name_len || memcmp(p, sd->status.name, name_len))
{
- free(buf);
/* Disallow malformed/spoofed messages. */
clif_setwaitclose(fd);
WARN_MALFORMED_MSG(sd, "spoofed name/invalid format");
- return NULL;
+ return std::string();
}
/* Step beyond the separator. */
- *message = pos + 3;
- /* Don't count the sender's name, the extra eight bytes, or the NUL. */
- *message_len = buf_len - min_len - 8 - 1;
+ p = pos + 3;
}
+ std::string buf(p, pend);
+
return buf;
}
diff --git a/src/map/intif.cpp b/src/map/intif.cpp
index 53ff80e..1010047 100644
--- a/src/map/intif.cpp
+++ b/src/map/intif.cpp
@@ -88,7 +88,7 @@ int intif_wis_message_to_gm(const char *Wisp_name, int min_gm_level, const char
WFIFOW(char_fd, 0) = 0x3003;
WFIFOW(char_fd, 2) = mes_len + 30;
memcpy(WFIFOP(char_fd, 4), Wisp_name, 24);
- WFIFOW(char_fd, 28) = (short) min_gm_level;
+ WFIFOW(char_fd, 28) = min_gm_level;
memcpy(WFIFOP(char_fd, 30), mes, mes_len);
WFIFOSET(char_fd, WFIFOW(char_fd, 2));
@@ -159,7 +159,7 @@ int intif_create_party(dumb_ptr<map_session_data> sd, const char *name)
WFIFOL(char_fd, 2) = sd->status.account_id;
memcpy(WFIFOP(char_fd, 6), name, 24);
memcpy(WFIFOP(char_fd, 30), sd->status.name, 24);
- memcpy(WFIFOP(char_fd, 54), map[sd->bl_m].name, 16);
+ memcpy(WFIFOP(char_fd, 54), sd->bl_m->name, 16);
WFIFOW(char_fd, 70) = sd->status.base_level;
WFIFOSET(char_fd, 72);
// if(battle_config.etc_log)
@@ -191,7 +191,7 @@ int intif_party_addmember(int party_id, int account_id)
WFIFOL(char_fd, 2) = party_id;
WFIFOL(char_fd, 6) = account_id;
memcpy(WFIFOP(char_fd, 10), sd->status.name, 24);
- memcpy(WFIFOP(char_fd, 34), map[sd->bl_m].name, 16);
+ memcpy(WFIFOP(char_fd, 34), sd->bl_m->name, 16);
WFIFOW(char_fd, 50) = sd->status.base_level;
WFIFOSET(char_fd, 52);
}
@@ -230,7 +230,7 @@ int intif_party_changemap(dumb_ptr<map_session_data> sd, int online)
WFIFOW(char_fd, 0) = 0x3025;
WFIFOL(char_fd, 2) = sd->status.party_id;
WFIFOL(char_fd, 6) = sd->status.account_id;
- memcpy(WFIFOP(char_fd, 10), map[sd->bl_m].name, 16);
+ memcpy(WFIFOP(char_fd, 10), sd->bl_m->name, 16);
WFIFOB(char_fd, 26) = online;
WFIFOW(char_fd, 27) = sd->status.base_level;
WFIFOSET(char_fd, 29);
@@ -273,7 +273,6 @@ static
int intif_parse_WisMessage(int fd)
{ // rewritten by [Yor]
dumb_ptr<map_session_data> sd;
- int i;
if (battle_config.etc_log)
PRINTF("intif_parse_wismessage: id: %d, from: %s, to: %s, message: '%s'\n",
@@ -281,27 +280,14 @@ int intif_parse_WisMessage(int fd)
static_cast<const char *>(RFIFOP(fd, 8)),
static_cast<const char *>(RFIFOP(fd, 32)),
static_cast<const char *>(RFIFOP(fd, 56)));
- sd = map_nick2sd((const char *)RFIFOP(fd, 32)); // Searching destination player
- if (sd != NULL && strcmp(sd->status.name, (const char *)RFIFOP(fd, 32)) == 0)
- { // exactly same name (inter-server have checked the name before)
- // if player ignore all
- if (sd->ignoreAll == 1)
- intif_wis_replay(RFIFOL(fd, 4), 2); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
- else
+ sd = map_nick2sd(static_cast<const char *>(RFIFOP(fd, 32))); // Searching destination player
+ if (sd != NULL && strcmp(sd->status.name, static_cast<const char *>(RFIFOP(fd, 32))) == 0)
+ {
+ // exactly same name (inter-server have checked the name before)
{
- const char *wisp_source = (const char *)RFIFOP(fd, 8); // speed up
- // if player ignore the source character
- for (i = 0; i < (sizeof(sd->ignore) / sizeof(sd->ignore[0]));
- i++)
- if (strcmp(sd->ignore[i].name, wisp_source) == 0)
- {
- intif_wis_replay(RFIFOL(fd, 4), 2); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
- break;
- }
// if source player not found in ignore list
- if (i == (sizeof(sd->ignore) / sizeof(sd->ignore[0])))
{
- clif_wis_message(sd->fd, (const char *)RFIFOP(fd, 8), (const char *)RFIFOP(fd, 56),
+ clif_wis_message(sd->fd, static_cast<const char *>(RFIFOP(fd, 8)), static_cast<const char *>(RFIFOP(fd, 56)),
RFIFOW(fd, 2) - 56);
intif_wis_replay(RFIFOL(fd, 4), 0); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
}
@@ -322,7 +308,7 @@ int intif_parse_WisEnd(int fd)
// 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",
static_cast<const char *>(RFIFOP(fd, 2)), RFIFOB(fd, 26));
- sd = map_nick2sd((const char *)RFIFOP(fd, 2));
+ sd = map_nick2sd(static_cast<const char *>(RFIFOP(fd, 2)));
if (sd != NULL)
clif_wis_end(sd->fd, RFIFOB(fd, 26));
@@ -336,19 +322,18 @@ int mapif_parse_WisToGM(int fd)
// 0x3003/0x3803 <packet_len>.w <wispname>.24B <min_gm_level>.w <message>.?B
int min_gm_level, len;
char Wisp_name[24];
- char mbuf[255];
if (RFIFOW(fd, 2) - 30 <= 0)
return 0;
len = RFIFOW(fd, 2) - 30;
- char *message = ((len) >= 255) ? (char *) malloc(len) : mbuf;
+ char message[len + 1];
- min_gm_level = (int) RFIFOW(fd, 28);
+ min_gm_level = RFIFOW(fd, 28);
memcpy(Wisp_name, RFIFOP(fd, 4), 24);
Wisp_name[23] = '\0';
memcpy(message, RFIFOP(fd, 30), len);
- message[len - 1] = '\0';
+ message[len] = '\0';
// information is sended to all online GM
for (int i = 0; i < fd_max; i++)
{
@@ -361,9 +346,6 @@ int mapif_parse_WisToGM(int fd)
strlen(message) + 1);
}
- if (message != mbuf)
- free(message);
-
return 0;
}
@@ -457,7 +439,7 @@ int intif_parse_PartyCreated(int fd)
if (battle_config.etc_log)
PRINTF("intif: party created\n");
party_created(RFIFOL(fd, 2), RFIFOB(fd, 6), RFIFOL(fd, 7),
- (const char *)RFIFOP(fd, 11));
+ static_cast<const char *>(RFIFOP(fd, 11)));
return 0;
}
@@ -511,8 +493,8 @@ int intif_parse_PartyMemberLeaved(int fd)
{
if (battle_config.etc_log)
PRINTF("intif: party member leaved %d %d %s\n", RFIFOL(fd, 2),
- RFIFOL(fd, 6), (const char *)RFIFOP(fd, 10));
- party_member_leaved(RFIFOL(fd, 2), RFIFOL(fd, 6), (const char *)RFIFOP(fd, 10));
+ RFIFOL(fd, 6), static_cast<const char *>(RFIFOP(fd, 10)));
+ party_member_leaved(RFIFOL(fd, 2), RFIFOL(fd, 6), static_cast<const char *>(RFIFOP(fd, 10)));
return 0;
}
@@ -530,7 +512,7 @@ int intif_parse_PartyMove(int fd)
{
// if(battle_config.etc_log)
// PRINTF("intif: party move %d %d %s %d %d\n",RFIFOL(fd,2),RFIFOL(fd,6),RFIFOP(fd,10),RFIFOB(fd,26),RFIFOW(fd,27));
- party_recv_movemap(RFIFOL(fd, 2), RFIFOL(fd, 6), (const char *)RFIFOP(fd, 10),
+ party_recv_movemap(RFIFOL(fd, 2), RFIFOL(fd, 6), static_cast<const char *>(RFIFOP(fd, 10)),
RFIFOB(fd, 26), RFIFOW(fd, 27));
return 0;
}
@@ -541,7 +523,7 @@ int intif_parse_PartyMessage(int fd)
{
// if(battle_config.etc_log)
// PRINTF("intif_parse_PartyMessage: %s\n",RFIFOP(fd,12));
- party_recv_message(RFIFOL(fd, 4), RFIFOL(fd, 8), (const char *)RFIFOP(fd, 12),
+ party_recv_message(RFIFOL(fd, 4), RFIFOL(fd, 8), static_cast<const char *>(RFIFOP(fd, 12)),
RFIFOW(fd, 2) - 12);
return 0;
}
@@ -581,7 +563,7 @@ int intif_parse(int fd)
{
case 0x3800:
clif_GMmessage(NULL,
- const_string((const char *)RFIFOP(fd, 4),
+ const_string(static_cast<const char *>(RFIFOP(fd, 4)),
(packet_len - 4) - 1), 0);
break;
case 0x3801:
diff --git a/src/map/itemdb.cpp b/src/map/itemdb.cpp
index f60dc53..147db91 100644
--- a/src/map/itemdb.cpp
+++ b/src/map/itemdb.cpp
@@ -367,10 +367,8 @@ int itemdb_read_noequip(void)
static
void itemdb_final(struct item_data *id)
{
- if (id->use_script)
- free(const_cast<ScriptCode *>(id->use_script));
- if (id->equip_script)
- free(const_cast<ScriptCode *>(id->equip_script));
+ id->use_script.reset();
+ id->equip_script.reset();
}
void itemdb_reload(void)
diff --git a/src/map/itemdb.hpp b/src/map/itemdb.hpp
index 279c7a8..02da73a 100644
--- a/src/map/itemdb.hpp
+++ b/src/map/itemdb.hpp
@@ -27,8 +27,8 @@ struct item_data
int elv;
int wlv;
int refine;
- const ScriptCode *use_script;
- const ScriptCode *equip_script;
+ std::unique_ptr<const ScriptBuffer> use_script;
+ std::unique_ptr<const ScriptBuffer> equip_script;
struct
{
unsigned available:1;
@@ -67,9 +67,9 @@ int itemdb_weight(int n)
return itemdb_search(n)->weight;
}
inline
-const ScriptCode *itemdb_equipscript(int n)
+const ScriptBuffer *itemdb_equipscript(int n)
{
- return itemdb_search(n)->equip_script;
+ return itemdb_search(n)->equip_script.get();
}
inline
int itemdb_wlv(int n)
diff --git a/src/map/magic-expr-eval.hpp b/src/map/magic-expr-eval.hpp
index bc5ce6e..9c9591b 100644
--- a/src/map/magic-expr-eval.hpp
+++ b/src/map/magic-expr-eval.hpp
@@ -10,13 +10,13 @@
int magic_signature_check(const char *opname, const char *funname, const char *signature,
int args_nr, val_t *args, int line, int column);
-void magic_area_rect(int *m, int *x, int *y, int *width, int *height,
- area_t *area);
+void magic_area_rect(map_local **m, int *x, int *y, int *width, int *height,
+ area_t& area);
#define ARGINT(x) args[x].v.v_int
#define ARGDIR(x) args[x].v.v_dir
#define ARGSTR(x) args[x].v.v_string
-#define ARGENTITY(x) dumb_ptr<block_list>(args[x].v.v_entity)
+#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
diff --git a/src/map/magic-expr.cpp b/src/map/magic-expr.cpp
index c0eaf9f..7739847 100644
--- a/src/map/magic-expr.cpp
+++ b/src/map/magic-expr.cpp
@@ -16,7 +16,7 @@
#include "../poison.hpp"
static
-void free_area(area_t *area)
+void free_area(dumb_ptr<area_t> area)
{
if (!area)
return;
@@ -31,13 +31,13 @@ void free_area(area_t *area)
break;
}
- free(area);
+ area.delete_();
}
static
-area_t *dup_area(area_t *area)
+dumb_ptr<area_t> dup_area(dumb_ptr<area_t> area)
{
- area_t *retval = (area_t *)malloc(sizeof(area_t));
+ dumb_ptr<area_t> retval = dumb_ptr<area_t>::make();
*retval = *area;
switch (area->ty)
@@ -60,7 +60,7 @@ void magic_copy_var(val_t *dest, val_t *src)
switch (dest->ty)
{
case TYPE::STRING:
- dest->v.v_string = strdup(dest->v.v_string);
+ dest->v.v_string = dest->v.v_string.dup();
break;
case TYPE::AREA:
dest->v.v_area = dup_area(dest->v.v_area);
@@ -76,7 +76,7 @@ void magic_clear_var(val_t *v)
switch (v->ty)
{
case TYPE::STRING:
- free(v->v.v_string);
+ v->v.v_string.delete_();
break;
case TYPE::AREA:
free_area(v->v.v_area);
@@ -139,12 +139,12 @@ void stringify(val_t *v, int within_op)
break;
case TYPE::ENTITY:
- buf = show_entity(dumb_ptr<block_list>(v->v.v_entity));
+ buf = show_entity(v->v.v_entity);
break;
case TYPE::LOCATION:
buf = STRPRINTF("<\"%s\", %d, %d>",
- map[v->v.v_location.m].name,
+ v->v.v_location.m->name,
v->v.v_location.x,
v->v.v_location.y);
break;
@@ -161,7 +161,7 @@ void stringify(val_t *v, int within_op)
case TYPE::INVOCATION:
{
dumb_ptr<invocation> invocation_ = within_op
- ? dumb_ptr<invocation>(v->v.v_invocation)
+ ? v->v.v_invocation
: map_id2bl(v->v.v_int)->as_spell();
buf = invocation_->spell->name;
}
@@ -173,7 +173,7 @@ void stringify(val_t *v, int within_op)
return;
}
- v->v.v_string = strdup(buf.c_str());
+ v->v.v_string = dumb_string::copys(buf);
v->ty = TYPE::STRING;
}
@@ -189,18 +189,17 @@ void intify(val_t *v)
}
static
-area_t *area_new(AREA ty)
+dumb_ptr<area_t> area_new(AREA ty)
{
- area_t *retval;
- CREATE(retval, area_t, 1);
+ auto retval = dumb_ptr<area_t>::make();
retval->ty = ty;
return retval;
}
static
-area_t *area_union(area_t *area, area_t *other_area)
+dumb_ptr<area_t> area_union(dumb_ptr<area_t> area, dumb_ptr<area_t> other_area)
{
- area_t *retval = area_new(AREA::UNION);
+ 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 */
@@ -215,7 +214,7 @@ void make_area(val_t *v)
{
if (v->ty == TYPE::LOCATION)
{
- area_t *a = (area_t *)malloc(sizeof(area_t));
+ auto a = dumb_ptr<area_t>::make();
v->ty = TYPE::AREA;
a->ty = AREA::LOCATION;
a->a.a_loc = v->v.v_location;
@@ -240,7 +239,7 @@ void make_spell(val_t *v)
{
if (v->ty == TYPE::INVOCATION)
{
- dumb_ptr<invocation> invoc = dumb_ptr<invocation>(v->v.v_invocation);
+ dumb_ptr<invocation> invoc = v->v.v_invocation;
//invoc = (dumb_ptr<invocation>) map_id2bl(v->v.v_int);
if (!invoc)
v->ty = TYPE::FAIL;
@@ -253,7 +252,7 @@ void make_spell(val_t *v)
}
static
-int fun_add(env_t *, int, val_t *result, val_t *args)
+int fun_add(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
if (ARG_TYPE(0) == TYPE::INT && ARG_TYPE(1) == TYPE::INT)
{
@@ -277,31 +276,29 @@ int fun_add(env_t *, int, val_t *result, val_t *args)
stringify(&args[0], 1);
stringify(&args[1], 1);
/* Yes, we could speed this up. */
- RESULTSTR =
- (char *) malloc(1 + strlen(ARGSTR(0)) + strlen(ARGSTR(1)));
- strcpy(RESULTSTR, ARGSTR(0));
- strcat(RESULTSTR, ARGSTR(1));
+ // ugh
+ RESULTSTR = dumb_string::copys(ARGSTR(0).str() + ARGSTR(1).str());
result->ty = TYPE::STRING;
}
return 0;
}
static
-int fun_sub(env_t *, int, val_t *result, val_t *args)
+int fun_sub(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
RESULTINT = ARGINT(0) - ARGINT(1);
return 0;
}
static
-int fun_mul(env_t *, int, val_t *result, val_t *args)
+int fun_mul(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
RESULTINT = ARGINT(0) * ARGINT(1);
return 0;
}
static
-int fun_div(env_t *, int, val_t *result, val_t *args)
+int fun_div(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
if (!ARGINT(1))
return 1; /* division by zero */
@@ -310,7 +307,7 @@ int fun_div(env_t *, int, val_t *result, val_t *args)
}
static
-int fun_mod(env_t *, int, val_t *result, val_t *args)
+int fun_mod(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
if (!ARGINT(1))
return 1; /* division by zero */
@@ -319,41 +316,42 @@ int fun_mod(env_t *, int, val_t *result, val_t *args)
}
static
-int fun_or(env_t *, int, val_t *result, val_t *args)
+int fun_or(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
RESULTINT = ARGINT(0) || ARGINT(1);
return 0;
}
static
-int fun_and(env_t *, int, val_t *result, val_t *args)
+int fun_and(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
RESULTINT = ARGINT(0) && ARGINT(1);
return 0;
}
static
-int fun_not(env_t *, int, val_t *result, val_t *args)
+int fun_not(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
RESULTINT = !ARGINT(0);
return 0;
}
static
-int fun_neg(env_t *, int, val_t *result, val_t *args)
+int fun_neg(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
RESULTINT = ~ARGINT(0);
return 0;
}
static
-int fun_gte(env_t *, int, val_t *result, val_t *args)
+int fun_gte(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
if (ARG_TYPE(0) == TYPE::STRING || ARG_TYPE(1) == TYPE::STRING)
{
stringify(&args[0], 1);
stringify(&args[1], 1);
- RESULTINT = strcmp(ARGSTR(0), ARGSTR(1)) >= 0;
+ using namespace operators;
+ RESULTINT = ARGSTR(0) >= ARGSTR(1);
}
else
{
@@ -365,13 +363,14 @@ int fun_gte(env_t *, int, val_t *result, val_t *args)
}
static
-int fun_gt(env_t *, int, val_t *result, val_t *args)
+int fun_gt(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
if (ARG_TYPE(0) == TYPE::STRING || ARG_TYPE(1) == TYPE::STRING)
{
stringify(&args[0], 1);
stringify(&args[1], 1);
- RESULTINT = strcmp(ARGSTR(0), ARGSTR(1)) > 0;
+ using namespace operators;
+ RESULTINT = ARGSTR(0) > ARGSTR(1);
}
else
{
@@ -383,13 +382,14 @@ int fun_gt(env_t *, int, val_t *result, val_t *args)
}
static
-int fun_eq(env_t *, int, val_t *result, val_t *args)
+int fun_eq(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
if (ARG_TYPE(0) == TYPE::STRING || ARG_TYPE(1) == TYPE::STRING)
{
stringify(&args[0], 1);
stringify(&args[1], 1);
- RESULTINT = strcmp(ARGSTR(0), ARGSTR(1)) == 0;
+ using namespace operators;
+ RESULTINT = ARGSTR(0) == ARGSTR(1);
}
else if (ARG_TYPE(0) == TYPE::DIR && ARG_TYPE(1) == TYPE::DIR)
RESULTINT = ARGDIR(0) == ARGDIR(1);
@@ -415,56 +415,56 @@ int fun_eq(env_t *, int, val_t *result, val_t *args)
}
static
-int fun_bitand(env_t *, int, val_t *result, val_t *args)
+int fun_bitand(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
RESULTINT = ARGINT(0) & ARGINT(1);
return 0;
}
static
-int fun_bitor(env_t *, int, val_t *result, val_t *args)
+int fun_bitor(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
RESULTINT = ARGINT(0) | ARGINT(1);
return 0;
}
static
-int fun_bitxor(env_t *, int, val_t *result, val_t *args)
+int fun_bitxor(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
RESULTINT = ARGINT(0) ^ ARGINT(1);
return 0;
}
static
-int fun_bitshl(env_t *, int, val_t *result, val_t *args)
+int fun_bitshl(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
RESULTINT = ARGINT(0) << ARGINT(1);
return 0;
}
static
-int fun_bitshr(env_t *, int, val_t *result, val_t *args)
+int fun_bitshr(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
RESULTINT = ARGINT(0) >> ARGINT(1);
return 0;
}
static
-int fun_max(env_t *, int, val_t *result, val_t *args)
+int fun_max(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
RESULTINT = max(ARGINT(0), ARGINT(1));
return 0;
}
static
-int fun_min(env_t *, int, val_t *result, val_t *args)
+int fun_min(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
RESULTINT = min(ARGINT(0), ARGINT(1));
return 0;
}
static
-int fun_if_then_else(env_t *, int, val_t *result, val_t *args)
+int fun_if_then_else(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
if (ARGINT(0))
magic_copy_var(result, &args[1]);
@@ -473,9 +473,10 @@ int fun_if_then_else(env_t *, int, val_t *result, val_t *args)
return 0;
}
-void magic_area_rect(int *m, int *x, int *y, int *width, int *height,
- area_t *area)
+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)
{
case AREA::UNION:
@@ -547,7 +548,7 @@ void magic_area_rect(int *m, int *x, int *y, int *width, int *height,
}
}
-int magic_location_in_area(int m, int x, int y, area_t *area)
+int magic_location_in_area(map_local *m, int x, int y, dumb_ptr<area_t> area)
{
switch (area->ty)
{
@@ -558,9 +559,9 @@ int magic_location_in_area(int m, int x, int y, area_t *area)
case AREA::RECT:
case AREA::BAR:
{
- int am;
+ map_local *am;
int ax, ay, awidth, aheight;
- magic_area_rect(&am, &ax, &ay, &awidth, &aheight, area);
+ magic_area_rect(&am, &ax, &ay, &awidth, &aheight, *area);
return (am == m
&& (x >= ax) && (y >= ay)
&& (x < ax + awidth) && (y < ay + aheight));
@@ -572,7 +573,7 @@ int magic_location_in_area(int m, int x, int y, area_t *area)
}
static
-int fun_is_in(env_t *, int, val_t *result, val_t *args)
+int fun_is_in(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
RESULTINT = magic_location_in_area(ARGLOCATION(0).m,
ARGLOCATION(0).x,
@@ -581,7 +582,7 @@ int fun_is_in(env_t *, int, val_t *result, val_t *args)
}
static
-int fun_skill(env_t *, int, val_t *result, val_t *args)
+int fun_skill(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
if (ENTITY_TYPE(0) != BL::PC
// don't convert to enum until after the range check
@@ -599,7 +600,7 @@ int fun_skill(env_t *, int, val_t *result, val_t *args)
}
static
-int fun_has_shroud(env_t *, int, val_t *result, val_t *args)
+int fun_has_shroud(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
RESULTINT = (ENTITY_TYPE(0) == BL::PC && ARGPC(0)->state.shroud_active);
return 0;
@@ -607,7 +608,7 @@ int fun_has_shroud(env_t *, int, val_t *result, val_t *args)
#define BATTLE_GETTER(name) \
static \
-int fun_get_##name(env_t *, int, val_t *result, val_t *args) \
+int fun_get_##name(dumb_ptr<env_t>, val_t *result, const_array<val_t> args) \
{ \
RESULTINT = battle_get_##name(ARGENTITY(0)); \
return 0; \
@@ -625,7 +626,7 @@ BATTLE_GETTER(mdef)
BATTLE_GETTER(def)
BATTLE_GETTER(max_hp)
static
-int fun_get_dir(env_t *, int, val_t *result, val_t *args)
+int fun_get_dir(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
RESULTDIR = battle_get_dir(ARGENTITY(0));
return 0;
@@ -633,7 +634,7 @@ int fun_get_dir(env_t *, int, val_t *result, val_t *args)
#define MMO_GETTER(name) \
static \
-int fun_get_##name(env_t *, int, val_t *result, val_t *args) \
+int fun_get_##name(dumb_ptr<env_t>, val_t *result, const_array<val_t> args) \
{ \
if (ENTITY_TYPE(0) == BL::PC) \
RESULTINT = ARGPC(0)->status.name; \
@@ -646,21 +647,21 @@ MMO_GETTER(sp)
MMO_GETTER(max_sp)
static
-int fun_name_of(env_t *, int, val_t *result, val_t *args)
+int fun_name_of(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
if (ARG_TYPE(0) == TYPE::ENTITY)
{
- RESULTSTR = strdup(show_entity(ARGENTITY(0)));
+ RESULTSTR = dumb_string::copy(show_entity(ARGENTITY(0)));
return 0;
}
else if (ARG_TYPE(0) == TYPE::SPELL)
{
- RESULTSTR = strdup(ARGSPELL(0)->name);
+ RESULTSTR = dumb_string::copys(ARGSPELL(0)->name);
return 0;
}
else if (ARG_TYPE(0) == TYPE::INVOCATION)
{
- RESULTSTR = strdup(ARGINVOCATION(0)->spell->name);
+ RESULTSTR = dumb_string::copys(ARGINVOCATION(0)->spell->name);
return 0;
}
return 1;
@@ -668,7 +669,7 @@ int fun_name_of(env_t *, int, val_t *result, val_t *args)
/* [Freeyorp] I'm putting this one in as name_of seems to have issues with summoned or spawned mobs. */
static
-int fun_mob_id(env_t *, int, val_t *result, val_t *args)
+int fun_mob_id(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
if (ENTITY_TYPE(0) != BL::MOB)
return 1;
@@ -693,14 +694,14 @@ void COPY_LOCATION(location_t& dest, block_list& src)
}
static
-int fun_location(env_t *, int, val_t *result, val_t *args)
+int fun_location(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
COPY_LOCATION(RESULTLOCATION, *(ARGENTITY(0)));
return 0;
}
static
-int fun_random(env_t *, int, val_t *result, val_t *args)
+int fun_random(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
int delta = ARGINT(0);
if (delta < 0)
@@ -718,7 +719,7 @@ int fun_random(env_t *, int, val_t *result, val_t *args)
}
static
-int fun_random_dir(env_t *, int, val_t *result, val_t *args)
+int fun_random_dir(dumb_ptr<env_t>, val_t *result, const_array<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});
@@ -728,14 +729,14 @@ int fun_random_dir(env_t *, int, val_t *result, val_t *args)
}
static
-int fun_hash_entity(env_t *, int, val_t *result, val_t *args)
+int fun_hash_entity(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
RESULTINT = ARGENTITY(0)->bl_id;
return 0;
}
int // ret -1: not a string, ret 1: no such item, ret 0: OK
-magic_find_item(val_t *args, int index, struct item *item, int *stackable)
+magic_find_item(const_array<val_t> args, int index, struct item *item, int *stackable)
{
struct item_data *item_data;
int must_add_sequentially;
@@ -743,7 +744,7 @@ magic_find_item(val_t *args, int index, struct item *item, int *stackable)
if (ARG_TYPE(index) == TYPE::INT)
item_data = itemdb_exists(ARGINT(index));
else if (ARG_TYPE(index) == TYPE::STRING)
- item_data = itemdb_searchname(ARGSTR(index));
+ item_data = itemdb_searchname(ARGSTR(index).c_str());
else
return -1;
@@ -768,7 +769,7 @@ magic_find_item(val_t *args, int index, struct item *item, int *stackable)
}
static
-int fun_count_item(env_t *, int, val_t *result, val_t *args)
+int fun_count_item(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
dumb_ptr<map_session_data> chr = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL;
int stackable;
@@ -784,7 +785,7 @@ int fun_count_item(env_t *, int, val_t *result, val_t *args)
}
static
-int fun_is_equipped(env_t *, int, val_t *result, val_t *args)
+int fun_is_equipped(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
dumb_ptr<map_session_data> chr = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL;
int stackable;
@@ -810,33 +811,33 @@ int fun_is_equipped(env_t *, int, val_t *result, val_t *args)
}
static
-int fun_is_married(env_t *, int, val_t *result, val_t *args)
+int fun_is_married(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
RESULTINT = (ENTITY_TYPE(0) == BL::PC && ARGPC(0)->status.partner_id);
return 0;
}
static
-int fun_is_dead(env_t *, int, val_t *result, val_t *args)
+int fun_is_dead(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
RESULTINT = (ENTITY_TYPE(0) == BL::PC && pc_isdead(ARGPC(0)));
return 0;
}
static
-int fun_is_pc(env_t *, int, val_t *result, val_t *args)
+int fun_is_pc(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
RESULTINT = (ENTITY_TYPE(0) == BL::PC);
return 0;
}
static
-int fun_partner(env_t *, int, val_t *result, val_t *args)
+int fun_partner(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
if (ENTITY_TYPE(0) == BL::PC && ARGPC(0)->status.partner_id)
{
RESULTENTITY =
- map_nick2sd(map_charid2nick(ARGPC(0)->status.partner_id)).operator->();
+ map_nick2sd(map_charid2nick(ARGPC(0)->status.partner_id));
return 0;
}
else
@@ -844,14 +845,14 @@ int fun_partner(env_t *, int, val_t *result, val_t *args)
}
static
-int fun_awayfrom(env_t *, int, val_t *result, val_t *args)
+int fun_awayfrom(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
location_t *loc = &ARGLOCATION(0);
int dx = dirx[ARGDIR(1)];
int dy = diry[ARGDIR(1)];
int distance = ARGINT(2);
while (distance--
- && !bool(read_gat(loc->m, loc->x + dx, loc->y + dy)
+ && !bool(read_gatp(loc->m, loc->x + dx, loc->y + dy)
& MapCell::UNWALKABLE))
{
loc->x += dx;
@@ -863,28 +864,28 @@ int fun_awayfrom(env_t *, int, val_t *result, val_t *args)
}
static
-int fun_failed(env_t *, int, val_t *result, val_t *args)
+int fun_failed(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
RESULTINT = ARG_TYPE(0) == TYPE::FAIL;
return 0;
}
static
-int fun_npc(env_t *, int, val_t *result, val_t *args)
+int fun_npc(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
- RESULTENTITY = npc_name2id(ARGSTR(0)).operator->();
+ RESULTENTITY = npc_name2id(ARGSTR(0).c_str());
return RESULTENTITY == NULL;
}
static
-int fun_pc(env_t *, int, val_t *result, val_t *args)
+int fun_pc(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
- RESULTENTITY = map_nick2sd(ARGSTR(0)).operator->();
+ RESULTENTITY = map_nick2sd(ARGSTR(0).c_str());
return RESULTENTITY == NULL;
}
static
-int fun_distance(env_t *, int, val_t *result, val_t *args)
+int fun_distance(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
if (ARGLOCATION(0).m != ARGLOCATION(1).m)
RESULTINT = 0x7fffffff;
@@ -895,7 +896,7 @@ int fun_distance(env_t *, int, val_t *result, val_t *args)
}
static
-int fun_rdistance(env_t *, int, val_t *result, val_t *args)
+int fun_rdistance(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
if (ARGLOCATION(0).m != ARGLOCATION(1).m)
RESULTINT = 0x7fffffff;
@@ -903,15 +904,15 @@ int fun_rdistance(env_t *, int, val_t *result, val_t *args)
{
int dx = ARGLOCATION(0).x - ARGLOCATION(1).x;
int dy = ARGLOCATION(0).y - ARGLOCATION(1).y;
- RESULTINT = (int)(sqrt((dx * dx) + (dy * dy)));
+ RESULTINT = static_cast<int>(sqrt((dx * dx) + (dy * dy)));
}
return 0;
}
static
-int fun_anchor(env_t *env, int, val_t *result, val_t *args)
+int fun_anchor(dumb_ptr<env_t> env, val_t *result, const_array<val_t> args)
{
- teleport_anchor_t *anchor = magic_find_anchor(ARGSTR(0));
+ dumb_ptr<teleport_anchor_t> anchor = magic_find_anchor(ARGSTR(0).str());
if (!anchor)
return 1;
@@ -929,7 +930,7 @@ int fun_anchor(env_t *env, int, val_t *result, val_t *args)
}
static
-int fun_line_of_sight(env_t *, int, val_t *result, val_t *args)
+int fun_line_of_sight(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
block_list e1, e2;
@@ -941,7 +942,7 @@ int fun_line_of_sight(env_t *, int, val_t *result, val_t *args)
return 0;
}
-void magic_random_location(location_t *dest, area_t *area)
+void magic_random_location(location_t *dest, dumb_ptr<area_t> area)
{
switch (area->ty)
{
@@ -958,8 +959,9 @@ void magic_random_location(location_t *dest, area_t *area)
case AREA::RECT:
case AREA::BAR:
{
- int m, x, y, w, h;
- magic_area_rect(&m, &x, &y, &w, &h, area);
+ map_local *m;
+ int x, y, w, h;
+ magic_area_rect(&m, &x, &y, &w, &h, *area);
if (w <= 1)
w = 1;
@@ -984,27 +986,27 @@ void magic_random_location(location_t *dest, area_t *area)
}
static
-int fun_pick_location(env_t *, int, val_t *result, val_t *args)
+int fun_pick_location(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
magic_random_location(&result->v.v_location, ARGAREA(0));
return 0;
}
static
-int fun_read_script_int(env_t *, int, val_t *result, val_t *args)
+int fun_read_script_int(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
dumb_ptr<block_list> subject_p = ARGENTITY(0);
- char *var_name = ARGSTR(1);
+ dumb_string var_name = ARGSTR(1);
if (subject_p->bl_type != BL::PC)
return 1;
- RESULTINT = pc_readglobalreg(subject_p->as_player(), var_name);
+ RESULTINT = pc_readglobalreg(subject_p->as_player(), var_name.c_str());
return 0;
}
static
-int fun_rbox(env_t *, int, val_t *result, val_t *args)
+int fun_rbox(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
location_t loc = ARGLOCATION(0);
int radius = ARGINT(1);
@@ -1020,7 +1022,7 @@ int fun_rbox(env_t *, int, val_t *result, val_t *args)
}
static
-int fun_running_status_update(env_t *, int, val_t *result, val_t *args)
+int fun_running_status_update(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
if (ENTITY_TYPE(0) != BL::PC && ENTITY_TYPE(0) != BL::MOB)
return 1;
@@ -1031,66 +1033,67 @@ int fun_running_status_update(env_t *, int, val_t *result, val_t *args)
}
static
-int fun_status_option(env_t *, int, val_t *result, val_t *args)
+int fun_status_option(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
RESULTINT = (bool((ARGPC(0))->status.option & static_cast<Option>(ARGINT(0))));
return 0;
}
static
-int fun_element(env_t *, int, val_t *result, val_t *args)
+int fun_element(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
RESULTINT = static_cast<int>(battle_get_element(ARGENTITY(0)).element);
return 0;
}
static
-int fun_element_level(env_t *, int, val_t *result, val_t *args)
+int fun_element_level(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
RESULTINT = battle_get_element(ARGENTITY(0)).level;
return 0;
}
static
-int fun_index(env_t *, int, val_t *result, val_t *args)
+int fun_index(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
- RESULTINT = ARGSPELL(0)->index;
+ RESULTINT = ARGSPELL(0)->index_;
return 0;
}
static
-int fun_is_exterior(env_t *, int, val_t *result, val_t *args)
+int fun_is_exterior(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
- RESULTINT = map[ARGLOCATION(0).m].name[4] == '1';
+#warning "Evil assumptions!"
+ RESULTINT = ARGLOCATION(0).m->name[4] == '1';
return 0;
}
static
-int fun_contains_string(env_t *, int, val_t *result, val_t *args)
+int fun_contains_string(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
- RESULTINT = NULL != strstr(ARGSTR(0), ARGSTR(1));
+ RESULTINT = NULL != strstr(ARGSTR(0).c_str(), ARGSTR(1).c_str());
return 0;
}
static
-int fun_strstr(env_t *, int, val_t *result, val_t *args)
+int fun_strstr(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
- char *offset = strstr(ARGSTR(0), ARGSTR(1));
- RESULTINT = offset - ARGSTR(0);
+ const char *offset = strstr(ARGSTR(0).c_str(), ARGSTR(1).c_str());
+ RESULTINT = offset - ARGSTR(0).c_str();
return offset == NULL;
}
static
-int fun_strlen(env_t *, int, val_t *result, val_t *args)
+int fun_strlen(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
- RESULTINT = strlen(ARGSTR(0));
+ RESULTINT = strlen(ARGSTR(0).c_str());
return 0;
}
static
-int fun_substr(env_t *, int, val_t *result, val_t *args)
+int fun_substr(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
- const char *src = ARGSTR(0);
+ const char *src = ARGSTR(0).c_str();
const int slen = strlen(src);
int offset = ARGINT(1);
int len = ARGINT(2);
@@ -1106,30 +1109,33 @@ int fun_substr(env_t *, int, val_t *result, val_t *args)
if (offset + len > slen)
len = slen - offset;
- RESULTSTR = (char *) calloc(1, 1 + len);
- memcpy(RESULTSTR, src + offset, len);
+ const char *begin = src + offset;
+ const char *end = begin + len;
+ RESULTSTR = dumb_string::copy(begin, end);
return 0;
}
static
-int fun_sqrt(env_t *, int, val_t *result, val_t *args)
+int fun_sqrt(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
- RESULTINT = (int) sqrt(ARGINT(0));
+ RESULTINT = static_cast<int>(sqrt(ARGINT(0)));
return 0;
}
static
-int fun_map_level(env_t *, int, val_t *result, val_t *args)
+int fun_map_level(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
- RESULTINT = map[ARGLOCATION(0).m].name[4] - '0';
+#warning "Evil assumptions!"
+ RESULTINT = ARGLOCATION(0).m->name[4] - '0';
return 0;
}
static
-int fun_map_nr(env_t *, int, val_t *result, val_t *args)
+int fun_map_nr(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
- const char *mapname = map[ARGLOCATION(0).m].name;
+#warning "Evil assumptions!"
+ const char *mapname = ARGLOCATION(0).m->name;
RESULTINT = ((mapname[0] - '0') * 100)
+ ((mapname[1] - '0') * 10) + ((mapname[2] - '0'));
@@ -1137,7 +1143,7 @@ int fun_map_nr(env_t *, int, val_t *result, val_t *args)
}
static
-int fun_dir_towards(env_t *, int, val_t *result, val_t *args)
+int fun_dir_towards(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
int dx;
int dy;
@@ -1203,7 +1209,7 @@ int fun_dir_towards(env_t *, int, val_t *result, val_t *args)
}
static
-int fun_extract_healer_xp(env_t *, int, val_t *result, val_t *args)
+int fun_extract_healer_xp(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
dumb_ptr<map_session_data> sd = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL;
@@ -1215,7 +1221,8 @@ int fun_extract_healer_xp(env_t *, int, val_t *result, val_t *args)
}
static
-fun_t functions[] = {
+fun_t functions[] =
+{
{"+", "..", '.', fun_add},
{"-", "ii", 'i', fun_sub},
{"*", "ii", 'i', fun_mul},
@@ -1297,16 +1304,16 @@ fun_t functions[] = {
static
int functions_are_sorted = 0;
-static
+static __attribute__((deprecated))
int compare_fun(const void *lhs, const void *rhs)
{
- return strcmp(((const fun_t *) lhs)->name, ((const fun_t *) rhs)->name);
+ return strcmp(static_cast<const fun_t *>(lhs)->name, static_cast<const fun_t *>(rhs)->name);
}
-fun_t *magic_get_fun(const char *name, int *index)
+fun_t *magic_get_fun(const std::string& name, int *index)
{
static
-int functions_nr;
+ int functions_nr;
fun_t *result;
fun_t key;
@@ -1322,9 +1329,9 @@ int functions_nr;
functions_are_sorted = 1;
}
- key.name = name;
- result = (fun_t *) bsearch(&key, functions, functions_nr, sizeof(fun_t),
- compare_fun);
+ key.name = name.c_str();
+ result = static_cast<fun_t *>(bsearch(&key, functions, functions_nr, sizeof(fun_t),
+ compare_fun));
if (result && index)
*index = result - functions;
@@ -1332,9 +1339,9 @@ int functions_nr;
return result;
}
+// 1 on failure
static
-int // 1 on failure
-eval_location(env_t *env, location_t *dest, e_location_t *expr)
+int eval_location(dumb_ptr<env_t> env, location_t *dest, e_location_t *expr)
{
val_t m, x, y;
magic_eval(env, &m, expr->m);
@@ -1344,9 +1351,9 @@ eval_location(env_t *env, location_t *dest, e_location_t *expr)
if (CHECK_TYPE(&m, TYPE::STRING)
&& CHECK_TYPE(&x, TYPE::INT) && CHECK_TYPE(&y, TYPE::INT))
{
- int map_id = map_mapname2mapid(m.v.v_string);
+ map_local *map_id = map_mapname2mapid(m.v.v_string.c_str());
magic_clear_var(&m);
- if (map_id < 0)
+ if (!map_id)
return 1;
dest->m = map_id;
dest->x = x.v.v_int;
@@ -1363,9 +1370,10 @@ eval_location(env_t *env, location_t *dest, e_location_t *expr)
}
static
-area_t *eval_area(env_t *env, e_area_t *expr)
+dumb_ptr<area_t> eval_area(dumb_ptr<env_t> env, e_area_t& expr_)
{
- area_t *area = (area_t *)malloc(sizeof(area_t));
+ e_area_t *expr = &expr_; // temporary hack to reduce diff
+ auto area = dumb_ptr<area_t>::make();
area->ty = expr->ty;
switch (expr->ty)
@@ -1374,7 +1382,7 @@ area_t *eval_area(env_t *env, e_area_t *expr)
area->size = 1;
if (eval_location(env, &area->a.a_loc, &expr->a.a_loc))
{
- free(area);
+ area.delete_();
return NULL;
}
else
@@ -1385,7 +1393,7 @@ area_t *eval_area(env_t *env, e_area_t *expr)
int i, fail = 0;
for (i = 0; i < 2; i++)
{
- area->a.a_union[i] = eval_area(env, expr->a.a_union[i]);
+ area->a.a_union[i] = eval_area(env, *expr->a.a_union[i]);
if (!area->a.a_union[i])
fail = 1;
}
@@ -1397,7 +1405,7 @@ area_t *eval_area(env_t *env, e_area_t *expr)
if (area->a.a_union[i])
free_area(area->a.a_union[i]);
}
- free(area);
+ area.delete_();
return NULL;
}
area->size = area->a.a_union[0]->size + area->a.a_union[1]->size;
@@ -1425,7 +1433,7 @@ area_t *eval_area(env_t *env, e_area_t *expr)
}
else
{
- free(area);
+ area.delete_();
magic_clear_var(&width);
magic_clear_var(&height);
return NULL;
@@ -1458,7 +1466,7 @@ area_t *eval_area(env_t *env, e_area_t *expr)
}
else
{
- free(area);
+ area.delete_();
magic_clear_var(&width);
magic_clear_var(&depth);
magic_clear_var(&dir);
@@ -1469,7 +1477,7 @@ area_t *eval_area(env_t *env, e_area_t *expr)
default:
FPRINTF(stderr, "INTERNAL ERROR: Unknown area type %d\n",
area->ty);
- free(area);
+ area.delete_();
return NULL;
}
}
@@ -1514,13 +1522,13 @@ int magic_signature_check(const char *opname, const char *funname, const char *s
if (ty == TYPE::ENTITY)
{
/* Dereference entities in preparation for calling function */
- arg->v.v_entity = map_id2bl(arg->v.v_int).operator->();
+ arg->v.v_entity = map_id2bl(arg->v.v_int);
if (!arg->v.v_entity)
ty = arg->ty = TYPE::FAIL;
}
else if (ty == TYPE::INVOCATION)
{
- arg->v.v_invocation = map_id2bl(arg->v.v_int)->as_spell().operator->();
+ arg->v.v_invocation = map_id2bl(arg->v.v_int)->as_spell();
if (!arg->v.v_entity)
ty = arg->ty = TYPE::FAIL;
}
@@ -1584,11 +1592,8 @@ int magic_signature_check(const char *opname, const char *funname, const char *s
return 0;
}
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wshadow"
-void magic_eval(env_t *env, val_t *dest, expr_t *expr)
+void magic_eval(dumb_ptr<env_t> env, val_t *dest, dumb_ptr<expr_t> expr)
{
-#pragma GCC diagnostic pop
switch (expr->ty)
{
case EXPR::VAL:
@@ -1603,7 +1608,7 @@ void magic_eval(env_t *env, val_t *dest, expr_t *expr)
break;
case EXPR::AREA:
- if ((dest->v.v_area = eval_area(env, &expr->e.e_area)))
+ if ((dest->v.v_area = eval_area(env, expr->e.e_area)))
dest->ty = TYPE::AREA;
else
dest->ty = TYPE::FAIL;
@@ -1619,8 +1624,8 @@ void magic_eval(env_t *env, val_t *dest, expr_t *expr)
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, args_nr, arguments,
- expr->e.e_funapp.line_nr, expr->e.e_funapp.column)
- || f->fun(env, args_nr, dest, arguments))
+ expr->e.e_funapp.line_nr, expr->e.e_funapp.column)
+ || f->fun(env, dest, const_array<val_t>(arguments, args_nr)))
dest->ty = TYPE::FAIL;
else
{
@@ -1645,7 +1650,7 @@ void magic_eval(env_t *env, val_t *dest, expr_t *expr)
case EXPR::ID:
{
- val_t v = VAR(expr->e.e_id);
+ val_t v = env->VAR(expr->e.e_id);
magic_copy_var(dest, &v);
break;
}
@@ -1664,11 +1669,7 @@ void magic_eval(env_t *env, val_t *dest, expr_t *expr)
dest->ty = TYPE::UNDEF;
else
{
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wshadow"
- env_t *env = t->env;
-#pragma GCC diagnostic pop
- val_t val = VAR(id);
+ val_t val = t->env->VAR(id);
magic_copy_var(dest, &val);
}
}
@@ -1676,7 +1677,7 @@ void magic_eval(env_t *env, val_t *dest, expr_t *expr)
{
FPRINTF(stderr,
"[magic] Attempt to access field %s on non-spell\n",
- env->base_env->var_name[id]);
+ env->base_env->varv[id].name);
dest->ty = TYPE::FAIL;
}
break;
@@ -1690,7 +1691,7 @@ void magic_eval(env_t *env, val_t *dest, expr_t *expr)
}
}
-int magic_eval_int(env_t *env, expr_t *expr)
+int magic_eval_int(dumb_ptr<env_t> env, dumb_ptr<expr_t> expr)
{
val_t result;
magic_eval(env, &result, expr);
@@ -1703,22 +1704,22 @@ int magic_eval_int(env_t *env, expr_t *expr)
return result.v.v_int;
}
-char *magic_eval_str(env_t *env, expr_t *expr)
+std::string 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 strdup("?");
+ return "?";
stringify(&result, 0);
- return result.v.v_string;
+ return result.v.v_string.str();
}
-expr_t *magic_new_expr(EXPR ty)
+dumb_ptr<expr_t> magic_new_expr(EXPR ty)
{
- expr_t *expr = (expr_t *) malloc(sizeof(expr_t));
+ auto expr = dumb_ptr<expr_t>::make();
expr->ty = ty;
return expr;
}
diff --git a/src/map/magic-expr.hpp b/src/map/magic-expr.hpp
index 419c833..7f3e1e1 100644
--- a/src/map/magic-expr.hpp
+++ b/src/map/magic-expr.hpp
@@ -21,14 +21,14 @@ typedef struct fun
const char *name;
const char *signature;
char ret_ty;
- int(*fun)(env_t *env, int args_nr, val_t *result, val_t *args);
+ int (*fun)(dumb_ptr<env_t> env, val_t *result, const_array<val_t> arga);
} fun_t;
typedef struct op
{
const char *name;
const char *signature;
- int(*op)(env_t *env, int args_nr, val_t *args);
+ int (*op)(dumb_ptr<env_t> env, const_array<val_t> arga);
} op_t;
/**
@@ -36,40 +36,40 @@ typedef struct op
* @param name The name to look up
* @return A function of that name, or NULL, and a function index
*/
-fun_t *magic_get_fun(const char *name, int *index);
+fun_t *magic_get_fun(const std::string& name, int *index);
/**
* 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(char *name, int *index);
+op_t *magic_get_op(const std::string& name, int *index);
/**
* Evaluates an expression and stores the result in `dest'
*/
-void magic_eval(env_t *env, val_t *dest, expr_t *expr);
+void magic_eval(dumb_ptr<env_t> env, val_t *dest, dumb_ptr<expr_t> expr);
/**
* Evaluates an expression and coerces the result into an integer
*/
-int magic_eval_int(env_t *env, expr_t *expr);
+int magic_eval_int(dumb_ptr<env_t> env, dumb_ptr<expr_t> expr);
/**
* Evaluates an expression and coerces the result into a string
*/
-char *magic_eval_str(env_t *env, expr_t *expr);
+std::string magic_eval_str(dumb_ptr<env_t> env, dumb_ptr<expr_t> expr);
-expr_t *magic_new_expr(EXPR ty);
+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_random_location(location_t *dest, area_t *area);
+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(val_t *args, int index, struct item *item, int *stackable);
+int magic_find_item(const_array<val_t> args, int index, struct item *item, int *stackable);
#define GET_ARG_ITEM(index, dest, stackable) \
switch (magic_find_item(args, index, &dest, &stackable)) \
@@ -79,6 +79,6 @@ int magic_find_item(val_t *args, int index, struct item *item, int *stackable);
default: break; \
}
-int magic_location_in_area(int m, int x, int y, area_t *area);
+int magic_location_in_area(map_local *m, int x, int y, dumb_ptr<area_t> area);
#endif // MAGIC_EXPR_HPP
diff --git a/src/map/magic-interpreter-aux.hpp b/src/map/magic-interpreter-aux.hpp
index 4bb0a82..2ff597f 100644
--- a/src/map/magic-interpreter-aux.hpp
+++ b/src/map/magic-interpreter-aux.hpp
@@ -9,10 +9,4 @@ bool CHECK_TYPE(T *v, TYPE t)
return v->ty == t;
}
-// FIXME: macro capture!
-#define VAR(i) \
- ((!env->vars || env->vars[i].ty == TYPE::UNDEF) \
- ? env->base_env->vars[i] \
- : env->vars[i])
-
#endif // MAGIC_INTERPRETER_AUX_HPP
diff --git a/src/map/magic-interpreter-base.cpp b/src/map/magic-interpreter-base.cpp
index 775e7e4..e6c1f37 100644
--- a/src/map/magic-interpreter-base.cpp
+++ b/src/map/magic-interpreter-base.cpp
@@ -17,6 +17,7 @@ void set_int_p(val_t *v, int i, TYPE t)
v->v.v_int = i;
}
+#warning "This code should die"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-macros"
@@ -26,7 +27,7 @@ void set_int_p(val_t *v, int i, TYPE t)
#define SETTER(tty, dyn_ty, field) (val_t *v, tty x) { v->ty = dyn_ty; v->v.field = x; }
static
-void set_string SETTER(char *, TYPE::STRING, v_string)
+void set_string SETTER(dumb_string, TYPE::STRING, v_string)
static
void set_entity(val_t *v, dumb_ptr<block_list> e)
@@ -43,9 +44,9 @@ void set_invocation(val_t *v, dumb_ptr<invocation> i)
}
static
-void set_spell SETTER(spell_t *, TYPE::SPELL, v_spell)
+void set_spell SETTER(dumb_ptr<spell_t>, TYPE::SPELL, v_spell)
-#define setenv(f, v, x) f(&(env->vars[v]), x)
+#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)
@@ -61,100 +62,45 @@ void set_spell SETTER(spell_t *, TYPE::SPELL, v_spell)
magic_conf_t magic_conf; /* Global magic conf */
env_t magic_default_env = { &magic_conf, NULL };
-static
-int spells_sorted = 0;
-
-const char *magic_find_invocation(const char *spellname)
+const char *magic_find_invocation(const std::string& spellname)
{
- int i;
-
- for (i = 0; i < abs(magic_conf.spells_nr); i++)
- if (!strcmp(magic_conf.spells[i]->name, spellname))
- return magic_conf.spells[i]->invocation;
+ auto it = magic_conf.spells_by_name.find(spellname);
+ if (it != magic_conf.spells_by_name.end())
+ return it->second->invocation.c_str();
return NULL;
}
-static
-int spell_compare(const void *lhs, const void *rhs)
-{
- return strcmp((*((const spell_t *const*) lhs))->invocation,
- (*((const spell_t *const*) rhs))->invocation);
-}
-
-spell_t *magic_find_spell(char *invocation)
+dumb_ptr<spell_t> magic_find_spell(const std::string& invocation)
{
- spell_t key;
- spell_t *keyp = &key;
- spell_t **retval;
+ auto it = magic_conf.spells_by_invocation.find(invocation);
+ if (it != magic_conf.spells_by_invocation.end())
+ return it->second;
- if (!spells_sorted)
- {
- qsort(magic_conf.spells, magic_conf.spells_nr, sizeof(spell_t *),
- spell_compare);
- spells_sorted = 1;
- }
-
- key.invocation = invocation;
-
- retval =
- ((spell_t **)
- bsearch(&keyp, magic_conf.spells, magic_conf.spells_nr,
- sizeof(spell_t *), spell_compare));
-
- if (!retval)
- return NULL;
- else
- return *retval;
+ return NULL;
}
/* -------------------------------------------------------------------------------- */
/* Spell anchors */
/* -------------------------------------------------------------------------------- */
-static
-int compare_teleport_anchor(const void *lhs, const void *rhs)
-{
- return strcmp((*((const teleport_anchor_t *const*) lhs))->invocation,
- (*((const teleport_anchor_t *const*) rhs))->invocation);
-}
-
-const char *magic_find_anchor_invocation(const char *anchor_name)
+const char *magic_find_anchor_invocation(const std::string& anchor_name)
{
- int i;
+ auto it = magic_conf.anchors_by_name.find(anchor_name);
- for (i = 0; i < abs(magic_conf.anchors_nr); i++)
- if (!strcmp(magic_conf.anchors[i]->name, anchor_name))
- return magic_conf.anchors[i]->invocation;
+ if (it != magic_conf.anchors_by_name.end())
+ return it->second->invocation.c_str();
return NULL;
}
-teleport_anchor_t *magic_find_anchor(char *name)
+dumb_ptr<teleport_anchor_t> magic_find_anchor(const std::string& name)
{
- teleport_anchor_t key;
- teleport_anchor_t *keyp = &key;
- teleport_anchor_t **retval;
-
- if (magic_conf.anchors_nr > 0)
- { /* unsorted */
- qsort(magic_conf.anchors, magic_conf.anchors_nr,
- sizeof(teleport_anchor_t *), compare_teleport_anchor);
- magic_conf.anchors_nr = -magic_conf.anchors_nr;
- }
-
- key.invocation = name;
-
- retval = (teleport_anchor_t **) bsearch(&keyp,
- magic_conf.anchors,
- -magic_conf.anchors_nr,
- sizeof(teleport_anchor_t *),
- compare_teleport_anchor);
+ auto it = magic_conf.anchors_by_invocation.find(name);
+ if (it != magic_conf.anchors_by_invocation.end())
+ return it->second;
- if (!retval)
- return NULL;
- else
- return *retval;
+ return NULL;
}
/* -------------------------------------------------------------------------------- */
@@ -162,63 +108,59 @@ teleport_anchor_t *magic_find_anchor(char *name)
/* -------------------------------------------------------------------------------- */
static
-env_t *alloc_env(magic_conf_t *conf)
+dumb_ptr<env_t> alloc_env(magic_conf_t *conf)
{
- env_t *env;
- CREATE(env, env_t, 1);
- CREATE(env->vars, val_t, conf->vars_nr);
+ auto env = dumb_ptr<env_t>::make();
+ env->varu = make_unique<val_t[]>(conf->varv.size());
env->base_env = conf;
return env;
}
static
-env_t *clone_env(env_t *src)
+dumb_ptr<env_t> clone_env(dumb_ptr<env_t> src)
{
- env_t *retval = alloc_env(src->base_env);
- int i;
+ dumb_ptr<env_t> retval = alloc_env(src->base_env);
- for (i = 0; i < src->base_env->vars_nr; i++)
- magic_copy_var(&retval->vars[i], &src->vars[i]);
+ for (int i = 0; i < src->base_env->varv.size(); i++)
+ magic_copy_var(&retval->varu[i], &src->varu[i]);
return retval;
}
-void magic_free_env(env_t *env)
+void magic_free_env(dumb_ptr<env_t> env)
{
- int i;
- for (i = 0; i < env->base_env->vars_nr; i++)
- magic_clear_var(&env->vars[i]);
- free(env);
+ for (int i = 0; i < env->base_env->varv.size(); i++)
+ magic_clear_var(&env->varu[i]);
+ // handled by std::unique_ptr now. Was a memory leak before.
+ // delete[] env->vars;
+ env.delete_();
}
-env_t *spell_create_env(magic_conf_t *conf, spell_t *spell,
- dumb_ptr<map_session_data> caster, int spellpower, char *param)
+dumb_ptr<env_t> spell_create_env(magic_conf_t *conf, dumb_ptr<spell_t> spell,
+ dumb_ptr<map_session_data> caster, int spellpower, const_string param)
{
- env_t *env = alloc_env(conf);
+ dumb_ptr<env_t> env = alloc_env(conf);
switch (spell->spellarg_ty)
{
case SPELLARG::STRING:
- set_env_string(spell->arg, param);
+ set_env_string(spell->arg, dumb_string::copyc(param));
break;
case SPELLARG::PC:
{
- dumb_ptr<map_session_data> subject = map_nick2sd(param);
+ dumb_ptr<map_session_data> subject = map_nick2sd(std::string(param.begin(), param.end()).c_str());
if (!subject)
subject = caster;
set_env_entity(spell->arg, subject);
- free(param);
break;
}
case SPELLARG::NONE:
- free(param);
break;
default:
- free(param);
FPRINTF(stderr, "Unexpected spellarg type %d\n",
spell->spellarg_ty);
}
@@ -231,24 +173,23 @@ env_t *spell_create_env(magic_conf_t *conf, spell_t *spell,
}
static
-void free_components(component_t ** component_holder)
+void free_components(dumb_ptr<component_t> *component_holder)
{
if (*component_holder == NULL)
return;
free_components(&(*component_holder)->next);
- free(*component_holder);
+ (*component_holder).delete_();
*component_holder = NULL;
}
-void magic_add_component(component_t ** component_holder, int id, int count)
+void magic_add_component(dumb_ptr<component_t> *component_holder, int id, int count)
{
if (count <= 0)
return;
if (*component_holder == NULL)
{
- component_t *component =
- (component_t *) malloc(sizeof(component_t));
+ auto component = dumb_ptr<component_t>::make();
component->next = NULL;
component->item_id = id;
component->count = count;
@@ -256,7 +197,7 @@ void magic_add_component(component_t ** component_holder, int id, int count)
}
else
{
- component_t *component = *component_holder;
+ dumb_ptr<component_t> component = *component_holder;
if (component->item_id == id)
{
component->count += count;
@@ -269,30 +210,28 @@ void magic_add_component(component_t ** component_holder, int id, int count)
}
static
-void copy_components(component_t ** component_holder, component_t *component)
+void copy_components(dumb_ptr<component_t> *component_holder, dumb_ptr<component_t> component)
{
if (component == NULL)
return;
- magic_add_component(component_holder, component->item_id,
- component->count);
+ magic_add_component(component_holder, component->item_id, component->count);
copy_components(component_holder, component->next);
}
typedef struct spellguard_check
{
- component_t *catalysts, *components;
+ dumb_ptr<component_t> catalysts, components;
int mana;
interval_t casttime;
} spellguard_check_t;
static
-int check_prerequisites(dumb_ptr<map_session_data> caster, component_t *component)
+int check_prerequisites(dumb_ptr<map_session_data> caster, dumb_ptr<component_t> component)
{
while (component)
{
- if (pc_count_all_items(caster, component->item_id)
- < component->count)
+ if (pc_count_all_items(caster, component->item_id) < component->count)
return 0; /* insufficient */
component = component->next;
@@ -302,7 +241,7 @@ int check_prerequisites(dumb_ptr<map_session_data> caster, component_t *componen
}
static
-void consume_components(dumb_ptr<map_session_data> caster, component_t *component)
+void consume_components(dumb_ptr<map_session_data> caster, dumb_ptr<component_t> component)
{
while (component)
{
@@ -313,7 +252,7 @@ void consume_components(dumb_ptr<map_session_data> caster, component_t *componen
static
int spellguard_can_satisfy(spellguard_check_t *check, dumb_ptr<map_session_data> caster,
- env_t *env, int *near_miss)
+ dumb_ptr<env_t> env, int *near_miss)
{
tick_t tick = gettick();
@@ -330,8 +269,8 @@ int spellguard_can_satisfy(spellguard_check_t *check, dumb_ptr<map_session_data>
{
interval_t casttime = check->casttime;
- if (VAR(VAR_MIN_CASTTIME).ty == TYPE::INT)
- casttime = max(casttime, static_cast<interval_t>(VAR(VAR_MIN_CASTTIME).v.v_int));
+ if (env->VAR(VAR_MIN_CASTTIME).ty == TYPE::INT)
+ casttime = max(casttime, static_cast<interval_t>(env->VAR(VAR_MIN_CASTTIME).v.v_int));
caster->cast_tick = tick + casttime; /* Make sure not to cast too frequently */
@@ -344,9 +283,10 @@ int spellguard_can_satisfy(spellguard_check_t *check, dumb_ptr<map_session_data>
static
effect_set_t *spellguard_check_sub(spellguard_check_t *check,
- spellguard_t *guard,
- dumb_ptr<map_session_data> caster, env_t *env,
- int *near_miss)
+ dumb_ptr<spellguard_t> guard,
+ dumb_ptr<map_session_data> caster,
+ dumb_ptr<env_t> env,
+ int *near_miss)
{
if (guard == NULL)
return NULL;
@@ -413,9 +353,9 @@ effect_set_t *spellguard_check_sub(spellguard_check_t *check,
}
static
-effect_set_t *check_spellguard(spellguard_t *guard,
- dumb_ptr<map_session_data> caster, env_t *env,
- int *near_miss)
+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;
@@ -436,18 +376,16 @@ effect_set_t *check_spellguard(spellguard_t *guard,
/* Public API */
/* -------------------------------------------------------------------------------- */
-effect_set_t *spell_trigger(spell_t *spell, dumb_ptr<map_session_data> caster,
- env_t *env, int *near_miss)
+effect_set_t *spell_trigger(dumb_ptr<spell_t> spell, dumb_ptr<map_session_data> caster,
+ dumb_ptr<env_t> env, int *near_miss)
{
- int i;
- spellguard_t *guard = spell->spellguard;
+ dumb_ptr<spellguard_t> guard = spell->spellguard;
if (near_miss)
*near_miss = 0;
- for (i = 0; i < spell->letdefs_nr; i++)
- magic_eval(env,
- &env->vars[spell->letdefs[i].id], spell->letdefs[i].expr);
+ for (letdef_t& ld : spell->letdefv)
+ magic_eval(env, &env->varu[ld.id], ld.expr);
return check_spellguard(guard, caster, env, near_miss);
}
@@ -455,11 +393,11 @@ effect_set_t *spell_trigger(spell_t *spell, dumb_ptr<map_session_data> caster,
static
void spell_set_location(dumb_ptr<invocation> invocation, dumb_ptr<block_list> entity)
{
- magic_clear_var(&invocation->env->vars[VAR_LOCATION]);
- invocation->env->vars[VAR_LOCATION].ty = TYPE::LOCATION;
- invocation->env->vars[VAR_LOCATION].v.v_location.m = entity->bl_m;
- invocation->env->vars[VAR_LOCATION].v.v_location.x = entity->bl_x;
- invocation->env->vars[VAR_LOCATION].v.v_location.y = entity->bl_y;
+ 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;
}
void spell_update_location(dumb_ptr<invocation> invocation)
@@ -477,7 +415,7 @@ void spell_update_location(dumb_ptr<invocation> invocation)
}
}
-dumb_ptr<invocation> spell_instantiate(effect_set_t *effect_set, env_t *env)
+dumb_ptr<invocation> spell_instantiate(effect_set_t *effect_set, dumb_ptr<env_t> env)
{
dumb_ptr<invocation> retval;
retval.new_();
@@ -485,8 +423,8 @@ dumb_ptr<invocation> spell_instantiate(effect_set_t *effect_set, env_t *env)
retval->env = env;
- retval->caster = VAR(VAR_CASTER).v.v_int;
- retval->spell = VAR(VAR_SPELL).v.v_spell;
+ retval->caster = env->VAR(VAR_CASTER).v.v_int;
+ retval->spell = env->VAR(VAR_SPELL).v.v_spell;
retval->stack_size = 0;
retval->current_effect = effect_set->effect;
retval->trigger_effect = effect_set->at_trigger;
@@ -516,7 +454,7 @@ dumb_ptr<invocation> spell_clone_effect(dumb_ptr<invocation> base)
retval->next_invocation = NULL;
retval->flags = INVOCATION_FLAG::ZERO;
- env_t *env = retval->env = clone_env(base->env);
+ dumb_ptr<env_t> env = retval->env = clone_env(base->env);
retval->spell = base->spell;
retval->caster = base->caster;
retval->subject = 0;
@@ -528,8 +466,7 @@ dumb_ptr<invocation> spell_clone_effect(dumb_ptr<invocation> base)
retval->current_effect = base->trigger_effect;
retval->trigger_effect = base->trigger_effect;
retval->end_effect = NULL;
- retval->status_change_refs_nr = 0;
- retval->status_change_refs = NULL;
+ // retval->status_change_refs = NULL;
retval->bl_id = 0;
retval->bl_prev = NULL;
@@ -568,7 +505,7 @@ void spell_bind(dumb_ptr<map_session_data> subject, dumb_ptr<invocation> invocat
invocation->subject = subject->bl_id;
}
- spell_set_location(invocation, (dumb_ptr<block_list> ) subject);
+ spell_set_location(invocation, subject);
}
int spell_unbind(dumb_ptr<map_session_data> subject, dumb_ptr<invocation> invocation_)
diff --git a/src/map/magic-interpreter-lexer.lpp b/src/map/magic-interpreter-lexer.lpp
index f593d4a..c0a554b 100644
--- a/src/map/magic-interpreter-lexer.lpp
+++ b/src/map/magic-interpreter-lexer.lpp
@@ -102,24 +102,25 @@
"WAIT" {FIXLOC; return SLEEP;}
\{([^\}]|\\.)*\} {
- char *string = strdup(yytext);
- magic_frontend_lval.s = string;
+ magic_frontend_lval.s = dumb_string::copy(yytext);
FIXLOC;
return SCRIPT_DATA;
}
\"([^\"]|\\.)*\" {
- char *string = strdup(yytext + 1);
- char *src = string;
- char *dst = string;
+ dumb_string string = dumb_string::copy(yytext + 1);
+ const char *src = string.c_str();
+ char *dst = &string[0];
while (*src && *src != '"')
- if (*src == '\\')
{
- *dst++ = src[1];
- src += 2;
+ if (*src == '\\')
+ {
+ *dst++ = src[1];
+ src += 2;
+ }
+ else
+ *dst++ = *src++;
}
- else
- *dst++ = *src++;
*dst = '\0'; /* terminate */
magic_frontend_lval.s = string;
FIXLOC;
@@ -139,7 +140,7 @@
}
[a-zA-Z][-_a-zA-Z0-9]* {
- magic_frontend_lval.s = strdup(yytext);
+ magic_frontend_lval.s = dumb_string::copy(yytext);
FIXLOC;
return ID;
}
diff --git a/src/map/magic-interpreter-parser.ypp b/src/map/magic-interpreter-parser.ypp
index 2baa854..2cec1f2 100644
--- a/src/map/magic-interpreter-parser.ypp
+++ b/src/map/magic-interpreter-parser.ypp
@@ -7,8 +7,10 @@
{
#include "magic-interpreter-parser.hpp"
+#include <cassert>
#include <cstdarg> // exception to "no va_list" rule, even after cxxstdio
+#include "../common/const_array.hpp"
#include "../common/cxxstdio.hpp"
#include "itemdb.hpp"
@@ -17,22 +19,26 @@
// I still don't get why this is necessary.
#define YYLEX_PARAM 0, 0
+#pragma GCC diagnostic warning "-Wall"
+#pragma GCC diagnostic warning "-Wextra"
+#pragma GCC diagnostic warning "-Wformat"
+
static
-int intern_id(const char *id_name);
+size_t intern_id(const_string id_name);
static
-expr_t *fun_expr(const char *name, int args_nr, expr_t **args, int line, int column);
+dumb_ptr<expr_t> fun_expr(const std::string& name, const_array<dumb_ptr<expr_t>> argv, int line, int column);
static
-expr_t *dot_expr(expr_t *lhs, int id);
+dumb_ptr<expr_t> dot_expr(dumb_ptr<expr_t> lhs, int id);
static
-void BIN_EXPR(expr_t *& x, const char *name, expr_t *arg1, expr_t *arg2, int line, int column)
+void BIN_EXPR(dumb_ptr<expr_t> & x, const std::string& name, dumb_ptr<expr_t> arg1, dumb_ptr<expr_t> arg2, int line, int column)
{
- expr_t *e[2];
+ dumb_ptr<expr_t> e[2];
e[0] = arg1;
e[1] = arg2;
- x = fun_expr(name, 2, e, line, column);
+ x = fun_expr(name, const_array<dumb_ptr<expr_t>>(e, 2), line, column);
}
static
@@ -41,47 +47,47 @@ int failed_flag = 0;
static
void magic_frontend_error(const char *msg);
-static
+static __attribute__((format(printf, 3, 4)))
void fail(int line, int column, const char *fmt, ...);
static
-spell_t *new_spell(spellguard_t *guard);
+dumb_ptr<spell_t> new_spell(dumb_ptr<spellguard_t> guard);
static
-spellguard_t *spellguard_implication(spellguard_t *a, spellguard_t *b);
+dumb_ptr<spellguard_t> spellguard_implication(dumb_ptr<spellguard_t> a, dumb_ptr<spellguard_t> b);
static
-spellguard_t *new_spellguard(SPELLGUARD ty);
+dumb_ptr<spellguard_t> new_spellguard(SPELLGUARD ty);
static
-effect_t *new_effect(EFFECT ty);
+dumb_ptr<effect_t> new_effect(EFFECT ty);
static
-effect_t *set_effect_continuation(effect_t *src, effect_t *continuation);
+dumb_ptr<effect_t> set_effect_continuation(dumb_ptr<effect_t> src, dumb_ptr<effect_t> continuation);
static
-void add_spell(spell_t *spell, int line_nr);
+void add_spell(dumb_ptr<spell_t> spell, int line_nr);
static
-void add_teleport_anchor(teleport_anchor_t *anchor, int line_nr);
+void add_teleport_anchor(dumb_ptr<teleport_anchor_t> anchor, int line_nr);
static
-effect_t *op_effect(char *name, int args_nr, expr_t **args, int line, int column);
+dumb_ptr<effect_t> op_effect(const std::string& name, const_array<dumb_ptr<expr_t>> argv, int line, int column);
// in magic-interpreter-lexer.cpp
int magic_frontend_lex(YYSTYPE *, YYLTYPE *);
static
-void install_proc(proc_t *proc);
+void install_proc(dumb_ptr<proc_t> proc);
static
-effect_t *call_proc(char *name, int args_nr, expr_t **args, int line_nr, int column);
+dumb_ptr<effect_t> call_proc(const_string name, dumb_ptr<std::vector<dumb_ptr<expr_t>>> argvp, int line_nr, int column);
static
-void bind_constant(char *name, val_t *val, int line_nr);
+void bind_constant(const std::string& name, val_t *val, int line_nr);
static
-val_t *find_constant(char *name);
+val_t *find_constant(const std::string& name);
} // %code
@@ -95,23 +101,29 @@ val_t *find_constant(char *name);
SPELL_FLAG spell_flags;
SPELLARG spell_arg;
FOREACH_FILTER foreach_filter;
- char *s;
+ dumb_string s;
int op;
- magic_conf_t *magic_conf;
+ // magic_conf_t *magic_conf;
val_t value;
- expr_t *expr;
+ dumb_ptr<expr_t> expr;
e_location_t location;
e_area_t area;
args_rec_t arg_list;
- struct { int letdefs_nr; letdef_t *letdefs; } letdefs;
- spell_t *spell;
+ dumb_ptr<std::vector<letdef_t>> letdefvp;
+ dumb_ptr<spell_t> spell;
struct { int id; SPELLARG ty; } spellarg_def;
letdef_t vardef;
- spellguard_t *spellguard;
- component_t *components;
- struct {int id, count; } component;
- effect_t *effect;
- proc_t *proc;
+ dumb_ptr<spellguard_t> spellguard;
+ dumb_ptr<component_t> components;
+ struct { int id, count; } component;
+ dumb_ptr<effect_t> effect;
+ dumb_ptr<proc_t> proc;
+
+ // evil hackery
+ YYSTYPE() { memset(this, '\0', sizeof(*this)); }
+ ~YYSTYPE() = default;
+ YYSTYPE(const YYSTYPE& rhs) = default;
+ YYSTYPE& operator = (const YYSTYPE& rhs) = default;
} // %union
%expect 7
@@ -193,7 +205,7 @@ val_t *find_constant(char *name);
%type <area> area
%type <arg_list> arg_list
%type <arg_list> arg_list_ne
-%type <letdefs> defs
+%type <letdefvp> defs
%type <spell> spelldef
%type <spellarg_def> argopt
%type <vardef> def
@@ -257,7 +269,7 @@ proc_formals_list
: /* empty */
{
- CREATE($$, proc_t, 1);
+ $$ = dumb_ptr<proc_t>::make();
}
| proc_formals_list_ne
@@ -272,17 +284,16 @@ proc_formals_list_ne
: ID
{
- CREATE($$, proc_t, 1);
- $$->args_nr = 1;
- $$->args = (int*)malloc(sizeof(int));
- $$->args[0] = intern_id($1);
+ $$ = dumb_ptr<proc_t>::make();
+ $$->argv.push_back(intern_id($1));
+ $1.delete_();
}
| proc_formals_list_ne ',' ID
{
$$ = $1;
- $$->args = (int *)realloc($$->args, sizeof(int) * (1 + $$->args_nr));
- $$->args[$$->args_nr++] = intern_id($3);
+ $$->argv.push_back(intern_id($3));
+ $3.delete_();
}
;
@@ -292,56 +303,59 @@ spellconf_option
: ID '=' expr
{
- int var_id;
- if (find_constant($1))
+ if (find_constant($1.str()))
{
- fail(@1.first_line, 0, "Attempt to redefine constant `%s' as global\n", $1);
- free($1);
+ fail(@1.first_line, 0, "Attempt to redefine constant `%s' as global\n", $1.c_str());
}
else
{
- var_id = intern_id($1);
- magic_eval(&magic_default_env, &magic_conf.vars[var_id], $3);
+ int var_id = intern_id($1);
+ magic_eval(dumb_ptr<env_t>(&magic_default_env), &magic_conf.varv[var_id].val, $3);
}
+ $1.delete_();
}
| CONST ID '=' expr
{
val_t var;
- magic_eval(&magic_default_env, &var, $4);
- bind_constant($2, &var, @1.first_line);
+ magic_eval(dumb_ptr<env_t>(&magic_default_env), &var, $4);
+ bind_constant($2.str(), &var, @1.first_line);
+ $2.delete_();
}
| TELEPORT_ANCHOR ID ':' expr '=' expr
{
- teleport_anchor_t *anchor;
- CREATE(anchor, teleport_anchor_t, 1);
- anchor->name = $2;
- anchor->invocation = magic_eval_str(&magic_default_env, $4);
- anchor->location = $6;
+ auto anchor = dumb_ptr<teleport_anchor_t>::make();
+ anchor->name = $2.str();
+ $2.delete_();
+ anchor->invocation = magic_eval_str(dumb_ptr<env_t>(&magic_default_env), $4);
+ anchor->location = $6;
- if (!failed_flag)
- add_teleport_anchor(anchor, @1.first_line);
- else
- free(anchor);
- failed_flag = 0;
+ if (!failed_flag)
+ add_teleport_anchor(anchor, @1.first_line);
+ else
+ anchor.delete_();
+ failed_flag = 0;
}
| PROCEDURE ID '(' proc_formals_list ')' '=' effect_list
{
- proc_t *proc = $4;
- proc->name = $2;
- proc->body = $7;
- if (!failed_flag)
- install_proc(proc);
- failed_flag = 0;
+ dumb_ptr<proc_t> proc = $4;
+ proc->name = $2.str();
+ $2.delete_();
+ proc->body = $7;
+ if (!failed_flag)
+ install_proc(proc);
+ proc.delete_();
+ failed_flag = 0;
}
| spell_flags SPELL ID argopt ':' expr '=' spelldef
{
- spell_t *spell = $8;
- spell->name = $3;
- spell->invocation = magic_eval_str(&magic_default_env, $6);
+ dumb_ptr<spell_t> spell = $8;
+ spell->name = $3.str();
+ $3.delete_();
+ spell->invocation = magic_eval_str(dumb_ptr<env_t>(&magic_default_env), $6);
spell->arg = $4.id;
spell->spellarg_ty = $4.ty;
spell->flags = $1;
@@ -394,6 +408,7 @@ argopt
| '(' ID ':' arg_ty ')'
{
$$.id = intern_id($2);
+ $2.delete_();
$$.ty = $4;
}
@@ -448,8 +463,8 @@ expr
| ID
{
- val_t *val;
- if ((val = find_constant($1)))
+ val_t *val = find_constant($1.str());
+ if (val)
{
$$ = magic_new_expr(EXPR::VAL);
$$->e.e_val = *val;
@@ -459,6 +474,7 @@ expr
$$ = magic_new_expr(EXPR::ID);
$$->e.e_id = intern_id($1);
}
+ $1.delete_();
}
| area
@@ -560,15 +576,14 @@ expr
| expr NEQ expr
{
BIN_EXPR($$, "=", $1, $3, @1.first_line, @1.first_column);
- $$ = fun_expr("not", 1, &$$, @1.first_line, @1.first_column);
+ $$ = fun_expr("not", const_array<dumb_ptr<expr_t>>(&$$, 1), @1.first_line, @1.first_column);
}
| ID '(' arg_list ')'
{
- $$ = fun_expr($1, $3.args_nr, $3.args, @1.first_line, @1.first_column);
- if ($3.args)
- free($3.args);
- free($1);
+ $$ = fun_expr($1.str(), *$3.argvp, @1.first_line, @1.first_column);
+ $3.argvp.delete_();
+ $1.delete_(); // allocated from m-i-lexer.lpp
}
| '(' expr ')'
@@ -579,6 +594,7 @@ expr
| expr '.' ID
{
$$ = dot_expr($1, intern_id($3));
+ $3.delete_();
}
;
@@ -588,7 +604,7 @@ arg_list
: /* empty */
{
- $$.args_nr = 0;
+ $$.argvp.new_();
}
| arg_list_ne
@@ -603,15 +619,15 @@ arg_list_ne
: expr
{
- CREATE($$.args, expr_t *, 1);
- $$.args_nr = 1;
- $$.args[0] = $1;
+ $$.argvp.new_();
+ $$.argvp->push_back($1);
}
| arg_list_ne ',' expr
{
- RECREATE($$.args, expr_t *, 1 + $$.args_nr);
- $$.args[$$.args_nr++] = $3;
+ // yikes! Fate is officially banned from ever touching my code again.
+ $$ = $1;
+ $$.argvp->push_back($3);
}
;
@@ -667,8 +683,8 @@ spelldef
| LET defs IN spellbody_list
{
$$ = new_spell($4);
- $$->letdefs_nr = $2.letdefs_nr;
- $$->letdefs = $2.letdefs;
+ $$->letdefv = std::move(*$2);
+ $2.delete_();
$$->spellguard = $4;
}
@@ -679,16 +695,13 @@ defs
: semicolons
{
- $$.letdefs_nr = 0;
- CREATE($$.letdefs, letdef_t, 1);
+ $$.new_();
}
| defs def semicolons
{
$$ = $1;
- $$.letdefs_nr++;
- RECREATE($$.letdefs, letdef_t, $$.letdefs_nr);
- $$.letdefs[$1.letdefs_nr] = $2;
+ $$->push_back($2);
}
;
@@ -698,16 +711,16 @@ def
: ID '=' expr
{
- if (find_constant($1))
+ if (find_constant($1.str()))
{
- fail(@1.first_line, @1.first_column, "Attempt to re-define constant `%s' as LET-bound variable.\n", $1);
- free($1);
+ fail(@1.first_line, @1.first_column, "Attempt to re-define constant `%s' as LET-bound variable.\n", $1.c_str());
}
else
{
$$.id = intern_id($1);
$$.expr = $3;
}
+ $1.delete_();
}
;
@@ -722,7 +735,7 @@ spellbody_list
| spellbody '|' spellbody_list
{
- spellguard_t *sg = new_spellguard(SPELLGUARD::CHOICE);
+ dumb_ptr<spellguard_t> sg = new_spellguard(SPELLGUARD::CHOICE);
sg->next = $1;
sg->s.s_alt = $3;
$$ = sg;
@@ -745,7 +758,7 @@ spellbody
| EFFECT_ effect_list maybe_trigger maybe_end
{
- spellguard_t *sg = new_spellguard(SPELLGUARD::EFFECT);
+ dumb_ptr<spellguard_t> sg = new_spellguard(SPELLGUARD::EFFECT);
sg->s.s_effect.effect = $2;
sg->s.s_effect.at_trigger = $3;
sg->s.s_effect.at_end = $4;
@@ -794,7 +807,7 @@ spellguard
| spellguard OR spellguard
{
- spellguard_t *sg = new_spellguard(SPELLGUARD::CHOICE);
+ dumb_ptr<spellguard_t> sg = new_spellguard(SPELLGUARD::CHOICE);
sg->next = $1;
sg->s.s_alt = $3;
$$ = sg;
@@ -906,15 +919,15 @@ item_name
: STRING
{
- struct item_data *item = itemdb_searchname($1);
+ struct item_data *item = itemdb_searchname($1.c_str());
if (!item)
{
- fail(@1.first_line, @1.first_column, "Unknown item `%s'\n", $1);
+ fail(@1.first_line, @1.first_column, "Unknown item `%s'\n", $1.c_str());
$$ = 0;
}
else
$$ = item->nameid;
- free($1);
+ $1.delete_();
}
| INT
@@ -989,10 +1002,9 @@ effect
| ID '=' expr ';'
{
- if (find_constant($1))
+ if (find_constant($1.str()))
{
- fail(@1.first_line, @1.first_column, "Attempt to re-define constant `%s' in assignment.", $1);
- free($1);
+ fail(@1.first_line, @1.first_column, "Attempt to re-define constant `%s' in assignment.", $1.c_str());
}
else
{
@@ -1000,12 +1012,14 @@ effect
$$->e.e_assign.id = intern_id($1);
$$->e.e_assign.expr = $3;
}
+ $1.delete_();
}
| FOREACH selection ID IN expr DO effect
{
$$ = new_effect(EFFECT::FOREACH);
$$->e.e_foreach.id = intern_id($3);
+ $3.delete_();
$$->e.e_foreach.area = $5;
$$->e.e_foreach.body = $7;
$$->e.e_foreach.filter = $2;
@@ -1015,6 +1029,7 @@ effect
{
$$ = new_effect(EFFECT::FOR);
$$->e.e_for.id = intern_id($2);
+ $2.delete_();
$$->e.e_for.start = $4;
$$->e.e_for.stop = $6;
$$->e.e_for.body = $8;
@@ -1044,23 +1059,23 @@ effect
| ID '(' arg_list ')' ';'
{
- $$ = op_effect($1, $3.args_nr, $3.args, @1.first_line, @1.first_column);
- free($1);
+ $$ = op_effect($1.str(), *$3.argvp, @1.first_line, @1.first_column);
+ $1.delete_();
}
| SCRIPT_DATA
{
$$ = new_effect(EFFECT::SCRIPT);
- $$->e.e_script = parse_script($1, @1.first_line);
- free($1);
+ $$->e.e_script = dumb_ptr<const ScriptBuffer>(parse_script($1.c_str(), @1.first_line).release());
+ $1.delete_();
if ($$->e.e_script == NULL)
fail(@1.first_line, @1.first_column, "Failed to compile script\n");
}
| CALL ID '(' arg_list ')' ';'
{
- $$ = call_proc($2, $4.args_nr, $4.args, @1.first_line, @1.first_column);
- free($2);
+ $$ = call_proc($2, $4.argvp, @1.first_line, @1.first_column);
+ $2.delete_();
}
;
@@ -1083,84 +1098,63 @@ effect_list
%%
-/* We do incremental realloc here to store our results. Since this happens only once
- * during startup for a relatively manageable set of configs, it should be fine. */
-
-static
-int intern_id(const char *id_name)
+size_t intern_id(const_string id_name_)
{
- int i;
- for (i = 0; i < magic_conf.vars_nr; i++)
- if (!strcmp(id_name, magic_conf.var_name[i]))
- {
- free((char*)id_name);
+ std::string id_name(id_name_.begin(), id_name_.end());
+ size_t i;
+ for (i = 0; i < magic_conf.varv.size(); i++)
+ if (id_name == magic_conf.varv[i].name)
return i;
- }
+ // i = magic_conf.varv.size();
/* Must add new */
- i = magic_conf.vars_nr++;
- RECREATE(magic_conf.var_name, const char *, magic_conf.vars_nr);
- magic_conf.var_name[i] = id_name;
- RECREATE(magic_conf.vars, val_t, magic_conf.vars_nr);
- magic_conf.vars[i].ty = TYPE::UNDEF;
+ magic_conf_t::mcvar new_var {};
+ new_var.name = id_name;
+ new_var.val.ty = TYPE::UNDEF;
+ magic_conf.varv.push_back(new_var);
return i;
}
-static
-void add_spell(spell_t *spell, int line_nr)
+void add_spell(dumb_ptr<spell_t> spell, int line_nr)
{
- int index = magic_conf.spells_nr;
- int i;
-
- for (i = 0; i < index; i++)
+ auto pair1 = magic_conf.spells_by_name.insert({spell->name, spell});
+ if (!pair1.second)
{
- if (!strcmp(magic_conf.spells[i]->name, spell->name))
- {
- fail(line_nr, 0, "Attempt to redefine spell `%s'\n", spell->name);
- return;
- }
- if (!strcmp(magic_conf.spells[i]->invocation, spell->invocation))
- {
- fail(line_nr, 0, "Attempt to redefine spell invocation `%s' between spells `%s' and `%s'\n",
- spell->invocation, magic_conf.spells[i]->name, spell->name);
- return;
- }
+ fail(line_nr, 0, "Attempt to redefine spell `%s'\n", spell->name.c_str());
+ return;
}
- magic_conf.spells_nr++;
- RECREATE(magic_conf.spells, spell_t *, magic_conf.spells_nr);
- magic_conf.spells[index] = spell;
+ auto pair2 = magic_conf.spells_by_invocation.insert({spell->invocation, spell});
+ if (!pair2.second)
+ {
+ fail(line_nr, 0, "Attempt to redefine spell invocation `%s' between spells `%s' and `%s'\n",
+ spell->invocation.c_str(), pair1.first->second->name.c_str(), spell->name.c_str());
+ magic_conf.spells_by_name.erase(pair1.first);
+ return;
+ }
}
-static
-void add_teleport_anchor(teleport_anchor_t *anchor, int line_nr)
+void add_teleport_anchor(dumb_ptr<teleport_anchor_t> anchor, int line_nr)
{
- int index = magic_conf.anchors_nr;
- int i;
-
- for (i = 0; i < index; i++)
+ auto pair1 = magic_conf.anchors_by_name.insert({anchor->name, anchor});
+ if (!pair1.second)
{
- if (!strcmp(magic_conf.anchors[i]->name, anchor->name))
- {
- fail(line_nr, 0, "Attempt to redefine teleport anchor `%s'\n", anchor->name);
- return;
- }
- if (!strcmp(magic_conf.anchors[i]->invocation, anchor->invocation))
- {
- fail(line_nr, 0, "Attempt to redefine anchor invocation `%s' between anchors `%s' and `%s'\n",
- anchor->invocation, magic_conf.anchors[i]->name, anchor->name);
- return;
- }
+ fail(line_nr, 0, "Attempt to redefine teleport anchor `%s'\n", anchor->name.c_str());
+ return;
}
- magic_conf.anchors_nr++;
- RECREATE(magic_conf.anchors, teleport_anchor_t *, magic_conf.anchors_nr);
- magic_conf.anchors[index] = anchor;
+ auto pair2 = magic_conf.anchors_by_invocation.insert({anchor->name, anchor});
+ if (!pair2.second)
+ {
+ fail(line_nr, 0, "Attempt to redefine anchor invocation `%s' between anchors `%s' and `%s'\n",
+ anchor->invocation.c_str(), pair1.first->second->name.c_str(), anchor->name.c_str());
+ magic_conf.anchors_by_name.erase(pair1.first);
+ return;
+ }
}
-static __attribute__((format(printf, 3, 4)))
void fail(int line, int column, const char *fmt, ...)
{
va_list ap;
@@ -1170,43 +1164,41 @@ void fail(int line, int column, const char *fmt, ...)
failed_flag = 1;
}
-static
-expr_t *dot_expr(expr_t *expr, int id)
+dumb_ptr<expr_t> dot_expr(dumb_ptr<expr_t> expr, int id)
{
- expr_t *retval = magic_new_expr(EXPR::SPELLFIELD);
+ dumb_ptr<expr_t> retval = magic_new_expr(EXPR::SPELLFIELD);
retval->e.e_field.id = id;
retval->e.e_field.expr = expr;
return retval;
}
-static
-expr_t *fun_expr(const char *name, int args_nr, expr_t **args, int line, int column)
+dumb_ptr<expr_t> fun_expr(const std::string& name, const_array<dumb_ptr<expr_t>> argv, int line, int column)
{
int id;
- expr_t *expr;
+ dumb_ptr<expr_t> expr;
fun_t *fun = magic_get_fun(name, &id);
if (!fun)
- fail(line, column, "Unknown function `%s'\n", name);
- else if (strlen(fun->signature) != args_nr)
+ fail(line, column, "Unknown function `%s'\n", name.c_str());
+ else if (strlen(fun->signature) != argv.size())
{
- fail(line, column, "Incorrect number of arguments to function `%s': Expected %zu, found %d\n", name, strlen(fun->signature), args_nr);
+ fail(line, column, "Incorrect number of arguments to function `%s': Expected %zu, found %zu\n",
+ name.c_str(), strlen(fun->signature), argv.size());
fun = NULL;
}
if (fun)
{
- int i;
-
expr = magic_new_expr(EXPR::FUNAPP);
expr->e.e_funapp.line_nr = line;
expr->e.e_funapp.column = column;
expr->e.e_funapp.id = id;
- expr->e.e_funapp.args_nr = args_nr;
- for (i = 0; i < args_nr; i++)
- expr->e.e_funapp.args[i] = args[i];
+ assert (argv.size() < MAX_ARGS);
+ expr->e.e_funapp.args_nr = argv.size();
+
+ std::copy(argv.begin(), argv.end(), expr->e.e_funapp.args);
}
else
{
@@ -1218,29 +1210,26 @@ expr_t *fun_expr(const char *name, int args_nr, expr_t **args, int line, int col
return expr;
}
-static
-spell_t *new_spell(spellguard_t *guard)
+dumb_ptr<spell_t> new_spell(dumb_ptr<spellguard_t> guard)
{
static int spell_counter = 0;
- spell_t *retval = (spell_t*)calloc(1, sizeof(spell_t));
- retval->index = ++spell_counter;
+ auto retval = dumb_ptr<spell_t>::make();
+ retval->index_ = ++spell_counter;
retval->spellguard = guard;
return retval;
}
-static
-spellguard_t *new_spellguard(SPELLGUARD ty)
+dumb_ptr<spellguard_t> new_spellguard(SPELLGUARD ty)
{
- spellguard_t *retval = (spellguard_t *)calloc(1, sizeof(spellguard_t));
+ dumb_ptr<spellguard_t> retval = dumb_ptr<spellguard_t>::make();
retval->ty = ty;
return retval;
}
-static
-spellguard_t *spellguard_implication(spellguard_t *a, spellguard_t *b)
+dumb_ptr<spellguard_t> spellguard_implication(dumb_ptr<spellguard_t> a, dumb_ptr<spellguard_t> b)
{
- spellguard_t *retval = a;
+ dumb_ptr<spellguard_t> retval = a;
if (a == b)
{
@@ -1269,18 +1258,16 @@ spellguard_t *spellguard_implication(spellguard_t *a, spellguard_t *b)
return retval;
}
-static
-effect_t *new_effect(EFFECT ty)
+dumb_ptr<effect_t> new_effect(EFFECT ty)
{
- effect_t *effect = (effect_t *) calloc(1, sizeof(effect_t));
+ auto effect = dumb_ptr<effect_t>::make();
effect->ty = ty;
return effect;
}
-static
-effect_t *set_effect_continuation(effect_t *src, effect_t *continuation)
+dumb_ptr<effect_t> set_effect_continuation(dumb_ptr<effect_t> src, dumb_ptr<effect_t> continuation)
{
- effect_t *retval = src;
+ dumb_ptr<effect_t> retval = src;
/* This function is completely analogous to `spellguard_implication' above; read the control flow implications above first before pondering it. */
if (src == continuation)
@@ -1301,33 +1288,31 @@ effect_t *set_effect_continuation(effect_t *src, effect_t *continuation)
return retval;
}
-static
-effect_t *op_effect(char *name, int args_nr, expr_t **args, int line, int column)
+dumb_ptr<effect_t> op_effect(const std::string& name, const_array<dumb_ptr<expr_t>> argv, int line, int column)
{
int id;
- effect_t *effect;
+ dumb_ptr<effect_t> effect;
op_t *op = magic_get_op(name, &id);
if (!op)
- fail(line, column, "Unknown operation `%s'\n", name);
- else if (strlen(op->signature) != args_nr)
+ fail(line, column, "Unknown operation `%s'\n", name.c_str());
+ else if (strlen(op->signature) != argv.size())
{
- fail(line, column, "Incorrect number of arguments to operation `%s': Expected %zu, found %d\n", name, strlen(op->signature), args_nr);
+ fail(line, column, "Incorrect number of arguments to operation `%s': Expected %zu, found %zu\n",
+ name.c_str(), strlen(op->signature), argv.size());
op = NULL;
}
if (op)
{
- int i;
-
effect = new_effect(EFFECT::OP);
effect->e.e_op.line_nr = line;
effect->e.e_op.column = column;
effect->e.e_op.id = id;
- effect->e.e_op.args_nr = args_nr;
+ assert (argv.size() < MAX_ARGS);
+ effect->e.e_op.args_nr = argv.size();
- for (i = 0; i < args_nr; i++)
- effect->e.e_op.args[i] = args[i];
+ std::copy(argv.begin(), argv.end(), effect->e.e_op.args);
}
else /* failure */
effect = new_effect(EFFECT::SKIP);
@@ -1336,99 +1321,55 @@ effect_t *op_effect(char *name, int args_nr, expr_t **args, int line, int column
}
-proc_t *procs = NULL;
-int procs_nr = 0;
+std::map<std::string, proc_t> procs;
-// I think this is a memory leak, or undefined behavior
-static
-void install_proc(proc_t *proc)
+// I think this was a memory leak (or undefined behavior)
+void install_proc(dumb_ptr<proc_t> proc)
{
- if (!procs)
- {
- procs = proc;
- procs_nr = 1;
- }
- else
- {
- RECREATE(procs, proc_t, 1 + procs_nr);
- procs[procs_nr++] = *proc;
- }
+ procs.insert({proc->name, std::move(*proc)});
}
-static
-effect_t *call_proc(char *name, int args_nr, expr_t **args, int line_nr, int column)
+dumb_ptr<effect_t> call_proc(const_string name_, dumb_ptr<std::vector<dumb_ptr<expr_t>>> argvp, int line_nr, int column)
{
- proc_t *p = NULL;
- int i;
- effect_t *retval;
-
- for (i = 0; i < procs_nr; i++)
- if (!strcmp(procs[i].name, name))
- {
- p = &procs[i];
- break;
- }
-
- if (!p)
+ std::string name(name_.begin(), name_.end());
+ auto pi = procs.find(name);
+ if (pi == procs.end())
{
- fail(line_nr, column, "Unknown procedure `%s'\n", name);
+ fail(line_nr, column, "Unknown procedure `%s'\n", name.c_str());
return new_effect(EFFECT::SKIP);
}
- if (p->args_nr != args_nr)
+ proc_t *p = &pi->second;
+
+ if (p->argv.size() != argvp->size())
{
- fail(line_nr, column, "Procedure %s/%d invoked with %d parameters\n", name, p->args_nr, args_nr);
+ fail(line_nr, column, "Procedure %s/%zu invoked with %zu parameters\n",
+ name.c_str(), p->argv.size(), argvp->size());
return new_effect(EFFECT::SKIP);
}
- retval = new_effect(EFFECT::CALL);
+ dumb_ptr<effect_t> retval = new_effect(EFFECT::CALL);
retval->e.e_call.body = p->body;
- retval->e.e_call.args_nr = args_nr;
- retval->e.e_call.formals = p->args;
- retval->e.e_call.actuals = args;
+ retval->e.e_call.formalv = &p->argv;
+ retval->e.e_call.actualvp = argvp;
return retval;
}
-struct const_def_rec
-{
- char *name;
- val_t val;
-} *const_defs = NULL;
-
-int const_defs_nr = 0;
+std::map<std::string, val_t> const_defm;
-static
-void bind_constant(char *name, val_t *val, int line_nr)
+void bind_constant(const std::string& name, val_t *val, int line_nr)
{
- if (find_constant(name))
+ if (!const_defm.insert({name, *val}).second)
{
- fail(line_nr, 0, "Redefinition of constant `%s'\n", name);
- return;
+ fail(line_nr, 0, "Redefinition of constant `%s'\n", name.c_str());
}
-
- if (!const_defs)
- const_defs = (struct const_def_rec *)malloc(sizeof(struct const_def_rec));
- else
- const_defs = (struct const_def_rec *)realloc(const_defs,
- (const_defs_nr + 1) * sizeof(struct const_def_rec));
-
- const_defs[const_defs_nr].name = name;
- const_defs[const_defs_nr].val = *val;
- ++const_defs_nr;
}
-static
-val_t *find_constant(char *name)
+val_t *find_constant(const std::string& name)
{
- int i;
- for (i = 0; i < const_defs_nr; i++)
- {
- if (!strcmp(const_defs[i].name, name))
- {
- free(name);
- return &const_defs[i].val;
- }
- }
+ auto it = const_defm.find(name);
+ if (it != const_defm.end())
+ return &it->second;
return NULL;
}
@@ -1455,20 +1396,6 @@ int magic_init(const char *conffile)
{
error_flag = 0;
- magic_conf.vars_nr = 0;
- // can these be left NULL ? I'm afraid to change anything.
- magic_conf.var_name = (const char **)malloc(1);
- magic_conf.vars = (val_t *)malloc(1);
-
- magic_conf.obscure_chance = 95;
- magic_conf.min_casttime = 100;
-
- magic_conf.spells_nr = 0;
- CREATE(magic_conf.spells, spell_t *, 1);
-
- magic_conf.anchors_nr = 0;
- CREATE(magic_conf.anchors, teleport_anchor_t *, 1);
-
INTERN_ASSERT("min_casttime", VAR_MIN_CASTTIME);
INTERN_ASSERT("obscure_chance", VAR_OBSCURE_CHANCE);
INTERN_ASSERT("caster", VAR_CASTER);
@@ -1487,23 +1414,14 @@ int magic_init(const char *conffile)
}
magic_frontend_parse();
- if (magic_conf.vars[VAR_MIN_CASTTIME].ty == TYPE::INT)
- magic_conf.min_casttime = magic_conf.vars[VAR_MIN_CASTTIME].v.v_int;
-
- if (magic_conf.vars[VAR_OBSCURE_CHANCE].ty == TYPE::INT)
- magic_conf.obscure_chance = magic_conf.vars[VAR_OBSCURE_CHANCE].v.v_int;
+ PRINTF("[magic-conf] Magic initialised. %zu spells, %zu teleport anchors.\n",
+ magic_conf.spells_by_name.size(), magic_conf.anchors_by_name.size());
- PRINTF("[magic-conf] Magic initialised; obscure at %d%%. %d spells, %d teleport anchors.\n",
- magic_conf.obscure_chance, magic_conf.spells_nr, magic_conf.anchors_nr);
-
- if (procs)
- free(procs);
return error_flag;
}
extern int magic_frontend_lineno;
-static
void magic_frontend_error(const char *msg)
{
FPRINTF(stderr, "[magic-conf] Parse error: %s at line %d\n", msg, magic_frontend_lineno);
diff --git a/src/map/magic-interpreter.hpp b/src/map/magic-interpreter.hpp
index 432245d..f233f37 100644
--- a/src/map/magic-interpreter.hpp
+++ b/src/map/magic-interpreter.hpp
@@ -3,27 +3,29 @@
#include "magic-interpreter.t.hpp"
+#include <cassert>
+
#include "magic.hpp"
#include "map.hpp"
#include "script.hpp"
#include "skill.t.hpp"
-struct expr;
-struct val;
-struct location;
-struct area;
-struct spell;
+struct expr_t;
+struct val_t;
+struct location_t;
+struct area_t;
+struct spell_t;
struct invocation;
-typedef struct location
+struct location_t
{
- int m;
+ map_local *m;
int x, y;
-} location_t;
+};
-typedef struct area
+struct area_t
{
- union a
+ union au
{
location_t a_loc;
struct
@@ -37,29 +39,39 @@ typedef struct area
location_t loc;
int width, height;
} a_rect;
- struct area *a_union[2];
+ dumb_ptr<area_t> a_union[2];
+
+ au() { memset(this, '\0', sizeof(*this)); }
+ ~au() = default;
+ au(const au&) = default;
+ au& operator = (const au&) = default;
} a;
int size;
AREA ty;
-} area_t;
+};
-typedef struct val
+struct val_t
{
union v
{
int v_int;
DIR v_dir;
- char *v_string;
- // can't be dumb_ptr<block_list>
- block_list *v_entity; /* Used ONLY during operation/function invocation; otherwise we use v_int */
- area_t *v_area;
+ 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;
- // can't be dumb_ptr<invocation>
- invocation *v_invocation; /* Used ONLY during operation/function invocation; otherwise we use v_int */
- struct spell *v_spell;
+ /* Used ONLY during operation/function invocation; otherwise we use v_int */
+ dumb_ptr<invocation> v_invocation;
+ dumb_ptr<spell_t> v_spell;
+
+ v() { memset(this, '\0', sizeof(*this)); }
+ ~v() = default;
+ v(const v&) = default;
+ v& operator = (const v&) = default;
} v;
TYPE ty;
-} val_t;
+};
/* ----------- */
/* Expressions */
@@ -67,12 +79,12 @@ typedef struct val
#define MAX_ARGS 7 /* Max. # of args used in builtin primitive functions */
-typedef struct e_location
+struct e_location_t
{
- struct expr *m, *x, *y;
-} e_location_t;
+ dumb_ptr<expr_t> m, x, y;
+};
-typedef struct e_area
+struct e_area_t
{
union a0
{
@@ -80,21 +92,26 @@ typedef struct e_area
struct
{
e_location_t loc;
- struct expr *width, *depth, *dir;
+ dumb_ptr<expr_t> width, depth, dir;
} a_bar;
struct
{
e_location_t loc;
- struct expr *width, *height;
+ dumb_ptr<expr_t> width, height;
} a_rect;
- struct e_area *a_union[2];
+ dumb_ptr<e_area_t> a_union[2];
+
+ a0() { memset(this, '\0', sizeof(*this)); }
+ ~a0() = default;
+ a0(const a0&) = default;
+ a0& operator = (const a0&) = default;
} a;
AREA ty;
-} e_area_t;
+};
-typedef struct expr
+struct expr_t
{
- union e
+ union eu
{
val_t e_val;
e_location_t e_location;
@@ -103,153 +120,165 @@ typedef struct expr
{
int id, line_nr, column;
int args_nr;
- struct expr *args[MAX_ARGS];
+ dumb_ptr<expr_t> args[MAX_ARGS];
} e_funapp;
int e_id;
struct
{
- struct expr *expr;
+ dumb_ptr<expr_t> expr;
int id;
} e_field;
+
+ eu() { memset(this, '\0', sizeof(*this)); }
+ ~eu() = default;
+ eu(const eu&) = default;
+ eu& operator = (const eu&) = default;
} e;
EXPR ty;
-} expr_t;
+};
-typedef struct effect
+struct effect_t
{
- struct effect *next;
+ dumb_ptr<effect_t> next;
union e0
{
struct
{
int id;
- expr_t *expr;
+ dumb_ptr<expr_t> expr;
} e_assign;
struct
{
int id;
- expr_t *area;
- struct effect *body;
+ dumb_ptr<expr_t> area;
+ dumb_ptr<effect_t> body;
FOREACH_FILTER filter;
} e_foreach;
struct
{
int id;
- expr_t *start, *stop;
- struct effect *body;
+ dumb_ptr<expr_t> start, stop;
+ dumb_ptr<effect_t> body;
} e_for;
struct
{
- expr_t *cond;
- struct effect *true_branch, *false_branch;
+ dumb_ptr<expr_t> cond;
+ dumb_ptr<effect_t> true_branch, false_branch;
} e_if;
- expr_t *e_sleep; /* sleep time */
- const ScriptCode *e_script;
+ dumb_ptr<expr_t> e_sleep; /* sleep time */
+ dumb_ptr<const ScriptBuffer> e_script;
struct
{
int id;
int args_nr;
int line_nr, column;
- expr_t *args[MAX_ARGS];
+ dumb_ptr<expr_t> args[MAX_ARGS];
} e_op;
struct
{
- int args_nr, *formals;
- expr_t **actuals;
- struct effect *body;
+ std::vector<int> *formalv;
+ dumb_ptr<std::vector<dumb_ptr<expr_t>>> actualvp;
+ dumb_ptr<effect_t> body;
} e_call;
+
+ e0() { memset(this, '\0', sizeof(*this)); }
+ ~e0() = default;
+ e0(const e0&) = default;
+ e0& operator = (const e0&) = default;
} e;
EFFECT ty;
-} effect_t;
+};
/* ---------- */
/* Components */
/* ---------- */
-typedef struct component
+struct component_t
{
- struct component *next;
+ dumb_ptr<component_t> next;
int item_id;
int count;
-} component_t;
+};
-typedef struct effect_set
+struct effect_set_t
{
- effect_t *effect, *at_trigger, *at_end;
-} effect_set_t;
+ dumb_ptr<effect_t> effect, at_trigger, at_end;
+};
-typedef struct spellguard
+struct spellguard_t
{
- struct spellguard *next;
- union s
+ dumb_ptr<spellguard_t> next;
+ union su
{
- expr_t *s_condition;
- expr_t *s_mana;
- expr_t *s_casttime;
- component_t *s_components;
- component_t *s_catalysts;
- struct spellguard *s_alt; /* either `next' or `s.s_alt' */
+ 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() { memset(this, '\0', sizeof(*this)); }
+ ~su() = default;
+ su(const su&) = default;
+ su& operator = (const su&) = default;
} s;
SPELLGUARD ty;
-} spellguard_t;
+};
/* ------ */
/* Spells */
/* ------ */
-typedef struct letdef
+struct letdef_t
{
int id;
- expr_t *expr;
-} letdef_t;
+ dumb_ptr<expr_t> expr;
+};
-typedef struct spell
+struct spell_t
{
- char *name;
- char *invocation;
- int index; // Relative location in the definitions file
+ std::string name;
+ std::string invocation;
+ int index_; // Relative location in the definitions file
SPELL_FLAG flags;
int arg;
SPELLARG spellarg_ty;
- int letdefs_nr;
- letdef_t *letdefs;
+ std::vector<letdef_t> letdefv;
- spellguard_t *spellguard;
-} spell_t;
+ dumb_ptr<spellguard_t> spellguard;
+};
/* ------- */
/* Anchors */
/* ------- */
-typedef struct teleport_anchor
+struct teleport_anchor_t
{
- char *name;
- char *invocation;
- expr_t *location;
-} teleport_anchor_t;
+ std::string name;
+ std::string invocation;
+ dumb_ptr<expr_t> location;
+};
/* ------------------- */
/* The big config blob */
/* ------------------- */
-typedef struct
+struct magic_conf_t
{
- int vars_nr;
- const char **var_name;
- val_t *vars; /* Initial assignments, if any, or NULL */
-
- int obscure_chance;
- int min_casttime;
+ struct mcvar
+ {
+ std::string name;
+ val_t val;
+ };
+ // This should probably be done by a dedicated "intern pool" class
+ std::vector<mcvar> varv;
- int spells_nr;
- spell_t **spells;
+ std::map<std::string, dumb_ptr<spell_t>> spells_by_name, spells_by_invocation;
- int anchors_nr; /* NEGATIVE iff we have sorted the anchors */
- teleport_anchor_t **anchors;
-} magic_conf_t;
+ std::map<std::string, dumb_ptr<teleport_anchor_t>> anchors_by_name, anchors_by_invocation;
+};
/* Execution environment */
@@ -266,57 +295,72 @@ typedef struct
struct magic_config;
-typedef struct env
+struct env_t
{
magic_conf_t *base_env;
- val_t *vars;
-} env_t;
+ std::unique_ptr<val_t[]> varu;
+
+ val_t& VAR(size_t i)
+ {
+ assert (varu);
+ if (varu[i].ty == TYPE::UNDEF)
+ return base_env->varv[i].val;
+ else
+ return varu[i];
+ }
+
+};
#define MAX_STACK_SIZE 32
-typedef struct cont_activation_record
+struct cont_activation_record_t
{
- effect_t *return_location;
- union c
+ dumb_ptr<effect_t> return_location;
+ union cu
{
struct
{
int id;
TYPE ty;
- effect_t *body;
- int entities_nr;
- int *entities;
+ dumb_ptr<effect_t> body;
+ dumb_ptr<std::vector<int>> entities_vp;
int index;
} c_foreach;
struct
{
int id;
- effect_t *body;
+ dumb_ptr<effect_t> body;
int current;
int stop;
} c_for;
struct
{
- int args_nr, *formals;
- val_t *old_actuals;
+ int args_nr;
+ int *formalap;
+ dumb_ptr<val_t[]> old_actualpa;
} c_proc;
+
+ cu() { memset(this, '\0', sizeof(*this)); }
+ ~cu() {}
+ cu(const cu&) = delete;
+ cu& operator = (const cu&) = delete;
} c;
CONT_STACK ty;
-} cont_activation_record_t;
+};
-typedef struct status_change_ref
+struct status_change_ref_t
{
StatusChange sc_type;
int bl_id;
-} status_change_ref_t;
+};
struct invocation : block_list
{
dumb_ptr<invocation> next_invocation; /* used for spells directly associated with a caster: they form a singly-linked list */
INVOCATION_FLAG flags;
- env_t *env;
- spell_t *spell;
+ 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 */
@@ -326,13 +370,12 @@ struct invocation : block_list
cont_activation_record_t stack[MAX_STACK_SIZE];
int script_pos; /* Script position; if nonzero, resume the script we were running. */
- effect_t *current_effect;
- effect_t *trigger_effect; /* If non-NULL, this is used to spawn a cloned effect based on the same environment */
- 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> 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. */
/* Status change references: for status change updates, keep track of whom we updated where */
- int status_change_refs_nr;
- status_change_ref_t *status_change_refs;
+ std::vector<status_change_ref_t> status_change_refv;
};
@@ -345,25 +388,23 @@ 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(component_t ** component_holder, int id, int count);
+void magic_add_component(dumb_ptr<component_t> *component_holder, int id, int count);
-teleport_anchor_t *magic_find_anchor(char *name);
+dumb_ptr<teleport_anchor_t> magic_find_anchor(const std::string& name);
-/**
- * The parameter `param' must have been dynamically allocated; ownership is transferred to the resultant env_t.
- */
-env_t *spell_create_env(magic_conf_t *conf, spell_t *spell,
- dumb_ptr<map_session_data> caster, int spellpower, char *param);
+dumb_ptr<env_t> spell_create_env(magic_conf_t *conf, dumb_ptr<spell_t> spell,
+ dumb_ptr<map_session_data> caster, int spellpower, const_string param);
-void magic_free_env(env_t *env);
+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(spell_t *spell, dumb_ptr<map_session_data> caster,
- env_t *env, int *near_miss);
+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, env_t *env);
+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).
@@ -378,22 +419,26 @@ int spell_unbind(dumb_ptr<map_session_data> subject, dumb_ptr<invocation> invoca
*/
dumb_ptr<invocation> spell_clone_effect(dumb_ptr<invocation> source);
-spell_t *magic_find_spell(char *invocation);
+dumb_ptr<spell_t> magic_find_spell(const std::string& invocation);
/* The following is used only by the parser: */
-typedef struct args_rec
+struct args_rec_t
{
- int args_nr;
- expr_t **args;
-} args_rec_t;
+ dumb_ptr<std::vector<dumb_ptr<expr_t>>> argvp;
+};
-typedef struct
+struct proc_t
{
- char *name;
- int args_nr;
- int *args;
- effect_t *body;
-} proc_t;
+ std::string name;
+ std::vector<int> argv;
+ dumb_ptr<effect_t> body;
+
+ proc_t()
+ : name()
+ , argv()
+ , body()
+ {}
+};
// must be called after itemdb initialisation
int magic_init(const char *);
diff --git a/src/map/magic-stmt.cpp b/src/map/magic-stmt.cpp
index d7944f1..f24167c 100644
--- a/src/map/magic-stmt.cpp
+++ b/src/map/magic-stmt.cpp
@@ -71,10 +71,10 @@ void clear_activation_record(cont_activation_record_t *ar)
switch (ar->ty)
{
case CONT_STACK::FOREACH:
- free(ar->c.c_foreach.entities);
+ ar->c.c_foreach.entities_vp.delete_();
break;
case CONT_STACK::PROC:
- free(ar->c.c_proc.old_actuals);
+ ar->c.c_proc.old_actualpa.delete_();
break;
}
}
@@ -103,13 +103,7 @@ void clear_stack(dumb_ptr<invocation> invocation_)
void spell_free_invocation(dumb_ptr<invocation> invocation_)
{
- if (invocation_->status_change_refs)
- {
- free(invocation_->status_change_refs);
- /* The following cleanup shouldn't be necessary, but I've added it to help tracking a certain bug */
- invocation_->status_change_refs = NULL;
- invocation_->status_change_refs_nr = 0;
- }
+ invocation_->status_change_refv.clear();
if (bool(invocation_->flags & INVOCATION_FLAG::BOUND))
{
@@ -200,7 +194,7 @@ void magic_stop_completely(dumb_ptr<map_session_data> c)
static
void try_to_finish_invocation(dumb_ptr<invocation> invocation)
{
- if (invocation->status_change_refs_nr == 0 && !invocation->current_effect)
+ if (invocation->status_change_refv.empty() && !invocation->current_effect)
{
if (invocation->end_effect)
{
@@ -225,20 +219,20 @@ int trigger_spell(int subject, int spell)
invocation_ = spell_clone_effect(invocation_);
spell_bind(map_id_as_player(subject), invocation_);
- magic_clear_var(&invocation_->env->vars[VAR_CASTER]);
- invocation_->env->vars[VAR_CASTER].ty = TYPE::ENTITY;
- invocation_->env->vars[VAR_CASTER].v.v_int = subject;
+ 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;
return invocation_->bl_id;
}
static
-void entity_warp(dumb_ptr<block_list> target, int destm, int destx, int desty);
+void entity_warp(dumb_ptr<block_list> target, map_local *destm, int destx, int desty);
static
void char_update(dumb_ptr<map_session_data> character)
{
- entity_warp((dumb_ptr<block_list> ) character, character->bl_m, character->bl_x,
+ entity_warp(character, character->bl_m, character->bl_x,
character->bl_y);
}
@@ -276,7 +270,7 @@ void timer_callback_effect_npc_delete(TimerData *, tick_t, int npc_id)
}
static
-dumb_ptr<npc_data> local_spell_effect(int m, int x, int y, int effect,
+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 */
@@ -295,7 +289,7 @@ dumb_ptr<npc_data> local_spell_effect(int m, int x, int y, int effect,
}
static
-int op_sfx(env_t *, int, val_t *args)
+int op_sfx(dumb_ptr<env_t>, const_array<val_t> args)
{
interval_t delay = static_cast<interval_t>(ARGINT(2));
@@ -316,10 +310,10 @@ int op_sfx(env_t *, int, val_t *args)
}
static
-int op_instaheal(env_t *env, int, val_t *args)
+int op_instaheal(dumb_ptr<env_t> env, const_array<val_t> args)
{
- dumb_ptr<block_list> caster = (VAR(VAR_CASTER).ty == TYPE::ENTITY)
- ? map_id2bl(VAR(VAR_CASTER).v.v_int) : NULL;
+ dumb_ptr<block_list> caster = (env->VAR(VAR_CASTER).ty == TYPE::ENTITY)
+ ? map_id2bl(env->VAR(VAR_CASTER).v.v_int) : NULL;
dumb_ptr<block_list> subject = ARGENTITY(0);
if (!caster)
caster = subject;
@@ -337,7 +331,7 @@ int op_instaheal(env_t *env, int, val_t *args)
}
static
-int op_itemheal(env_t *env, int args_nr, val_t *args)
+int op_itemheal(dumb_ptr<env_t> env, const_array<val_t> args)
{
dumb_ptr<block_list> subject = ARGENTITY(0);
if (subject->bl_type == BL::PC)
@@ -346,7 +340,7 @@ int op_itemheal(env_t *env, int args_nr, val_t *args)
ARGINT(1), ARGINT(2));
}
else
- return op_instaheal(env, args_nr, args);
+ return op_instaheal(env, args);
return 0;
}
@@ -367,7 +361,7 @@ using e::Shroud;
#define ARGCHAR(n) (ARGENTITY(n)->is_player())
static
-int op_shroud(env_t *, int, val_t *args)
+int op_shroud(dumb_ptr<env_t>, const_array<val_t> args)
{
dumb_ptr<map_session_data> subject = ARGCHAR(0);
Shroud arg = static_cast<Shroud>(ARGINT(1));
@@ -386,7 +380,7 @@ int op_shroud(env_t *, int, val_t *args)
}
static
-int op_reveal(env_t *, int, val_t *args)
+int op_reveal(dumb_ptr<env_t>, const_array<val_t> args)
{
dumb_ptr<map_session_data> subject = ARGCHAR(0);
@@ -397,7 +391,7 @@ int op_reveal(env_t *, int, val_t *args)
}
static
-int op_message(env_t *, int, val_t *args)
+int op_message(dumb_ptr<env_t>, const_array<val_t> args)
{
dumb_ptr<map_session_data> subject = ARGCHAR(0);
@@ -416,13 +410,13 @@ void timer_callback_kill_npc(TimerData *, tick_t, int npc_id)
}
static
-int op_messenger_npc(env_t *, int, val_t *args)
+int op_messenger_npc(dumb_ptr<env_t>, const_array<val_t> args)
{
dumb_ptr<npc_data> npc;
location_t *loc = &ARGLOCATION(0);
npc = npc_spawn_text(loc->m, loc->x, loc->y,
- ARGINT(1), ARGSTR(2), ARGSTR(3));
+ ARGINT(1), ARGSTR(2).c_str(), ARGSTR(3).c_str());
Timer(gettick() + static_cast<interval_t>(ARGINT(4)),
std::bind(timer_callback_kill_npc, ph::_1, ph::_2,
@@ -433,7 +427,7 @@ int op_messenger_npc(env_t *, int, val_t *args)
}
static
-void entity_warp(dumb_ptr<block_list> target, int destm, int destx, int desty)
+void entity_warp(dumb_ptr<block_list> target, map_local *destm, int destx, int desty)
{
if (target->bl_type == BL::PC || target->bl_type == BL::MOB)
{
@@ -453,7 +447,7 @@ void entity_warp(dumb_ptr<block_list> target, int destm, int destx, int desty)
pc_touch_all_relevant_npcs(character);
// Note that touching NPCs may have triggered warping and thereby updated x and y:
- map_name = map[character->bl_m].name;
+ map_name = character->bl_m->name;
// Warp part #1: update relevant data, interrupt trading etc.:
pc_setpos(character, map_name, character->bl_x, character->bl_y, BeingRemoveWhy::GONE);
@@ -473,7 +467,7 @@ void entity_warp(dumb_ptr<block_list> target, int destm, int destx, int desty)
}
static
-int op_move(env_t *, int, val_t *args)
+int op_move(dumb_ptr<env_t>, const_array<val_t> args)
{
dumb_ptr<block_list> subject = ARGENTITY(0);
DIR dir = ARGDIR(1);
@@ -488,7 +482,7 @@ int op_move(env_t *, int, val_t *args)
}
static
-int op_warp(env_t *, int, val_t *args)
+int op_warp(dumb_ptr<env_t>, const_array<val_t> args)
{
dumb_ptr<block_list> subject = ARGENTITY(0);
location_t *loc = &ARGLOCATION(1);
@@ -499,7 +493,7 @@ int op_warp(env_t *, int, val_t *args)
}
static
-int op_banish(env_t *, int, val_t *args)
+int op_banish(dumb_ptr<env_t>, const_array<val_t> args)
{
dumb_ptr<block_list> subject = ARGENTITY(0);
@@ -515,26 +509,22 @@ int op_banish(env_t *, int, val_t *args)
}
static
-void record_status_change(dumb_ptr<invocation> invocation, int bl_id,
+void record_status_change(dumb_ptr<invocation> invocation_, int bl_id,
StatusChange sc_id)
{
- int index = invocation->status_change_refs_nr++;
- status_change_ref_t *cr;
-
- RECREATE(invocation->status_change_refs, status_change_ref_t, invocation->status_change_refs_nr);
+ status_change_ref_t cr {};
+ cr.sc_type = sc_id;
+ cr.bl_id = bl_id;
- cr = &invocation->status_change_refs[index];
-
- cr->sc_type = sc_id;
- cr->bl_id = bl_id;
+ invocation_->status_change_refv.push_back(cr);
}
static
-int op_status_change(env_t *env, int, val_t *args)
+int op_status_change(dumb_ptr<env_t> env, const_array<val_t> args)
{
dumb_ptr<block_list> subject = ARGENTITY(0);
- int invocation_id = VAR(VAR_INVOCATION).ty == TYPE::INVOCATION
- ? VAR(VAR_INVOCATION).v.v_int : 0;
+ int invocation_id = env->VAR(VAR_INVOCATION).ty == TYPE::INVOCATION
+ ? env->VAR(VAR_INVOCATION).v.v_int : 0;
dumb_ptr<invocation> invocation_ = map_id_as_spell(invocation_id);
assert (!ARGINT(3));
@@ -551,7 +541,7 @@ int op_status_change(env_t *env, int, val_t *args)
}
static
-int op_stop_status_change(env_t *, int, val_t *args)
+int op_stop_status_change(dumb_ptr<env_t>, const_array<val_t> args)
{
dumb_ptr<block_list> subject = ARGENTITY(0);
@@ -562,7 +552,7 @@ int op_stop_status_change(env_t *, int, val_t *args)
}
static
-int op_override_attack(env_t *env, int, val_t *args)
+int op_override_attack(dumb_ptr<env_t> env, const_array<val_t> args)
{
dumb_ptr<block_list> psubject = ARGENTITY(0);
int charges = ARGINT(1);
@@ -586,7 +576,7 @@ int op_override_attack(env_t *env, int, val_t *args)
}
subject->attack_spell_override =
- trigger_spell(subject->bl_id, VAR(VAR_INVOCATION).v.v_int);
+ trigger_spell(subject->bl_id, env->VAR(VAR_INVOCATION).v.v_int);
subject->attack_spell_charges = charges;
if (subject->attack_spell_override)
@@ -603,7 +593,7 @@ int op_override_attack(env_t *env, int, val_t *args)
}
static
-int op_create_item(env_t *, int, val_t *args)
+int op_create_item(dumb_ptr<env_t>, const_array<val_t> args)
{
struct item item;
dumb_ptr<block_list> entity = ARGENTITY(0);
@@ -641,7 +631,7 @@ bool AGGRAVATION_MODE_MAKES_AGGRESSIVE(int n)
}
static
-int op_aggravate(env_t *, int, val_t *args)
+int op_aggravate(dumb_ptr<env_t>, const_array<val_t> args)
{
dumb_ptr<block_list> victim = ARGENTITY(2);
int mode = ARGINT(1);
@@ -676,9 +666,9 @@ enum class MonsterAttitude
};
static
-int op_spawn(env_t *, int, val_t *args)
+int op_spawn(dumb_ptr<env_t>, const_array<val_t> args)
{
- area_t *area = ARGAREA(0);
+ dumb_ptr<area_t> area = ARGAREA(0);
dumb_ptr<block_list> owner_e = ARGENTITY(1);
int monster_id = ARGINT(2);
MonsterAttitude monster_attitude = static_cast<MonsterAttitude>(ARGINT(3));
@@ -699,7 +689,7 @@ int op_spawn(env_t *, int, val_t *args)
int mob_id;
dumb_ptr<mob_data> mob;
- mob_id = mob_once_spawn(owner, map[loc.m].name, loc.x, loc.y, "--ja--", // Is that needed?
+ mob_id = mob_once_spawn(owner, loc.m->name, loc.x, loc.y, "--ja--", // Is that needed?
monster_id, 1, "");
mob = map_id_as_mob(mob_id);
@@ -752,22 +742,22 @@ int op_spawn(env_t *, int, val_t *args)
}
static
-const char *get_invocation_name(env_t *env)
+const char *get_invocation_name(dumb_ptr<env_t> env)
{
dumb_ptr<invocation> invocation_;
- if (VAR(VAR_INVOCATION).ty != TYPE::INVOCATION)
+ if (env->VAR(VAR_INVOCATION).ty != TYPE::INVOCATION)
return "?";
- invocation_ = map_id_as_spell(VAR(VAR_INVOCATION).v.v_int);
+ invocation_ = map_id_as_spell(env->VAR(VAR_INVOCATION).v.v_int);
if (invocation_)
- return invocation_->spell->name;
+ return invocation_->spell->name.c_str();
else
return "??";
}
static
-int op_injure(env_t *env, int, val_t *args)
+int op_injure(dumb_ptr<env_t> env, const_array<val_t> args)
{
dumb_ptr<block_list> caster = ARGENTITY(0);
dumb_ptr<block_list> target = ARGENTITY(1);
@@ -777,7 +767,7 @@ int op_injure(env_t *env, int, val_t *args)
int mdef = battle_get_mdef(target);
if (target->bl_type == BL::PC
- && !map[target->bl_m].flag.pvp
+ && !target->bl_m->flag.pvp
&& !target->as_player()->special_state.killable
&& (caster->bl_type != BL::PC || !caster->as_player()->special_state.killer))
return 0; /* Cannot damage other players outside of pvp */
@@ -817,7 +807,7 @@ int op_injure(env_t *env, int, val_t *args)
}
static
-int op_emote(env_t *, int, val_t *args)
+int op_emote(dumb_ptr<env_t>, const_array<val_t> args)
{
dumb_ptr<block_list> victim = ARGENTITY(0);
int emotion = ARGINT(1);
@@ -827,20 +817,20 @@ int op_emote(env_t *, int, val_t *args)
}
static
-int op_set_script_variable(env_t *, int, val_t *args)
+int op_set_script_variable(dumb_ptr<env_t>, const_array<val_t> args)
{
dumb_ptr<map_session_data> c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL;
if (!c)
return 1;
- pc_setglobalreg(c, ARGSTR(1), ARGINT(2));
+ pc_setglobalreg(c, ARGSTR(1).c_str(), ARGINT(2));
return 0;
}
static
-int op_set_hair_colour(env_t *, int, val_t *args)
+int op_set_hair_colour(dumb_ptr<env_t>, const_array<val_t> args)
{
dumb_ptr<map_session_data> c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL;
@@ -853,7 +843,7 @@ int op_set_hair_colour(env_t *, int, val_t *args)
}
static
-int op_set_hair_style(env_t *, int, val_t *args)
+int op_set_hair_style(dumb_ptr<env_t>, const_array<val_t> args)
{
dumb_ptr<map_session_data> c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL;
@@ -866,15 +856,15 @@ int op_set_hair_style(env_t *, int, val_t *args)
}
static
-int op_drop_item_for (env_t *, int args_nr, val_t *args)
+int op_drop_item_for (dumb_ptr<env_t>, const_array<val_t> args)
{
struct 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_nr > 4) && (ENTITY_TYPE(4) == BL::PC)) ? ARGPC(4) : NULL;
- interval_t delay = (args_nr > 5) ? static_cast<interval_t>(ARGINT(5)) : interval_t::zero();
+ dumb_ptr<map_session_data> c = ((args.size() > 4) && (ENTITY_TYPE(4) == BL::PC)) ? ARGPC(4) : NULL;
+ 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 };
@@ -892,7 +882,7 @@ int op_drop_item_for (env_t *, int args_nr, val_t *args)
}
static
-int op_gain_exp(env_t *, int, val_t *args)
+int op_gain_exp(dumb_ptr<env_t>, const_array<val_t> args)
{
dumb_ptr<map_session_data> c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL;
@@ -905,7 +895,8 @@ int op_gain_exp(env_t *, int, val_t *args)
}
static
-op_t operations[] = {
+op_t operations[] =
+{
{"sfx", ".ii", op_sfx},
{"instaheal", "eii", op_instaheal},
{"itemheal", "eii", op_itemheal},
@@ -938,13 +929,13 @@ int operations_sorted = 0;
static
int operation_count;
-static
+static __attribute__((deprecated))
int compare_operations(const void *lhs, const void *rhs)
{
- return strcmp(((const op_t *) lhs)->name, ((const op_t *) rhs)->name);
+ return strcmp(static_cast<const op_t *>(lhs)->name, static_cast<const op_t *>(rhs)->name);
}
-op_t *magic_get_op(char *name, int *index)
+op_t *magic_get_op(const std::string& name, int *index)
{
op_t key;
@@ -962,9 +953,9 @@ op_t *magic_get_op(char *name, int *index)
operations_sorted = 1;
}
- key.name = name;
- op_t *op = (op_t *)bsearch(&key, operations, operation_count, sizeof(op_t),
- compare_operations);
+ key.name = name.c_str();
+ op_t *op = static_cast<op_t *>(bsearch(&key, operations, operation_count, sizeof(op_t),
+ compare_operations));
if (op && index)
*index = op - operations;
@@ -975,24 +966,23 @@ op_t *magic_get_op(char *name, int *index)
void spell_effect_report_termination(int invocation_id, int bl_id,
StatusChange sc_id, int)
{
- int i;
- int index = -1;
dumb_ptr<invocation> invocation_ = map_id_as_spell(invocation_id);
if (!invocation_ || invocation_->bl_type != BL::SPELL)
return;
- for (i = 0; i < invocation_->status_change_refs_nr; i++)
+ for (status_change_ref_t& cr : invocation_->status_change_refv)
{
- status_change_ref_t *cr = &invocation_->status_change_refs[i];
- if (cr->sc_type == sc_id && cr->bl_id == bl_id)
+ if (cr.sc_type == sc_id && cr.bl_id == bl_id)
{
- index = i;
- break;
+ if (&cr != &invocation_->status_change_refv.back())
+ std::swap(cr, invocation_->status_change_refv.back());
+ invocation_->status_change_refv.pop_back();
+
+ try_to_finish_invocation(invocation_);
}
}
- if (index == -1)
{
dumb_ptr<block_list> entity = map_id2bl(bl_id);
if (entity->bl_type == BL::PC)
@@ -1002,17 +992,10 @@ void spell_effect_report_termination(int invocation_id, int bl_id,
return;
}
- if (index == invocation_->status_change_refs_nr - 1)
- invocation_->status_change_refs_nr--;
- else /* Copy last change ref to the one we are deleting */
- invocation_->status_change_refs[index] =
- invocation_->status_change_refs[--invocation_->status_change_refs_nr];
-
- try_to_finish_invocation(invocation_);
}
static
-effect_t *return_to_stack(dumb_ptr<invocation> invocation_)
+dumb_ptr<effect_t> return_to_stack(dumb_ptr<invocation> invocation_)
{
if (!invocation_->stack_size)
return NULL;
@@ -1022,20 +1005,18 @@ effect_t *return_to_stack(dumb_ptr<invocation> invocation_)
invocation_->stack + (invocation_->stack_size - 1);
switch (ar->ty)
{
-
case CONT_STACK::PROC:
{
- effect_t *ret = ar->return_location;
- int i;
-
- for (i = 0; i < ar->c.c_proc.args_nr; i++)
+ dumb_ptr<effect_t> ret = ar->return_location;
+ for (int i = 0; i < ar->c.c_proc.args_nr; i++)
{
val_t *var =
- &invocation_->env->vars[ar->c.c_proc.formals[i]];
+ &invocation_->env->varu[ar->c.c_proc.formalap[i]];
magic_clear_var(var);
- *var = ar->c.c_proc.old_actuals[i];
+ *var = ar->c.c_proc.old_actualpa[i];
}
+ // pop the stack
clear_activation_record(ar);
--invocation_->stack_size;
@@ -1045,20 +1026,23 @@ effect_t *return_to_stack(dumb_ptr<invocation> invocation_)
case CONT_STACK::FOREACH:
{
int entity_id;
- val_t *var = &invocation_->env->vars[ar->c.c_foreach.id];
+ val_t *var = &invocation_->env->varu[ar->c.c_foreach.id];
do
{
- if (ar->c.c_foreach.index >= ar->c.c_foreach.entities_nr)
+ // 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())
{
- effect_t *ret = ar->return_location;
+ // pop the stack
+ dumb_ptr<effect_t> ret = ar->return_location;
clear_activation_record(ar);
--invocation_->stack_size;
return ret;
}
entity_id =
- ar->c.c_foreach.entities[ar->c.c_foreach.index++];
+ (*ar->c.c_foreach.entities_vp)[ar->c.c_foreach.index++];
}
while (!entity_id || !map_id2bl(entity_id));
@@ -1072,15 +1056,16 @@ effect_t *return_to_stack(dumb_ptr<invocation> invocation_)
case CONT_STACK::FOR:
if (ar->c.c_for.current > ar->c.c_for.stop)
{
- effect_t *ret = ar->return_location;
+ dumb_ptr<effect_t> ret = ar->return_location;
+ // pop the stack
clear_activation_record(ar);
--invocation_->stack_size;
return ret;
}
- magic_clear_var(&invocation_->env->vars[ar->c.c_for.id]);
- invocation_->env->vars[ar->c.c_for.id].ty = TYPE::INT;
- invocation_->env->vars[ar->c.c_for.id].v.v_int =
+ 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;
@@ -1096,7 +1081,7 @@ effect_t *return_to_stack(dumb_ptr<invocation> invocation_)
static
cont_activation_record_t *add_stack_entry(dumb_ptr<invocation> invocation_,
- CONT_STACK ty, effect_t *return_location)
+ CONT_STACK ty, dumb_ptr<effect_t> return_location)
{
cont_activation_record_t *ar =
invocation_->stack + invocation_->stack_size++;
@@ -1116,20 +1101,9 @@ cont_activation_record_t *add_stack_entry(dumb_ptr<invocation> invocation_,
static
void find_entities_in_area_c(dumb_ptr<block_list> target,
- int *entities_allocd_p,
- int *entities_nr_p,
- int **entities_p,
+ std::vector<int> *entities_vp,
FOREACH_FILTER filter)
{
-/* The following macro adds an entity to the result list: */
-#define ADD_ENTITY(e) \
- if (*entities_nr_p == *entities_allocd_p) { \
- /* Need more space */ \
- (*entities_allocd_p) += 32; \
- RECREATE(*entities_p, int, *entities_allocd_p); \
- } \
- (*entities_p)[(*entities_nr_p)++] = e;
-
switch (target->bl_type)
{
@@ -1137,7 +1111,7 @@ void find_entities_in_area_c(dumb_ptr<block_list> target,
if (filter == FOREACH_FILTER::PC
|| filter == FOREACH_FILTER::ENTITY
|| (filter == FOREACH_FILTER::TARGET
- && map[target->bl_m].flag.pvp))
+ && target->bl_m->flag.pvp))
break;
else if (filter == FOREACH_FILTER::SPELL)
{ /* Check all spells bound to the caster */
@@ -1146,7 +1120,7 @@ void find_entities_in_area_c(dumb_ptr<block_list> target,
while (invoc)
{
- ADD_ENTITY(invoc->bl_id);
+ entities_vp->push_back(invoc->bl_id);
invoc = invoc->next_invocation;
}
}
@@ -1184,42 +1158,45 @@ void find_entities_in_area_c(dumb_ptr<block_list> target,
return;
}
- ADD_ENTITY(target->bl_id);
-#undef ADD_ENTITY
+ entities_vp->push_back(target->bl_id);
}
static
-void find_entities_in_area(area_t *area, int *entities_allocd_p,
- int *entities_nr_p, int **entities_p, FOREACH_FILTER filter)
+void find_entities_in_area(area_t& area_,
+ std::vector<int> *entities_vp,
+ FOREACH_FILTER filter)
{
+ area_t *area = &area_; // temporary hack to "keep diff small". Heh.
switch (area->ty)
{
case AREA::UNION:
- find_entities_in_area(area->a.a_union[0], entities_allocd_p,
- entities_nr_p, entities_p, filter);
- find_entities_in_area(area->a.a_union[1], entities_allocd_p,
- entities_nr_p, entities_p, filter);
+ 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:
{
- int m, 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_allocd_p, entities_nr_p, entities_p, filter),
- m, x, y, x + width, y + height,
- BL::NUL /* filter elsewhere */);
+ 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 */);
}
}
}
static
-effect_t *run_foreach(dumb_ptr<invocation> invocation, effect_t *foreach,
- effect_t *return_location)
+dumb_ptr<effect_t> run_foreach(dumb_ptr<invocation> invocation,
+ dumb_ptr<effect_t> foreach,
+ dumb_ptr<effect_t> return_location)
{
val_t area;
FOREACH_FILTER filter = foreach->e.e_foreach.filter;
int id = foreach->e.e_foreach.id;
- effect_t *body = foreach->e.e_foreach.body;
+ dumb_ptr<effect_t> body = foreach->e.e_foreach.body;
magic_eval(invocation->env, &area, foreach->e.e_foreach.area);
@@ -1228,32 +1205,28 @@ effect_t *run_foreach(dumb_ptr<invocation> invocation, effect_t *foreach,
magic_clear_var(&area);
FPRINTF(stderr,
"[magic] Error in spell `%s': FOREACH loop over non-area\n",
- invocation->spell->name);
+ invocation->spell->name.c_str());
return return_location;
}
else
{
cont_activation_record_t *ar =
add_stack_entry(invocation, CONT_STACK::FOREACH, return_location);
- int entities_allocd = 64;
- int *entities;
- int entities_nr = 0;
if (!ar)
return return_location;
- CREATE(entities, int, entities_allocd);
- find_entities_in_area(area.v.v_area, &entities_allocd, &entities_nr,
- &entities, filter);
- RECREATE(entities, int, entities_nr);
+ std::vector<int> entities_v;
+ find_entities_in_area(*area.v.v_area,
+ &entities_v, filter);
+ entities_v.shrink_to_fit();
// iterator_pair will go away when this gets properly containerized.
- random_::shuffle(iterator_pair(entities, entities + entities_nr));
+ 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_nr = entities_nr;
- ar->c.c_foreach.entities = entities;
+ ar->c.c_foreach.entities_vp.new_(std::move(entities_v));
ar->c.c_foreach.ty =
(filter == FOREACH_FILTER::SPELL) ? TYPE::INVOCATION : TYPE::ENTITY;
@@ -1264,8 +1237,9 @@ effect_t *run_foreach(dumb_ptr<invocation> invocation, effect_t *foreach,
}
static
-effect_t *run_for (dumb_ptr<invocation> invocation, effect_t *for_,
- effect_t *return_location)
+dumb_ptr<effect_t> run_for (dumb_ptr<invocation> invocation,
+ dumb_ptr<effect_t> for_,
+ dumb_ptr<effect_t> return_location)
{
cont_activation_record_t *ar;
int id = for_->e.e_for.id;
@@ -1299,28 +1273,24 @@ effect_t *run_for (dumb_ptr<invocation> invocation, effect_t *for_,
}
static
-effect_t *run_call(dumb_ptr<invocation> invocation,
- effect_t *return_location)
+dumb_ptr<effect_t> run_call(dumb_ptr<invocation> invocation,
+ dumb_ptr<effect_t> return_location)
{
- effect_t *current = invocation->current_effect;
+ dumb_ptr<effect_t> current = invocation->current_effect;
cont_activation_record_t *ar;
- int args_nr = current->e.e_call.args_nr;
- int *formals = current->e.e_call.formals;
- val_t *old_actuals;
- CREATE(old_actuals, val_t, args_nr);
- int i;
+ int args_nr = current->e.e_call.formalv->size();
+ int *formals = current->e.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.formals = formals;
- ar->c.c_proc.old_actuals = old_actuals;
- for (i = 0; i < args_nr; i++)
+ ar->c.c_proc.formalap = formals;
+ ar->c.c_proc.old_actualpa = old_actuals;
+ for (int i = 0; i < args_nr; i++)
{
- val_t *env_val = &invocation->env->vars[formals[i]];
- val_t result;
+ val_t *env_val = &invocation->env->varu[formals[i]];
magic_copy_var(&old_actuals[i], env_val);
- magic_eval(invocation->env, &result, current->e.e_call.actuals[i]);
- *env_val = result;
+ magic_eval(invocation->env, env_val, (*current->e.e_call.actualvp)[i]);
}
return current->e.e_call.body;
@@ -1414,8 +1384,8 @@ interval_t spell_run(dumb_ptr<invocation> invocation_, int allow_delete)
#endif
while (invocation_->current_effect)
{
- effect_t *e = invocation_->current_effect;
- effect_t *next = e->next;
+ dumb_ptr<effect_t> e = invocation_->current_effect;
+ dumb_ptr<effect_t> next = e->next;
int i;
#ifdef DEBUG
@@ -1439,7 +1409,7 @@ interval_t spell_run(dumb_ptr<invocation> invocation_, int allow_delete)
case EFFECT::ASSIGN:
magic_eval(invocation_->env,
- &invocation_->env->vars[e->e.e_assign.id],
+ &invocation_->env->varu[e->e.e_assign.id],
e->e.e_assign.expr);
break;
@@ -1473,19 +1443,16 @@ interval_t spell_run(dumb_ptr<invocation> invocation_, int allow_delete)
dumb_ptr<map_session_data> caster = map_id_as_player(invocation_->caster);
if (caster)
{
- env_t *env = invocation_->env;
- argrec_t arg[] = { {"@target",
- VAR(VAR_TARGET).ty ==
- TYPE::ENTITY ? 0 : VAR(VAR_TARGET).
- v.v_int}
- ,
- {"@caster", invocation_->caster}
- ,
- {"@caster_name$", caster ? caster->status.name : ""}
+ dumb_ptr<env_t> env = invocation_->env;
+ argrec_t arg[] =
+ {
+ {"@target", env->VAR(VAR_TARGET).ty == TYPE::ENTITY ? 0 : env->VAR(VAR_TARGET).v.v_int},
+ {"@caster", invocation_->caster},
+ {"@caster_name$", caster ? caster->status.name : ""},
};
int message_recipient =
- VAR(VAR_SCRIPTTARGET).ty ==
- TYPE::ENTITY ? VAR(VAR_SCRIPTTARGET).
+ env->VAR(VAR_SCRIPTTARGET).ty ==
+ TYPE::ENTITY ? env->VAR(VAR_SCRIPTTARGET).
v.v_int : invocation_->caster;
dumb_ptr<map_session_data> recipient = map_id_as_player(message_recipient);
@@ -1499,11 +1466,11 @@ interval_t spell_run(dumb_ptr<invocation> invocation_, int allow_delete)
// We have to do this or otherwise the client won't think that it's
// dealing with an NPC
- int newpos = run_script_l(e->e.e_script,
- invocation_->script_pos,
- message_recipient,
- invocation_->bl_id,
- 3, arg);
+ int newpos = run_script_l(
+ ScriptPointer(&*e->e.e_script, invocation_->script_pos),
+ message_recipient,
+ invocation_->bl_id,
+ 3, arg);
/* Returns the new script position, or -1 once the script is finished */
if (newpos != -1)
{
@@ -1536,7 +1503,7 @@ interval_t spell_run(dumb_ptr<invocation> invocation_, int allow_delete)
e->e.e_op.args_nr, args,
e->e.e_op.line_nr,
e->e.e_op.column))
- op->op(invocation_->env, e->e.e_op.args_nr, args);
+ op->op(invocation_->env, const_array<val_t>(args, e->e.e_op.args_nr));
for (i = 0; i < e->e.e_op.args_nr; i++)
magic_clear_var(&args[i]);
@@ -1615,9 +1582,9 @@ int spell_attack(int caster_id, int target_id)
if (invocation_ && caster->attack_spell_charges > 0)
{
- magic_clear_var(&invocation_->env->vars[VAR_TARGET]);
- invocation_->env->vars[VAR_TARGET].ty = TYPE::ENTITY;
- invocation_->env->vars[VAR_TARGET].v.v_int = target_id;
+ magic_clear_var(&invocation_->env->varu[VAR_TARGET]);
+ invocation_->env->varu[VAR_TARGET].ty = TYPE::ENTITY;
+ invocation_->env->varu[VAR_TARGET].v.v_int = target_id;
invocation_->current_effect = invocation_->trigger_effect;
invocation_->flags &= ~INVOCATION_FLAG::ABORTED;
diff --git a/src/map/magic.cpp b/src/map/magic.cpp
index f6da29b..e225830 100644
--- a/src/map/magic.cpp
+++ b/src/map/magic.cpp
@@ -9,83 +9,58 @@
#undef DEBUG
+/// Return a pair of strings, {spellname, parameter}
+/// Parameter may be empty.
static
-char *magic_preprocess_message(dumb_ptr<map_session_data> character, char *start,
- char *end)
+std::pair<std::string, std::string> magic_tokenise(std::string src)
{
- if (character->state.shroud_active
- && character->state.shroud_disappears_on_talk)
- magic_unshroud(character);
+ std::string retval = std::move(src);
+ const std::string::iterator rvb = retval.begin(), rve = retval.end();
+ std::string::iterator seeker = std::find(rvb, rve, ' ');
- if (character->state.shroud_active
- && character->state.shroud_hides_name_talking)
+ if (seeker == retval.end())
{
- int len = strlen(end);
- strcpy(start, "? ");
- memmove(start + 2, end, len + 1);
- return start + 4;
+ return {retval, std::string()};
}
else
- return end + 2; /* step past blank */
-}
-
-/* Returns a dynamically allocated copy of `src'.
- * `*parameter' may point within that copy or be NULL. */
-static
-char *magic_tokenise(char *src, char **parameter)
-{
- char *retval = strdup(src);
- char *seeker = retval;
-
- while (*seeker && *seeker != ' ')
- ++seeker;
-
- if (!*seeker)
- *parameter = NULL;
- else
{
- *seeker = 0; /* Terminate invocation */
+ std::string rv1(rvb, seeker);
++seeker;
- while (*seeker == ' ')
+ while (seeker != rve && *seeker == ' ')
++seeker;
- *parameter = seeker;
+ // Note: this very well could be empty
+ std::string rv2(seeker, rve);
+ return {rv1, rv2};
}
-
- return retval;
}
-int magic_message(dumb_ptr<map_session_data> caster, char *spell_, size_t)
+int magic_message(dumb_ptr<map_session_data> caster, const std::string& source_invocation)
{
if (pc_isdead(caster))
return 0;
int power = caster->matk1;
- char *invocation_base = spell_ + 8;
- char *source_invocation =
- 1 + invocation_base + strlen(caster->status.name);
- spell_t *spell;
- char *parameter;
- char *spell_invocation;
-
- if (!source_invocation)
- return 0;
- /* Pre-message filter in case some spell alters output */
- source_invocation =
- magic_preprocess_message(caster, invocation_base, source_invocation);
+ // This was the only thing worth saving from magic_preprocess_message.
+ // May it rest only, and never rise again.
+ // For more information on how this code worked, travel through time
+ // and watch all the comments I wrote for myself while trying to figure
+ // out if it was safe to delete.
+ if (caster->state.shroud_active && caster->state.shroud_disappears_on_talk)
+ magic_unshroud(caster);
- spell_invocation = magic_tokenise(source_invocation, &parameter);
- parameter = parameter ? strdup(parameter) : strdup("");
+ auto pair = magic_tokenise(source_invocation);
+ std::string spell_invocation = std::move(pair.first);
+ std::string parameter = std::move(pair.second);
- spell = magic_find_spell(spell_invocation);
- free(spell_invocation);
+ dumb_ptr<spell_t> spell = magic_find_spell(spell_invocation);
if (spell)
{
int near_miss;
- env_t *env =
+ dumb_ptr<env_t> env =
spell_create_env(&magic_conf, spell, caster, power, parameter);
effect_set_t *effects;
@@ -118,8 +93,6 @@ int magic_message(dumb_ptr<map_session_data> caster, char *spell_, size_t)
return 1;
}
- else
- free(parameter);
return 0; /* Not a spell */
}
diff --git a/src/map/magic.hpp b/src/map/magic.hpp
index cc66eb4..cec5bf4 100644
--- a/src/map/magic.hpp
+++ b/src/map/magic.hpp
@@ -14,14 +14,14 @@ struct invocation; /* Spell invocation */
* Try to cast magic.
*
* As an intended side effect, the magic message may be distorted (text only).
+ * No, it can't. Thank God.
*
* \param caster Player attempting to cast magic
- * \param spell The prospective incantation
- * \param spell_len Number of characters in the incantation
+ * \param source_invocation The prospective incantation
* \return 1 or -1 if the input message was magic and was handled by this function, 0 otherwise. -1 is returned when the
* message should not be repeated.
*/
-int magic_message(dumb_ptr<map_session_data> caster, char *spell, size_t spell_len);
+int magic_message(dumb_ptr<map_session_data> caster, const std::string& source_invocation);
/**
* Removes the shroud from a character
@@ -51,14 +51,14 @@ void do_init_magic(void);
*
* Returns NULL if not found
*/
-const char *magic_find_invocation(const char *spellame);
+const char *magic_find_invocation(const std::string& spellame);
/**
* Identifies the invocation used to denote a teleport location
*
* Returns NULL if not found
*/
-const char *magic_find_anchor_invocation(const char *teleport_location);
+const char *magic_find_anchor_invocation(const std::string& teleport_location);
/**
* Execute a spell invocation and sets up timers to finish
diff --git a/src/map/map.cpp b/src/map/map.cpp
index 96e9f5e..414fcd7 100644
--- a/src/map/map.cpp
+++ b/src/map/map.cpp
@@ -41,8 +41,7 @@
DMap<int, dumb_ptr<block_list>> id_db;
-static
-DMap<std::string, struct map_data *> map_db;
+UPMap<std::string, map_abstract> maps_db;
static
DMap<std::string, dumb_ptr<map_session_data>> nick_db;
@@ -63,9 +62,6 @@ dumb_ptr<block_list> object[MAX_FLOORITEM];
static
int first_free_object_id = 0, last_object_id = 0;
-struct map_data map[MAX_MAP_PER_SERVER];
-int map_num = 0;
-
static
int map_port = 0;
@@ -78,11 +74,11 @@ char help_txt[256] = "conf/help.txt";
char wisp_server_name[24] = "Server"; // can be modified in char-server configuration file
static
-int map_delmap(const char *mapname);
+void map_delmap(const std::string& mapname);
void SessionDeleter::operator()(SessionData *sd)
{
- delete static_cast<map_session_data *>(sd);
+ really_delete1 static_cast<map_session_data *>(sd);
}
/*==========================================
@@ -148,8 +144,6 @@ struct block_list bl_head;
*/
int map_addblock(dumb_ptr<block_list> bl)
{
- int m, x, y;
-
nullpo_ret(bl);
if (bl->bl_prev)
@@ -159,35 +153,30 @@ int map_addblock(dumb_ptr<block_list> bl)
return 0;
}
- m = bl->bl_m;
- x = bl->bl_x;
- y = bl->bl_y;
- if (m < 0 || m >= map_num ||
- x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys)
+ map_local *m = bl->bl_m;
+ int x = bl->bl_x;
+ int y = bl->bl_y;
+ if (!m ||
+ x < 0 || x >= m->xs || y < 0 || y >= m->ys)
return 1;
if (bl->bl_type == BL::MOB)
{
- bl->bl_next =
- map[m].block_mob[x / BLOCK_SIZE + (y / BLOCK_SIZE) * map[m].bxs];
+ bl->bl_next = m->blocks.ref(x / BLOCK_SIZE, y / BLOCK_SIZE).mobs_only;
bl->bl_prev = dumb_ptr<block_list>(&bl_head);
if (bl->bl_next)
bl->bl_next->bl_prev = bl;
- map[m].block_mob[x / BLOCK_SIZE + (y / BLOCK_SIZE) * map[m].bxs] = bl;
- map[m].block_mob_count[x / BLOCK_SIZE +
- (y / BLOCK_SIZE) * map[m].bxs]++;
+ m->blocks.ref(x / BLOCK_SIZE, y / BLOCK_SIZE).mobs_only = bl;
}
else
{
- bl->bl_next =
- map[m].block[x / BLOCK_SIZE + (y / BLOCK_SIZE) * map[m].bxs];
+ bl->bl_next = m->blocks.ref(x / BLOCK_SIZE, y / BLOCK_SIZE).normal;
bl->bl_prev = dumb_ptr<block_list>(&bl_head);
if (bl->bl_next)
bl->bl_next->bl_prev = bl;
- map[m].block[x / BLOCK_SIZE + (y / BLOCK_SIZE) * map[m].bxs] = bl;
- map[m].block_count[x / BLOCK_SIZE + (y / BLOCK_SIZE) * map[m].bxs]++;
+ m->blocks.ref(x / BLOCK_SIZE, y / BLOCK_SIZE).normal = bl;
if (bl->bl_type == BL::PC)
- map[m].users++;
+ m->users++;
}
return 0;
@@ -200,7 +189,6 @@ int map_addblock(dumb_ptr<block_list> bl)
*/
int map_delblock(dumb_ptr<block_list> bl)
{
- int b;
nullpo_ret(bl);
// 既にblocklistから抜けている
@@ -215,10 +203,8 @@ int map_delblock(dumb_ptr<block_list> bl)
return 0;
}
- b = bl->bl_x / BLOCK_SIZE + (bl->bl_y / BLOCK_SIZE) * map[bl->bl_m].bxs;
-
if (bl->bl_type == BL::PC)
- map[bl->bl_m].users--;
+ bl->bl_m->users--;
if (bl->bl_next)
bl->bl_next->bl_prev = bl->bl_prev;
@@ -227,15 +213,11 @@ int map_delblock(dumb_ptr<block_list> bl)
// リストの頭なので、map[]のblock_listを更新する
if (bl->bl_type == BL::MOB)
{
- map[bl->bl_m].block_mob[b] = bl->bl_next;
- if ((map[bl->bl_m].block_mob_count[b]--) < 0)
- map[bl->bl_m].block_mob_count[b] = 0;
+ bl->bl_m->blocks.ref(bl->bl_x / BLOCK_SIZE, bl->bl_y / BLOCK_SIZE).mobs_only = bl->bl_next;
}
else
{
- map[bl->bl_m].block[b] = bl->bl_next;
- if ((map[bl->bl_m].block_count[b]--) < 0)
- map[bl->bl_m].block_count[b] = 0;
+ bl->bl_m->blocks.ref(bl->bl_x / BLOCK_SIZE, bl->bl_y / BLOCK_SIZE).normal = bl->bl_next;
}
}
else
@@ -252,28 +234,25 @@ int map_delblock(dumb_ptr<block_list> bl)
* セル上のPCとMOBの数を数える (グランドクロス用)
*------------------------------------------
*/
-int map_count_oncell(int m, int x, int y)
+int map_count_oncell(map_local *m, int x, int y)
{
int bx, by;
dumb_ptr<block_list> bl = NULL;
- int i, c;
int count = 0;
- if (x < 0 || y < 0 || (x >= map[m].xs) || (y >= map[m].ys))
+ if (x < 0 || y < 0 || (x >= m->xs) || (y >= m->ys))
return 1;
bx = x / BLOCK_SIZE;
by = y / BLOCK_SIZE;
- bl = map[m].block[bx + by * map[m].bxs];
- c = map[m].block_count[bx + by * map[m].bxs];
- for (i = 0; i < c && bl; i++, bl = bl->bl_next)
+ bl = m->blocks.ref(bx, by).normal;
+ for (; bl; bl = bl->bl_next)
{
if (bl->bl_x == x && bl->bl_y == y && bl->bl_type == BL::PC)
count++;
}
- bl = map[m].block_mob[bx + by * map[m].bxs];
- c = map[m].block_mob_count[bx + by * map[m].bxs];
- for (i = 0; i < c && bl; i++, bl = bl->bl_next)
+ bl = m->blocks.ref(bx, by).mobs_only;
+ for (; bl; bl = bl->bl_next)
{
if (bl->bl_x == x && bl->bl_y == y)
count++;
@@ -290,33 +269,30 @@ int map_count_oncell(int m, int x, int y)
*------------------------------------------
*/
void map_foreachinarea(std::function<void(dumb_ptr<block_list>)> func,
- int m,
+ map_local *m,
int x0, int y0, int x1, int y1,
BL type)
{
std::vector<dumb_ptr<block_list>> bl_list;
- if (m < 0)
+ if (!m)
return;
if (x0 < 0)
x0 = 0;
if (y0 < 0)
y0 = 0;
- if (x1 >= map[m].xs)
- x1 = map[m].xs - 1;
- if (y1 >= map[m].ys)
- y1 = map[m].ys - 1;
+ if (x1 >= m->xs)
+ x1 = m->xs - 1;
+ if (y1 >= m->ys)
+ y1 = m->ys - 1;
if (type == BL::NUL || type != BL::MOB)
for (int by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++)
{
for (int bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++)
{
- dumb_ptr<block_list> bl = map[m].block[bx + by * map[m].bxs];
- int c = map[m].block_count[bx + by * map[m].bxs];
- for (int i = 0; i < c && bl; i++, bl = bl->bl_next)
+ dumb_ptr<block_list> bl = m->blocks.ref(bx, by).normal;
+ for (; bl; bl = bl->bl_next)
{
- if (!bl)
- continue;
if (type != BL::NUL && bl->bl_type != type)
continue;
if (bl->bl_x >= x0 && bl->bl_x <= x1
@@ -330,12 +306,9 @@ void map_foreachinarea(std::function<void(dumb_ptr<block_list>)> func,
{
for (int bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++)
{
- dumb_ptr<block_list> bl = map[m].block_mob[bx + by * map[m].bxs];
- int c = map[m].block_mob_count[bx + by * map[m].bxs];
- for (int i = 0; i < c && bl; i++, bl = bl->bl_next)
+ dumb_ptr<block_list> bl = m->blocks.ref(bx, by).mobs_only;
+ for (; bl; bl = bl->bl_next)
{
- if (!bl)
- continue;
if (bl->bl_x >= x0 && bl->bl_x <= x1
&& bl->bl_y >= y0 && bl->bl_y <= y1)
bl_list.push_back(bl);
@@ -359,7 +332,7 @@ void map_foreachinarea(std::function<void(dumb_ptr<block_list>)> func,
*------------------------------------------
*/
void map_foreachinmovearea(std::function<void(dumb_ptr<block_list>)> func,
- int m,
+ map_local *m,
int x0, int y0, int x1, int y1,
int dx, int dy,
BL type)
@@ -389,32 +362,26 @@ void map_foreachinmovearea(std::function<void(dumb_ptr<block_list>)> func,
x0 = 0;
if (y0 < 0)
y0 = 0;
- if (x1 >= map[m].xs)
- x1 = map[m].xs - 1;
- if (y1 >= map[m].ys)
- y1 = map[m].ys - 1;
+ if (x1 >= m->xs)
+ x1 = m->xs - 1;
+ if (y1 >= m->ys)
+ y1 = m->ys - 1;
for (int by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++)
{
for (int bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++)
{
- dumb_ptr<block_list> bl = map[m].block[bx + by * map[m].bxs];
- int c = map[m].block_count[bx + by * map[m].bxs];
- for (int i = 0; i < c && bl; i++, bl = bl->bl_next)
+ dumb_ptr<block_list> bl = m->blocks.ref(bx, by).normal;
+ for (; bl; bl = bl->bl_next)
{
- if (!bl)
- continue;
if (type != BL::NUL && bl->bl_type != type)
continue;
if (bl->bl_x >= x0 && bl->bl_x <= x1
&& bl->bl_y >= y0 && bl->bl_y <= y1)
bl_list.push_back(bl);
}
- bl = map[m].block_mob[bx + by * map[m].bxs];
- c = map[m].block_mob_count[bx + by * map[m].bxs];
- for (int i = 0; i < c && bl; i++, bl = bl->bl_next)
+ bl = m->blocks.ref(bx, by).mobs_only;
+ for (; bl; bl = bl->bl_next)
{
- if (!bl)
- continue;
if (type != BL::NUL && bl->bl_type != type)
continue;
if (bl->bl_x >= x0 && bl->bl_x <= x1
@@ -432,20 +399,17 @@ void map_foreachinmovearea(std::function<void(dumb_ptr<block_list>)> func,
x0 = 0;
if (y0 < 0)
y0 = 0;
- if (x1 >= map[m].xs)
- x1 = map[m].xs - 1;
- if (y1 >= map[m].ys)
- y1 = map[m].ys - 1;
+ if (x1 >= m->xs)
+ x1 = m->xs - 1;
+ if (y1 >= m->ys)
+ y1 = m->ys - 1;
for (int by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++)
{
for (int bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++)
{
- dumb_ptr<block_list> bl = map[m].block[bx + by * map[m].bxs];
- int c = map[m].block_count[bx + by * map[m].bxs];
- for (int i = 0; i < c && bl; i++, bl = bl->bl_next)
+ dumb_ptr<block_list> bl = m->blocks.ref(bx, by).normal;
+ for (; bl; bl = bl->bl_next)
{
- if (!bl)
- continue;
if (type != BL::NUL && bl->bl_type != type)
continue;
if (!(bl->bl_x >= x0 && bl->bl_x <= x1
@@ -457,14 +421,13 @@ void map_foreachinmovearea(std::function<void(dumb_ptr<block_list>)> func,
|| (dy < 0 && bl->bl_y > y1 + dy))
bl_list.push_back(bl);
}
- bl = map[m].block_mob[bx + by * map[m].bxs];
- c = map[m].block_mob_count[bx + by * map[m].bxs];
- for (int i = 0; i < c && bl; i++, bl = bl->bl_next)
+ bl = m->blocks.ref(bx, by).mobs_only;
+ for (; bl; bl = bl->bl_next)
{
if (type != BL::NUL && bl->bl_type != type)
continue;
- if (!(bl->bl_x >= x0 && bl->bl_x <= x1 && bl->bl_y >= y0
- && bl->bl_y <= y1))
+ if (!(bl->bl_x >= x0 && bl->bl_x <= x1
+ && bl->bl_y >= y0 && bl->bl_y <= y1))
continue;
if ((dx > 0 && bl->bl_x < x0 + dx)
|| (dx < 0 && bl->bl_x > x1 + dx)
@@ -489,7 +452,7 @@ void map_foreachinmovearea(std::function<void(dumb_ptr<block_list>)> func,
// area radius - may be more useful in some instances)
//
void map_foreachincell(std::function<void(dumb_ptr<block_list>)> func,
- int m,
+ map_local *m,
int x, int y,
BL type)
{
@@ -499,12 +462,9 @@ void map_foreachincell(std::function<void(dumb_ptr<block_list>)> func,
if (type == BL::NUL || type != BL::MOB)
{
- dumb_ptr<block_list> bl = map[m].block[bx + by * map[m].bxs];
- int c = map[m].block_count[bx + by * map[m].bxs];
- for (int i = 0; i < c && bl; i++, bl = bl->bl_next)
+ dumb_ptr<block_list> bl = m->blocks.ref(bx, by).normal;
+ for (; bl; bl = bl->bl_next)
{
- if (!bl)
- continue;
if (type != BL::NUL && bl->bl_type != type)
continue;
if (bl->bl_x == x && bl->bl_y == y)
@@ -514,12 +474,9 @@ void map_foreachincell(std::function<void(dumb_ptr<block_list>)> func,
if (type == BL::NUL || type == BL::MOB)
{
- dumb_ptr<block_list> bl = map[m].block_mob[bx + by * map[m].bxs];
- int c = map[m].block_mob_count[bx + by * map[m].bxs];
- for (int i = 0; i < c && bl; i++, bl = bl->bl_next)
+ dumb_ptr<block_list> bl = m->blocks.ref(bx, by).mobs_only;
+ for (; bl; bl = bl->bl_next)
{
- if (!bl)
- continue;
if (bl->bl_x == x && bl->bl_y == y)
bl_list.push_back(bl);
}
@@ -670,13 +627,14 @@ void map_clearflooritem_timer(TimerData *tid, tick_t, int id)
map_delobject(fitem->bl_id, BL::ITEM);
}
-std::pair<uint16_t, uint16_t> map_randfreecell(int m, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
+std::pair<uint16_t, uint16_t> map_randfreecell(map_local *m,
+ uint16_t x, uint16_t y, uint16_t w, uint16_t h)
{
for (int itr : random_::iterator(w * h))
{
int dx = itr % w;
int dy = itr / w;
- if (!bool(read_gat(m, x + dx, y + dy) & MapCell::UNWALKABLE))
+ 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)};
@@ -684,7 +642,7 @@ std::pair<uint16_t, uint16_t> map_randfreecell(int m, uint16_t x, uint16_t y, ui
/// Return a randomly selected passable cell within a given range.
static
-std::pair<uint16_t, uint16_t> map_searchrandfreecell(int m, int x, int y, int range)
+std::pair<uint16_t, uint16_t> map_searchrandfreecell(map_local *m, int x, int y, int range)
{
int whole_range = 2 * range + 1;
return map_randfreecell(m, x - range, y - range, whole_range, whole_range);
@@ -697,7 +655,7 @@ std::pair<uint16_t, uint16_t> map_searchrandfreecell(int m, int x, int y, int ra
*------------------------------------------
*/
int map_addflooritem_any(struct item *item_data, int amount,
- int m, int x, int y,
+ map_local *m, int x, int y,
dumb_ptr<map_session_data> *owners, interval_t *owner_protection,
interval_t lifetime, int dispersal)
{
@@ -762,7 +720,7 @@ int map_addflooritem_any(struct item *item_data, int amount,
}
int map_addflooritem(struct item *item_data, int amount,
- int m, int x, int y,
+ map_local *m, int x, int y,
dumb_ptr<map_session_data> first_sd,
dumb_ptr<map_session_data> second_sd,
dumb_ptr<map_session_data> third_sd)
@@ -872,8 +830,7 @@ void map_quit(dumb_ptr<map_session_data> sd)
else if (sd->state.storage_open)
storage_storage_quit(sd);
- if (sd->npc_stackbuf && sd->npc_stackbuf != NULL)
- free(sd->npc_stackbuf);
+ sd->npc_stackbuf.clear();
map_delblock(sd);
@@ -1062,30 +1019,30 @@ dumb_ptr<block_list> map_id2bl(int id)
* map.npcへ追加 (warp等の領域持ちのみ)
*------------------------------------------
*/
-int map_addnpc(int m, dumb_ptr<npc_data> nd)
+int map_addnpc(map_local *m, dumb_ptr<npc_data> nd)
{
int i;
- if (m < 0 || m >= map_num)
+ if (!m)
return -1;
- for (i = 0; i < map[m].npc_num && i < MAX_NPC_PER_MAP; i++)
- if (map[m].npc[i] == NULL)
+ for (i = 0; i < m->npc_num && i < MAX_NPC_PER_MAP; i++)
+ if (m->npc[i] == NULL)
break;
if (i == MAX_NPC_PER_MAP)
{
if (battle_config.error_log)
- PRINTF("too many NPCs in one map %s\n", map[m].name);
+ PRINTF("too many NPCs in one map %s\n", m->name);
return -1;
}
- if (i == map[m].npc_num)
+ if (i == m->npc_num)
{
- map[m].npc_num++;
+ m->npc_num++;
}
nullpo_ret(nd);
- map[m].npc[i] = nd;
+ m->npc[i] = nd;
nd->n = i;
- id_db.put(nd->bl_id, (dumb_ptr<block_list>)nd);
+ id_db.put(nd->bl_id, nd);
return i;
}
@@ -1093,23 +1050,26 @@ int map_addnpc(int m, dumb_ptr<npc_data> nd)
static
void map_removenpc(void)
{
- int i, m, n = 0;
+ int n = 0;
- for (m = 0; m < map_num; m++)
+ for (auto& mitp : maps_db)
{
- for (i = 0; i < map[m].npc_num && i < MAX_NPC_PER_MAP; i++)
+ if (!mitp.second->gat)
+ continue;
+ 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 (map[m].npc[i] != NULL)
+ if (m->npc[i] != NULL)
{
- clif_clearchar(map[m].npc[i], BeingRemoveWhy::QUIT);
- map_delblock(map[m].npc[i]);
- id_db.put(map[m].npc[i]->bl_id, nullptr);
- if (map[m].npc[i]->npc_subtype == NpcSubtype::SCRIPT)
+ clif_clearchar(m->npc[i], BeingRemoveWhy::QUIT);
+ map_delblock(m->npc[i]);
+ id_db.put(m->npc[i]->bl_id, nullptr);
+ if (m->npc[i]->npc_subtype == NpcSubtype::SCRIPT)
{
-// free(map[m].npc[i]->u.scr.script);
-// free(map[m].npc[i]->u.scr.label_list);
+// free(m->npc[i]->u.scr.script);
+// free(m->npc[i]->u.scr.label_list);
}
- map[m].npc[i].delete_();
+ m->npc[i].delete_();
n++;
}
}
@@ -1121,12 +1081,12 @@ void map_removenpc(void)
* map名からmap番号へ変換
*------------------------------------------
*/
-int map_mapname2mapid(const char *name)
+map_local *map_mapname2mapid(const char *name)
{
- struct map_data *md = map_db.get(name);
+ map_abstract *md = maps_db.get(name);
if (md == NULL || md->gat == NULL)
- return -1;
- return md->m;
+ return nullptr;
+ return static_cast<map_local *>(md);
}
/*==========================================
@@ -1135,9 +1095,10 @@ int map_mapname2mapid(const char *name)
*/
int map_mapname2ipport(const char *name, struct in_addr *ip, int *port)
{
- struct map_data_other_server *mdos = (struct map_data_other_server *)map_db.get(name);
- if (mdos == NULL || mdos->gat)
+ map_abstract *md = maps_db.get(name);
+ if (md == NULL || md->gat)
return -1;
+ map_remote *mdos = static_cast<map_remote *>(md);
*ip = mdos->ip;
*port = mdos->port;
return 0;
@@ -1219,22 +1180,22 @@ DIR map_calc_dir(dumb_ptr<block_list> src, int x, int y)
* (m,x,y)の状態を調べる
*------------------------------------------
*/
-MapCell map_getcell(int m, int x, int y)
+MapCell map_getcell(map_local *m, int x, int y)
{
- if (x < 0 || x >= map[m].xs - 1 || y < 0 || y >= map[m].ys - 1)
+ if (x < 0 || x >= m->xs - 1 || y < 0 || y >= m->ys - 1)
return MapCell::UNWALKABLE;
- return map[m].gat[x + y * map[m].xs];
+ return m->gat[x + y * m->xs];
}
/*==========================================
* (m,x,y)の状態をtにする
*------------------------------------------
*/
-void map_setcell(int m, int x, int y, MapCell t)
+void map_setcell(map_local *m, int x, int y, MapCell t)
{
- if (x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys)
+ if (x < 0 || x >= m->xs || y < 0 || y >= m->ys)
return;
- map[m].gat[x + y * map[m].xs] = t;
+ m->gat[x + y * m->xs] = t;
}
/*==========================================
@@ -1243,17 +1204,16 @@ void map_setcell(int m, int x, int y, MapCell t)
*/
int map_setipport(const char *name, struct in_addr ip, int port)
{
- struct map_data *md = map_db.get(name);
+ map_abstract *md = maps_db.get(name);
if (md == NULL)
{
- struct map_data_other_server *mdos = NULL;
// not exist -> add new data
- CREATE(mdos, struct map_data_other_server, 1);
+ auto mdos = make_unique<map_remote>();
memcpy(mdos->name, name, 24);
mdos->gat = NULL;
mdos->ip = ip;
mdos->port = port;
- map_db.put(mdos->name, (struct map_data *)mdos);
+ maps_db.put(mdos->name, std::move(mdos));
}
else
{
@@ -1270,8 +1230,7 @@ int map_setipport(const char *name, struct in_addr ip, int port)
else
{
// update
- struct map_data_other_server *mdos = NULL;
- mdos = (struct map_data_other_server *) md;
+ map_remote *mdos = static_cast<map_remote *>(md);
mdos->ip = ip;
mdos->port = port;
}
@@ -1284,7 +1243,7 @@ int map_setipport(const char *name, struct in_addr ip, int port)
*------------------------------------------
*/
static
-bool map_readmap(int m, const_string fn)
+bool map_readmap(map_local *m, size_t num, const std::string& fn)
{
// read & convert fn
std::vector<uint8_t> gat_v = grfio_reads(fn);
@@ -1292,39 +1251,27 @@ bool map_readmap(int m, const_string fn)
return false;
size_t s = gat_v.size() - 4;
- map[m].m = m;
- int xs = map[m].xs = gat_v[0] | gat_v[1] << 8;
- int ys = map[m].ys = gat_v[2] | gat_v[3] << 8;
- PRINTF("\rLoading Maps [%d/%d]: %-30s (%i, %i)",
- m, map_num, std::string(fn.begin(), fn.end()), xs, ys);
+ 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)",
+ num, maps_db.size(),
+ std::string(fn.begin(), fn.end()), xs, ys);
fflush(stdout);
assert (s == xs * ys);
- map[m].gat = make_unique<MapCell[]>(s);
- if (map[m].gat == NULL)
- {
- PRINTF("out of memory : map_readmap gat\n");
- exit(1);
- }
+ m->gat = make_unique<MapCell[]>(s);
- map[m].npc_num = 0;
- map[m].users = 0;
- memset(&map[m].flag, 0, sizeof(map[m].flag));
+ m->npc_num = 0;
+ m->users = 0;
+ memset(&m->flag, 0, sizeof(m->flag));
if (battle_config.pk_mode)
- map[m].flag.pvp = 1; // make all maps pvp for pk_mode [Valaris]
+ m->flag.pvp = 1; // make all maps pvp for pk_mode [Valaris]
MapCell *gat_m = reinterpret_cast<MapCell *>(&gat_v[4]);
- std::copy(gat_m, gat_m + s, &map[m].gat[0]);
-
- map[m].bxs = (xs + BLOCK_SIZE - 1) / BLOCK_SIZE;
- map[m].bys = (ys + BLOCK_SIZE - 1) / BLOCK_SIZE;
- size_t size = map[m].bxs * map[m].bys;
+ std::copy(gat_m, gat_m + s, &m->gat[0]);
- CREATE(map[m].block, dumb_ptr<block_list>, size);
- CREATE(map[m].block_mob, dumb_ptr<block_list>, size);
- CREATE(map[m].block_count, int, size);
- CREATE(map[m].block_mob_count, int, size);
-
- map_db.put(map[m].name, &map[m]);
+ size_t bxs = (xs + BLOCK_SIZE - 1) / BLOCK_SIZE;
+ size_t bys = (ys + BLOCK_SIZE - 1) / BLOCK_SIZE;
+ m->blocks.reset(bxs, bys);
return true;
}
@@ -1336,24 +1283,35 @@ bool map_readmap(int m, const_string fn)
static
int map_readallmap(void)
{
- int i, maps_removed = 0;
+ int maps_removed = 0;
+ int num = 0;
- for (i = 0; i < map_num; i++)
+ for (auto& mit : maps_db)
{
- assert (strstr(map[i].name, ".gat") != NULL);
+ assert (strstr(mit.second->name, ".gat") != NULL);
{
{
- if (!map_readmap(i, map[i].name))
+ map_local *ml = static_cast<map_local *>(mit.second.get());
+ if (!map_readmap(ml, num, mit.first))
{
- map_delmap(map[i].name);
+ // Can't remove while implicitly iterating,
+ // and I don't feel like explicitly iterating.
+ //map_delmap(map[i].name);
maps_removed++;
}
+ else
+ num++;
}
}
}
- PRINTF("\rMaps Loaded: %d %60s\n", map_num, "");
- PRINTF("\rMaps Removed: %d \n", maps_removed);
+ PRINTF("\rMaps Loaded: %-65zu\n", maps_db.size());
+ if (maps_removed)
+ {
+ PRINTF("Cowardly refusing to keep going after removing %d maps.\n",
+ maps_removed);
+ exit(1);
+ }
return 0;
}
@@ -1362,50 +1320,31 @@ int map_readallmap(void)
*------------------------------------------
*/
static
-int map_addmap(const char *mapname)
+void map_addmap(const std::string& mapname)
{
- if (strcasecmp(mapname, "clear") == 0)
+ if (mapname == "clear")
{
- map_num = 0;
- return 0;
+ maps_db.clear();
+ return;
}
- if (map_num >= MAX_MAP_PER_SERVER - 1)
- {
- PRINTF("too many map\n");
- return 1;
- }
- memcpy(map[map_num].name, mapname, 24);
- map_num++;
- return 0;
+ auto newmap = make_unique<map_local>();
+ strzcpy(newmap->name, mapname.c_str(), sizeof(newmap->name));
}
/*==========================================
* 読み込むmapを削除する
*------------------------------------------
*/
-static
-int map_delmap(const char *mapname)
+void map_delmap(const std::string& mapname)
{
- int i;
-
- if (strcasecmp(mapname, "all") == 0)
+ if (mapname == "all")
{
- map_num = 0;
- return 0;
+ maps_db.clear();
+ return;
}
- for (i = 0; i < map_num; i++)
- {
- if (strcmp(map[i].name, mapname) == 0)
- {
- PRINTF("Removing map [ %s ] from maplist\n", map[i].name);
- memmove(map + i, map + i + 1,
- sizeof(map[0]) * (map_num - i - 1));
- map_num--;
- }
- }
- return 0;
+ maps_db.put(mapname, nullptr);
}
constexpr int LOGFILE_SECONDS_PER_CHUNK_SHIFT = 10;
@@ -1413,7 +1352,7 @@ constexpr int LOGFILE_SECONDS_PER_CHUNK_SHIFT = 10;
static
FILE *map_logfile = NULL;
static
-char *map_logfile_name = NULL;
+std::string map_logfile_name;
static
long map_logfile_index;
@@ -1454,20 +1393,20 @@ void map_start_logfile(long index)
map_logfile_index);
map_logfile = fopen(filename_buf.c_str(), "w+");
if (!map_logfile)
- perror(map_logfile_name);
+ perror(map_logfile_name.c_str());
}
static
-void map_set_logfile(const char *filename)
+void map_set_logfile(std::string filename)
{
struct timeval tv;
- map_logfile_name = strdup(filename);
+ map_logfile_name = std::move(filename);
gettimeofday(&tv, NULL);
map_start_logfile(tv.tv_sec);
- MAP_LOG("log-start v4");
+ MAP_LOG("log-start v5");
}
void map_log(const_string line)
@@ -1523,14 +1462,16 @@ int map_config_read(const char *cfgName)
if (h != NULL)
{
PRINTF("Character server IP address : %s -> %d.%d.%d.%d\n",
- w2, (unsigned char) h->h_addr[0],
- (unsigned char) h->h_addr[1],
- (unsigned char) h->h_addr[2],
- (unsigned char) h->h_addr[3]);
- SPRINTF(w2, "%d.%d.%d.%d", (unsigned char) h->h_addr[0],
- (unsigned char) h->h_addr[1],
- (unsigned char) h->h_addr[2],
- (unsigned char) h->h_addr[3]);
+ w2,
+ static_cast<uint8_t>(h->h_addr[0]),
+ static_cast<uint8_t>(h->h_addr[1]),
+ static_cast<uint8_t>(h->h_addr[2]),
+ static_cast<uint8_t>(h->h_addr[3]));
+ SPRINTF(w2, "%d.%d.%d.%d",
+ static_cast<uint8_t>(h->h_addr[0]),
+ static_cast<uint8_t>(h->h_addr[1]),
+ static_cast<uint8_t>(h->h_addr[2]),
+ static_cast<uint8_t>(h->h_addr[3]));
}
chrif_setip(w2.c_str());
}
@@ -1544,14 +1485,15 @@ int map_config_read(const char *cfgName)
if (h != NULL)
{
PRINTF("Map server IP address : %s -> %d.%d.%d.%d\n", w2,
- (unsigned char) h->h_addr[0],
- (unsigned char) h->h_addr[1],
- (unsigned char) h->h_addr[2],
- (unsigned char) h->h_addr[3]);
- SPRINTF(w2, "%d.%d.%d.%d", (unsigned char) h->h_addr[0],
- (unsigned char) h->h_addr[1],
- (unsigned char) h->h_addr[2],
- (unsigned char) h->h_addr[3]);
+ static_cast<uint8_t>(h->h_addr[0]),
+ static_cast<uint8_t>(h->h_addr[1]),
+ static_cast<uint8_t>(h->h_addr[2]),
+ static_cast<uint8_t>(h->h_addr[3]));
+ SPRINTF(w2, "%d.%d.%d.%d",
+ static_cast<uint8_t>(h->h_addr[0]),
+ static_cast<uint8_t>(h->h_addr[1]),
+ static_cast<uint8_t>(h->h_addr[2]),
+ static_cast<uint8_t>(h->h_addr[3]));
}
clif_setip(w2.c_str());
}
@@ -1595,7 +1537,7 @@ int map_config_read(const char *cfgName)
}
else if (w1 == "gm_log")
{
- gm_logfile_name = strdup(w2.c_str());
+ gm_logfile_name = std::move(w2);
}
else if (w1 == "log_file")
{
@@ -1643,33 +1585,26 @@ void term_func(void)
{
map_close_logfile();
- int map_id, i;
-
- for (map_id = 0; map_id < map_num; map_id++)
+ for (auto& mit : maps_db)
{
- if (map[map_id].m)
- map_foreachinarea(cleanup_sub, map_id,
- 0, 0, map[map_id].xs, map[map_id].ys,
- BL::NUL);
+ if (!mit.second->gat)
+ continue;
+ map_local *map_id = static_cast<map_local *>(mit.second.get());
+
+ map_foreachinarea(cleanup_sub,
+ map_id,
+ 0, 0,
+ map_id->xs, map_id->ys,
+ BL::NUL);
}
- for (i = 0; i < fd_max; i++)
+ for (int i = 0; i < fd_max; i++)
delete_session(i);
map_removenpc();
- for (i = 0; i <= map_num; i++)
- {
- map[i].gat = nullptr;
- if (map[i].block)
- free(map[i].block);
- if (map[i].block_mob)
- free(map[i].block_mob);
- if (map[i].block_count)
- free(map[i].block_count);
- if (map[i].block_mob_count)
- free(map[i].block_mob_count);
- }
+ maps_db.clear();
+
do_final_script();
do_final_itemdb();
do_final_storage();
diff --git a/src/map/map.hpp b/src/map/map.hpp
index cb2513a..c004315 100644
--- a/src/map/map.hpp
+++ b/src/map/map.hpp
@@ -8,6 +8,7 @@
#include <functional>
#include "../common/db.hpp"
+#include "../common/matrix.hpp"
#include "../common/socket.hpp"
#include "../common/timer.t.hpp"
@@ -22,7 +23,6 @@ constexpr int BLOCK_SIZE = 8;
#define AREA_SIZE battle_config.area_size
constexpr std::chrono::seconds LIFETIME_FLOORITEM = std::chrono::minutes(1);
constexpr int DAMAGELOG_SIZE = 30;
-constexpr int LOOTITEM_SIZE = 10;
constexpr int MAX_SKILL_LEVEL = 100;
constexpr int MAX_MOBSKILL = 32;
constexpr int MAX_EVENTQUEUE = 2;
@@ -40,12 +40,14 @@ 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;
- short bl_m, bl_x, bl_y;
+ map_local *bl_m;
+ short bl_x, bl_y;
BL bl_type;
// This deletes the copy-ctor also
@@ -153,12 +155,14 @@ struct map_session_data : block_list, SessionData
struct walkpath_data walkpath;
Timer walktimer;
int npc_id, areanpc_id, npc_shopid;
+ // this is important
int npc_pos;
int npc_menu;
int npc_amount;
- int npc_stack, npc_stackmax;
- const ScriptCode *npc_script, *npc_scriptroot;
- struct script_data *npc_stackbuf;
+ // I have no idea exactly what these are doing ...
+ // but one should probably be replaced with a ScriptPointer ???
+ const ScriptBuffer *npc_script, *npc_scriptroot;
+ std::vector<struct script_data> npc_stackbuf;
char npc_str[256];
struct
{
@@ -229,10 +233,10 @@ struct map_session_data : block_list, SessionData
int die_counter;
- int reg_num;
- struct script_reg *reg;
- int regstr_num;
- struct script_regstr *regstr;
+ // register keys are ints (interned)
+ DMap<int, int> regm;
+ // can't be DMap because we want predictable .c_str()s
+ Map<int, std::string> regstrm;
earray<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
short sc_count;
@@ -262,13 +266,6 @@ struct map_session_data : block_list, SessionData
struct
{
- char name[24];
- } ignore[80];
- int ignoreAll;
- short sg_count;
-
- struct
- {
unsigned in_progress:1;
} auto_ban_info;
@@ -339,16 +336,25 @@ class npc_data_script : public npc_data
public:
struct
{
- const ScriptCode *script;
+ // The bytecode unique to this NPC.
+ std::unique_ptr<const ScriptBuffer> script;
+ // Diameter.
short xs, ys;
+ // Tick counter through the timers.
+ // It is actually updated when frobbing the thing in any way.
+ // If this is timer_eventv().back().timer, it is expired
+ // rather than blank. It's probably a bad idea to rely on this.
interval_t timer;
+ // Actual timer that fires the event.
Timer timerid;
- int timeramount, nexttimer;
+ // Event to be fired, or .end() if no timer.
+ std::vector<npc_timerevent_list>::iterator nexttimer;
+ // When the timer started. Needed to get the true diff, or to stop.
tick_t timertick;
- struct npc_timerevent_list *timer_event;
- int label_list_num;
- struct npc_label_list *label_list;
- int src_id;
+ // List of label events to call.
+ std::vector<npc_timerevent_list> timer_eventv;
+ // List of (name, offset) label locations in the bytecode
+ std::vector<npc_label_list> label_listv;
} scr;
};
@@ -372,7 +378,7 @@ public:
class npc_data_message : public npc_data
{
public:
- char *message;
+ std::string message;
};
constexpr int MOB_XP_BONUS_BASE = 1024;
@@ -384,9 +390,13 @@ struct mob_data : block_list
short mob_class;
DIR dir;
MobMode mode;
- short m, x0, y0, xs, ys;
+ struct
+ {
+ map_local *m;
+ short x0, y0, xs, ys;
+ interval_t delay1, delay2;
+ } spawn;
char name[24];
- interval_t spawndelay1, spawndelay2;
struct
{
MS state;
@@ -416,8 +426,7 @@ struct mob_data : block_list
int id;
int dmg;
} dmglog[DAMAGELOG_SIZE];
- struct item *lootitem;
- short lootitem_count;
+ std::vector<struct item> lootitemv;
earray<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
short sc_count;
@@ -426,7 +435,6 @@ struct mob_data : block_list
Opt3 opt3;
Option option;
short min_chase;
- short sg_count;
Timer deletetimer;
Timer skilltimer;
@@ -444,18 +452,28 @@ struct mob_data : block_list
short size;
};
-struct map_data
+struct BlockLists
{
+ dumb_ptr<block_list> normal, mobs_only;
+};
+
+struct map_abstract
+{
+ // shouldn't this be 16?
+ // but beware of hard-coded memcpys
char name[24];
- char alias[24]; // [MouseJstr]
- // if NULL, actually a map_data_other_server
+ // gat is NULL for map_remote and non-NULL or map_local
std::unique_ptr<MapCell[]> gat;
- dumb_ptr<block_list> *block;
- dumb_ptr<block_list> *block_mob;
- int *block_count, *block_mob_count;
- int m;
+
+ virtual ~map_abstract() {};
+};
+extern
+UPMap<std::string, map_abstract> maps_db;
+
+struct map_local : map_abstract
+{
+ Matrix<BlockLists> blocks;
short xs, ys;
- short bxs, bys;
int npc_num;
int users;
struct
@@ -494,27 +512,18 @@ struct map_data
int drop_per;
} drop_list[MAX_DROP_PER_MAP];
};
-struct map_data_other_server
+
+struct map_remote : map_abstract
{
- char name[24];
- unsigned char *gat; // NULL固定にして判断
struct in_addr ip;
unsigned int port;
};
-extern struct map_data map[];
-extern int map_num;
-
inline
-MapCell read_gatp(struct map_data *m, int x, int y)
+MapCell read_gatp(map_local *m, int x, int y)
{
return m->gat[x + y * m->xs];
}
-inline
-MapCell read_gat(int m, int x, int y)
-{
- return read_gatp(&map[m], x, y);
-}
struct flooritem_data : block_list
{
@@ -552,21 +561,21 @@ public:
int map_addblock(dumb_ptr<block_list>);
int map_delblock(dumb_ptr<block_list>);
void map_foreachinarea(std::function<void(dumb_ptr<block_list>)>,
- int,
+ map_local *,
int, int, int, int,
BL);
// -- moonsoul (added map_foreachincell)
void map_foreachincell(std::function<void(dumb_ptr<block_list>)>,
- int,
+ map_local *,
int, int,
BL);
void map_foreachinmovearea(std::function<void(dumb_ptr<block_list>)>,
- int,
+ map_local *,
int, int, int, int,
int, int,
BL);
//block関連に追加
-int map_count_oncell(int m, int x, int y);
+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);
@@ -576,15 +585,15 @@ void map_foreachobject(std::function<void(dumb_ptr<block_list>)>,
//
void map_quit(dumb_ptr<map_session_data>);
// npc
-int map_addnpc(int, dumb_ptr<npc_data>);
+int map_addnpc(map_local *, dumb_ptr<npc_data>);
void map_log(const_string line);
#define MAP_LOG(format, ...) \
map_log(static_cast<const std::string&>(STRPRINTF(format, ## __VA_ARGS__)))
#define MAP_LOG_PC(sd, fmt, ...) \
- MAP_LOG("PC%d %d:%d,%d " fmt, \
- sd->status.char_id, sd->bl_m, sd->bl_x, sd->bl_y, ## __VA_ARGS__)
+ MAP_LOG("PC%d %s:%d,%d " fmt, \
+ sd->status.char_id, sd->bl_m->name, sd->bl_x, sd->bl_y, ## __VA_ARGS__)
// 床アイテム関連
void map_clearflooritem_timer(TimerData *, tick_t, int);
@@ -593,10 +602,12 @@ void map_clearflooritem(int id)
{
map_clearflooritem_timer(nullptr, tick_t(), id);
}
-int map_addflooritem_any(struct item *, int amount, int m, int x, int y,
+int map_addflooritem_any(struct item *, int amount,
+ map_local *m, int x, int y,
dumb_ptr<map_session_data> *owners, interval_t *owner_protection,
interval_t lifetime, int dispersal);
-int map_addflooritem(struct item *, int, int, int, int,
+int map_addflooritem(struct item *, int,
+ map_local *, int, int,
dumb_ptr<map_session_data>, dumb_ptr<map_session_data>,
dumb_ptr<map_session_data>);
@@ -672,7 +683,7 @@ dumb_ptr<invocation> map_id_is_spell(int id)
}
-int map_mapname2mapid(const char *);
+map_local *map_mapname2mapid(const char *);
int map_mapname2ipport(const char *, struct in_addr *, int *);
int map_setipport(const char *name, struct in_addr ip, int port);
void map_addiddb(dumb_ptr<block_list>);
@@ -690,17 +701,15 @@ dumb_ptr<map_session_data> map_get_prev_session(
dumb_ptr<map_session_data> current);
// gat関連
-MapCell map_getcell(int, int, int);
-void map_setcell(int, int, int, MapCell);
+MapCell map_getcell(map_local *, int, int);
+void map_setcell(map_local *, int, int, MapCell);
// その他
bool map_check_dir(DIR s_dir, DIR t_dir);
DIR map_calc_dir(dumb_ptr<block_list> src, int x, int y);
-// path.cより
-int path_search(struct walkpath_data *, int, int, int, int, int, int);
-
-std::pair<uint16_t, uint16_t> map_randfreecell(int m, uint16_t x, uint16_t y, uint16_t w, uint16_t h);
+std::pair<uint16_t, uint16_t> map_randfreecell(map_local *m,
+ uint16_t x, uint16_t y, uint16_t w, uint16_t h);
inline dumb_ptr<map_session_data> block_list::as_player() { return dumb_ptr<map_session_data>(static_cast<map_session_data *>(this)) ; }
inline dumb_ptr<npc_data> block_list::as_npc() { return dumb_ptr<npc_data>(static_cast<npc_data *>(this)) ; }
diff --git a/src/map/mob.cpp b/src/map/mob.cpp
index 828bca5..e4520d0 100644
--- a/src/map/mob.cpp
+++ b/src/map/mob.cpp
@@ -20,6 +20,7 @@
#include "map.hpp"
#include "npc.hpp"
#include "party.hpp"
+#include "path.hpp"
#include "pc.hpp"
#include "skill.hpp"
@@ -289,12 +290,11 @@ int mob_gen_exp(struct mob_db *mob)
bool(mob->mode & MobMode::AGGRESSIVE)
? 10.0 / 9.0
: 1.0;
- int xp =
- (int) floor(effective_hp *
- pow(sqrt(attack_factor) + sqrt(dodge_factor) +
- sqrt(persuit_factor) + 55,
- 3) * aggression_factor / 2000000.0 *
- (double) battle_config.base_exp_rate / 100.);
+ int xp = floor(effective_hp * pow(sqrt(attack_factor)
+ + sqrt(dodge_factor)
+ + sqrt(persuit_factor) + 55, 3)
+ * aggression_factor / 2000000.0
+ * 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);
@@ -371,14 +371,15 @@ int mob_once_spawn(dumb_ptr<map_session_data> sd, const char *mapname,
const char *event)
{
dumb_ptr<mob_data> md = NULL;
- int m, count, r = mob_class;
+ map_local *m;
+ int count, r = mob_class;
if (sd && strcmp(mapname, "this") == 0)
m = sd->bl_m;
else
m = map_mapname2mapid(mapname);
- if (m < 0 || amount <= 0 || (mob_class >= 0 && mob_class <= 1000) || mob_class > 2000) // 値が異常なら召喚を止める
+ if (m == nullptr || amount <= 0 || (mob_class >= 0 && mob_class <= 1000) || mob_class > 2000) // 値が異常なら召喚を止める
return 0;
if (sd)
@@ -396,11 +397,7 @@ int mob_once_spawn(dumb_ptr<map_session_data> sd, const char *mapname,
for (count = 0; count < amount; count++)
{
md.new_();
- if (bool(mob_db[mob_class].mode & MobMode::LOOTER))
- md->lootitem =
- (struct item *) calloc(LOOTITEM_SIZE, sizeof(struct item));
- else
- md->lootitem = NULL;
+ md->lootitemv.clear();
mob_spawn_dataset(md, mobname, mob_class);
md->bl_m = m;
@@ -409,13 +406,13 @@ int mob_once_spawn(dumb_ptr<map_session_data> sd, const char *mapname,
if (r < 0 && battle_config.dead_branch_active == 1)
//移動してアクティブで反撃する
md->mode = MobMode::war;
- md->m = m;
- md->x0 = x;
- md->y0 = y;
- md->xs = 0;
- md->ys = 0;
- md->spawndelay1 = static_cast<interval_t>(-1); // Only once is a flag.
- md->spawndelay2 = static_cast<interval_t>(-1); // Only once is a flag.
+ md->spawn.m = m;
+ md->spawn.x0 = x;
+ md->spawn.y0 = y;
+ md->spawn.xs = 0;
+ md->spawn.ys = 0;
+ md->spawn.delay1 = static_cast<interval_t>(-1); // Only once is a flag.
+ md->spawn.delay2 = static_cast<interval_t>(-1); // Only once is a flag.
memcpy(md->npc_event, event, sizeof(md->npc_event));
@@ -436,7 +433,7 @@ int mob_once_spawn_area(dumb_ptr<map_session_data> sd, const char *mapname,
const char *event)
{
int x, y, i, max, lx = -1, ly = -1, id = 0;
- int m;
+ map_local *m;
if (strcmp(mapname, "this") == 0)
m = sd->bl_m;
@@ -447,7 +444,7 @@ int mob_once_spawn_area(dumb_ptr<map_session_data> sd, const char *mapname,
if (max > 1000)
max = 1000;
- if (m < 0 || amount <= 0 || (mob_class >= 0 && mob_class <= 1000) || mob_class > 2000) // A summon is stopped if a value is unusual
+ 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;
for (i = 0; i < amount; i++)
@@ -618,9 +615,11 @@ int mob_walk(dumb_ptr<mob_data> md, tick_t tick, unsigned char data)
md->state.state = MS::WALK;
map_foreachinmovearea(std::bind(clif_moboutsight, ph::_1, md),
- md->bl_m, x - AREA_SIZE, y - AREA_SIZE,
+ md->bl_m,
+ x - AREA_SIZE, y - AREA_SIZE,
x + AREA_SIZE, y + AREA_SIZE,
- dx, dy, BL::PC);
+ dx, dy,
+ BL::PC);
x += dx;
y += dy;
@@ -635,9 +634,11 @@ int mob_walk(dumb_ptr<mob_data> md, tick_t tick, unsigned char data)
map_addblock(md);
map_foreachinmovearea(std::bind(clif_mobinsight, ph::_1, md),
- md->bl_m, x - AREA_SIZE, y - AREA_SIZE,
+ md->bl_m,
+ x - AREA_SIZE, y - AREA_SIZE,
x + AREA_SIZE, y + AREA_SIZE,
- -dx, -dy, BL::PC);
+ -dx, -dy,
+ BL::PC);
md->state.state = MS::IDLE;
}
interval_t i = calc_next_walk_step(md);
@@ -789,10 +790,12 @@ int mob_attack(dumb_ptr<mob_data> md, tick_t tick)
// If you are reading this, please note:
// it is highly platform-specific that this even works at all.
int radius = battle_config.mob_splash_radius;
- if (radius >= 0 && tbl->bl_type == BL::PC && !map[tbl->bl_m].flag.town)
+ if (radius >= 0 && tbl->bl_type == BL::PC && !tbl->bl_m->flag.town)
map_foreachinarea(std::bind(mob_ancillary_attack, ph::_1, md, tbl, tick),
- tbl->bl_m, tbl->bl_x - radius, tbl->bl_y - radius,
- tbl->bl_x + radius, tbl->bl_y + radius, BL::PC);
+ tbl->bl_m,
+ tbl->bl_x - radius, tbl->bl_y - radius,
+ tbl->bl_x + radius, tbl->bl_y + radius,
+ BL::PC);
md->attackabletime = tick + battle_get_adelay(md);
@@ -1016,22 +1019,18 @@ int mob_setdelayspawn(int id)
return -1;
// Processing of MOB which is not revitalized
- if (md->spawndelay1 == static_cast<interval_t>(-1)
- && md->spawndelay2 == static_cast<interval_t>(-1)
+ if (md->spawn.delay1 == static_cast<interval_t>(-1)
+ && md->spawn.delay2 == static_cast<interval_t>(-1)
&& md->n == 0)
{
map_deliddb(md);
- if (md->lootitem)
- {
- free(md->lootitem);
- md->lootitem = NULL;
- }
+ md->lootitemv.clear();
MapBlockLock::freeblock(md);
return 0;
}
- tick_t spawntime1 = md->last_spawntime + md->spawndelay1;
- tick_t spawntime2 = md->last_deadtime + md->spawndelay2;
+ 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 spawntime = std::max({spawntime1, spawntime2, spawntime3});
@@ -1071,22 +1070,22 @@ int mob_spawn(int id)
map_delblock(md);
}
- md->bl_m = md->m;
+ md->bl_m = md->spawn.m;
{
int i = 0;
do
{
- if (md->x0 == 0 && md->y0 == 0)
+ if (md->spawn.x0 == 0 && md->spawn.y0 == 0)
{
- x = random_::in(1, map[md->bl_m].xs - 2);
- y = random_::in(1, map[md->bl_m].ys - 2);
+ x = random_::in(1, md->bl_m->xs - 2);
+ y = random_::in(1, md->bl_m->ys - 2);
}
else
{
// TODO: move this logic earlier - possibly all the way
// into the data files
- x = md->x0 - md->xs / 2 + random_::in(0, md->xs);
- y = md->y0 - md->ys / 2 + random_::in(0, md->ys);
+ x = md->spawn.x0 - md->spawn.xs / 2 + random_::in(0, md->spawn.xs);
+ y = md->spawn.y0 - md->spawn.ys / 2 + random_::in(0, md->spawn.ys);
}
i++;
}
@@ -1131,7 +1130,6 @@ int mob_spawn(int id)
md->attackabletime = tick;
md->canmove_tick = tick;
- md->sg_count = 0;
// md->deletetimer = nullptr;
// md->skilltimer = nullptr;
@@ -1141,9 +1139,7 @@ int mob_spawn(int id)
md->skilllv = 0;
memset(md->dmglog, 0, sizeof(md->dmglog));
- if (md->lootitem)
- memset(md->lootitem, 0, sizeof(*md->lootitem));
- md->lootitem_count = 0;
+ md->lootitemv.clear();
for (StatusChange i : erange(StatusChange(), StatusChange::MAX_STATUSCHANGE))
{
@@ -1470,10 +1466,6 @@ void mob_ai_sub_hard_lootsearch(dumb_ptr<block_list> bl, dumb_ptr<mob_data> md,
if (!md->target_id && bool(mode & MobMode::LOOTER))
{
- if (!md->lootitem
- || (battle_config.monster_loot_type == 1
- && md->lootitem_count >= LOOTITEM_SIZE))
- return;
if (bl->bl_m == md->bl_m
&& (dist = distance(md->bl_x, md->bl_y, bl->bl_x, bl->bl_y)) < 9)
{
@@ -1560,7 +1552,7 @@ int mob_ai_sub_hard_slavemob(dumb_ptr<mob_data> md, tick_t tick)
// Since the master was in near immediately before, teleport is carried out and it pursues.
if (old_dist < 10 && md->master_dist > 18)
{
- mob_warp(md, -1, mmd->bl_x, mmd->bl_y, BeingRemoveWhy::WARPED);
+ mob_warp(md, nullptr, mmd->bl_x, mmd->bl_y, BeingRemoveWhy::WARPED);
md->state.master_check = 1;
return 0;
}
@@ -1779,8 +1771,10 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick)
if (!asd->invincible_timer && !pc_isinvisible(asd))
{
map_foreachinarea(std::bind(mob_ai_sub_hard_linksearch, ph::_1, md, asd),
- md->bl_m, md->bl_x - 13, md->bl_y - 13,
- md->bl_x + 13, md->bl_y + 13, BL::MOB);
+ md->bl_m,
+ md->bl_x - 13, md->bl_y - 13,
+ md->bl_x + 13, md->bl_y + 13,
+ BL::MOB);
}
}
}
@@ -1829,15 +1823,18 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick)
if (md->state.special_mob_ai)
{
map_foreachinarea(std::bind(mob_ai_sub_hard_activesearch, ph::_1, md, &i),
- md->bl_m, md->bl_x - AREA_SIZE * 2, md->bl_y - AREA_SIZE * 2,
+ md->bl_m,
+ md->bl_x - AREA_SIZE * 2, md->bl_y - AREA_SIZE * 2,
md->bl_x + AREA_SIZE * 2, md->bl_y + AREA_SIZE * 2,
BL::NUL);
}
else
{
map_foreachinarea(std::bind(mob_ai_sub_hard_activesearch, ph::_1, md, &i),
- md->bl_m, md->bl_x - AREA_SIZE * 2, md->bl_y - AREA_SIZE * 2,
- md->bl_x + AREA_SIZE * 2, md->bl_y + AREA_SIZE * 2, BL::PC);
+ md->bl_m,
+ md->bl_x - AREA_SIZE * 2, md->bl_y - AREA_SIZE * 2,
+ md->bl_x + AREA_SIZE * 2, md->bl_y + AREA_SIZE * 2,
+ BL::PC);
}
}
@@ -1848,8 +1845,10 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick)
{
i = 0;
map_foreachinarea(std::bind(mob_ai_sub_hard_lootsearch, ph::_1, md, &i),
- md->bl_m, md->bl_x - AREA_SIZE * 2, md->bl_y - AREA_SIZE * 2,
- md->bl_x + AREA_SIZE * 2, md->bl_y + AREA_SIZE * 2, BL::ITEM);
+ md->bl_m,
+ md->bl_x - AREA_SIZE * 2, md->bl_y - AREA_SIZE * 2,
+ md->bl_x + AREA_SIZE * 2, md->bl_y + AREA_SIZE * 2,
+ BL::ITEM);
}
// It will attack, if the candidate for an attack is.
@@ -1955,7 +1954,8 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick)
if (tbl == NULL || 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 || !md->lootitem)
+ tbl->bl_y)) >= md->min_chase
+ || !bool(mob_db[md->mob_class].mode & MobMode::LOOTER))
{
// 遠すぎるかアイテムがなくなった
mob_unlocktarget(md, tick);
@@ -1991,23 +1991,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick)
if (md->state.state == MS::WALK)
mob_stop_walking(md, 1); // 歩行中なら停止
fitem = tbl->as_item();
- if (md->lootitem_count < LOOTITEM_SIZE)
- memcpy(&md->lootitem[md->lootitem_count++],
- &fitem->item_data, sizeof(md->lootitem[0]));
- else if (battle_config.monster_loot_type == 1
- && md->lootitem_count >= LOOTITEM_SIZE)
- {
- mob_unlocktarget(md, tick);
- return;
- }
- else
- {
- for (i = 0; i < LOOTITEM_SIZE - 1; i++)
- memcpy(&md->lootitem[i], &md->lootitem[i + 1],
- sizeof(md->lootitem[0]));
- memcpy(&md->lootitem[LOOTITEM_SIZE - 1],
- &fitem->item_data, sizeof(md->lootitem[0]));
- }
+ md->lootitemv.push_back(fitem->item_data);
map_clearflooritem(tbl->bl_id);
mob_unlocktarget(md, tick);
}
@@ -2064,8 +2048,10 @@ void mob_ai_sub_foreachclient(dumb_ptr<map_session_data> sd, tick_t tick)
nullpo_retv(sd);
map_foreachinarea(std::bind(mob_ai_sub_hard, ph::_1, tick),
- sd->bl_m, sd->bl_x - AREA_SIZE * 2, sd->bl_y - AREA_SIZE * 2,
- sd->bl_x + AREA_SIZE * 2, sd->bl_y + AREA_SIZE * 2, BL::MOB);
+ sd->bl_m,
+ sd->bl_x - AREA_SIZE * 2, sd->bl_y - AREA_SIZE * 2,
+ sd->bl_x + AREA_SIZE * 2, sd->bl_y + AREA_SIZE * 2,
+ BL::MOB);
}
/*==========================================
@@ -2108,7 +2094,7 @@ void mob_ai_sub_lazy(dumb_ptr<block_list> bl, tick_t tick)
&& mob_can_move(md))
{
- if (map[md->bl_m].users > 0)
+ if (md->bl_m->users > 0)
{
// Since PC is in the same map, somewhat better negligent processing is carried out.
@@ -2118,7 +2104,7 @@ 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->x0 <= 0
+ && md->spawn.x0 <= 0
&& md->master_id != 0
&& !bool(mob_db[md->mob_class].mode & MobMode::BOSS))
mob_spawn(md->bl_id);
@@ -2130,10 +2116,10 @@ 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->x0 <= 0
+ && md->spawn.x0 <= 0
&& md->master_id != 0
&& !bool(mob_db[md->mob_class].mode & MobMode::BOSS))
- mob_warp(md, -1, -1, -1, BeingRemoveWhy::NEGATIVE1);
+ mob_warp(md, nullptr, -1, -1, BeingRemoveWhy::NEGATIVE1);
}
md->next_walktime = tick + std::chrono::seconds(5) + std::chrono::milliseconds(random_::to(10 * 1000));
@@ -2159,14 +2145,16 @@ void mob_ai_lazy(TimerData *, tick_t tick)
*/
struct delay_item_drop
{
- int m, x, y;
+ map_local *m;
+ int x, y;
int nameid, amount;
dumb_ptr<map_session_data> first_sd, second_sd, third_sd;
};
struct delay_item_drop2
{
- int m, x, y;
+ map_local *m;
+ int x, y;
struct item item_data;
dumb_ptr<map_session_data> first_sd, second_sd, third_sd;
};
@@ -2176,39 +2164,33 @@ struct delay_item_drop2
*------------------------------------------
*/
static
-void mob_delay_item_drop(TimerData *, tick_t, struct delay_item_drop *ditem)
+void mob_delay_item_drop(TimerData *, tick_t, struct delay_item_drop ditem)
{
- struct item temp_item;
+ struct item temp_item {};
PickupFail flag;
- nullpo_retv(ditem);
-
- memset(&temp_item, 0, sizeof(temp_item));
- temp_item.nameid = ditem->nameid;
- temp_item.amount = ditem->amount;
+ temp_item.nameid = ditem.nameid;
+ temp_item.amount = ditem.amount;
temp_item.identify = !itemdb_isequip3(temp_item.nameid);
if (battle_config.item_auto_get == 1)
{
- if (ditem->first_sd
+ if (ditem.first_sd
&& (flag =
- pc_additem(ditem->first_sd, &temp_item, ditem->amount))
+ pc_additem(ditem.first_sd, &temp_item, ditem.amount))
!= PickupFail::OKAY)
{
- clif_additem(ditem->first_sd, 0, 0, flag);
+ clif_additem(ditem.first_sd, 0, 0, flag);
map_addflooritem(&temp_item, 1,
- ditem->m, ditem->x, ditem->y,
- ditem->first_sd, ditem->second_sd, ditem->third_sd);
+ ditem.m, ditem.x, ditem.y,
+ ditem.first_sd, ditem.second_sd, ditem.third_sd);
}
- free(ditem);
return;
}
map_addflooritem(&temp_item, 1,
- ditem->m, ditem->x, ditem->y,
- ditem->first_sd, ditem->second_sd, ditem->third_sd);
-
- free(ditem);
+ ditem.m, ditem.x, ditem.y,
+ ditem.first_sd, ditem.second_sd, ditem.third_sd);
}
/*==========================================
@@ -2216,34 +2198,29 @@ void mob_delay_item_drop(TimerData *, tick_t, struct delay_item_drop *ditem)
*------------------------------------------
*/
static
-void mob_delay_item_drop2(TimerData *, tick_t, struct delay_item_drop2 *ditem)
+void mob_delay_item_drop2(TimerData *, tick_t, struct delay_item_drop2 ditem)
{
PickupFail flag;
- nullpo_retv(ditem);
-
if (battle_config.item_auto_get == 1)
{
- if (ditem->first_sd
+ if (ditem.first_sd
&& (flag =
- pc_additem(ditem->first_sd, &ditem->item_data,
- ditem->item_data.amount))
+ pc_additem(ditem.first_sd, &ditem.item_data,
+ ditem.item_data.amount))
!= PickupFail::OKAY)
{
- clif_additem(ditem->first_sd, 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);
+ clif_additem(ditem.first_sd, 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);
}
- free(ditem);
return;
}
- map_addflooritem(&ditem->item_data, ditem->item_data.amount,
- ditem->m, ditem->x, ditem->y,
- ditem->first_sd, ditem->second_sd, ditem->third_sd);
-
- free(ditem);
+ map_addflooritem(&ditem.item_data, ditem.item_data.amount,
+ ditem.m, ditem.x, ditem.y,
+ ditem.first_sd, ditem.second_sd, ditem.third_sd);
}
/*==========================================
@@ -2313,8 +2290,10 @@ int mob_deleteslave(dumb_ptr<mob_data> md)
nullpo_ret(md);
map_foreachinarea(std::bind(mob_deleteslave_sub, ph::_1, md->bl_id),
- md->bl_m, 0, 0,
- map[md->bl_m].xs, map[md->bl_m].ys, BL::MOB);
+ md->bl_m,
+ 0, 0,
+ md->bl_m->xs, md->bl_m->ys,
+ BL::MOB);
return 0;
}
@@ -2519,7 +2498,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
if (tmpsd[i]->bl_m != md->bl_m || pc_isdead(tmpsd[i]))
continue;
- tdmg += (double) md->dmglog[i].dmg;
+ tdmg += md->dmglog[i].dmg;
if (mvp_damage < md->dmglog[i].dmg)
{
third_sd = second_sd;
@@ -2530,7 +2509,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
}
// [MouseJstr]
- if ((map[md->bl_m].flag.pvp == 0) || (battle_config.pvp_exp == 1))
+ if ((md->bl_m->flag.pvp == 0) || (battle_config.pvp_exp == 1))
{
// 経験値の分配
for (int i = 0; i < DAMAGELOG_SIZE; i++)
@@ -2541,21 +2520,10 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
struct party *p;
if (tmpsd[i] == NULL || tmpsd[i]->bl_m != md->bl_m)
continue;
-/* jAthena's exp formula
- per = ((double)md->dmglog[i].dmg)* (9.+(double)((count > 6)? 6:count))/10./((double)max_hp) * dmg_rate;
- temp = ((double)mob_db[md->mob_class].base_exp * (double)battle_config.base_exp_rate / 100. * per);
- base_exp = (temp > 2147483647.)? 0x7fffffff:(int)temp;
- if (mob_db[md->mob_class].base_exp > 0 && base_exp < 1) base_exp = 1;
- if (base_exp < 0) base_exp = 0;
- temp = ((double)mob_db[md->mob_class].job_exp * (double)battle_config.job_exp_rate / 100. * per);
- job_exp = (temp > 2147483647.)? 0x7fffffff:(int)temp;
- if (mob_db[md->mob_class].job_exp > 0 && job_exp < 1) job_exp = 1;
- if (job_exp < 0) job_exp = 0;
-*/
-//eAthena's exp formula rather than jAthena's
-// per=(double)md->dmglog[i].dmg*256*(9+(double)((count > 6)? 6:count))/10/(double)max_hp;
// [Fate] The above is the old formula. We do a more involved computation below.
- per = (double) md->dmglog[i].dmg * 256 / (double) max_hp; // 256 = 100% of the score
+ // [o11c] Look in git history for old code, you idiot!
+ // 256 = 100% of the score
+ per = static_cast<double>(md->dmglog[i].dmg) * 256 / static_cast<double>(max_hp);
per *= damage_bonus_factor[count > DAMAGE_BONUS_COUNT ? DAMAGE_BONUS_COUNT : count]; // Bonus for party attack
if (per > 512)
per = 512; // [Fate] Retained from before. The maximum a single individual can get is double the original value.
@@ -2626,8 +2594,6 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
{
for (int i = 0; i < 8; i++)
{
- struct delay_item_drop *ditem;
-
if (md->state.special_mob_ai >= 1 && battle_config.alchemist_summon_reward != 1) // Added [Valaris]
break; // End
@@ -2642,42 +2608,38 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
if (!random_::chance(drop_rate))
continue;
- ditem = (struct delay_item_drop *)
- calloc(1, sizeof(struct delay_item_drop));
- ditem->nameid = mob_db[md->mob_class].dropitem[i].nameid;
- ditem->amount = 1;
- ditem->m = md->bl_m;
- ditem->x = md->bl_x;
- ditem->y = md->bl_y;
- ditem->first_sd = mvp_sd;
- ditem->second_sd = second_sd;
- ditem->third_sd = third_sd;
+ struct delay_item_drop ditem {};
+ ditem.nameid = mob_db[md->mob_class].dropitem[i].nameid;
+ ditem.amount = 1;
+ ditem.m = md->bl_m;
+ ditem.x = md->bl_x;
+ ditem.y = md->bl_y;
+ 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),
std::bind(mob_delay_item_drop, ph::_1, ph::_2,
ditem)
).detach();
}
- if (md->lootitem)
{
- for (int i = 0; i < md->lootitem_count; i++)
+ int i = 0;
+ for (struct item lit : md->lootitemv)
{
- struct delay_item_drop2 *ditem;
-
- ditem = (struct delay_item_drop2 *)
- calloc(1, sizeof(struct delay_item_drop2));
- memcpy(&ditem->item_data, &md->lootitem[i],
- sizeof(md->lootitem[0]));
- ditem->m = md->bl_m;
- ditem->x = md->bl_x;
- ditem->y = md->bl_y;
- ditem->first_sd = mvp_sd;
- ditem->second_sd = second_sd;
- ditem->third_sd = third_sd;
+ struct delay_item_drop2 ditem {};
+ ditem.item_data = lit;
+ ditem.m = md->bl_m;
+ ditem.x = md->bl_x;
+ ditem.y = md->bl_y;
+ ditem.first_sd = mvp_sd;
+ ditem.second_sd = second_sd;
+ ditem.third_sd = third_sd;
// ?
Timer(tick + std::chrono::milliseconds(540) + static_cast<interval_t>(i),
std::bind(mob_delay_item_drop2, ph::_1, ph::_2,
ditem)
).detach();
+ i++;
}
}
}
@@ -2748,7 +2710,7 @@ void mob_warpslave_sub(dumb_ptr<block_list> bl, int id, int x, int y)
if (md->master_id == id)
{
- mob_warp(md, -1, x, y, BeingRemoveWhy::QUIT);
+ mob_warp(md, nullptr, x, y, BeingRemoveWhy::QUIT);
}
}
@@ -2761,8 +2723,10 @@ 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,
- x + AREA_SIZE, y + AREA_SIZE, BL::MOB);
+ md->bl_m,
+ x - AREA_SIZE, y - AREA_SIZE,
+ x + AREA_SIZE, y + AREA_SIZE,
+ BL::MOB);
return 0;
}
@@ -2770,7 +2734,7 @@ int mob_warpslave(dumb_ptr<mob_data> md, int x, int y)
* mobワープ
*------------------------------------------
*/
-int mob_warp(dumb_ptr<mob_data> md, int m, int x, int y, BeingRemoveWhy type)
+int mob_warp(dumb_ptr<mob_data> md, map_local *m, int x, int y, BeingRemoveWhy type)
{
int i = 0, xs = 0, ys = 0, bx = x, by = y;
@@ -2779,12 +2743,12 @@ int mob_warp(dumb_ptr<mob_data> md, int m, int x, int y, BeingRemoveWhy type)
if (md->bl_prev == NULL)
return 0;
- if (m < 0)
+ if (m == nullptr)
m = md->bl_m;
if (type != BeingRemoveWhy::NEGATIVE1)
{
- if (map[md->bl_m].flag.monster_noteleport)
+ if (md->bl_m->flag.monster_noteleport)
return 0;
clif_clearchar(md, type);
}
@@ -2797,7 +2761,7 @@ int mob_warp(dumb_ptr<mob_data> md, int m, int x, int y, BeingRemoveWhy type)
while ((x < 0
|| y < 0
- || bool(read_gat(m, x, y) & MapCell::UNWALKABLE))
+ || bool(read_gatp(m, x, y) & MapCell::UNWALKABLE))
&& (i++) < 1000)
{
if (xs > 0 && ys > 0 && i < 250)
@@ -2809,8 +2773,8 @@ int mob_warp(dumb_ptr<mob_data> md, int m, int x, int y, BeingRemoveWhy type)
else
{
// 完全ランダム探索
- x = random_::in(1, map[m].xs - 2);
- y = random_::in(1, map[m].ys - 2);
+ x = random_::in(1, m->xs - 2);
+ y = random_::in(1, m->ys - 2);
}
}
md->dir = DIR::S;
@@ -2878,8 +2842,10 @@ int mob_countslave(dumb_ptr<mob_data> md)
nullpo_ret(md);
map_foreachinarea(std::bind(mob_countslave_sub, ph::_1, md->bl_id, &c),
- md->bl_m, 0, 0,
- map[md->bl_m].xs - 1, map[md->bl_m].ys - 1, BL::MOB);
+ md->bl_m,
+ 0, 0,
+ md->bl_m->xs - 1, md->bl_m->ys - 1,
+ BL::MOB);
return c;
}
@@ -2890,14 +2856,14 @@ int mob_countslave(dumb_ptr<mob_data> md)
int mob_summonslave(dumb_ptr<mob_data> md2, int *value, int amount, int flag)
{
dumb_ptr<mob_data> md;
- int bx, by, m, count = 0, mob_class, k, a = amount;
+ int bx, by, count = 0, mob_class, k, a = amount;
nullpo_ret(md2);
nullpo_ret(value);
bx = md2->bl_x;
by = md2->bl_y;
- m = md2->bl_m;
+ map_local *m = md2->bl_m;
if (value[0] <= 1000 || value[0] > 2000) // 値が異常なら召喚を止める
return 0;
@@ -2917,10 +2883,7 @@ int mob_summonslave(dumb_ptr<mob_data> md2, int *value, int amount, int flag)
int x = 0, y = 0, i = 0;
md.new_();
if (bool(mob_db[mob_class].mode & MobMode::LOOTER))
- md->lootitem = (struct item *)
- calloc(LOOTITEM_SIZE, sizeof(struct item));
- else
- md->lootitem = NULL;
+ md->lootitemv.clear();
while ((x <= 0
|| y <= 0
@@ -2943,14 +2906,14 @@ int mob_summonslave(dumb_ptr<mob_data> md2, int *value, int amount, int flag)
md->bl_x = x;
md->bl_y = y;
- md->m = m;
- md->x0 = x;
- md->y0 = y;
- md->xs = 0;
- md->ys = 0;
+ md->spawn.m = m;
+ md->spawn.x0 = x;
+ md->spawn.y0 = y;
+ md->spawn.xs = 0;
+ md->spawn.ys = 0;
md->stats[mob_stat::SPEED] = md2->stats[mob_stat::SPEED];
- md->spawndelay1 = static_cast<interval_t>(-1); // 一度のみフラグ
- md->spawndelay2 = static_cast<interval_t>(-1); // 一度のみフラグ
+ md->spawn.delay1 = static_cast<interval_t>(-1); // 一度のみフラグ
+ md->spawn.delay2 = static_cast<interval_t>(-1); // 一度のみフラグ
memset(md->npc_event, 0, sizeof(md->npc_event));
md->bl_type = BL::MOB;
@@ -3005,7 +2968,8 @@ int mob_counttargeted(dumb_ptr<mob_data> md, dumb_ptr<block_list> src,
nullpo_ret(md);
map_foreachinarea(std::bind(mob_counttargeted_sub, ph::_1, md->bl_id, &c, src, target_lv),
- md->bl_m, md->bl_x - AREA_SIZE, md->bl_y - AREA_SIZE,
+ md->bl_m,
+ md->bl_x - AREA_SIZE, md->bl_y - AREA_SIZE,
md->bl_x + AREA_SIZE, md->bl_y + AREA_SIZE,
BL::NUL);
return c;
@@ -3313,7 +3277,7 @@ int mobskill_use(dumb_ptr<mob_data> md, tick_t tick,
flag = (md->hp < max_hp * ms[ii].cond2i / 100);
break;
case MobSkillCondition::MSC_NOTINTOWN: // Only outside of towns.
- flag = !map[md->bl_m].flag.town;
+ flag = !md->bl_m->flag.town;
break;
case MobSkillCondition::MSC_SLAVELT: // slave < num
flag = (mob_countslave(md) < ms[ii].cond2i);
diff --git a/src/map/mob.hpp b/src/map/mob.hpp
index 7421fca..1c7cfab 100644
--- a/src/map/mob.hpp
+++ b/src/map/mob.hpp
@@ -92,7 +92,7 @@ int mob_deleteslave(dumb_ptr<mob_data> md);
int mob_counttargeted(dumb_ptr<mob_data> md, dumb_ptr<block_list> src,
ATK target_lv);
-int mob_warp(dumb_ptr<mob_data> md, int m, int x, int y, BeingRemoveWhy type);
+int mob_warp(dumb_ptr<mob_data> md, map_local *m, int x, int y, BeingRemoveWhy type);
int mobskill_use(dumb_ptr<mob_data> md, tick_t tick, MobSkillCondition event);
int mobskill_event(dumb_ptr<mob_data> md, BF flag);
diff --git a/src/map/npc.cpp b/src/map/npc.cpp
index 43766e9..b46f3f5 100644
--- a/src/map/npc.cpp
+++ b/src/map/npc.cpp
@@ -5,6 +5,8 @@
#include <cstring>
#include <ctime>
+#include <list>
+
#include "../common/cxxstdio.hpp"
#include "../common/db.hpp"
#include "../common/nullpo.hpp"
@@ -22,15 +24,9 @@
#include "../poison.hpp"
-struct npc_src_list
-{
- struct npc_src_list *next;
- struct npc_src_list *prev;
- char name[4];
-};
-
static
-struct npc_src_list *npc_src_first, *npc_src_last;
+std::list<std::string> npc_srcs;
+
static
int npc_id = START_NPC_NUM;
static
@@ -64,27 +60,25 @@ static
void npc_enable_sub(dumb_ptr<block_list> bl, dumb_ptr<npc_data> nd)
{
dumb_ptr<map_session_data> sd;
- char *name = (char *) calloc(50, sizeof(char));
+ char aname[50] {};
nullpo_retv(bl);
- if (bl->bl_type == BL::PC)
+ assert (bl->bl_type == BL::PC);
{
sd = bl->as_player();
- if (nd->flag & 1) // 無効化されている
+ // not if disabled
+ if (nd->flag & 1)
return;
- memcpy(name, nd->name, sizeof(nd->name));
+ memcpy(aname, nd->name, sizeof(nd->name));
if (sd->areanpc_id == nd->bl_id)
- {
- free(name);
return;
- }
sd->areanpc_id = nd->bl_id;
- npc_event(sd, strcat(name, "::OnTouch"), 0);
+ strcat(aname, "::OnTouch");
+ npc_event(sd, aname, 0);
}
- free(name);
}
int npc_enable(const char *name, bool flag)
@@ -113,8 +107,10 @@ int npc_enable(const char *name, bool flag)
if (flag && (xs > 0 || ys > 0))
map_foreachinarea(std::bind(npc_enable_sub, ph::_1, nd),
- nd->bl_m, nd->bl_x - xs, nd->bl_y - ys,
- nd->bl_x + xs, nd->bl_y + ys, BL::PC);
+ nd->bl_m,
+ nd->bl_x - xs, nd->bl_y - ys,
+ nd->bl_x + xs, nd->bl_y + ys,
+ BL::PC);
return 0;
}
@@ -180,7 +176,7 @@ int npc_timer_event(const char *eventname) // Added by RoVeRT
return 0;
}
- run_script(nd->scr.script, ev->pos, nd->bl_id, nd->bl_id);
+ run_script(ScriptPointer(nd->scr.script.get(), ev->pos), nd->bl_id, nd->bl_id);
return 0;
}
@@ -199,7 +195,7 @@ void npc_event_doall_sub(const std::string& key, struct event_data *ev,
if ((p = strchr(p, ':')) && p && strcasecmp(name, p) == 0)
{
- run_script_l(ev->nd->scr.script, ev->pos, rid, ev->nd->bl_id, argc,
+ run_script_l(ScriptPointer(ev->nd->scr.script.get(), ev->pos), rid, ev->nd->bl_id, argc,
argv);
(*c)++;
}
@@ -227,7 +223,7 @@ void npc_event_do_sub(const std::string& key, struct event_data *ev,
if (p && strcasecmp(name, p) == 0)
{
- run_script_l(ev->nd->scr.script, ev->pos, rid, ev->nd->bl_id, argc,
+ run_script_l(ScriptPointer(ev->nd->scr.script.get(), ev->pos), rid, ev->nd->bl_id, argc,
argv);
(*c)++;
}
@@ -304,75 +300,81 @@ static
void npc_timerevent(TimerData *, tick_t tick, int id, interval_t data)
{
dumb_ptr<npc_data_script> nd = map_id2bl(id)->as_npc()->as_script();
- struct npc_timerevent_list *te;
assert (nd != NULL);
assert (nd->npc_subtype == NpcSubtype::SCRIPT);
- assert (nd->scr.nexttimer >= 0);
+ assert (nd->scr.nexttimer != nd->scr.timer_eventv.end());
nd->scr.timertick = tick;
- te = nd->scr.timer_event + nd->scr.nexttimer;
+ auto te = nd->scr.nexttimer;
// nd->scr.timerid = nullptr;
+ // er, isn't this the same as nd->scr.timer = te->timer?
interval_t t = nd->scr.timer += data;
- nd->scr.nexttimer++;
- if (nd->scr.timeramount > nd->scr.nexttimer)
+ assert (t == te->timer);
+ ++nd->scr.nexttimer;
+ if (nd->scr.nexttimer != nd->scr.timer_eventv.end())
{
- interval_t next = nd->scr.timer_event[nd->scr.nexttimer].timer - t;
+ interval_t next = nd->scr.nexttimer->timer - t;
nd->scr.timerid = Timer(tick + next,
std::bind(npc_timerevent, ph::_1, ph::_2,
id, next));
}
- run_script(nd->scr.script, te->pos, 0, nd->bl_id);
+ run_script(ScriptPointer(nd->scr.script.get(), te->pos), 0, nd->bl_id);
}
/*==========================================
* タイマーイベント開始
*------------------------------------------
*/
-int npc_timerevent_start(dumb_ptr<npc_data_script> nd)
+void npc_timerevent_start(dumb_ptr<npc_data_script> nd)
{
- int j, n;
+ nullpo_retv(nd);
- nullpo_ret(nd);
+ if (nd->scr.timer_eventv.empty())
+ return;
+ if (nd->scr.nexttimer != nd->scr.timer_eventv.end())
+ return;
+ if (nd->scr.timer == nd->scr.timer_eventv.back().timer)
+ return;
- n = nd->scr.timeramount;
- if (nd->scr.nexttimer >= 0 || n == 0)
- return 0;
+ npc_timerevent_list phony {};
+ phony.timer = nd->scr.timer;
- for (j = 0; j < n; j++)
- {
- if (nd->scr.timer_event[j].timer > nd->scr.timer)
- break;
- }
- nd->scr.nexttimer = j;
+ // find the first element such that el.timer > phony.timer;
+ auto jt = std::upper_bound(nd->scr.timer_eventv.begin(), nd->scr.timer_eventv.end(), phony,
+ [](const npc_timerevent_list& l, const npc_timerevent_list& r)
+ {
+ return l.timer < r.timer;
+ }
+ );
+ nd->scr.nexttimer = jt;
nd->scr.timertick = gettick();
- if (j >= n)
- return 0;
+ if (jt == nd->scr.timer_eventv.end())
+ // shouldn't happen?
+ return;
- interval_t next = nd->scr.timer_event[j].timer - nd->scr.timer;
+ interval_t next = jt->timer - nd->scr.timer;
nd->scr.timerid = Timer(gettick() + next,
std::bind(npc_timerevent, ph::_1, ph::_2,
nd->bl_id, next));
- return 0;
}
/*==========================================
* タイマーイベント終了
*------------------------------------------
*/
-int npc_timerevent_stop(dumb_ptr<npc_data_script> nd)
+void npc_timerevent_stop(dumb_ptr<npc_data_script> nd)
{
- nullpo_ret(nd);
+ nullpo_retv(nd);
- if (nd->scr.nexttimer >= 0)
+ if (nd->scr.nexttimer != nd->scr.timer_eventv.end())
{
- nd->scr.nexttimer = -1;
+ nd->scr.nexttimer = nd->scr.timer_eventv.end();
nd->scr.timer += gettick() - nd->scr.timertick;
nd->scr.timerid.cancel();
}
- return 0;
}
/*==========================================
@@ -385,7 +387,11 @@ interval_t npc_gettimerevent_tick(dumb_ptr<npc_data_script> nd)
interval_t tick = nd->scr.timer;
- if (nd->scr.nexttimer >= 0)
+ // Couldn't we just check the truthiness of the timer?
+ // Or would that be affected by the (new!) detach logic?
+ // Of course, you'd be slightly crazy to check the tick when you are
+ // called with it.
+ if (nd->scr.nexttimer != nd->scr.timer_eventv.end())
tick += gettick() - nd->scr.timertick;
return tick;
}
@@ -394,19 +400,16 @@ interval_t npc_gettimerevent_tick(dumb_ptr<npc_data_script> nd)
* タイマー値の設定
*------------------------------------------
*/
-int npc_settimerevent_tick(dumb_ptr<npc_data_script> nd, interval_t newtimer)
+void npc_settimerevent_tick(dumb_ptr<npc_data_script> nd, interval_t newtimer)
{
- int flag;
-
- nullpo_ret(nd);
+ nullpo_retv(nd);
- flag = nd->scr.nexttimer;
+ bool flag = nd->scr.nexttimer != nd->scr.timer_eventv.end();
npc_timerevent_stop(nd);
nd->scr.timer = newtimer;
- if (flag >= 0)
+ if (flag)
npc_timerevent_start(nd);
- return 0;
}
/*==========================================
@@ -496,7 +499,7 @@ int npc_event(dumb_ptr<map_session_data> sd, const char *eventname,
sd->npc_id = nd->bl_id;
sd->npc_pos =
- run_script(nd->scr.script, ev->pos, sd->bl_id, nd->bl_id);
+ run_script(ScriptPointer(nd->scr.script.get(), ev->pos), sd->bl_id, nd->bl_id);
return 0;
}
@@ -512,7 +515,7 @@ void npc_command_sub(const std::string& key, struct event_data *ev, const char *
sscanf(&p[11], "%s", temp);
if (strcmp(command, temp) == 0)
- run_script(ev->nd->scr.script, ev->pos, 0, ev->nd->bl_id);
+ run_script(ScriptPointer(ev->nd->scr.script.get(), ev->pos), 0, ev->nd->bl_id);
}
}
@@ -528,7 +531,7 @@ int npc_command(dumb_ptr<map_session_data>, const char *npcname, const char *com
* 接触型のNPC処理
*------------------------------------------
*/
-int npc_touch_areanpc(dumb_ptr<map_session_data> sd, int m, int x, int y)
+int npc_touch_areanpc(dumb_ptr<map_session_data> sd, map_local *m, int x, int y)
{
int i, f = 1;
int xs, ys;
@@ -538,19 +541,19 @@ int npc_touch_areanpc(dumb_ptr<map_session_data> sd, int m, int x, int y)
if (sd->npc_id)
return 1;
- for (i = 0; i < map[m].npc_num; i++)
+ for (i = 0; i < m->npc_num; i++)
{
- if (map[m].npc[i]->flag & 1)
+ if (m->npc[i]->flag & 1)
{ // 無効化されている
f = 0;
continue;
}
- switch (map[m].npc[i]->npc_subtype)
+ switch (m->npc[i]->npc_subtype)
{
case NpcSubtype::WARP:
- xs = map[m].npc[i]->as_warp()->warp.xs;
- ys = map[m].npc[i]->as_warp()->warp.ys;
+ xs = m->npc[i]->as_warp()->warp.xs;
+ ys = m->npc[i]->as_warp()->warp.ys;
break;
case NpcSubtype::MESSAGE:
assert (0 && "I'm pretty sure these are never put on a map");
@@ -558,19 +561,19 @@ int npc_touch_areanpc(dumb_ptr<map_session_data> sd, int m, int x, int y)
ys = 0;
break;
case NpcSubtype::SCRIPT:
- xs = map[m].npc[i]->as_script()->scr.xs;
- ys = map[m].npc[i]->as_script()->scr.ys;
+ xs = m->npc[i]->as_script()->scr.xs;
+ ys = m->npc[i]->as_script()->scr.ys;
break;
default:
continue;
}
- if (x >= map[m].npc[i]->bl_x - xs / 2
- && x < map[m].npc[i]->bl_x - xs / 2 + xs
- && y >= map[m].npc[i]->bl_y - ys / 2
- && y < map[m].npc[i]->bl_y - ys / 2 + ys)
+ if (x >= m->npc[i]->bl_x - xs / 2
+ && x < m->npc[i]->bl_x - xs / 2 + xs
+ && y >= m->npc[i]->bl_y - ys / 2
+ && y < m->npc[i]->bl_y - ys / 2 + ys)
break;
}
- if (i == map[m].npc_num)
+ if (i == m->npc_num)
{
if (f)
{
@@ -579,27 +582,28 @@ int npc_touch_areanpc(dumb_ptr<map_session_data> sd, int m, int x, int y)
}
return 1;
}
- switch (map[m].npc[i]->npc_subtype)
+ switch (m->npc[i]->npc_subtype)
{
case NpcSubtype::WARP:
skill_stop_dancing(sd, 0);
- pc_setpos(sd, map[m].npc[i]->as_warp()->warp.name,
- map[m].npc[i]->as_warp()->warp.x, map[m].npc[i]->as_warp()->warp.y, BeingRemoveWhy::GONE);
+ pc_setpos(sd, m->npc[i]->as_warp()->warp.name,
+ m->npc[i]->as_warp()->warp.x, m->npc[i]->as_warp()->warp.y, BeingRemoveWhy::GONE);
break;
case NpcSubtype::MESSAGE:
assert (0 && "I'm pretty sure these NPCs are never put on a map.");
break;
case NpcSubtype::SCRIPT:
{
- char *name = (char *)malloc(50);
-
- memcpy(name, map[m].npc[i]->name, 50);
- if (sd->areanpc_id == map[m].npc[i]->bl_id)
- return 1; // TODO fix leak of 'name'
- sd->areanpc_id = map[m].npc[i]->bl_id;
- if (npc_event(sd, strcat(name, "::OnTouch"), 0) > 0)
- npc_click(sd, map[m].npc[i]->bl_id);
- free(name);
+ char aname[50] {};
+ memcpy(aname, m->npc[i]->name, sizeof(m->npc[i]->name));
+
+ if (sd->areanpc_id == m->npc[i]->bl_id)
+ return 1;
+
+ sd->areanpc_id = m->npc[i]->bl_id;
+ strcat(aname, "::OnTouch");
+ if (npc_event(sd, aname, 0) > 0)
+ npc_click(sd, m->npc[i]->bl_id);
break;
}
}
@@ -670,12 +674,12 @@ int npc_click(dumb_ptr<map_session_data> sd, int id)
npc_event_dequeue(sd);
break;
case NpcSubtype::SCRIPT:
- sd->npc_pos = run_script(nd->as_script()->scr.script, 0, sd->bl_id, id);
+ sd->npc_pos = run_script(ScriptPointer(nd->as_script()->scr.script.get(), 0), sd->bl_id, id);
break;
case NpcSubtype::MESSAGE:
- if (nd->as_message()->message)
+ if (!nd->as_message()->message.empty())
{
- clif_scriptmes(sd, id, nd->as_message()->message);
+ clif_scriptmes(sd, id, nd->as_message()->message.c_str());
clif_scriptclose(sd, id);
}
break;
@@ -711,7 +715,7 @@ int npc_scriptcont(dumb_ptr<map_session_data> sd, int id)
return 0;
}
- sd->npc_pos = run_script(nd->as_script()->scr.script, sd->npc_pos, sd->bl_id, id);
+ sd->npc_pos = run_script(ScriptPointer(nd->as_script()->scr.script.get(), sd->npc_pos), sd->bl_id, id);
return 0;
}
@@ -784,7 +788,7 @@ int npc_buylist(dumb_ptr<map_session_data> sd, int n,
if (j == nd->as_shop()->shop_items.size())
return 3;
- z += (double) nd->as_shop()->shop_items[j].value * item_list[i * 2];
+ z += static_cast<double>(nd->as_shop()->shop_items[j].value) * item_list[i * 2];
itemamount += item_list[i * 2];
switch (pc_checkadditem(sd, item_list[i * 2 + 1], item_list[i * 2]))
@@ -804,7 +808,7 @@ int npc_buylist(dumb_ptr<map_session_data> sd, int n,
w += itemdb_weight(item_list[i * 2 + 1]) * item_list[i * 2];
}
- if (z > (double) sd->status.zeny)
+ if (z > static_cast<double>(sd->status.zeny))
return 1; // zeny不足
if (w + sd->weight > sd->max_weight)
return 2; // 重量超過
@@ -813,7 +817,7 @@ int npc_buylist(dumb_ptr<map_session_data> sd, int n,
if (sd->trade_partner != 0)
return 4; // cant buy while trading
- pc_payzeny(sd, (int) z);
+ pc_payzeny(sd, static_cast<int>(z));
for (i = 0; i < n; i++)
{
@@ -874,13 +878,13 @@ int npc_selllist(dumb_ptr<map_session_data> sd, int n,
return 1;
if (sd->trade_partner != 0)
return 2; // cant sell while trading
- z += (double) itemdb_value_sell(nameid) * item_list[i * 2 + 1];
+ z += static_cast<double>(itemdb_value_sell(nameid)) * item_list[i * 2 + 1];
itemamount += item_list[i * 2 + 1];
}
if (z > MAX_ZENY)
z = MAX_ZENY;
- pc_getzeny(sd, (int) z);
+ pc_getzeny(sd, static_cast<int>(z));
for (i = 0; i < n; i++)
{
int item_id = item_list[i * 2] - 2;
@@ -902,16 +906,7 @@ int npc_selllist(dumb_ptr<map_session_data> sd, int n,
static
void npc_clearsrcfile(void)
{
- struct npc_src_list *p = npc_src_first;
-
- while (p)
- {
- struct npc_src_list *p2 = p;
- p = p->next;
- free(p2);
- }
- npc_src_first = NULL;
- npc_src_last = NULL;
+ npc_srcs.clear();
}
/*==========================================
@@ -920,25 +915,13 @@ void npc_clearsrcfile(void)
*/
void npc_addsrcfile(const char *name)
{
- struct npc_src_list *new_src;
- size_t len;
-
if (strcasecmp(name, "clear") == 0)
{
npc_clearsrcfile();
return;
}
- len = sizeof(*new_src) + strlen(name);
- new_src = (struct npc_src_list *) calloc(1, len);
- new_src->next = NULL;
- strncpy(new_src->name, name, strlen(name) + 1);
- if (npc_src_first == NULL)
- npc_src_first = new_src;
- if (npc_src_last)
- npc_src_last->next = new_src;
-
- npc_src_last = new_src;
+ npc_srcs.push_back(name);
}
/*==========================================
@@ -947,23 +930,18 @@ void npc_addsrcfile(const char *name)
*/
void npc_delsrcfile(const char *name)
{
- struct npc_src_list *p = npc_src_first, *pp = NULL, **lp = &npc_src_first;
-
if (strcasecmp(name, "all") == 0)
{
npc_clearsrcfile();
return;
}
- for (; p; lp = &p->next, pp = p, p = p->next)
+ for (auto it = npc_srcs.begin(); it != npc_srcs.end(); ++it)
{
- if (strcmp(p->name, name) == 0)
+ if (*it == name)
{
- *lp = p->next;
- if (npc_src_last == p)
- npc_src_last = pp;
- free(p);
- break;
+ npc_srcs.erase(it);
+ return;
}
}
}
@@ -974,7 +952,7 @@ void npc_delsrcfile(const char *name)
*/
int npc_parse_warp(const char *w1, const char *, const char *w3, const char *w4)
{
- int x, y, xs, ys, to_x, to_y, m;
+ int x, y, xs, ys, to_x, to_y;
int i, j;
char mapname[24], to_mapname[24];
dumb_ptr<npc_data_warp> nd;
@@ -988,7 +966,7 @@ int npc_parse_warp(const char *w1, const char *, const char *w3, const char *w4)
return 1;
}
- m = map_mapname2mapid(mapname);
+ map_local *m = map_mapname2mapid(mapname);
nd.new_();
nd->bl_id = npc_get_new_npc_id();
@@ -1056,7 +1034,6 @@ int npc_parse_shop(char *w1, char *, char *w3, char *w4)
char *p;
int x, y;
DIR dir;
- int m;
char mapname[24];
dumb_ptr<npc_data_shop> nd;
@@ -1070,7 +1047,7 @@ int npc_parse_shop(char *w1, char *, char *w3, char *w4)
return 1;
}
dir = static_cast<DIR>(dir_);
- m = map_mapname2mapid(mapname);
+ map_local *m = map_mapname2mapid(mapname);
nd.new_();
p = strchr(w4, ',');
@@ -1151,27 +1128,12 @@ int npc_parse_shop(char *w1, char *, char *w3, char *w4)
static
void npc_convertlabel_db(const std::string& lname, int pos, dumb_ptr<npc_data_script> nd)
{
- struct npc_label_list *lst;
- int num;
-
nullpo_retv(nd);
- lst = nd->scr.label_list;
- num = nd->scr.label_list_num;
- if (!lst)
- {
- lst = (struct npc_label_list *)
- calloc(1, sizeof(struct npc_label_list));
- num = 0;
- }
- else
- lst = (struct npc_label_list *)
- realloc(lst, sizeof(struct npc_label_list) * (num + 1));
-
- strzcpy(lst[num].name, lname.c_str(), sizeof(lst[num].name));
- lst[num].pos = pos;
- nd->scr.label_list = lst;
- nd->scr.label_list_num = num + 1;
+ struct npc_label_list eln {};
+ strzcpy(eln.name, lname.c_str(), sizeof(eln.name));
+ eln.pos = pos;
+ nd->scr.label_listv.push_back(std::move(eln));
}
/*==========================================
@@ -1184,25 +1146,19 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4,
{
int x, y;
DIR dir = DIR::S;
- int m, xs = 0, ys = 0, npc_class = 0; // [Valaris] thanks to fov
+ map_local *m;
+ int xs = 0, ys = 0, npc_class = 0; // [Valaris] thanks to fov
char mapname[24];
- char *srcbuf = NULL;
- const ScriptCode *script = NULL;
- int srcsize = 65536;
- int startline = 0;
- char line[1024];
+ std::unique_ptr<const ScriptBuffer> script = NULL;
dumb_ptr<npc_data_script> nd;
int evflag = 0;
char *p;
- struct npc_label_list *label_dup = NULL;
- int label_dupnum = 0;
- int src_id = 0;
if (strcmp(w1, "-") == 0)
{
x = 0;
y = 0;
- m = -1;
+ m = nullptr;
}
else
{
@@ -1221,61 +1177,48 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4,
if (strcmp(w2, "script") == 0)
{
- // スクリプトの解析
- srcbuf = (char *) calloc(srcsize, sizeof(char));
- if (strchr(first_line, '{'))
- {
- strcpy(srcbuf, strchr(first_line, '{'));
- startline = *lines;
- }
- else
- srcbuf[0] = 0;
+ // may be empty
+ std::string srcbuf = strchrnul(first_line, '{');
+ // Note: it was a bug that this was missing. I think.
+ int startline = *lines;
+
while (1)
{
- int i;
- for (i = strlen(srcbuf) - 1; i >= 0 && isspace(srcbuf[i]); i--);
- if (i >= 0 && srcbuf[i] == '}')
+ size_t i = srcbuf.find_last_not_of(" \t\n\r\f\v");
+ if (i != std::string::npos && srcbuf[i] == '}')
break;
+ char line[1024];
if (!fgets(line, 1020, fp))
+ // eof
break;
(*lines)++;
if (feof(fp))
break;
- if (strlen(srcbuf) + strlen(line) + 1 >= srcsize)
- {
- srcsize += 65536;
- srcbuf = (char *) realloc(srcbuf, srcsize);
- memset(srcbuf + srcsize - 65536, '\0', 65536);
- }
- if (srcbuf[0] != '{')
+ if (srcbuf.empty())
{
- if (strchr(line, '{'))
- {
- strcpy(srcbuf, strchr(line, '{'));
- startline = *lines;
- }
+ // may be a no-op
+ srcbuf = strchrnul(line, '{');
+ // safe to execute more than once
+ // But will usually only happen once
+ startline = *lines;
}
else
- strcat(srcbuf, line);
+ srcbuf += line;
}
- script = parse_script(srcbuf, startline);
+ script = parse_script(srcbuf.c_str(), startline);
if (script == NULL)
- {
// script parse error?
- free(srcbuf);
return 1;
- }
-
}
else
{
- PRINTF("duplicate() is no longer supported!\n");
+ assert(0 && "duplicate() is no longer supported!\n");
return 0;
- } // end of スクリプト解析
+ }
nd.new_();
- if (m == -1)
+ if (m == nullptr)
{
// スクリプトコピー用のダミーNPC
}
@@ -1318,7 +1261,7 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4,
nd->scr.ys = 0;
}
- if (npc_class < 0 && m >= 0)
+ if (npc_class < 0 && m != nullptr)
{ // イベント型NPC
evflag = 1;
}
@@ -1349,8 +1292,7 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4,
nd->flag = 0;
nd->npc_class = npc_class;
nd->speed = std::chrono::milliseconds(200);
- nd->scr.script = script;
- nd->scr.src_id = src_id;
+ nd->scr.script = std::move(script);
nd->option = Option::ZERO;
nd->opt1 = Opt1::ZERO;
nd->opt2 = Opt2::ZERO;
@@ -1360,7 +1302,7 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4,
npc_script++;
nd->bl_type = BL::NPC;
nd->npc_subtype = NpcSubtype::SCRIPT;
- if (m >= 0)
+ if (m != nullptr)
{
nd->n = map_addnpc(m, nd);
map_addblock(nd);
@@ -1377,37 +1319,13 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4,
}
npcname_db.put(nd->exname, nd);
- //-----------------------------------------
- // ラベルデータの準備
- if (srcbuf)
- {
- // script本体がある場合の処理
-
- // ラベルデータのコンバート
- for (auto& pair : scriptlabel_db)
- npc_convertlabel_db(pair.first, pair.second, nd);
+ for (auto& pair : scriptlabel_db)
+ npc_convertlabel_db(pair.first, pair.second, nd);
- // もう使わないのでバッファ解放
- free(srcbuf);
-
- }
- else
+ for (npc_label_list& el : nd->scr.label_listv)
{
- // duplicate
-
-// nd->scr.label_list=malloc(sizeof(struct npc_label_list)*label_dupnum);
-// memcpy(nd->scr.label_list,label_dup,sizeof(struct npc_label_list)*label_dupnum);
-
- nd->scr.label_list = label_dup; // ラベルデータ共有
- nd->scr.label_list_num = label_dupnum;
- }
-
- //-----------------------------------------
- // イベント用ラベルデータのエクスポート
- for (int i = 0; i < nd->scr.label_list_num; i++)
- {
- char *lname = nd->scr.label_list[i].name;
- int pos = nd->scr.label_list[i].pos;
+ char *lname = el.name;
+ int pos = el.pos;
if ((lname[0] == 'O' || lname[0] == 'o')
&& (lname[1] == 'N' || lname[1] == 'n'))
@@ -1427,42 +1345,31 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4,
//-----------------------------------------
// ラベルデータからタイマーイベント取り込み
- for (int i = 0; i < nd->scr.label_list_num; i++)
+ for (npc_label_list& el : nd->scr.label_listv)
{
int t_ = 0, n = 0;
- char *lname = nd->scr.label_list[i].name;
- int pos = nd->scr.label_list[i].pos;
+ char *lname = el.name;
+ int pos = el.pos;
if (sscanf(lname, "OnTimer%d%n", &t_, &n) == 1 && lname[n] == '\0')
{
interval_t t = static_cast<interval_t>(t_);
- // タイマーイベント
- struct npc_timerevent_list *te = nd->scr.timer_event;
- int j, k = nd->scr.timeramount;
- if (te == NULL)
- te = (struct npc_timerevent_list *) calloc(1,
- sizeof(struct
- npc_timerevent_list));
- else
- te = (struct npc_timerevent_list *) realloc(te,
- sizeof(struct
- npc_timerevent_list)
- * (k + 1));
- for (j = 0; j < k; j++)
- {
- if (te[j].timer > t)
- {
- memmove(te + j + 1, te + j,
- sizeof(struct npc_timerevent_list) * (k - j));
- break;
- }
- }
- te[j].timer = t;
- te[j].pos = pos;
- nd->scr.timer_event = te;
- nd->scr.timeramount = k + 1;
+
+ npc_timerevent_list tel {};
+ tel.timer = t;
+ tel.pos = pos;
+
+ auto it = std::lower_bound(nd->scr.timer_eventv.begin(), nd->scr.timer_eventv.end(), tel,
+ [](const npc_timerevent_list& l, const npc_timerevent_list& r)
+ {
+ return l.timer < r.timer;
+ }
+ );
+ assert (it == nd->scr.timer_eventv.end() || it->timer != tel.timer);
+
+ nd->scr.timer_eventv.insert(it, std::move(tel));
}
}
- nd->scr.nexttimer = -1;
+ nd->scr.nexttimer = nd->scr.timer_eventv.end();
// nd->scr.timerid = nullptr;
return 0;
@@ -1476,62 +1383,37 @@ static
int npc_parse_function(char *, char *, char *w3, char *,
char *first_line, FILE * fp, int *lines)
{
- char *srcbuf = NULL;
- const ScriptCode *script;
- int srcsize = 65536;
- int startline = 0;
- char line[1024];
- int i;
+ std::string srcbuf = strchrnul(first_line, '{');
+ int startline = *lines;
- // スクリプトの解析
- srcbuf = (char *) calloc(srcsize, sizeof(char));
- if (strchr(first_line, '{'))
- {
- strcpy(srcbuf, strchr(first_line, '{'));
- startline = *lines;
- }
- else
- srcbuf[0] = 0;
while (1)
{
- for (i = strlen(srcbuf) - 1; i >= 0 && isspace(srcbuf[i]); i--);
- if (i >= 0 && srcbuf[i] == '}')
+ size_t i = srcbuf.find_last_not_of(" \t\n\r\f\v");
+ if (i != std::string::npos && srcbuf[i] == '}')
break;
+ char line[1024];
if (!fgets(line, 1020, fp))
break;
(*lines)++;
if (feof(fp))
break;
- if (strlen(srcbuf) + strlen(line) + 1 >= srcsize)
+ if (srcbuf.empty())
{
- srcsize += 65536;
- srcbuf = (char *) realloc(srcbuf, srcsize);
- memset(srcbuf + srcsize - 65536, '\0', 65536);
- }
- if (srcbuf[0] != '{')
- {
- if (strchr(line, '{'))
- {
- strcpy(srcbuf, strchr(line, '{'));
- startline = *lines;
- }
+ srcbuf = strchrnul(line, '{');
+ startline = *lines;
}
else
- strcat(srcbuf, line);
+ srcbuf += line;
}
- script = parse_script(srcbuf, startline);
+ std::unique_ptr<const ScriptBuffer> script = parse_script(srcbuf.c_str(), startline);
if (script == NULL)
{
// script parse error?
- free(srcbuf);
return 1;
}
std::string p = w3;
- userfunc_db.put(p, script);
-
- // もう使わないのでバッファ解放
- free(srcbuf);
+ userfunc_db.put(p, std::move(script));
return 0;
}
@@ -1543,7 +1425,7 @@ int npc_parse_function(char *, char *, char *w3, char *,
static
int npc_parse_mob(const char *w1, const char *, const char *w3, const char *w4)
{
- int m, x, y, xs, ys, mob_class, num;
+ int x, y, xs, ys, mob_class, num;
int i;
char mapname[24];
char eventname[24] = "";
@@ -1562,7 +1444,7 @@ int npc_parse_mob(const char *w1, const char *, const char *w3, const char *w4)
interval_t delay1 = std::chrono::milliseconds(delay1_);
interval_t delay2 = std::chrono::milliseconds(delay2_);
- m = map_mapname2mapid(mapname);
+ map_local *m = map_mapname2mapid(mapname);
if (num > 1 && battle_config.mob_count_rate != 100)
{
@@ -1589,29 +1471,23 @@ int npc_parse_mob(const char *w1, const char *, const char *w3, const char *w4)
md->n = i;
md->mob_class = mob_class;
md->bl_id = npc_get_new_npc_id();
- md->m = m;
- md->x0 = x;
- md->y0 = y;
- md->xs = xs;
- md->ys = ys;
- md->spawndelay1 = delay1;
- md->spawndelay2 = delay2;
+ md->spawn.m = m;
+ md->spawn.x0 = x;
+ md->spawn.y0 = y;
+ md->spawn.xs = xs;
+ md->spawn.ys = ys;
+ md->spawn.delay1 = delay1;
+ md->spawn.delay2 = delay2;
memset(&md->state, 0, sizeof(md->state));
// md->timer = nullptr;
md->target_id = 0;
md->attacked_id = 0;
- if (bool(mob_db[mob_class].mode & MobMode::LOOTER))
- md->lootitem =
- (struct item *) calloc(LOOTITEM_SIZE, sizeof(struct item));
- else
- md->lootitem = NULL;
+ md->lootitemv.clear();
if (strlen(eventname) >= 4)
- {
memcpy(md->npc_event, eventname, 24);
- }
else
memset(md->npc_event, 0, 24);
@@ -1633,7 +1509,6 @@ int npc_parse_mob(const char *w1, const char *, const char *w3, const char *w4)
static
int npc_parse_mapflag(char *w1, char *, char *w3, char *w4)
{
- int m;
char mapname[24], savemap[16];
int savex, savey;
@@ -1642,8 +1517,8 @@ int npc_parse_mapflag(char *w1, char *, char *w3, char *w4)
if (sscanf(w1, "%[^,]", mapname) != 1)
return 1;
- m = map_mapname2mapid(mapname);
- if (m < 0)
+ map_local *m = map_mapname2mapid(mapname);
+ if (m == nullptr)
return 1;
//マップフラグ
@@ -1651,113 +1526,113 @@ int npc_parse_mapflag(char *w1, char *, char *w3, char *w4)
{
if (strcmp(w4, "SavePoint") == 0)
{
- memcpy(map[m].save.map, "SavePoint", 16);
- map[m].save.x = -1;
- map[m].save.y = -1;
+ memcpy(m->save.map, "SavePoint", 16);
+ m->save.x = -1;
+ m->save.y = -1;
}
else if (sscanf(w4, "%[^,],%d,%d", savemap, &savex, &savey) == 3)
{
- memcpy(map[m].save.map, savemap, 16);
- map[m].save.x = savex;
- map[m].save.y = savey;
+ memcpy(m->save.map, savemap, 16);
+ m->save.x = savex;
+ m->save.y = savey;
}
- map[m].flag.nosave = 1;
+ m->flag.nosave = 1;
}
else if (strcasecmp(w3, "nomemo") == 0)
{
- map[m].flag.nomemo = 1;
+ m->flag.nomemo = 1;
}
else if (strcasecmp(w3, "noteleport") == 0)
{
- map[m].flag.noteleport = 1;
+ m->flag.noteleport = 1;
}
else if (strcasecmp(w3, "nowarp") == 0)
{
- map[m].flag.nowarp = 1;
+ m->flag.nowarp = 1;
}
else if (strcasecmp(w3, "nowarpto") == 0)
{
- map[m].flag.nowarpto = 1;
+ m->flag.nowarpto = 1;
}
else if (strcasecmp(w3, "noreturn") == 0)
{
- map[m].flag.noreturn = 1;
+ m->flag.noreturn = 1;
}
else if (strcasecmp(w3, "monster_noteleport") == 0)
{
- map[m].flag.monster_noteleport = 1;
+ m->flag.monster_noteleport = 1;
}
else if (strcasecmp(w3, "nobranch") == 0)
{
- map[m].flag.nobranch = 1;
+ m->flag.nobranch = 1;
}
else if (strcasecmp(w3, "nopenalty") == 0)
{
- map[m].flag.nopenalty = 1;
+ m->flag.nopenalty = 1;
}
else if (strcasecmp(w3, "pvp") == 0)
{
- map[m].flag.pvp = 1;
+ m->flag.pvp = 1;
}
else if (strcasecmp(w3, "pvp_noparty") == 0)
{
- map[m].flag.pvp_noparty = 1;
+ m->flag.pvp_noparty = 1;
}
else if (strcasecmp(w3, "pvp_nocalcrank") == 0)
{
- map[m].flag.pvp_nocalcrank = 1;
+ m->flag.pvp_nocalcrank = 1;
}
else if (strcasecmp(w3, "nozenypenalty") == 0)
{
- map[m].flag.nozenypenalty = 1;
+ m->flag.nozenypenalty = 1;
}
else if (strcasecmp(w3, "notrade") == 0)
{
- map[m].flag.notrade = 1;
+ m->flag.notrade = 1;
}
else if (battle_config.pk_mode && strcasecmp(w3, "nopvp") == 0)
{ // nopvp for pk mode [Valaris]
- map[m].flag.nopvp = 1;
- map[m].flag.pvp = 0;
+ m->flag.nopvp = 1;
+ m->flag.pvp = 0;
}
else if (strcasecmp(w3, "noicewall") == 0)
{ // noicewall [Valaris]
- map[m].flag.noicewall = 1;
+ m->flag.noicewall = 1;
}
else if (strcasecmp(w3, "snow") == 0)
{ // snow [Valaris]
- map[m].flag.snow = 1;
+ m->flag.snow = 1;
}
else if (strcasecmp(w3, "fog") == 0)
{ // fog [Valaris]
- map[m].flag.fog = 1;
+ m->flag.fog = 1;
}
else if (strcasecmp(w3, "sakura") == 0)
{ // sakura [Valaris]
- map[m].flag.sakura = 1;
+ m->flag.sakura = 1;
}
else if (strcasecmp(w3, "leaves") == 0)
{ // leaves [Valaris]
- map[m].flag.leaves = 1;
+ m->flag.leaves = 1;
}
else if (strcasecmp(w3, "rain") == 0)
{ // rain [Valaris]
- map[m].flag.rain = 1;
+ m->flag.rain = 1;
}
else if (strcasecmp(w3, "no_player_drops") == 0)
{ // no player drops [Jaxad0127]
- map[m].flag.no_player_drops = 1;
+ m->flag.no_player_drops = 1;
}
else if (strcasecmp(w3, "town") == 0)
{ // town/safe zone [remoitnane]
- map[m].flag.town = 1;
+ m->flag.town = 1;
}
return 0;
}
-dumb_ptr<npc_data> npc_spawn_text(int m, int x, int y,
- int npc_class, const char *name, const char *message)
+dumb_ptr<npc_data> npc_spawn_text(map_local *m, int x, int y,
+ int npc_class, const char *name, const char *message)
{
dumb_ptr<npc_data_message> retval;
retval.new_();
@@ -1772,7 +1647,8 @@ dumb_ptr<npc_data> npc_spawn_text(int m, int x, int y,
strncpy(retval->exname, name, 23);
retval->name[15] = 0;
retval->exname[15] = 0;
- retval->message = message ? strdup(message) : NULL;
+ if (message)
+ retval->message = message;
retval->npc_class = npc_class;
retval->speed = std::chrono::milliseconds(200);
@@ -1792,26 +1668,17 @@ void npc_free_internal(dumb_ptr<npc_data> nd_)
if (nd_->npc_subtype == NpcSubtype::SCRIPT)
{
dumb_ptr<npc_data_script> nd = nd_->as_script();
- if (nd->scr.timer_event)
- free(nd->scr.timer_event);
- if (nd->scr.src_id == 0)
+ nd->scr.timer_eventv.clear();
+
{
- if (nd->scr.script)
- {
- free(const_cast<ScriptCode *>(nd->scr.script));
- nd->scr.script = NULL;
- }
- if (nd->scr.label_list)
- {
- free(nd->scr.label_list);
- nd->scr.label_list = NULL;
- }
+ nd->scr.script.reset();
+ nd->scr.label_listv.clear();
}
}
else if (nd_->npc_subtype == NpcSubtype::MESSAGE)
{
dumb_ptr<npc_data_message> nd = nd_->as_message();
- free(nd->message);
+ nd->message.clear();
}
nd_.delete_();
}
@@ -1826,8 +1693,10 @@ void npc_propagate_update(dumb_ptr<npc_data> nd)
ys = nd_->scr.ys;
}
map_foreachinarea(std::bind(npc_enable_sub, ph::_1, nd),
- nd->bl_m, nd->bl_x - xs, nd->bl_y - ys,
- nd->bl_x + xs, nd->bl_y + ys, BL::PC);
+ nd->bl_m,
+ nd->bl_x - xs, nd->bl_y - ys,
+ nd->bl_x + xs, nd->bl_y + ys,
+ BL::PC);
}
void npc_free(dumb_ptr<npc_data> nd)
@@ -1845,27 +1714,19 @@ void npc_free(dumb_ptr<npc_data> nd)
*/
int do_init_npc(void)
{
- struct npc_src_list *nsl;
- FILE *fp;
- char line[1024];
- int m, lines;
-
memset(&ev_tm_b, -1, sizeof(ev_tm_b));
- for (nsl = npc_src_first; nsl; nsl = nsl->next)
+ for (; !npc_srcs.empty(); npc_srcs.pop_front())
{
- if (nsl->prev)
- {
- free(nsl->prev);
- nsl->prev = NULL;
- }
- fp = fopen_(nsl->name, "r");
+ std::string& nsl = npc_srcs.front();
+ FILE *fp = fopen_(nsl.c_str(), "r");
if (fp == NULL)
{
- PRINTF("file not found : %s\n", nsl->name);
+ PRINTF("file not found : %s\n", nsl);
exit(1);
}
- lines = 0;
+ int lines = 0;
+ char line[1024];
while (fgets(line, 1020, fp))
{
char w1[1024], w2[1024], w3[1024], w4[1024], mapname[1024];
@@ -1906,8 +1767,8 @@ int do_init_npc(void)
if (strcmp(w1, "-") != 0 && strcasecmp(w1, "function") != 0)
{
sscanf(w1, "%[^,]", mapname);
- m = map_mapname2mapid(mapname);
- if (strlen(mapname) > 16 || m < 0)
+ map_local *m = map_mapname2mapid(mapname);
+ if (strlen(mapname) > 16 || m == nullptr)
{
// "mapname" is not assigned to this server
continue;
@@ -1952,7 +1813,7 @@ int do_init_npc(void)
}
fclose_(fp);
PRINTF("\rLoading NPCs [%d]: %-54s", npc_id - START_NPC_NUM,
- nsl->name);
+ nsl);
fflush(stdout);
}
PRINTF("\rNPCs Loaded: %d [Warps:%d Shops:%d Scripts:%d Mobs:%d]\n",
diff --git a/src/map/npc.hpp b/src/map/npc.hpp
index 5760ca1..539152f 100644
--- a/src/map/npc.hpp
+++ b/src/map/npc.hpp
@@ -18,7 +18,7 @@ int npc_event_dequeue(dumb_ptr<map_session_data> sd);
int npc_event(dumb_ptr<map_session_data> sd, const char *npcname, int);
int npc_timer_event(const char *eventname); // Added by RoVeRT
int npc_command(dumb_ptr<map_session_data> sd, const char *npcname, const char *command);
-int npc_touch_areanpc(dumb_ptr<map_session_data>, int, int, int);
+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);
@@ -36,7 +36,8 @@ int npc_get_new_npc_id(void);
*
* \param message The message to speak. If message is NULL, the NPC will not do anything at all.
*/
-dumb_ptr<npc_data> npc_spawn_text(int m, int x, int y, int class_, const char *name, const char *message); // message is strdup'd within
+dumb_ptr<npc_data> npc_spawn_text(map_local *m, int x, int y,
+ int class_, const char *name, const char *message); // message is strdup'd within
/**
* Uninstalls and frees an NPC
@@ -64,10 +65,10 @@ int npc_event_do(const char *name)
return npc_event_do_l(name, 0, 0, NULL);
}
-int npc_timerevent_start(dumb_ptr<npc_data_script> nd);
-int npc_timerevent_stop(dumb_ptr<npc_data_script> nd);
+void npc_timerevent_start(dumb_ptr<npc_data_script> nd);
+void npc_timerevent_stop(dumb_ptr<npc_data_script> nd);
interval_t npc_gettimerevent_tick(dumb_ptr<npc_data_script> nd);
-int npc_settimerevent_tick(dumb_ptr<npc_data_script> nd, interval_t newtimer);
+void npc_settimerevent_tick(dumb_ptr<npc_data_script> nd, interval_t newtimer);
int npc_delete(dumb_ptr<npc_data> nd);
#endif // NPC_HPP
diff --git a/src/map/party.cpp b/src/map/party.cpp
index 1f2c78a..451dcfa 100644
--- a/src/map/party.cpp
+++ b/src/map/party.cpp
@@ -704,7 +704,7 @@ void party_send_hp_check(dumb_ptr<block_list> bl, int party_id, int *flag)
}
// 経験値公平分配
-int party_exp_share(struct party *p, int mapid, int base_exp, int job_exp)
+int party_exp_share(struct party *p, map_local *mapid, int base_exp, int job_exp)
{
dumb_ptr<map_session_data> sd;
int i, c;
diff --git a/src/map/party.hpp b/src/map/party.hpp
index e2cabb3..4037a04 100644
--- a/src/map/party.hpp
+++ b/src/map/party.hpp
@@ -42,7 +42,7 @@ int party_recv_message(int party_id, int account_id, const char *mes, int len);
int party_send_xy_clear(struct party *p);
void party_send_hp_check(dumb_ptr<block_list> bl, int party_id, int *flag);
-int party_exp_share(struct party *p, int map, int base_exp, int job_exp);
+int party_exp_share(struct party *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);
diff --git a/src/map/path.cpp b/src/map/path.cpp
index 7a8eb37..b938e3b 100644
--- a/src/map/path.cpp
+++ b/src/map/path.cpp
@@ -1,9 +1,12 @@
+#include "path.hpp"
+
+#include <cassert>
+
#include "../common/cxxstdio.hpp"
#include "../common/random.hpp"
#include "../common/nullpo.hpp"
#include "battle.hpp"
-#include "map.hpp"
#include "../poison.hpp"
@@ -182,7 +185,7 @@ int add_path(int *heap, struct tmp_path *tp, int x, int y, int dist,
*------------------------------------------
*/
static
-bool can_place(struct map_data *m, int x, int y)
+bool can_place(struct map_local *m, int x, int y)
{
nullpo_ret(m);
@@ -194,7 +197,7 @@ bool can_place(struct map_data *m, int x, int y)
*------------------------------------------
*/
static
-int can_move(struct map_data *m, int x0, int y0, int x1, int y1)
+int can_move(struct map_local *m, int x0, int y0, int x1, int y1)
{
nullpo_ret(m);
@@ -217,19 +220,17 @@ int can_move(struct map_data *m, int x0, int y0, int x1, int y1)
* path探索 (x0,y0)->(x1,y1)
*------------------------------------------
*/
-int path_search(struct walkpath_data *wpd, int m, int x0, int y0, int x1, int y1, int flag)
+int path_search(struct walkpath_data *wpd, map_local *m, int x0, int y0, int x1, int y1, int flag)
{
int heap[MAX_HEAP + 1];
struct tmp_path tp[MAX_WALKPATH * MAX_WALKPATH];
int i, rp, x, y;
- struct map_data *md;
int dx, dy;
nullpo_ret(wpd);
- if (!map[m].gat)
- return -1;
- md = &map[m];
+ assert (m->gat);
+ map_local *md = m;
if (x1 < 0 || x1 >= md->xs || y1 < 0 || y1 >= md->ys
|| bool(read_gatp(md, x1, y1) & MapCell::UNWALKABLE))
return -1;
diff --git a/src/map/path.hpp b/src/map/path.hpp
new file mode 100644
index 0000000..8dace6f
--- /dev/null
+++ b/src/map/path.hpp
@@ -0,0 +1,8 @@
+#ifndef PATH_HPP
+#define PATH_HPP
+
+#include "map.hpp"
+
+int path_search(struct walkpath_data *, map_local *, int, int, int, int, int);
+
+#endif // PATH_HPP
diff --git a/src/map/pc.cpp b/src/map/pc.cpp
index 23e7f81..f2dcab2 100644
--- a/src/map/pc.cpp
+++ b/src/map/pc.cpp
@@ -21,6 +21,7 @@
#include "mob.hpp"
#include "npc.hpp"
#include "party.hpp"
+#include "path.hpp"
#include "script.hpp"
#include "skill.hpp"
#include "storage.hpp"
@@ -216,9 +217,7 @@ earray<EPOS, EQUIP, EQUIP::COUNT> equip_pos //=
}};
static
-struct GM_Account *gm_accounts = NULL;
-static
-int GM_num = 0;
+std::map<int, uint8_t> gm_accountm;
static
int pc_checkoverhp(dumb_ptr<map_session_data> sd);
@@ -234,17 +233,14 @@ void pc_setdead(dumb_ptr<map_session_data> sd)
sd->state.dead_sit = 1;
}
-int pc_isGM(dumb_ptr<map_session_data> sd)
+uint8_t pc_isGM(dumb_ptr<map_session_data> sd)
{
- int i;
-
nullpo_ret(sd);
- for (i = 0; i < GM_num; i++)
- if (gm_accounts[i].account_id == sd->status.account_id)
- return gm_accounts[i].level;
+ auto it = gm_accountm.find(sd->status.account_id);
+ if (it != gm_accountm.end())
+ return it->second;
return 0;
-
}
int pc_iskiller(dumb_ptr<map_session_data> src,
@@ -265,23 +261,12 @@ int pc_iskiller(dumb_ptr<map_session_data> src,
return 0;
}
-int pc_set_gm_level(int account_id, int level)
+void pc_set_gm_level(int account_id, uint8_t level)
{
- int i;
- for (i = 0; i < GM_num; i++)
- {
- if (account_id == gm_accounts[i].account_id)
- {
- gm_accounts[i].level = level;
- return 0;
- }
- }
-
- GM_num++;
- RECREATE(gm_accounts, struct GM_Account, GM_num);
- gm_accounts[GM_num - 1].account_id = account_id;
- gm_accounts[GM_num - 1].level = level;
- return 0;
+ if (level)
+ gm_accountm[account_id] = level;
+ else
+ gm_accountm.erase(account_id);
}
static
@@ -391,8 +376,10 @@ int pc_counttargeted(dumb_ptr<map_session_data> sd, dumb_ptr<block_list> src,
{
int c = 0;
map_foreachinarea(std::bind(pc_counttargeted_sub, ph::_1, sd->bl_id, &c, src, target_lv),
- sd->bl_m, sd->bl_x - AREA_SIZE, sd->bl_y - AREA_SIZE,
- sd->bl_x + AREA_SIZE, sd->bl_y + AREA_SIZE, BL::NUL);
+ sd->bl_m,
+ sd->bl_x - AREA_SIZE, sd->bl_y - AREA_SIZE,
+ sd->bl_x + AREA_SIZE, sd->bl_y + AREA_SIZE,
+ BL::NUL);
return c;
}
@@ -430,9 +417,9 @@ int pc_makesavestatus(dumb_ptr<map_session_data> sd)
}
// セーブ禁止マップだったので指定位置に移動
- if (map[sd->bl_m].flag.nosave)
+ if (sd->bl_m->flag.nosave)
{
- struct map_data *m = &map[sd->bl_m];
+ map_local *m = sd->bl_m;
if (strcmp(m->save.map, "SavePoint") == 0)
memcpy(&sd->status.last_point, &sd->status.save_point,
sizeof(sd->status.last_point));
@@ -609,7 +596,7 @@ int pc_isequip(dumb_ptr<map_session_data> sd, int n)
if (item->elv > 0 && sd->status.base_level < item->elv)
return 0;
- if (map[sd->bl_m].flag.pvp
+ if (sd->bl_m->flag.pvp
&& (item->flag.no_equip == 1 || item->flag.no_equip == 3))
return 0;
return 1;
@@ -663,7 +650,6 @@ int pc_authok(int id, int login_id2, TimeT connect_until_time,
// sd->walktimer = nullptr;
// sd->attacktimer = nullptr;
// sd->invincible_timer = nullptr;
- sd->sg_count = 0;
sd->deal_locked = 0;
sd->trade_partner = 0;
@@ -711,9 +697,6 @@ int pc_authok(int id, int login_id2, TimeT connect_until_time,
sd->sc_count = 0;
sd->status.option = Option::ZERO;
- // init ignore list
- memset(sd->ignore, 0, sizeof(sd->ignore));
-
// パーティー関係の初期化
sd->party_sended = 0;
sd->party_invite = 0;
@@ -801,7 +784,7 @@ int pc_authok(int id, int login_id2, TimeT connect_until_time,
sd->packet_flood_in = 0;
// Obtain IP address (if they are still connected)
- if (!getpeername(sd->fd, (struct sockaddr *)&sai, &sa_len))
+ if (!getpeername(sd->fd, reinterpret_cast<struct sockaddr *>(&sai), &sa_len))
sd->ip = sai.sin_addr;
// message of the limited time of the account
@@ -1059,7 +1042,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
{
if (sd->status.inventory[index].card[0] != 0x00ff
&& sd->status.inventory[index].card[0] != 0x00fe
- && sd->status.inventory[index].card[0] != (short) 0xff00)
+ && sd->status.inventory[index].card[0] != static_cast<short>(0xff00))
{
int j;
for (j = 0; j < sd->inventory_data[index]->slot; j++)
@@ -1075,7 +1058,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
if (i == EQUIP::SHIELD
&& sd->status.inventory[index].equip == EPOS::SHIELD)
sd->state.lr_flag = 1;
- run_script_l(itemdb_equipscript(c), 0, sd->bl_id,
+ run_script_l(ScriptPointer(itemdb_equipscript(c), 0), sd->bl_id,
0, 2, arg);
sd->state.lr_flag = 0;
}
@@ -1086,7 +1069,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
{ // 防具
if (sd->status.inventory[index].card[0] != 0x00ff
&& sd->status.inventory[index].card[0] != 0x00fe
- && sd->status.inventory[index].card[0] != (short) 0xff00)
+ && sd->status.inventory[index].card[0] != static_cast<short>(0xff00))
{
int j;
for (j = 0; j < sd->inventory_data[index]->slot; j++)
@@ -1098,7 +1081,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
arg[0].v.i = int(i);
arg[1].name = "@itemId";
arg[1].v.i = sd->inventory_data[index]->nameid;
- run_script_l(itemdb_equipscript(c), 0, sd->bl_id,
+ run_script_l(ScriptPointer(itemdb_equipscript(c), 0), sd->bl_id,
0, 2, arg);
}
}
@@ -1161,7 +1144,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
arg[0].v.i = int(i);
arg[1].name = "@itemId";
arg[1].v.i = sd->inventory_data[index]->nameid;
- run_script_l(sd->inventory_data[index]->equip_script, 0,
+ run_script_l(ScriptPointer(sd->inventory_data[index]->equip_script.get(), 0),
sd->bl_id, 0, 2, arg);
}
sd->state.lr_flag = 0;
@@ -1184,7 +1167,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
sd->star += (sd->status.inventory[index].card[1] >> 8); // 星のかけら
}
sd->attackrange += sd->inventory_data[index]->range;
- run_script_l(sd->inventory_data[index]->equip_script, 0,
+ run_script_l(ScriptPointer(sd->inventory_data[index]->equip_script.get(), 0),
sd->bl_id, 0, 2, arg);
}
}
@@ -1198,7 +1181,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
sd->watk += sd->inventory_data[index]->atk;
refinedef +=
sd->status.inventory[index].refine * 0;
- run_script_l(sd->inventory_data[index]->equip_script, 0,
+ run_script_l(ScriptPointer(sd->inventory_data[index]->equip_script.get(), 0),
sd->bl_id, 0, 2, arg);
}
}
@@ -1223,7 +1206,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
arg[1].name = "@itemId";
arg[1].v.i = sd->inventory_data[index]->nameid;
sd->state.lr_flag = 2;
- run_script_l(sd->inventory_data[index]->equip_script, 0, sd->bl_id,
+ run_script_l(ScriptPointer(sd->inventory_data[index]->equip_script.get(), 0), sd->bl_id,
0, 2, arg);
sd->state.lr_flag = 0;
sd->arrow_atk += sd->inventory_data[index]->atk;
@@ -1929,12 +1912,11 @@ int pc_inventoryblank(dumb_ptr<map_session_data> sd)
*/
int pc_payzeny(dumb_ptr<map_session_data> sd, int zeny)
{
- double z;
-
nullpo_ret(sd);
- z = (double) sd->status.zeny;
- if (sd->status.zeny < zeny || z - (double) zeny > MAX_ZENY)
+#warning "Why is this a double?"
+ double z = sd->status.zeny;
+ if (sd->status.zeny < zeny || z - zeny > MAX_ZENY)
return 1;
sd->status.zeny -= zeny;
clif_updatestatus(sd, SP::ZENY);
@@ -1948,12 +1930,10 @@ int pc_payzeny(dumb_ptr<map_session_data> sd, int zeny)
*/
int pc_getzeny(dumb_ptr<map_session_data> sd, int zeny)
{
- double z;
-
nullpo_ret(sd);
- z = (double) sd->status.zeny;
- if (z + (double) zeny > MAX_ZENY)
+ double z = sd->status.zeny;
+ if (z + zeny > MAX_ZENY)
{
zeny = 0;
sd->status.zeny = MAX_ZENY;
@@ -2273,16 +2253,11 @@ int pc_isUseitem(dumb_ptr<map_session_data> sd, int n)
if (itemdb_type(nameid) != ItemType::USE)
return 0;
if (nameid == 601
- && (map[sd->bl_m].flag.noteleport))
+ && (sd->bl_m->flag.noteleport))
{
return 0;
}
- if (nameid == 602 && map[sd->bl_m].flag.noreturn)
- return 0;
- if (nameid == 604
- && (map[sd->bl_m].flag.nobranch))
- return 0;
if (item->sex != 2 && sd->status.sex != item->sex)
return 0;
if (item->elv > 0 && sd->status.base_level < item->elv)
@@ -2312,7 +2287,7 @@ int pc_useitem(dumb_ptr<map_session_data> sd, int n)
return 1;
}
- run_script(sd->inventory_data[n]->use_script, 0, sd->bl_id, 0);
+ run_script(ScriptPointer(sd->inventory_data[n]->use_script.get(), 0), sd->bl_id, 0);
clif_useitemack(sd, n, amount - 1, 1);
pc_delitem(sd, n, 1, 1);
@@ -2355,7 +2330,6 @@ int pc_setpos(dumb_ptr<map_session_data> sd, const char *mapname_org, int x, int
BeingRemoveWhy clrtype)
{
char mapname[24];
- int m = 0;
nullpo_ret(sd);
@@ -2384,8 +2358,8 @@ int pc_setpos(dumb_ptr<map_session_data> sd, const char *mapname_org, int x, int
strcat(mapname, ".gat");
}
- m = map_mapname2mapid(mapname);
- if (m < 0)
+ map_local *m = map_mapname2mapid(mapname);
+ if (!m)
{
if (sd->mapname[0])
{
@@ -2419,10 +2393,10 @@ int pc_setpos(dumb_ptr<map_session_data> sd, const char *mapname_org, int x, int
return 1;
}
- if (x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys)
+ if (x < 0 || x >= m->xs || y < 0 || y >= m->ys)
x = y = 0;
if ((x == 0 && y == 0)
- || bool(read_gat(m, x, y) & MapCell::UNWALKABLE))
+ || bool(read_gatp(m, x, y) & MapCell::UNWALKABLE))
{
if (x || y)
{
@@ -2431,10 +2405,10 @@ int pc_setpos(dumb_ptr<map_session_data> sd, const char *mapname_org, int x, int
}
do
{
- x = random_::in(1, map[m].xs - 2);
- y = random_::in(1, map[m].ys - 2);
+ x = random_::in(1, m->xs - 2);
+ y = random_::in(1, m->ys - 2);
}
- while (bool(read_gat(m, x, y) & MapCell::UNWALKABLE));
+ while (bool(read_gatp(m, x, y) & MapCell::UNWALKABLE));
}
if (sd->mapname[0] && sd->bl_prev != NULL)
@@ -2442,7 +2416,7 @@ int pc_setpos(dumb_ptr<map_session_data> sd, const char *mapname_org, int x, int
clif_clearchar(sd, clrtype);
skill_gangsterparadise(sd, 0);
map_delblock(sd);
- clif_changemap(sd, map[m].name, x, y); // [MouseJstr]
+ clif_changemap(sd, m->name, x, y); // [MouseJstr]
}
memcpy(sd->mapname, mapname, 24);
@@ -2468,25 +2442,24 @@ int pc_setpos(dumb_ptr<map_session_data> sd, const char *mapname_org, int x, int
int pc_randomwarp(dumb_ptr<map_session_data> sd, BeingRemoveWhy type)
{
int x, y, i = 0;
- int m;
nullpo_ret(sd);
- m = sd->bl_m;
+ map_local *m = sd->bl_m;
- if (map[sd->bl_m].flag.noteleport) // テレポート禁止
+ if (sd->bl_m->flag.noteleport) // テレポート禁止
return 0;
do
{
- x = random_::in(1, map[m].xs - 2);
- y = random_::in(1, map[m].ys - 2);
+ x = random_::in(1, m->xs - 2);
+ y = random_::in(1, m->ys - 2);
}
- while (bool(read_gat(m, x, y) & MapCell::UNWALKABLE)
+ while (bool(read_gatp(m, x, y) & MapCell::UNWALKABLE)
&& (i++) < 1000);
if (i < 1000)
- pc_setpos(sd, map[m].name, x, y, type);
+ pc_setpos(sd, m->name, x, y, type);
return 0;
}
@@ -2589,7 +2562,8 @@ void pc_walk(TimerData *, tick_t tick, int id, unsigned char data)
// sd->walktimer = dummy value that is not nullptr;
map_foreachinmovearea(std::bind(clif_pcoutsight, ph::_1, sd),
- sd->bl_m, x - AREA_SIZE, y - AREA_SIZE,
+ sd->bl_m,
+ x - AREA_SIZE, y - AREA_SIZE,
x + AREA_SIZE, y + AREA_SIZE,
dx, dy,
BL::NUL);
@@ -2605,7 +2579,8 @@ void pc_walk(TimerData *, tick_t tick, int id, unsigned char data)
map_addblock(sd);
map_foreachinmovearea(std::bind(clif_pcinsight, ph::_1, sd),
- sd->bl_m, x - AREA_SIZE, y - AREA_SIZE,
+ sd->bl_m,
+ x - AREA_SIZE, y - AREA_SIZE,
x + AREA_SIZE, y + AREA_SIZE,
-dx, -dy,
BL::NUL);
@@ -2618,7 +2593,8 @@ void pc_walk(TimerData *, tick_t tick, int id, unsigned char data)
{
int p_flag = 0;
map_foreachinmovearea(std::bind(party_send_hp_check, ph::_1, sd->status.party_id, &p_flag),
- sd->bl_m, x - AREA_SIZE, y - AREA_SIZE,
+ sd->bl_m,
+ x - AREA_SIZE, y - AREA_SIZE,
x + AREA_SIZE, y + AREA_SIZE,
-dx, -dy,
BL::PC);
@@ -2772,7 +2748,8 @@ int pc_movepos(dumb_ptr<map_session_data> sd, int dst_x, int dst_y)
|| sd->bl_y / BLOCK_SIZE != dst_y / BLOCK_SIZE);
map_foreachinmovearea(std::bind(clif_pcoutsight, ph::_1, sd),
- sd->bl_m, sd->bl_x - AREA_SIZE, sd->bl_y - AREA_SIZE,
+ sd->bl_m,
+ sd->bl_x - AREA_SIZE, sd->bl_y - AREA_SIZE,
sd->bl_x + AREA_SIZE, sd->bl_y + AREA_SIZE,
dx, dy,
BL::NUL);
@@ -2785,7 +2762,8 @@ int pc_movepos(dumb_ptr<map_session_data> sd, int dst_x, int dst_y)
map_addblock(sd);
map_foreachinmovearea(std::bind(clif_pcinsight, ph::_1, sd),
- sd->bl_m, sd->bl_x - AREA_SIZE, sd->bl_y - AREA_SIZE,
+ sd->bl_m,
+ sd->bl_x - AREA_SIZE, sd->bl_y - AREA_SIZE,
sd->bl_x + AREA_SIZE, sd->bl_y + AREA_SIZE,
-dx, -dy,
BL::NUL);
@@ -2797,7 +2775,8 @@ int pc_movepos(dumb_ptr<map_session_data> sd, int dst_x, int dst_y)
{
int flag = 0;
map_foreachinmovearea(std::bind(party_send_hp_check, ph::_1, sd->status.party_id, &flag),
- sd->bl_m, sd->bl_x - AREA_SIZE, sd->bl_y - AREA_SIZE,
+ sd->bl_m,
+ sd->bl_x - AREA_SIZE, sd->bl_y - AREA_SIZE,
sd->bl_x + AREA_SIZE, sd->bl_y + AREA_SIZE,
-dx, -dy,
BL::PC);
@@ -3110,7 +3089,7 @@ int pc_gainexp_reason(dumb_ptr<map_session_data> sd, int base_exp, int job_exp,
if (sd->bl_prev == NULL || pc_isdead(sd))
return 0;
- if ((battle_config.pvp_exp == 0) && map[sd->bl_m].flag.pvp) // [MouseJstr]
+ if ((battle_config.pvp_exp == 0) && sd->bl_m->flag.pvp) // [MouseJstr]
return 0; // no exp on pvp maps
earray<const char *, PC_GAINEXP_REASON, PC_GAINEXP_REASON::COUNT> reasons //=
@@ -3588,28 +3567,28 @@ int pc_damage(dumb_ptr<block_list> src, dumb_ptr<map_session_data> sd,
if (battle_config.death_penalty_type > 0 && sd->status.base_level >= 20)
{ // changed penalty options, added death by player if pk_mode [Valaris]
- if (!map[sd->bl_m].flag.nopenalty)
+ if (!sd->bl_m->flag.nopenalty)
{
if (battle_config.death_penalty_type == 1
&& battle_config.death_penalty_base > 0)
sd->status.base_exp -=
- (double) pc_nextbaseexp(sd) *
- (double) battle_config.death_penalty_base / 10000;
+ static_cast<double>(pc_nextbaseexp(sd)) *
+ static_cast<double>(battle_config.death_penalty_base) / 10000;
if (battle_config.pk_mode && src && src->bl_type == BL::PC)
sd->status.base_exp -=
- (double) pc_nextbaseexp(sd) *
- (double) battle_config.death_penalty_base / 10000;
+ static_cast<double>(pc_nextbaseexp(sd)) *
+ static_cast<double>(battle_config.death_penalty_base) / 10000;
else if (battle_config.death_penalty_type == 2
&& battle_config.death_penalty_base > 0)
{
if (pc_nextbaseexp(sd) > 0)
sd->status.base_exp -=
- (double) sd->status.base_exp *
- (double) battle_config.death_penalty_base / 10000;
+ static_cast<double>(sd->status.base_exp) *
+ static_cast<double>(battle_config.death_penalty_base) / 10000;
if (battle_config.pk_mode && src && src->bl_type == BL::PC)
sd->status.base_exp -=
- (double) sd->status.base_exp *
- (double) battle_config.death_penalty_base / 10000;
+ static_cast<double>(sd->status.base_exp) *
+ static_cast<double>(battle_config.death_penalty_base) / 10000;
}
if (sd->status.base_exp < 0)
sd->status.base_exp = 0;
@@ -3618,23 +3597,23 @@ int pc_damage(dumb_ptr<block_list> src, dumb_ptr<map_session_data> sd,
if (battle_config.death_penalty_type == 1
&& battle_config.death_penalty_job > 0)
sd->status.job_exp -=
- (double) pc_nextjobexp(sd) *
- (double) battle_config.death_penalty_job / 10000;
+ static_cast<double>(pc_nextjobexp(sd)) *
+ static_cast<double>(battle_config.death_penalty_job) / 10000;
if (battle_config.pk_mode && src && src->bl_type == BL::PC)
sd->status.job_exp -=
- (double) pc_nextjobexp(sd) *
- (double) battle_config.death_penalty_job / 10000;
+ static_cast<double>(pc_nextjobexp(sd)) *
+ static_cast<double>(battle_config.death_penalty_job) / 10000;
else if (battle_config.death_penalty_type == 2
&& battle_config.death_penalty_job > 0)
{
if (pc_nextjobexp(sd) > 0)
sd->status.job_exp -=
- (double) sd->status.job_exp *
- (double) battle_config.death_penalty_job / 10000;
+ static_cast<double>(sd->status.job_exp) *
+ static_cast<double>(battle_config.death_penalty_job) / 10000;
if (battle_config.pk_mode && src && src->bl_type == BL::PC)
sd->status.job_exp -=
- (double) sd->status.job_exp *
- (double) battle_config.death_penalty_job / 10000;
+ static_cast<double>(sd->status.job_exp) *
+ static_cast<double>(battle_config.death_penalty_job) / 10000;
}
if (sd->status.job_exp < 0)
sd->status.job_exp = 0;
@@ -3643,10 +3622,10 @@ int pc_damage(dumb_ptr<block_list> src, dumb_ptr<map_session_data> sd,
}
// pvp
- if (map[sd->bl_m].flag.pvp && !battle_config.pk_mode)
+ if (sd->bl_m->flag.pvp && !battle_config.pk_mode)
{ // disable certain pvp functions on pk_mode [Valaris]
//ランキング計算
- if (!map[sd->bl_m].flag.pvp_nocalcrank)
+ if (!sd->bl_m->flag.pvp_nocalcrank)
{
sd->pvp_point -= 5;
if (src && src->bl_type == BL::PC)
@@ -4182,56 +4161,33 @@ int pc_setoption(dumb_ptr<map_session_data> sd, Option type)
*/
int pc_readreg(dumb_ptr<map_session_data> sd, int reg)
{
- int i;
-
nullpo_ret(sd);
- for (i = 0; i < sd->reg_num; i++)
- if (sd->reg[i].index == reg)
- return sd->reg[i].data;
-
- return 0;
+ return sd->regm.get(reg);
}
/*==========================================
* script用変数の値を設定
*------------------------------------------
*/
-int pc_setreg(dumb_ptr<map_session_data> sd, int reg, int val)
+void pc_setreg(dumb_ptr<map_session_data> sd, int reg, int val)
{
- int i;
-
- nullpo_ret(sd);
-
- for (i = 0; i < sd->reg_num; i++)
- {
- if (sd->reg[i].index == reg)
- {
- sd->reg[i].data = val;
- return 0;
- }
- }
- sd->reg_num++;
- RECREATE(sd->reg, struct script_reg, sd->reg_num);
- sd->reg[i].index = reg;
- sd->reg[i].data = val;
+ nullpo_retv(sd);
- return 0;
+ sd->regm.put(reg, val);
}
/*==========================================
* script用文字列変数の値を読む
*------------------------------------------
*/
-char *pc_readregstr(dumb_ptr<map_session_data> sd, int reg)
+const char *pc_readregstr(dumb_ptr<map_session_data> sd, int reg)
{
- int i;
-
nullpo_ret(sd);
- for (i = 0; i < sd->regstr_num; i++)
- if (sd->regstr[i].index == reg)
- return sd->regstr[i].data;
+ std::string *s = sd->regstrm.search(reg);
+ if (s)
+ return s->c_str();
return NULL;
}
@@ -4240,30 +4196,18 @@ char *pc_readregstr(dumb_ptr<map_session_data> sd, int reg)
* script用文字列変数の値を設定
*------------------------------------------
*/
-int pc_setregstr(dumb_ptr<map_session_data> sd, int reg, const char *str)
+void pc_setregstr(dumb_ptr<map_session_data> sd, int reg, const char *str)
{
- int i;
+ nullpo_retv(sd);
- nullpo_ret(sd);
- if (strlen(str) + 1 > sizeof(sd->regstr[0].data))
+ if (!*str)
{
- PRINTF("pc_setregstr(): String too long!\n");
- return 0;
+ sd->regstrm.erase(reg);
+ return;
}
- for (i = 0; i < sd->regstr_num; i++)
- if (sd->regstr[i].index == reg)
- {
- strcpy(sd->regstr[i].data, str);
- return 0;
- }
- sd->regstr_num++;
- RECREATE(sd->regstr, struct script_regstr, sd->regstr_num);
- sd->regstr[i].index = reg;
- strcpy(sd->regstr[i].data, str);
-
- return 0;
+ sd->regstrm.insert(reg, str);
}
/*==========================================
@@ -4478,14 +4422,14 @@ int pc_setaccountreg2(dumb_ptr<map_session_data> sd, const char *reg, int val)
*------------------------------------------
*/
static
-void pc_eventtimer(TimerData *, tick_t, int id, const char *data)
+void pc_eventtimer(TimerData *, tick_t, int id, dumb_string data)
{
dumb_ptr<map_session_data> sd = map_id2sd(id);
assert (sd != NULL);
- npc_event(sd, data, 0);
+ npc_event(sd, data.c_str(), 0);
- free(const_cast<char *>(data));
+ data.delete_();
}
/*==========================================
@@ -4504,8 +4448,7 @@ int pc_addeventtimer(dumb_ptr<map_session_data> sd, interval_t tick, const char
if (i < MAX_EVENTTIMER)
{
- char *evname = (char *) calloc(24, 1);
- strzcpy(evname, name, 24);
+ dumb_string evname = dumb_string::copyn(name, 24);
sd->eventtimer[i] = Timer(gettick() + tick,
std::bind(pc_eventtimer, ph::_1, ph::_2,
sd->bl_id, evname));
@@ -4862,7 +4805,7 @@ int pc_checkitem(dumb_ptr<map_session_data> sd)
}
//装備制限チェック
if (bool(sd->status.inventory[i].equip)
- && map[sd->bl_m].flag.pvp
+ && sd->bl_m->flag.pvp
&& (it->flag.no_equip == 1 || it->flag.no_equip == 3))
{ //PvP制限
sd->status.inventory[i].equip = EPOS::ZERO;
@@ -4932,17 +4875,17 @@ 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)
{
- struct map_data *m;
-
nullpo_ret(sd);
- m = &map[sd->bl_m];
+ map_local *m = sd->bl_m;
nullpo_ret(m);
if (!(m->flag.pvp))
return 0;
sd->pvp_rank = 1;
map_foreachinarea(std::bind(pc_calc_pvprank_sub, ph::_1, sd),
- sd->bl_m, 0, 0, m->xs, m->ys,
+ sd->bl_m,
+ 0, 0,
+ m->xs, m->ys,
BL::PC);
return sd->pvp_rank;
}
@@ -5392,19 +5335,16 @@ void pc_autosave(TimerData *, tick_t)
int pc_read_gm_account(int fd)
{
- int i = 0;
- if (gm_accounts != NULL)
- free(gm_accounts);
- GM_num = 0;
+ gm_accountm.clear();
- CREATE(gm_accounts, struct GM_Account, (RFIFOW(fd, 2) - 4) / 5);
- for (i = 4; i < RFIFOW(fd, 2); i = i + 5)
+ // (RFIFOW(fd, 2) - 4) / 5
+ for (int i = 4; i < RFIFOW(fd, 2); i += 5)
{
- gm_accounts[GM_num].account_id = RFIFOL(fd, i);
- gm_accounts[GM_num].level = (int) RFIFOB(fd, i + 4);
- GM_num++;
+ int account_id = RFIFOL(fd, i);
+ uint8_t level = RFIFOB(fd, i + 4);
+ gm_accountm[account_id] = level;
}
- return GM_num;
+ return gm_accountm.size();
}
void pc_setstand(dumb_ptr<map_session_data> sd)
@@ -5467,7 +5407,7 @@ void pc_invisibility(dumb_ptr<map_session_data> sd, int enabled)
{
sd->status.option &= ~Option::INVISIBILITY;
clif_status_change(sd, StatusChange::CLIF_OPTION_SC_INVISIBILITY, 0);
- pc_setpos(sd, map[sd->bl_m].name, sd->bl_x, sd->bl_y, BeingRemoveWhy::WARPED);
+ pc_setpos(sd, sd->bl_m->name, sd->bl_x, sd->bl_y, BeingRemoveWhy::WARPED);
}
}
diff --git a/src/map/pc.hpp b/src/map/pc.hpp
index 4fa0b0c..c319543 100644
--- a/src/map/pc.hpp
+++ b/src/map/pc.hpp
@@ -42,7 +42,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);
-int pc_isGM(dumb_ptr<map_session_data> sd);
+uint8_t 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]
@@ -119,9 +119,9 @@ int pc_changelook(dumb_ptr<map_session_data>, LOOK, int);
int pc_readparam(dumb_ptr<map_session_data>, SP);
int pc_setparam(dumb_ptr<map_session_data>, SP, int);
int pc_readreg(dumb_ptr<map_session_data>, int);
-int pc_setreg(dumb_ptr<map_session_data>, int, int);
-char *pc_readregstr(dumb_ptr<map_session_data> sd, int reg);
-int pc_setregstr(dumb_ptr<map_session_data> sd, int reg, const char *str);
+void pc_setreg(dumb_ptr<map_session_data>, int, int);
+const char *pc_readregstr(dumb_ptr<map_session_data> sd, int reg);
+void pc_setregstr(dumb_ptr<map_session_data> sd, int reg, const char *str);
int pc_readglobalreg(dumb_ptr<map_session_data>, const char *);
int pc_setglobalreg(dumb_ptr<map_session_data>, const char *, int);
int pc_readaccountreg(dumb_ptr<map_session_data>, const char *);
@@ -140,7 +140,7 @@ 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);
-int pc_set_gm_level(int account_id, int level);
+void pc_set_gm_level(int account_id, uint8_t level);
void pc_setstand(dumb_ptr<map_session_data> sd);
void pc_cleanup(dumb_ptr<map_session_data> sd); // [Fate] Clean up after a logged-out PC
diff --git a/src/map/script.cpp b/src/map/script.cpp
index 6d65fd2..7281784 100644
--- a/src/map/script.cpp
+++ b/src/map/script.cpp
@@ -12,6 +12,7 @@
#include "../common/cxxstdio.hpp"
#include "../common/db.hpp"
#include "../common/extract.hpp"
+#include "../common/intern-pool.hpp"
#include "../common/lock.hpp"
#include "../common/random.hpp"
#include "../common/socket.hpp"
@@ -35,49 +36,33 @@
#include "../poison.hpp"
-//#define DEBUG_FUNCIN
-//#define DEBUG_DISP
-//#define DEBUG_RUN
+constexpr bool DEBUG_DISP = false;
+constexpr bool DEBUG_RUN = false;
-constexpr int SCRIPT_BLOCK_SIZE = 256;
-enum
-{ LABEL_NEXTLINE = 1, LABEL_START };
-static
-ScriptCode *script_buf;
-static
-int script_pos, script_size;
-
-static
-char *str_buf;
-static
-int str_pos, str_size;
-static
struct str_data_t
{
- ScriptCode type;
- int str;
+ ByteCode type;
+ std::string strs;
int backpatch;
- int label;
- void(*func)(ScriptState *);
+ int label_;
int val;
- int next;
-} *str_data;
+};
static
-int str_num = LABEL_START, str_data_size;
+Map<std::string, str_data_t> str_datam;
static
-int str_hash[16];
+str_data_t LABEL_NEXTLINE_;
static
DMap<int, int> mapreg_db;
static
-DMap<int, char *> mapregstr_db;
+Map<int, std::string> mapregstr_db;
static
int mapreg_dirty = -1;
char mapreg_txt[256] = "save/mapreg.txt";
constexpr std::chrono::milliseconds MAPREG_AUTOSAVE_INTERVAL = std::chrono::seconds(10);
Map<std::string, int> scriptlabel_db;
-DMap<std::string, const ScriptCode *> userfunc_db;
+UPMap<std::string, const ScriptBuffer> userfunc_db;
static
const char *pos[11] =
@@ -108,14 +93,7 @@ struct Script_Config
static
int parse_cmd_if = 0;
static
-int parse_cmd;
-
-/*==========================================
- * ローカルプロトタイプ宣言 (必要な物のみ)
- *------------------------------------------
- */
-static
-const char *parse_subexpr(const char *, int);
+str_data_t *parse_cmdp;
static
void run_func(ScriptState *st);
@@ -127,172 +105,84 @@ void mapreg_setregstr(int num, const char *str);
struct BuiltinFunction
{
- void(*func)(ScriptState *);
+ void (*func)(ScriptState *);
const char *name;
const char *arg;
};
// defined later
extern BuiltinFunction builtin_functions[];
+static
+InternPool variable_names;
-enum class ScriptCode : uint8_t
+enum class ByteCode : uint8_t
{
// types and specials
- NOP, POS, INT, PARAM, FUNC, STR, CONSTSTR, ARG,
- NAME, EOL, RETINFO,
+ NOP, POS, INT, PARAM_, FUNC_, STR, CONSTSTR, ARG,
+ VARIABLE, EOL, RETINFO,
// unary and binary operators
LOR, LAND, LE, LT, GE, GT, EQ, NE,
- XOR, OR, AND, ADD, SUB, MUL, DIV, MOD, NEG, LNOT,
- NOT, R_SHIFT, L_SHIFT
-};
+ XOR, OR, AND, ADD, SUB, MUL, DIV, MOD,
+ NEG, LNOT, NOT, R_SHIFT, L_SHIFT,
-/*==========================================
- * 文字列のハッシュを計算
- *------------------------------------------
- */
-static
-int calc_hash(const char *s)
-{
- const unsigned char *p = (const unsigned char *)s;
- int h = 0;
- while (*p)
- {
- h = (h << 1) + (h >> 3) + (h >> 5) + (h >> 8);
- h += *p++;
- }
- return h & 15;
-}
+ // additions
+ // needed because FUNC is used for the actual call
+ FUNC_REF,
+};
-/*==========================================
- * str_dataの中に名前があるか検索する
- *------------------------------------------
- */
-// 既存のであれば番号、無ければ-1
static
-int search_str(const char *p)
+str_data_t *search_strp(const std::string& p)
{
- int i;
- i = str_hash[calc_hash(p)];
- while (i)
- {
- if (strcmp(str_buf + str_data[i].str, p) == 0)
- {
- return i;
- }
- i = str_data[i].next;
- }
- return -1;
+ return str_datam.search(p);
}
-/*==========================================
- * str_dataに名前を登録
- *------------------------------------------
- */
-// 既存のであれば番号、無ければ登録して新規番号
static
-int add_str(const char *p)
+str_data_t *add_strp(const std::string& p)
{
- int i;
- char *lowcase;
-
// TODO remove lowcase
- lowcase = strdup(p);
- for (i = 0; lowcase[i]; i++)
- lowcase[i] = tolower(lowcase[i]);
- if ((i = search_str(lowcase)) >= 0)
- {
- free(lowcase);
- return i;
- }
- free(lowcase);
+ std::string lowcase = p;
+ for (char& c : lowcase)
+ c = tolower(c);
- i = calc_hash(p);
- if (str_hash[i] == 0)
- {
- str_hash[i] = str_num;
- }
- else
- {
- i = str_hash[i];
- for (;;)
- {
- if (strcmp(str_buf + str_data[i].str, p) == 0)
- {
- return i;
- }
- if (str_data[i].next == 0)
- break;
- i = str_data[i].next;
- }
- str_data[i].next = str_num;
- }
- if (str_num >= str_data_size)
- {
- str_data_size += 128;
- RECREATE(str_data, struct str_data_t, str_data_size);
- memset(str_data + (str_data_size - 128), '\0', 128);
- }
- while (str_pos + strlen(p) + 1 >= str_size)
- {
- str_size += 256;
- str_buf = (char *) realloc(str_buf, str_size);
- memset(str_buf + (str_size - 256), '\0', 256);
- }
- strcpy(str_buf + str_pos, p);
- str_data[str_num].type = ScriptCode::NOP;
- str_data[str_num].str = str_pos;
- str_data[str_num].next = 0;
- str_data[str_num].func = NULL;
- str_data[str_num].backpatch = -1;
- str_data[str_num].label = -1;
- str_pos += strlen(p) + 1;
- return str_num++;
-}
+ if (str_data_t *rv = search_strp(lowcase))
+ return rv;
-/*==========================================
- * スクリプトバッファサイズの確認と拡張
- *------------------------------------------
- */
-static
-void check_script_buf(int size)
-{
- if (script_pos + size >= script_size)
- {
- script_size += SCRIPT_BLOCK_SIZE;
- script_buf = (ScriptCode *) realloc(script_buf, script_size);
- memset(script_buf + script_size - SCRIPT_BLOCK_SIZE, '\0',
- SCRIPT_BLOCK_SIZE);
- }
+ // ?
+ if (str_data_t *rv = search_strp(p))
+ return rv;
+
+ str_data_t *datum = str_datam.init(p);
+ datum->type = ByteCode::NOP;
+ datum->strs = p;
+ datum->backpatch = -1;
+ datum->label_ = -1;
+ return datum;
}
/*==========================================
* スクリプトバッファに1バイト書き込む
*------------------------------------------
*/
-static
-void add_scriptc(ScriptCode a)
+void ScriptBuffer::add_scriptc(ByteCode a)
{
- check_script_buf(1);
- script_buf[script_pos++] = a;
+ script_buf.push_back(a);
}
/*==========================================
* スクリプトバッファにデータタイプを書き込む
*------------------------------------------
*/
-static
-void add_scriptb(uint8_t a)
+void ScriptBuffer::add_scriptb(uint8_t a)
{
- add_scriptc(static_cast<ScriptCode>(a));
+ add_scriptc(static_cast<ByteCode>(a));
}
/*==========================================
* スクリプトバッファに整数を書き込む
*------------------------------------------
*/
-static
-void add_scripti(unsigned int a)
+void ScriptBuffer::add_scripti(uint32_t a)
{
while (a >= 0x40)
{
@@ -307,37 +197,43 @@ void add_scripti(unsigned int a)
*------------------------------------------
*/
// 最大16Mまで
-static
-void add_scriptl(int l)
+void ScriptBuffer::add_scriptl(str_data_t *ld)
{
- int backpatch = str_data[l].backpatch;
+ int backpatch = ld->backpatch;
- switch (str_data[l].type)
+ switch (ld->type)
{
- case ScriptCode::POS:
- add_scriptc(ScriptCode::POS);
- add_scriptb({uint8_t(str_data[l].label)});
- add_scriptb({uint8_t(str_data[l].label >> 8)});
- add_scriptb({uint8_t(str_data[l].label >> 16)});
+ case ByteCode::POS:
+ add_scriptc(ByteCode::POS);
+ add_scriptb(static_cast<uint8_t>(ld->label_));
+ add_scriptb(static_cast<uint8_t>(ld->label_ >> 8));
+ add_scriptb(static_cast<uint8_t>(ld->label_ >> 16));
break;
- case ScriptCode::NOP:
- // ラベルの可能性があるのでbackpatch用データ埋め込み
- add_scriptc(ScriptCode::NAME);
- str_data[l].backpatch = script_pos;
- add_scriptb({uint8_t(backpatch)});
- add_scriptb({uint8_t(backpatch >> 8)});
- add_scriptb({uint8_t(backpatch >> 16)});
+ case ByteCode::NOP:
+ // need to set backpatch, because it might become a label later
+ add_scriptc(ByteCode::VARIABLE);
+ ld->backpatch = script_buf.size();
+ add_scriptb(static_cast<uint8_t>(backpatch));
+ add_scriptb(static_cast<uint8_t>(backpatch >> 8));
+ add_scriptb(static_cast<uint8_t>(backpatch >> 16));
break;
- case ScriptCode::INT:
- add_scripti(str_data[l].val);
+ case ByteCode::INT:
+ add_scripti(ld->val);
break;
- default:
- // もう他の用途と確定してるので数字をそのまま
- add_scriptc(ScriptCode::NAME);
- add_scriptb({uint8_t(l)});
- add_scriptb({uint8_t(l >> 8)});
- add_scriptb({uint8_t(l >> 16)});
+ case ByteCode::FUNC_:
+ add_scriptc(ByteCode::FUNC_REF);
+ add_scriptb(static_cast<uint8_t>(ld->val));
+ add_scriptb(static_cast<uint8_t>(ld->val >> 8));
+ add_scriptb(static_cast<uint8_t>(ld->val >> 16));
+ break;
+ case ByteCode::PARAM_:
+ add_scriptc(ByteCode::PARAM_);
+ add_scriptb(static_cast<uint8_t>(ld->val));
+ add_scriptb(static_cast<uint8_t>(ld->val >> 8));
+ add_scriptb(static_cast<uint8_t>(ld->val >> 16));
break;
+ default:
+ abort();
}
}
@@ -345,21 +241,23 @@ void add_scriptl(int l)
* ラベルを解決する
*------------------------------------------
*/
-static
-void set_label(int l, int pos_)
+void ScriptBuffer::set_label(str_data_t *ld, int pos_)
{
- int i, next;
+ int next;
- str_data[l].type = ScriptCode::POS;
- str_data[l].label = pos_;
- for (i = str_data[l].backpatch; i >= 0 && i != 0x00ffffff;)
+ ld->type = ByteCode::POS;
+ ld->label_ = pos_;
+ for (int i = ld->backpatch; i >= 0 && i != 0x00ffffff; i = next)
{
- next = (*(int *)(script_buf + i)) & 0x00ffffff;
- script_buf[i - 1] = ScriptCode::POS;
- script_buf[i] = static_cast<ScriptCode>(pos_);
- script_buf[i + 1] = static_cast<ScriptCode>(pos_ >> 8);
- script_buf[i + 2] = static_cast<ScriptCode>(pos_ >> 16);
- i = next;
+ next = 0;
+ // woot! no longer endian-dependent!
+ next |= static_cast<uint8_t>(script_buf[i + 0]) << 0;
+ next |= static_cast<uint8_t>(script_buf[i + 1]) << 8;
+ next |= static_cast<uint8_t>(script_buf[i + 2]) << 16;
+ script_buf[i - 1] = ByteCode::POS;
+ script_buf[i] = static_cast<ByteCode>(pos_);
+ script_buf[i + 1] = static_cast<ByteCode>(pos_ >> 8);
+ script_buf[i + 2] = static_cast<ByteCode>(pos_ >> 16);
}
}
@@ -474,16 +372,11 @@ void disp_error_message(const char *mes, const char *pos_)
* 項の解析
*------------------------------------------
*/
-static
-const char *parse_simpleexpr(const char *p)
+const char *ScriptBuffer::parse_simpleexpr(const char *p)
{
int i;
p = skip_space(p);
-#ifdef DEBUG_FUNCIN
- if (battle_config.etc_log)
- PRINTF("parse_simpleexpr %s\n", p);
-#endif
if (*p == ';' || *p == ',')
{
disp_error_message("unexpected expr end", p);
@@ -509,7 +402,7 @@ const char *parse_simpleexpr(const char *p)
}
else if (*p == '"')
{
- add_scriptc(ScriptCode::STR);
+ add_scriptc(ByteCode::STR);
p++;
while (*p && *p != '"')
{
@@ -532,57 +425,42 @@ const char *parse_simpleexpr(const char *p)
}
else
{
- int l;
// label , register , function etc
- if (skip_word(p) == p)
+ const char *p2 = skip_word(p);
+ if (p2 == p)
{
disp_error_message("unexpected character", p);
exit(1);
}
- char *p2 = const_cast<char *>(skip_word(p));
- char c = *p2;
- *p2 = 0; // 名前をadd_strする
- l = add_str(p);
+ str_data_t *ld = add_strp(std::string(p, p2));
- parse_cmd = l; // warn_*_mismatch_paramnumのために必要
- if (l == search_str("if")) // warn_cmd_no_commaのために必要
+ 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のために必要
parse_cmd_if++;
-/*
- // 廃止予定のl14/l15,およびプレフィックスlの警告
- if ( strcmp(str_buf+str_data[l].str,"l14")==0 ||
- strcmp(str_buf+str_data[l].str,"l15")==0 ){
- disp_error_message("l14 and l15 is DEPRECATED. use @menu instead of l15.",p);
- }else if (str_buf[str_data[l].str]=='l'){
- disp_error_message("prefix 'l' is DEPRECATED. use prefix '@' instead.",p2);
- }
-*/
- *p2 = c;
p = p2;
- if (str_data[l].type != ScriptCode::FUNC && c == '[')
+ if (ld->type != ByteCode::FUNC_ && *p == '[')
{
// array(name[i] => getelementofarray(name,i) )
- add_scriptl(search_str("getelementofarray"));
- add_scriptc(ScriptCode::ARG);
- add_scriptl(l);
+ add_scriptl(search_strp("getelementofarray"));
+ add_scriptc(ByteCode::ARG);
+ add_scriptl(ld);
p = parse_subexpr(p + 1, -1);
p = skip_space(p);
- if ((*p++) != ']')
+ if (*p != ']')
{
disp_error_message("unmatch ']'", p);
exit(1);
}
- add_scriptc(ScriptCode::FUNC);
+ p++;
+ add_scriptc(ByteCode::FUNC_);
}
else
- add_scriptl(l);
+ add_scriptl(ld);
}
-#ifdef DEBUG_FUNCIN
- if (battle_config.etc_log)
- PRINTF("parse_simpleexpr end %s\n", p);
-#endif
return p;
}
@@ -590,15 +468,11 @@ const char *parse_simpleexpr(const char *p)
* 式の解析
*------------------------------------------
*/
-const char *parse_subexpr(const char *p, int limit)
+const char *ScriptBuffer::parse_subexpr(const char *p, int limit)
{
- ScriptCode op;
+ ByteCode op;
int opl, len;
-#ifdef DEBUG_FUNCIN
- if (battle_config.etc_log)
- PRINTF("parse_subexpr %s\n", p);
-#endif
p = skip_space(p);
if (*p == '-')
@@ -606,14 +480,14 @@ const char *parse_subexpr(const char *p, int limit)
const char *tmpp = skip_space(p + 1);
if (*tmpp == ';' || *tmpp == ',')
{
- add_scriptl(LABEL_NEXTLINE);
+ add_scriptl(&LABEL_NEXTLINE_);
p++;
return p;
}
}
const char *tmpp = p;
- if ((op = ScriptCode::NEG, *p == '-') || (op = ScriptCode::LNOT, *p == '!')
- || (op = ScriptCode::NOT, *p == '~'))
+ if ((op = ByteCode::NEG, *p == '-') || (op = ByteCode::LNOT, *p == '!')
+ || (op = ByteCode::NOT, *p == '~'))
{
p = parse_subexpr(p + 1, 100);
add_scriptc(op);
@@ -621,39 +495,40 @@ const char *parse_subexpr(const char *p, int limit)
else
p = parse_simpleexpr(p);
p = skip_space(p);
- while (((op = ScriptCode::ADD, opl = 6, len = 1, *p == '+') ||
- (op = ScriptCode::SUB, opl = 6, len = 1, *p == '-') ||
- (op = ScriptCode::MUL, opl = 7, len = 1, *p == '*') ||
- (op = ScriptCode::DIV, opl = 7, len = 1, *p == '/') ||
- (op = ScriptCode::MOD, opl = 7, len = 1, *p == '%') ||
- (op = ScriptCode::FUNC, opl = 8, len = 1, *p == '(') ||
- (op = ScriptCode::LAND, opl = 1, len = 2, *p == '&' && p[1] == '&') ||
- (op = ScriptCode::AND, opl = 5, len = 1, *p == '&') ||
- (op = ScriptCode::LOR, opl = 0, len = 2, *p == '|' && p[1] == '|') ||
- (op = ScriptCode::OR, opl = 4, len = 1, *p == '|') ||
- (op = ScriptCode::XOR, opl = 3, len = 1, *p == '^') ||
- (op = ScriptCode::EQ, opl = 2, len = 2, *p == '=' && p[1] == '=') ||
- (op = ScriptCode::NE, opl = 2, len = 2, *p == '!' && p[1] == '=') ||
- (op = ScriptCode::R_SHIFT, opl = 5, len = 2, *p == '>' && p[1] == '>') ||
- (op = ScriptCode::GE, opl = 2, len = 2, *p == '>' && p[1] == '=') ||
- (op = ScriptCode::GT, opl = 2, len = 1, *p == '>') ||
- (op = ScriptCode::L_SHIFT, opl = 5, len = 2, *p == '<' && p[1] == '<') ||
- (op = ScriptCode::LE, opl = 2, len = 2, *p == '<' && p[1] == '=') ||
- (op = ScriptCode::LT, opl = 2, len = 1, *p == '<')) && opl > limit)
+ while (((op = ByteCode::ADD, opl = 6, len = 1, *p == '+') ||
+ (op = ByteCode::SUB, opl = 6, len = 1, *p == '-') ||
+ (op = ByteCode::MUL, opl = 7, len = 1, *p == '*') ||
+ (op = ByteCode::DIV, opl = 7, len = 1, *p == '/') ||
+ (op = ByteCode::MOD, opl = 7, len = 1, *p == '%') ||
+ (op = ByteCode::FUNC_, opl = 8, len = 1, *p == '(') ||
+ (op = ByteCode::LAND, opl = 1, len = 2, *p == '&' && p[1] == '&') ||
+ (op = ByteCode::AND, opl = 5, len = 1, *p == '&') ||
+ (op = ByteCode::LOR, opl = 0, len = 2, *p == '|' && p[1] == '|') ||
+ (op = ByteCode::OR, opl = 4, len = 1, *p == '|') ||
+ (op = ByteCode::XOR, opl = 3, len = 1, *p == '^') ||
+ (op = ByteCode::EQ, opl = 2, len = 2, *p == '=' && p[1] == '=') ||
+ (op = ByteCode::NE, opl = 2, len = 2, *p == '!' && p[1] == '=') ||
+ (op = ByteCode::R_SHIFT, opl = 5, len = 2, *p == '>' && p[1] == '>') ||
+ (op = ByteCode::GE, opl = 2, len = 2, *p == '>' && p[1] == '=') ||
+ (op = ByteCode::GT, opl = 2, len = 1, *p == '>') ||
+ (op = ByteCode::L_SHIFT, opl = 5, len = 2, *p == '<' && p[1] == '<') ||
+ (op = ByteCode::LE, opl = 2, len = 2, *p == '<' && p[1] == '=') ||
+ (op = ByteCode::LT, opl = 2, len = 1, *p == '<')) && opl > limit)
{
p += len;
- if (op == ScriptCode::FUNC)
+ if (op == ByteCode::FUNC_)
{
- int i = 0, func = parse_cmd;
+ int i = 0;
+ str_data_t *funcp = parse_cmdp;
const char *plist[128];
- if (str_data[func].type != ScriptCode::FUNC)
+ if (funcp->type != ByteCode::FUNC_)
{
disp_error_message("expect function", tmpp);
exit(0);
}
- add_scriptc(ScriptCode::ARG);
+ add_scriptc(ByteCode::ARG);
while (*p && *p != ')' && i < 128)
{
plist[i] = p;
@@ -670,16 +545,17 @@ const char *parse_subexpr(const char *p, int limit)
i++;
}
plist[i] = p;
- if (*(p++) != ')')
+ if (*p != ')')
{
disp_error_message("func request '(' ')'", p);
exit(1);
}
+ p++;
- if (str_data[func].type == ScriptCode::FUNC
+ if (funcp->type == ByteCode::FUNC_
&& script_config.warn_func_mismatch_paramnum)
{
- const char *arg = builtin_functions[str_data[func].val].arg;
+ const char *arg = builtin_functions[funcp->val].arg;
int j = 0;
for (j = 0; arg[j]; j++)
if (arg[j] == '*')
@@ -691,17 +567,13 @@ const char *parse_subexpr(const char *p, int limit)
}
}
}
- else // not op == ScriptCode::FUNC
+ else // not op == ByteCode::FUNC
{
p = parse_subexpr(p, opl);
}
add_scriptc(op);
p = skip_space(p);
}
-#ifdef DEBUG_FUNCIN
- if (battle_config.etc_log)
- PRINTF("parse_subexpr end %s\n", p);
-#endif
return p; /* return first untreated operator */
}
@@ -709,13 +581,8 @@ const char *parse_subexpr(const char *p, int limit)
* 式の評価
*------------------------------------------
*/
-static
-const char *parse_expr(const char *p)
+const char *ScriptBuffer::parse_expr(const char *p)
{
-#ifdef DEBUG_FUNCIN
- if (battle_config.etc_log)
- PRINTF("parse_expr %s\n", p);
-#endif
switch (*p)
{
case ')':
@@ -728,10 +595,6 @@ const char *parse_expr(const char *p)
exit(1);
}
p = parse_subexpr(p, -1);
-#ifdef DEBUG_FUNCIN
- if (battle_config.etc_log)
- PRINTF("parse_expr end %s\n", p);
-#endif
return p;
}
@@ -739,10 +602,9 @@ const char *parse_expr(const char *p)
* 行の解析
*------------------------------------------
*/
-static
-const char *parse_line(const char *p)
+const char *ScriptBuffer::parse_line(const char *p)
{
- int i = 0, cmd;
+ int i = 0;
const char *plist[128];
p = skip_space(p);
@@ -756,14 +618,14 @@ const char *parse_line(const char *p)
p = parse_simpleexpr(p);
p = skip_space(p);
- cmd = parse_cmd;
- if (str_data[cmd].type != ScriptCode::FUNC)
+ str_data_t *cmd = parse_cmdp;
+ if (cmd->type != ByteCode::FUNC_)
{
disp_error_message("expect command", p2);
// exit(0);
}
- add_scriptc(ScriptCode::ARG);
+ add_scriptc(ByteCode::ARG);
while (p && *p && *p != ';' && i < 128)
{
plist[i] = p;
@@ -787,12 +649,12 @@ const char *parse_line(const char *p)
disp_error_message("need ';'", p);
exit(1);
}
- add_scriptc(ScriptCode::FUNC);
+ add_scriptc(ByteCode::FUNC_);
- if (str_data[cmd].type == ScriptCode::FUNC
+ if (cmd->type == ByteCode::FUNC_
&& script_config.warn_cmd_mismatch_paramnum)
{
- const char *arg = builtin_functions[str_data[cmd].val].arg;
+ const char *arg = builtin_functions[cmd->val].arg;
int j = 0;
for (j = 0; arg[j]; j++)
if (arg[j] == '*')
@@ -814,13 +676,11 @@ const char *parse_line(const char *p)
static
void add_builtin_functions(void)
{
- int i, n;
- for (i = 0; builtin_functions[i].func; i++)
+ for (int i = 0; builtin_functions[i].func; i++)
{
- n = add_str(builtin_functions[i].name);
- str_data[n].type = ScriptCode::FUNC;
- str_data[n].val = i;
- str_data[n].func = builtin_functions[i].func;
+ str_data_t *n = add_strp(builtin_functions[i].name);
+ n->type = ByteCode::FUNC_;
+ n->val = i;
}
}
@@ -844,34 +704,33 @@ void read_constdb(void)
if (line[0] == '/' && line[1] == '/')
continue;
- char *name = nullptr;
+ std::string name;
int val;
int type = 0; // if not provided
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wformat"
- if (sscanf(line.c_str(), "%m[A-Za-z0-9_] %i %i", &name, &val, &type) < 2)
- {
- free(name);
- continue;
- }
-#pragma GCC diagnostic pop
- for (char *p = name; *p; ++p)
- *p = tolower(*p);
- int n = add_str(name);
- free(name);
- str_data[n].type = type ? ScriptCode::PARAM : ScriptCode::INT;
- str_data[n].val = val;
+ if (SSCANF(line, "%m[A-Za-z0-9_] %i %i", &name, &val, &type) < 2)
+ continue;
+ for (char& c : name)
+ c = tolower(c);
+ str_data_t *n = add_strp(name);
+ n->type = type ? ByteCode::PARAM_ : ByteCode::INT;
+ n->val = val;
}
}
+std::unique_ptr<const ScriptBuffer> parse_script(const char *src, int line)
+{
+ auto script_buf = make_unique<ScriptBuffer>();
+ script_buf->parse_script(src, line);
+ return std::move(script_buf);
+}
+
/*==========================================
* スクリプトの解析
*------------------------------------------
*/
-const ScriptCode *parse_script(const char *src, int line)
+void ScriptBuffer::parse_script(const char *src, int line)
{
const char *p;
- int i;
static int first = 1;
if (first)
@@ -880,19 +739,17 @@ const ScriptCode *parse_script(const char *src, int line)
read_constdb();
}
first = 0;
- script_buf = (ScriptCode *) calloc(SCRIPT_BLOCK_SIZE, 1);
- script_pos = 0;
- script_size = SCRIPT_BLOCK_SIZE;
- str_data[LABEL_NEXTLINE].type = ScriptCode::NOP;
- str_data[LABEL_NEXTLINE].backpatch = -1;
- str_data[LABEL_NEXTLINE].label = -1;
- for (i = LABEL_START; i < str_num; i++)
- {
- if (str_data[i].type == ScriptCode::POS || str_data[i].type == ScriptCode::NAME)
+ LABEL_NEXTLINE_.type = ByteCode::NOP;
+ LABEL_NEXTLINE_.backpatch = -1;
+ LABEL_NEXTLINE_.label_ = -1;
+ for (auto& pair : str_datam)
+ {
+ str_data_t& dit = pair.second;
+ if (dit.type == ByteCode::POS || dit.type == ByteCode::VARIABLE)
{
- str_data[i].type = ScriptCode::NOP;
- str_data[i].backpatch = -1;
- str_data[i].label = -1;
+ dit.type = ByteCode::NOP;
+ dit.backpatch = -1;
+ dit.label_ = -1;
}
}
@@ -908,7 +765,7 @@ const ScriptCode *parse_script(const char *src, int line)
if (*p != '{')
{
disp_error_message("not found '{'", p);
- return NULL;
+ abort();
}
for (p++; p && *p && *p != '}';)
{
@@ -916,20 +773,20 @@ const ScriptCode *parse_script(const char *src, int line)
// labelだけ特殊処理
if (*skip_space(skip_word(p)) == ':')
{
- char *tmpp = const_cast<char *>(skip_word(p));
- char c = *tmpp;
- *tmpp = '\0';
- int l = add_str(p);
- if (str_data[l].label != -1)
+ const char *tmpp = skip_word(p);
+ std::string str(p, tmpp);
+ str_data_t *ld = add_strp(str);
+ bool e1 = ld->type != ByteCode::NOP;
+ bool e2 = ld->type == ByteCode::POS;
+ bool e3 = ld->label_ != -1;
+ assert (e1 == e2 && e2 == e3);
+ if (e3)
{
- *tmpp = c;
disp_error_message("dup label ", p);
exit(1);
}
- set_label(l, script_pos);
- std::string str(p, skip_word(p));
- scriptlabel_db.insert(str, script_pos);
- *tmpp = c;
+ set_label(ld, script_buf.size());
+ scriptlabel_db.insert(str, script_buf.size());
p = tmpp + 1;
continue;
}
@@ -937,58 +794,63 @@ const ScriptCode *parse_script(const char *src, int line)
// 他は全部一緒くた
p = parse_line(p);
p = skip_space(p);
- add_scriptc(ScriptCode::EOL);
+ add_scriptc(ByteCode::EOL);
- set_label(LABEL_NEXTLINE, script_pos);
- str_data[LABEL_NEXTLINE].type = ScriptCode::NOP;
- str_data[LABEL_NEXTLINE].backpatch = -1;
- str_data[LABEL_NEXTLINE].label = -1;
+ set_label(&LABEL_NEXTLINE_, script_buf.size());
+ LABEL_NEXTLINE_.type = ByteCode::NOP;
+ LABEL_NEXTLINE_.backpatch = -1;
+ LABEL_NEXTLINE_.label_ = -1;
}
- add_scriptc(ScriptCode::NOP);
+ add_scriptc(ByteCode::NOP);
- script_size = script_pos;
- script_buf = (ScriptCode *) realloc(script_buf, script_pos + 1);
-
- // 未解決のラベルを解決
- for (i = LABEL_START; i < str_num; i++)
+ // resolve the unknown labels
+ for (auto& pair : str_datam)
{
- if (str_data[i].type == ScriptCode::NOP)
+ str_data_t& sit = pair.second;
+ if (sit.type == ByteCode::NOP)
{
- int j, next;
- str_data[i].type = ScriptCode::NAME;
- str_data[i].label = i;
- for (j = str_data[i].backpatch; j >= 0 && j != 0x00ffffff;)
+ sit.type = ByteCode::VARIABLE;
+ sit.label_ = 0; // anything but -1. Shouldn't matter, but helps asserts.
+ size_t pool_index = variable_names.intern(sit.strs);
+ for (int next, j = sit.backpatch; j >= 0 && j != 0x00ffffff; j = next)
{
- next = (*(int *)(script_buf + j)) & 0x00ffffff;
- script_buf[j] = static_cast<ScriptCode>(i);
- script_buf[j + 1] = static_cast<ScriptCode>(i >> 8);
- script_buf[j + 2] = static_cast<ScriptCode>(i >> 16);
- j = next;
+ next = 0;
+ next |= static_cast<uint8_t>(script_buf[j + 0]) << 0;
+ next |= static_cast<uint8_t>(script_buf[j + 1]) << 8;
+ next |= static_cast<uint8_t>(script_buf[j + 2]) << 16;
+ script_buf[j] = static_cast<ByteCode>(pool_index);
+ script_buf[j + 1] = static_cast<ByteCode>(pool_index >> 8);
+ script_buf[j + 2] = static_cast<ByteCode>(pool_index >> 16);
}
}
}
-#ifdef DEBUG_DISP
- for (i = 0; i < script_pos; i++)
+ if (!DEBUG_DISP)
+ return;
+ for (size_t i = 0; i < script_buf.size(); i++)
{
if ((i & 15) == 0)
- PRINTF("%04x : ", i);
+ PRINTF("%04zx : ", i);
PRINTF("%02x ", script_buf[i]);
if ((i & 15) == 15)
PRINTF("\n");
}
PRINTF("\n");
-#endif
-
- return script_buf;
}
//
// 実行系
//
-enum
-{ STOP = 1, END, RERUNLINE, GOTO, RETFUNC };
+enum class ScriptEndState
+{
+ ZERO,
+ STOP,
+ END,
+ RERUNLINE,
+ GOTO,
+ RETFUNC,
+};
/*==========================================
* ridからsdへの解決
@@ -1013,11 +875,20 @@ static
void get_val(ScriptState *st, struct script_data *data)
{
dumb_ptr<map_session_data> sd = NULL;
- if (data->type == ScriptCode::NAME)
+
+ if (data->type == ByteCode::PARAM_)
{
- char *name = str_buf + str_data[data->u.num & 0x00ffffff].str;
- char prefix = *name;
- char postfix = name[strlen(name) - 1];
+ if ((sd = script_rid2sd(st)) == NULL)
+ PRINTF("get_val error param SP::%d\n", data->u.num);
+ data->type = ByteCode::INT;
+ if (sd)
+ data->u.num = pc_readparam(sd, static_cast<SP>(data->u.num));
+ }
+ else if (data->type == ByteCode::VARIABLE)
+ {
+ const std::string& name = variable_names.outtern(data->u.num & 0x00ffffff);
+ char prefix = name.front();
+ char postfix = name.back();
if (prefix != '$')
{
@@ -1026,43 +897,29 @@ void get_val(ScriptState *st, struct script_data *data)
}
if (postfix == '$')
{
-
- data->type = ScriptCode::CONSTSTR;
+ data->type = ByteCode::CONSTSTR;
if (prefix == '@' || prefix == 'l')
{
if (sd)
- data->u.str = pc_readregstr(sd, data->u.num);
+ data->u.str = dumb_string::fake(pc_readregstr(sd, data->u.num));
}
else if (prefix == '$')
{
- data->u.str = mapregstr_db.get(data->u.num);
+ std::string *s = mapregstr_db.search(data->u.num);
+ data->u.str = s ? dumb_string::fake(s->c_str()) : dumb_string();
}
else
{
PRINTF("script: get_val: illegal scope string variable.\n");
- data->u.str = "!!ERROR!!";
+ data->u.str = dumb_string::fake("!!ERROR!!");
}
- if (data->u.str == NULL)
- data->u.str = "";
-
+ if (!data->u.str)
+ data->u.str = dumb_string::fake("");
}
else
{
-
- data->type = ScriptCode::INT;
- if (str_data[data->u.num & 0x00ffffff].type == ScriptCode::INT)
- {
- // unreachable
- data->u.num = str_data[data->u.num & 0x00ffffff].val;
- }
- else if (str_data[data->u.num & 0x00ffffff].type == ScriptCode::PARAM)
- {
- if (sd)
- data->u.num =
- pc_readparam(sd,
- SP(str_data[data->u.num & 0x00ffffff].val));
- }
- else if (prefix == '@' || prefix == 'l')
+ data->type = ByteCode::INT;
+ if (prefix == '@' || prefix == 'l')
{
if (sd)
data->u.num = pc_readreg(sd, data->u.num);
@@ -1076,18 +933,18 @@ void get_val(ScriptState *st, struct script_data *data)
if (name[1] == '#')
{
if (sd)
- data->u.num = pc_readaccountreg2(sd, name);
+ data->u.num = pc_readaccountreg2(sd, name.c_str());
}
else
{
if (sd)
- data->u.num = pc_readaccountreg(sd, name);
+ data->u.num = pc_readaccountreg(sd, name.c_str());
}
}
else
{
if (sd)
- data->u.num = pc_readglobalreg(sd, name);
+ data->u.num = pc_readglobalreg(sd, name.c_str());
}
}
}
@@ -1101,7 +958,7 @@ static
struct script_data get_val2(ScriptState *st, int num)
{
struct script_data dat;
- dat.type = ScriptCode::NAME;
+ dat.type = ByteCode::VARIABLE;
dat.u.num = num;
get_val(st, &dat);
return dat;
@@ -1112,21 +969,30 @@ struct script_data get_val2(ScriptState *st, int num)
*------------------------------------------
*/
static
-void set_reg(dumb_ptr<map_session_data> sd, int num, const char *name, struct script_data vd)
+void set_reg(dumb_ptr<map_session_data> sd, ByteCode type, size_t num, struct script_data vd)
{
- char prefix = *name;
- char postfix = name[strlen(name) - 1];
+ if (type == ByteCode::PARAM_)
+ {
+ int val = vd.u.num;
+ pc_setparam(sd, static_cast<SP>(num), val);
+ return;
+ }
+ assert (type == ByteCode::VARIABLE);
+
+ const std::string& name = variable_names.outtern(num);
+ char prefix = name.front();
+ char postfix = name.back();
if (postfix == '$')
{
- const char *str = vd.u.str;
+ dumb_string str = vd.u.str;
if (prefix == '@' || prefix == 'l')
{
- pc_setregstr(sd, num, str);
+ pc_setregstr(sd, num, str.c_str());
}
else if (prefix == '$')
{
- mapreg_setregstr(num, str);
+ mapreg_setregstr(num, str.c_str());
}
else
{
@@ -1137,11 +1003,7 @@ void set_reg(dumb_ptr<map_session_data> sd, int num, const char *name, struct sc
{
// 数値
int val = vd.u.num;
- if (str_data[num & 0x00ffffff].type == ScriptCode::PARAM)
- {
- pc_setparam(sd, SP(str_data[num & 0x00ffffff].val), val);
- }
- else if (prefix == '@' || prefix == 'l')
+ if (prefix == '@' || prefix == 'l')
{
pc_setreg(sd, num, val);
}
@@ -1152,31 +1014,31 @@ void set_reg(dumb_ptr<map_session_data> sd, int num, const char *name, struct sc
else if (prefix == '#')
{
if (name[1] == '#')
- pc_setaccountreg2(sd, name, val);
+ pc_setaccountreg2(sd, name.c_str(), val);
else
- pc_setaccountreg(sd, name, val);
+ pc_setaccountreg(sd, name.c_str(), val);
}
else
{
- pc_setglobalreg(sd, name, val);
+ pc_setglobalreg(sd, name.c_str(), val);
}
}
}
static
-void set_reg(dumb_ptr<map_session_data> sd, int num, const char *name, int id)
+void set_reg(dumb_ptr<map_session_data> sd, ByteCode type, size_t num, int id)
{
struct script_data vd;
vd.u.num = id;
- set_reg(sd, num, name, vd);
+ set_reg(sd, type, num, vd);
}
static
-void set_reg(dumb_ptr<map_session_data> sd, int num, const char *name, const char *zd)
+void set_reg(dumb_ptr<map_session_data> sd, ByteCode type, size_t num, dumb_string zd)
{
struct script_data vd;
vd.u.str = zd;
- set_reg(sd, num, name, vd);
+ set_reg(sd, type, num, vd);
}
/*==========================================
@@ -1184,26 +1046,16 @@ void set_reg(dumb_ptr<map_session_data> sd, int num, const char *name, const cha
*------------------------------------------
*/
static
-const char *conv_str(ScriptState *st, struct script_data *data)
+dumb_string conv_str(ScriptState *st, struct script_data *data)
{
get_val(st, data);
- assert (data->type != ScriptCode::RETINFO);
- if (data->type == ScriptCode::INT)
- {
- char *buf;
- buf = (char *) calloc(16, 1);
- sprintf(buf, "%d", data->u.num);
- data->type = ScriptCode::STR;
- data->u.str = buf;
- }
-#if 1
- else if (data->type == ScriptCode::NAME)
+ assert (data->type != ByteCode::RETINFO);
+ if (data->type == ByteCode::INT)
{
- // テンポラリ。本来無いはず
- data->type = ScriptCode::CONSTSTR;
- data->u.str = str_buf + str_data[data->u.num].str;
+ std::string buf = STRPRINTF("%d", data->u.num);
+ data->type = ByteCode::STR;
+ data->u.str = dumb_string::copys(buf);
}
-#endif
return data->u.str;
}
@@ -1215,23 +1067,23 @@ static
int conv_num(ScriptState *st, struct script_data *data)
{
get_val(st, data);
- assert (data->type != ScriptCode::RETINFO);
- if (data->type == ScriptCode::STR || data->type == ScriptCode::CONSTSTR)
+ assert (data->type != ByteCode::RETINFO);
+ if (data->type == ByteCode::STR || data->type == ByteCode::CONSTSTR)
{
- const char *p = data->u.str;
- data->u.num = atoi(p);
- if (data->type == ScriptCode::STR)
- free(const_cast<char *>(p));
- data->type = ScriptCode::INT;
+ dumb_string p = data->u.str;
+ data->u.num = atoi(p.c_str());
+ if (data->type == ByteCode::STR)
+ p.delete_();
+ data->type = ByteCode::INT;
}
return data->u.num;
}
static
-const ScriptCode *conv_script(ScriptState *st, struct script_data *data)
+const ScriptBuffer *conv_script(ScriptState *st, struct script_data *data)
{
get_val(st, data);
- assert (data->type == ScriptCode::RETINFO);
+ assert (data->type == ByteCode::RETINFO);
return data->u.script;
}
@@ -1240,45 +1092,27 @@ const ScriptCode *conv_script(ScriptState *st, struct script_data *data)
*------------------------------------------
*/
static
-void push_val(struct script_stack *stack, ScriptCode type, int val)
+void push_val(struct script_stack *stack, ByteCode type, int val)
{
- assert (type != ScriptCode::RETINFO);
- assert (type != ScriptCode::STR);
- assert (type != ScriptCode::CONSTSTR);
- if (stack->sp >= stack->sp_max)
- {
- stack->sp_max += 64;
- stack->stack_data = (struct script_data *)
- realloc(stack->stack_data, sizeof(stack->stack_data[0]) *
- stack->sp_max);
- memset(stack->stack_data + (stack->sp_max - 64), 0,
- 64 * sizeof(*(stack->stack_data)));
- }
-// if(battle_config.etc_log)
-// PRINTF("push (%d,%d)-> %d\n",type,val,stack->sp);
- stack->stack_data[stack->sp].type = type;
- stack->stack_data[stack->sp].u.num = val;
- stack->sp++;
+ assert (type != ByteCode::RETINFO);
+ assert (type != ByteCode::STR);
+ assert (type != ByteCode::CONSTSTR);
+
+ script_data nsd {};
+ nsd.type = type;
+ nsd.u.num = val;
+ stack->stack_datav.push_back(nsd);
}
static
-void push_script(struct script_stack *stack, ScriptCode type, const ScriptCode *code)
+void push_script(struct script_stack *stack, ByteCode type, const ScriptBuffer *code)
{
- assert (type == ScriptCode::RETINFO);
- if (stack->sp >= stack->sp_max)
- {
- stack->sp_max += 64;
- stack->stack_data = (struct script_data *)
- realloc(stack->stack_data, sizeof(stack->stack_data[0]) *
- stack->sp_max);
- memset(stack->stack_data + (stack->sp_max - 64), 0,
- 64 * sizeof(*(stack->stack_data)));
- }
-// if(battle_config.etc_log)
-// PRINTF("push (%d,%d)-> %d\n",type,val,stack->sp);
- stack->stack_data[stack->sp].type = type;
- stack->stack_data[stack->sp].u.script = code;
- stack->sp++;
+ assert (type == ByteCode::RETINFO);
+
+ script_data nsd {};
+ nsd.type = type;
+ nsd.u.script = code;
+ stack->stack_datav.push_back(nsd);
}
/*==========================================
@@ -1286,23 +1120,14 @@ void push_script(struct script_stack *stack, ScriptCode type, const ScriptCode *
*------------------------------------------
*/
static
-void push_str(struct script_stack *stack, ScriptCode type, const char *str)
+void push_str(struct script_stack *stack, ByteCode type, dumb_string str)
{
- assert (type == ScriptCode::STR || type == ScriptCode::CONSTSTR);
- if (stack->sp >= stack->sp_max)
- {
- stack->sp_max += 64;
- stack->stack_data = (struct script_data *)
- realloc(stack->stack_data, sizeof(stack->stack_data[0]) *
- stack->sp_max);
- memset(stack->stack_data + (stack->sp_max - 64), '\0',
- 64 * sizeof(*(stack->stack_data)));
- }
-// if(battle_config.etc_log)
-// PRINTF("push (%d,%x)-> %d\n",type,str,stack->sp);
- stack->stack_data[stack->sp].type = type;
- stack->stack_data[stack->sp].u.str = str;
- stack->sp++;
+ assert (type == ByteCode::STR || type == ByteCode::CONSTSTR);
+
+ script_data nsd {};
+ nsd.type = type;
+ nsd.u.str = str;
+ stack->stack_datav.push_back(nsd);
}
/*==========================================
@@ -1312,19 +1137,10 @@ void push_str(struct script_stack *stack, ScriptCode type, const char *str)
static
void push_copy(struct script_stack *stack, int pos_)
{
- switch (stack->stack_data[pos_].type)
- {
- case ScriptCode::CONSTSTR:
- push_str(stack, ScriptCode::CONSTSTR, stack->stack_data[pos_].u.str);
- break;
- case ScriptCode::STR:
- push_str(stack, ScriptCode::STR, strdup(stack->stack_data[pos_].u.str));
- break;
- default:
- push_val(stack, stack->stack_data[pos_].type,
- stack->stack_data[pos_].u.num);
- break;
- }
+ script_data csd = stack->stack_datav[pos_];
+ if (csd.type == ByteCode::STR)
+ csd.u.str = csd.u.str.dup();
+ stack->stack_datav.push_back(csd);
}
/*==========================================
@@ -1334,22 +1150,18 @@ void push_copy(struct script_stack *stack, int pos_)
static
void pop_stack(struct script_stack *stack, int start, int end)
{
- int i;
- for (i = start; i < end; i++)
+ for (int i = start; i < end; i++)
{
- if (stack->stack_data[i].type == ScriptCode::STR)
- {
- free(const_cast<char *>(stack->stack_data[i].u.str));
- }
- }
- if (stack->sp > end)
- {
- memmove(&stack->stack_data[start], &stack->stack_data[end],
- sizeof(stack->stack_data[0]) * (stack->sp - end));
+ if (stack->stack_datav[i].type == ByteCode::STR)
+ stack->stack_datav[i].u.str.delete_();
}
- stack->sp -= end - start;
+ auto it = stack->stack_datav.begin();
+ stack->stack_datav.erase(it + start, it + end);
}
+#define AARGO2(n) (st->stack->stack_datav[st->start + (n)])
+#define HARGO2(n) (st->end > st->start + (n))
+
//
// 埋め込み関数
//
@@ -1360,9 +1172,8 @@ void pop_stack(struct script_stack *stack, int start, int end)
static
void builtin_mes(ScriptState *st)
{
- conv_str(st, &(st->stack->stack_data[st->start + 2]));
- clif_scriptmes(script_rid2sd(st), st->oid,
- st->stack->stack_data[st->start + 2].u.str);
+ dumb_string mes = conv_str(st, &AARGO2(2));
+ clif_scriptmes(script_rid2sd(st), st->oid, mes.c_str());
}
/*==========================================
@@ -1372,15 +1183,15 @@ void builtin_mes(ScriptState *st)
static
void builtin_goto(ScriptState *st)
{
- if (st->stack->stack_data[st->start + 2].type != ScriptCode::POS)
+ if (AARGO2(2).type != ByteCode::POS)
{
PRINTF("script: goto: not label !\n");
- st->state = END;
+ st->state = ScriptEndState::END;
return;
}
- st->pos = conv_num(st, &(st->stack->stack_data[st->start + 2]));
- st->state = GOTO;
+ st->scriptp.pos = conv_num(st, &AARGO2(2));
+ st->state = ScriptEndState::GOTO;
}
/*==========================================
@@ -1390,10 +1201,10 @@ void builtin_goto(ScriptState *st)
static
void builtin_callfunc(ScriptState *st)
{
- const ScriptCode *scr;
- const char *str = conv_str(st, &(st->stack->stack_data[st->start + 2]));
+ dumb_string str = conv_str(st, &AARGO2(2));
+ const ScriptBuffer *scr = userfunc_db.get(str.str());
- if ((scr = userfunc_db.get(str)))
+ if (scr)
{
int j = 0;
assert (st->start + 3 == st->end);
@@ -1402,20 +1213,19 @@ void builtin_callfunc(ScriptState *st)
push_copy(st->stack, i);
#endif
- push_val(st->stack, ScriptCode::INT, j); // 引数の数をプッシュ
- push_val(st->stack, ScriptCode::INT, st->defsp); // 現在の基準スタックポインタをプッシュ
- push_val(st->stack, ScriptCode::INT, st->pos); // 現在のスクリプト位置をプッシュ
- push_script(st->stack, ScriptCode::RETINFO, st->script); // 現在のスクリプトをプッシュ
+ push_val(st->stack, ByteCode::INT, j); // 引数の数をプッシュ
+ push_val(st->stack, ByteCode::INT, st->defsp); // 現在の基準スタックポインタをプッシュ
+ push_val(st->stack, ByteCode::INT, st->scriptp.pos); // 現在のスクリプト位置をプッシュ
+ push_script(st->stack, ByteCode::RETINFO, st->scriptp.code); // 現在のスクリプトをプッシュ
- st->pos = 0;
- st->script = scr;
+ st->scriptp = ScriptPointer(scr, 0);
st->defsp = st->start + 4 + j;
- st->state = GOTO;
+ st->state = ScriptEndState::GOTO;
}
else
{
PRINTF("script:callfunc: function not found! [%s]\n", str);
- st->state = END;
+ st->state = ScriptEndState::END;
}
}
@@ -1426,7 +1236,7 @@ void builtin_callfunc(ScriptState *st)
static
void builtin_callsub(ScriptState *st)
{
- int pos_ = conv_num(st, &(st->stack->stack_data[st->start + 2]));
+ int pos_ = conv_num(st, &AARGO2(2));
int j = 0;
assert (st->start + 3 == st->end);
#if 0
@@ -1434,14 +1244,14 @@ void builtin_callsub(ScriptState *st)
push_copy(st->stack, i);
#endif
- push_val(st->stack, ScriptCode::INT, j); // 引数の数をプッシュ
- push_val(st->stack, ScriptCode::INT, st->defsp); // 現在の基準スタックポインタをプッシュ
- push_val(st->stack, ScriptCode::INT, st->pos); // 現在のスクリプト位置をプッシュ
- push_script(st->stack, ScriptCode::RETINFO, st->script); // 現在のスクリプトをプッシュ
+ push_val(st->stack, ByteCode::INT, j); // 引数の数をプッシュ
+ push_val(st->stack, ByteCode::INT, st->defsp); // 現在の基準スタックポインタをプッシュ
+ push_val(st->stack, ByteCode::INT, st->scriptp.pos); // 現在のスクリプト位置をプッシュ
+ push_script(st->stack, ByteCode::RETINFO, st->scriptp.code); // 現在のスクリプトをプッシュ
- st->pos = pos_;
+ st->scriptp.pos = pos_;
st->defsp = st->start + 4 + j;
- st->state = GOTO;
+ st->state = ScriptEndState::GOTO;
}
/*==========================================
@@ -1452,12 +1262,12 @@ static
void builtin_return(ScriptState *st)
{
#if 0
- if (st->end > st->start + 2)
+ if (HARGO2(2))
{ // 戻り値有り
push_copy(st->stack, st->start + 2);
}
#endif
- st->state = RETFUNC;
+ st->state = ScriptEndState::RETFUNC;
}
/*==========================================
@@ -1467,7 +1277,7 @@ void builtin_return(ScriptState *st)
static
void builtin_next(ScriptState *st)
{
- st->state = STOP;
+ st->state = ScriptEndState::STOP;
clif_scriptnext(script_rid2sd(st), st->oid);
}
@@ -1478,14 +1288,14 @@ void builtin_next(ScriptState *st)
static
void builtin_close(ScriptState *st)
{
- st->state = END;
+ st->state = ScriptEndState::END;
clif_scriptclose(script_rid2sd(st), st->oid);
}
static
void builtin_close2(ScriptState *st)
{
- st->state = STOP;
+ st->state = ScriptEndState::STOP;
clif_scriptclose(script_rid2sd(st), st->oid);
}
@@ -1496,69 +1306,54 @@ void builtin_close2(ScriptState *st)
static
void builtin_menu(ScriptState *st)
{
- char *buf;
- int i, len = 0; // [fate] len is the total # of bytes we need to transmit the string choices
- int menu_choices = 0;
- int finished_menu_items = 0; // [fate] set to 1 after we hit the first empty string
-
- dumb_ptr<map_session_data> sd;
-
- sd = script_rid2sd(st);
-
- // We don't need to do this iteration if the player cancels, strictly speaking.
- for (i = st->start + 2; i < st->end; i += 2)
- {
- int choice_len;
- conv_str(st, &(st->stack->stack_data[i]));
- choice_len = strlen(st->stack->stack_data[i].u.str);
- len += choice_len + 1; // count # of bytes we'll need for packet. Only used if menu_or_input = 0.
-
- if (choice_len && !finished_menu_items)
- ++menu_choices;
- else
- finished_menu_items = 1;
- }
+ dumb_ptr<map_session_data> sd = script_rid2sd(st);
if (sd->state.menu_or_input == 0)
{
- st->state = RERUNLINE;
+ // First half: show menu.
+ st->state = ScriptEndState::RERUNLINE;
sd->state.menu_or_input = 1;
- buf = (char *) calloc(len + 1, 1);
- buf[0] = 0;
- for (i = st->start + 2; menu_choices > 0; i += 2, --menu_choices)
+ std::string buf;
+ for (int i = st->start + 2; i < st->end; i += 2)
{
- strcat(buf, st->stack->stack_data[i].u.str);
- strcat(buf, ":");
+ dumb_string choice_str = conv_str(st, &AARGO2(i - st->start));
+ if (!choice_str[0])
+ break;
+ buf += choice_str.c_str();
+ buf += ':';
}
- clif_scriptmenu(script_rid2sd(st), st->oid, buf);
- free(buf);
- }
- else if (sd->npc_menu == 0xff)
- { // cansel
- sd->state.menu_or_input = 0;
- st->state = END;
+
+ clif_scriptmenu(script_rid2sd(st), st->oid, buf.c_str());
}
else
- { // goto動作
- // ragemu互換のため
- pc_setreg(sd, add_str("l15"), sd->npc_menu);
- pc_setreg(sd, add_str("@menu"), sd->npc_menu);
+ {
+ // Rerun: item is chosen from menu.
+ if (sd->npc_menu == 0xff)
+ {
+ // cancel
+ sd->state.menu_or_input = 0;
+ st->state = ScriptEndState::END;
+ return;
+ }
+
+ // Actually jump to the label.
+ // Logic change: menu_choices is the *total* number of labels,
+ // 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, variable_names.intern("@menu"), sd->npc_menu);
sd->state.menu_or_input = 0;
if (sd->npc_menu > 0 && sd->npc_menu <= menu_choices)
{
- if (st->stack->
- stack_data[st->start + sd->npc_menu * 2 + 1].type != ScriptCode::POS)
+ int arg_index = (sd->npc_menu - 1) * 2 + 1;
+ if (AARGO2(arg_index + 2).type != ByteCode::POS)
{
- st->state = END;
+ st->state = ScriptEndState::END;
return;
}
- st->pos =
- conv_num(st,
- &(st->
- stack->stack_data[st->start + sd->npc_menu * 2 +
- 1]));
- st->state = GOTO;
+ st->scriptp.pos = conv_num(st, &AARGO2(arg_index + 2));
+ st->state = ScriptEndState::GOTO;
}
}
}
@@ -1570,18 +1365,18 @@ void builtin_menu(ScriptState *st)
static
void builtin_rand(ScriptState *st)
{
- if (st->end > st->start + 3)
+ if (HARGO2(3))
{
- int min = conv_num(st, &(st->stack->stack_data[st->start + 2]));
- int max = conv_num(st, &(st->stack->stack_data[st->start + 3]));
+ int min = conv_num(st, &AARGO2(2));
+ int max = conv_num(st, &AARGO2(3));
if (min > max)
std::swap(max, min);
- push_val(st->stack, ScriptCode::INT, random_::in(min, max));
+ push_val(st->stack, ByteCode::INT, random_::in(min, max));
}
else
{
- int range = conv_num(st, &(st->stack->stack_data[st->start + 2]));
- push_val(st->stack, ScriptCode::INT, range <= 0 ? 0 : random_::to(range));
+ int range = conv_num(st, &AARGO2(2));
+ push_val(st->stack, ByteCode::INT, range <= 0 ? 0 : random_::to(range));
}
}
@@ -1594,10 +1389,11 @@ void builtin_pow(ScriptState *st)
{
int a, b;
- a = conv_num(st, &(st->stack->stack_data[st->start + 2]));
- b = conv_num(st, &(st->stack->stack_data[st->start + 3]));
+ a = conv_num(st, &AARGO2(2));
+ b = conv_num(st, &AARGO2(3));
- push_val(st->stack, ScriptCode::INT, (int) pow(a * 0.001, b));
+#warning "This is silly"
+ push_val(st->stack, ByteCode::INT, static_cast<int>(pow(a * 0.001, b)));
}
@@ -1611,17 +1407,17 @@ void builtin_isat(ScriptState *st)
int x, y;
dumb_ptr<map_session_data> sd = script_rid2sd(st);
- const char *str = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- x = conv_num(st, &(st->stack->stack_data[st->start + 3]));
- y = conv_num(st, &(st->stack->stack_data[st->start + 4]));
+ dumb_string str = conv_str(st, &AARGO2(2));
+ x = conv_num(st, &AARGO2(3));
+ y = conv_num(st, &AARGO2(4));
if (!sd)
return;
- push_val(st->stack, ScriptCode::INT,
- (x == sd->bl_x)
- && (y == sd->bl_y) && (!strcmp(str, map[sd->bl_m].name)));
-
+ using namespace operators;
+ push_val(st->stack, ByteCode::INT,
+ (x == sd->bl_x) && (y == sd->bl_y)
+ && (str == sd->bl_m->name));
}
/*==========================================
@@ -1634,29 +1430,30 @@ void builtin_warp(ScriptState *st)
int x, y;
dumb_ptr<map_session_data> sd = script_rid2sd(st);
- const char *str = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- x = conv_num(st, &(st->stack->stack_data[st->start + 3]));
- y = conv_num(st, &(st->stack->stack_data[st->start + 4]));
- if (strcmp(str, "Random") == 0)
+ dumb_string str = conv_str(st, &AARGO2(2));
+ x = conv_num(st, &AARGO2(3));
+ y = conv_num(st, &AARGO2(4));
+ using namespace operators;
+ if (str == "Random")
pc_randomwarp(sd, BeingRemoveWhy::WARPED);
- else if (strcmp(str, "SavePoint") == 0)
+ else if (str == "SavePoint")
{
- if (map[sd->bl_m].flag.noreturn) // 蝶禁止
+ if (sd->bl_m->flag.noreturn) // 蝶禁止
return;
pc_setpos(sd, sd->status.save_point.map,
sd->status.save_point.x, sd->status.save_point.y, BeingRemoveWhy::WARPED);
}
- else if (strcmp(str, "Save") == 0)
+ else if (str == "Save")
{
- if (map[sd->bl_m].flag.noreturn) // 蝶禁止
+ if (sd->bl_m->flag.noreturn) // 蝶禁止
return;
pc_setpos(sd, sd->status.save_point.map,
sd->status.save_point.x, sd->status.save_point.y, BeingRemoveWhy::WARPED);
}
else
- pc_setpos(sd, str, x, y, BeingRemoveWhy::GONE);
+ pc_setpos(sd, str.c_str(), x, y, BeingRemoveWhy::GONE);
}
/*==========================================
@@ -1664,35 +1461,40 @@ void builtin_warp(ScriptState *st)
*------------------------------------------
*/
static
-void builtin_areawarp_sub(dumb_ptr<block_list> bl, const char *mapname, int x, int y)
+void builtin_areawarp_sub(dumb_ptr<block_list> bl, dumb_string mapname, int x, int y)
{
dumb_ptr<map_session_data> sd = bl->as_player();
- if (strcmp(mapname, "Random") == 0)
+ using namespace operators;
+ if (mapname == "Random")
pc_randomwarp(sd, BeingRemoveWhy::WARPED);
else
- pc_setpos(sd, mapname, x, y, BeingRemoveWhy::GONE);
+ pc_setpos(sd, mapname.c_str(), x, y, BeingRemoveWhy::GONE);
}
static
void builtin_areawarp(ScriptState *st)
{
- int x, y, m;
+ int x, y;
int x0, y0, x1, y1;
- const char *mapname = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- x0 = conv_num(st, &(st->stack->stack_data[st->start + 3]));
- y0 = conv_num(st, &(st->stack->stack_data[st->start + 4]));
- x1 = conv_num(st, &(st->stack->stack_data[st->start + 5]));
- y1 = conv_num(st, &(st->stack->stack_data[st->start + 6]));
- const char *str = conv_str(st, &(st->stack->stack_data[st->start + 7]));
- x = conv_num(st, &(st->stack->stack_data[st->start + 8]));
- y = conv_num(st, &(st->stack->stack_data[st->start + 9]));
-
- if ((m = map_mapname2mapid(mapname)) < 0)
+ dumb_string mapname = conv_str(st, &AARGO2(2));
+ x0 = conv_num(st, &AARGO2(3));
+ y0 = conv_num(st, &AARGO2(4));
+ x1 = conv_num(st, &AARGO2(5));
+ y1 = conv_num(st, &AARGO2(6));
+ dumb_string str = conv_str(st, &AARGO2(7));
+ x = conv_num(st, &AARGO2(8));
+ y = conv_num(st, &AARGO2(9));
+
+ map_local *m = map_mapname2mapid(mapname.c_str());
+ if (m == nullptr)
return;
map_foreachinarea(std::bind(builtin_areawarp_sub, ph::_1, str, x, y),
- m, x0, y0, x1, y1, BL::PC);
+ m,
+ x0, y0,
+ x1, y1,
+ BL::PC);
}
/*==========================================
@@ -1704,8 +1506,8 @@ void builtin_heal(ScriptState *st)
{
int hp, sp;
- hp = conv_num(st, &(st->stack->stack_data[st->start + 2]));
- sp = conv_num(st, &(st->stack->stack_data[st->start + 3]));
+ hp = conv_num(st, &AARGO2(2));
+ sp = conv_num(st, &AARGO2(3));
pc_heal(script_rid2sd(st), hp, sp);
}
@@ -1718,8 +1520,8 @@ void builtin_itemheal(ScriptState *st)
{
int hp, sp;
- hp = conv_num(st, &(st->stack->stack_data[st->start + 2]));
- sp = conv_num(st, &(st->stack->stack_data[st->start + 3]));
+ hp = conv_num(st, &AARGO2(2));
+ sp = conv_num(st, &AARGO2(3));
pc_itemheal(script_rid2sd(st), hp, sp);
}
@@ -1732,8 +1534,8 @@ void builtin_percentheal(ScriptState *st)
{
int hp, sp;
- hp = conv_num(st, &(st->stack->stack_data[st->start + 2]));
- sp = conv_num(st, &(st->stack->stack_data[st->start + 3]));
+ hp = conv_num(st, &AARGO2(2));
+ sp = conv_num(st, &AARGO2(3));
pc_percentheal(script_rid2sd(st), hp, sp);
}
@@ -1745,57 +1547,42 @@ static
void builtin_input(ScriptState *st)
{
dumb_ptr<map_session_data> sd = NULL;
- int num =
- (st->end >
- st->start + 2) ? st->stack->stack_data[st->start + 2].u.num : 0;
- const char *name =
- (st->end >
- st->start + 2) ? str_buf + str_data[num & 0x00ffffff].str : "";
-// char prefix=*name;
- char postfix = name[strlen(name) - 1];
+ script_data& scrd = AARGO2(2);
+ ByteCode type = scrd.type;
+ assert (type == ByteCode::VARIABLE);
+
+ int num = scrd.u.num;
+ const std::string& name = variable_names.outtern(num & 0x00ffffff);
+// char prefix = name.front();
+ char postfix = name.back();
sd = script_rid2sd(st);
if (sd->state.menu_or_input)
{
+ // Second time (rerun)
sd->state.menu_or_input = 0;
if (postfix == '$')
{
- // 文字列
- if (st->end > st->start + 2)
- { // 引数1個
- set_reg(sd, num, name, sd->npc_str);
- }
- else
- {
- PRINTF("builtin_input: string discarded !!\n");
- }
+ set_reg(sd, type, num, dumb_string::fake(sd->npc_str));
}
else
{
-
//commented by Lupus (check Value Number Input fix in clif.c)
//** Fix by fritz :X keeps people from abusing old input bugs
+ // wtf?
if (sd->npc_amount < 0) //** If input amount is less then 0
{
clif_tradecancelled(sd); // added "Deal has been cancelled" message by Valaris
builtin_close(st); //** close
}
- // 数値
- if (st->end > st->start + 2)
- { // 引数1個
- set_reg(sd, num, name, sd->npc_amount);
- }
- else
- {
- // ragemu互換のため
- pc_setreg(sd, add_str("l14"), sd->npc_amount);
- }
+ set_reg(sd, type, num, sd->npc_amount);
}
}
else
{
- st->state = RERUNLINE;
+ // First time - send prompt to client, then wait
+ st->state = ScriptEndState::RERUNLINE;
if (postfix == '$')
clif_scriptinputstr(sd, st->oid);
else
@@ -1813,14 +1600,14 @@ void builtin_if (ScriptState *st)
{
int sel, i;
- sel = conv_num(st, &(st->stack->stack_data[st->start + 2]));
+ sel = conv_num(st, &AARGO2(2));
if (!sel)
return;
// 関数名をコピー
push_copy(st->stack, st->start + 3);
// 間に引数マーカを入れて
- push_val(st->stack, ScriptCode::ARG, 0);
+ push_val(st->stack, ByteCode::ARG, 0);
// 残りの引数をコピー
for (i = st->start + 4; i < st->end; i++)
{
@@ -1838,16 +1625,20 @@ static
void builtin_set(ScriptState *st)
{
dumb_ptr<map_session_data> sd = NULL;
- int num = st->stack->stack_data[st->start + 2].u.num;
- char *name = str_buf + str_data[num & 0x00ffffff].str;
- char prefix = *name;
- char postfix = name[strlen(name) - 1];
-
- if (st->stack->stack_data[st->start + 2].type != ScriptCode::NAME)
+ int num = AARGO2(2).u.num;
+ if (AARGO2(2).type == ByteCode::PARAM_)
{
- PRINTF("script: builtin_set: not name\n");
+ sd = script_rid2sd(st);
+
+ int val = conv_num(st, &AARGO2(3));
+ set_reg(sd, ByteCode::PARAM_, num, val);
return;
}
+ const std::string& name = variable_names.outtern(num & 0x00ffffff);
+ char prefix = name.front();
+ char postfix = name.back();
+
+ assert (AARGO2(2).type == ByteCode::VARIABLE);
if (prefix != '$')
sd = script_rid2sd(st);
@@ -1855,14 +1646,14 @@ void builtin_set(ScriptState *st)
if (postfix == '$')
{
// 文字列
- const char *str = conv_str(st, &(st->stack->stack_data[st->start + 3]));
- set_reg(sd, num, name, str);
+ dumb_string str = conv_str(st, &AARGO2(3));
+ set_reg(sd, ByteCode::VARIABLE, num, str);
}
else
{
// 数値
- int val = conv_num(st, &(st->stack->stack_data[st->start + 3]));
- set_reg(sd, num, name, val);
+ int val = conv_num(st, &AARGO2(3));
+ set_reg(sd, ByteCode::VARIABLE, num, val);
}
}
@@ -1875,11 +1666,11 @@ static
void builtin_setarray(ScriptState *st)
{
dumb_ptr<map_session_data> sd = NULL;
- int num = st->stack->stack_data[st->start + 2].u.num;
- char *name = str_buf + str_data[num & 0x00ffffff].str;
- char prefix = *name;
- char postfix = name[strlen(name) - 1];
- int i, j;
+ assert (AARGO2(2).type == ByteCode::VARIABLE);
+ int num = AARGO2(2).u.num;
+ const std::string& name = variable_names.outtern(num & 0x00ffffff);
+ char prefix = name.front();
+ char postfix = name.back();
if (prefix != '$' && prefix != '@')
{
@@ -1889,12 +1680,12 @@ void builtin_setarray(ScriptState *st)
if (prefix != '$')
sd = script_rid2sd(st);
- for (j = 0, i = st->start + 3; i < st->end && j < 128; i++, j++)
+ for (int j = 0, i = st->start + 3; i < st->end && j < 128; i++, j++)
{
if (postfix == '$')
- set_reg(sd, num + (j << 24), name, conv_str(st, &(st->stack->stack_data[i])));
+ set_reg(sd, ByteCode::VARIABLE, num + (j << 24), conv_str(st, &AARGO2(i - st->start)));
else
- set_reg(sd, num + (j << 24), name, conv_num(st, &(st->stack->stack_data[i])));
+ set_reg(sd, ByteCode::VARIABLE, num + (j << 24), conv_num(st, &AARGO2(i - st->start)));
}
}
@@ -1906,12 +1697,12 @@ static
void builtin_cleararray(ScriptState *st)
{
dumb_ptr<map_session_data> sd = NULL;
- int num = st->stack->stack_data[st->start + 2].u.num;
- char *name = str_buf + str_data[num & 0x00ffffff].str;
- char prefix = *name;
- char postfix = name[strlen(name) - 1];
- int sz = conv_num(st, &(st->stack->stack_data[st->start + 4]));
- int i;
+ assert (AARGO2(2).type == ByteCode::VARIABLE);
+ int num = AARGO2(2).u.num;
+ const std::string& name = variable_names.outtern(num & 0x00ffffff);
+ char prefix = name.front();
+ char postfix = name.back();
+ int sz = conv_num(st, &AARGO2(4));
if (prefix != '$' && prefix != '@')
{
@@ -1922,11 +1713,11 @@ void builtin_cleararray(ScriptState *st)
sd = script_rid2sd(st);
if (postfix == '$')
- for (i = 0; i < sz; i++)
- set_reg(sd, num + (i << 24), name, conv_str(st, &(st->stack->stack_data[st->start + 3])));
+ for (int i = 0; i < sz; i++)
+ set_reg(sd, ByteCode::VARIABLE, num + (i << 24), conv_str(st, &AARGO2(3)));
else
- for (i = 0; i < sz; i++)
- set_reg(sd, num + (i << 24), name, conv_num(st, &(st->stack->stack_data[st->start + 3])));
+ for (int i = 0; i < sz; i++)
+ set_reg(sd, ByteCode::VARIABLE, num + (i << 24), conv_num(st, &AARGO2(3)));
}
@@ -1941,7 +1732,7 @@ int getarraysize(ScriptState *st, int num, int postfix)
for (; i < 128; i++)
{
struct script_data vd = get_val2(st, num + (i << 24));
- if (postfix == '$' ? bool(*vd.u.str) : bool(vd.u.num))
+ if (postfix == '$' ? bool(vd.u.str[0]) : bool(vd.u.num))
c = i;
}
return c + 1;
@@ -1950,10 +1741,11 @@ int getarraysize(ScriptState *st, int num, int postfix)
static
void builtin_getarraysize(ScriptState *st)
{
- int num = st->stack->stack_data[st->start + 2].u.num;
- char *name = str_buf + str_data[num & 0x00ffffff].str;
- char prefix = *name;
- char postfix = name[strlen(name) - 1];
+ assert (AARGO2(2).type == ByteCode::VARIABLE);
+ int num = AARGO2(2).u.num;
+ const std::string& name = variable_names.outtern(num & 0x00ffffff);
+ char prefix = name.front();
+ char postfix = name.back();
if (prefix != '$' && prefix != '@')
{
@@ -1961,7 +1753,7 @@ void builtin_getarraysize(ScriptState *st)
return;
}
- push_val(st->stack, ScriptCode::INT, getarraysize(st, num, postfix));
+ push_val(st->stack, ByteCode::INT, getarraysize(st, num, postfix));
}
/*==========================================
@@ -1971,25 +1763,25 @@ void builtin_getarraysize(ScriptState *st)
static
void builtin_getelementofarray(ScriptState *st)
{
- if (st->stack->stack_data[st->start + 2].type == ScriptCode::NAME)
+ if (AARGO2(2).type == ByteCode::VARIABLE)
{
- int i = conv_num(st, &(st->stack->stack_data[st->start + 3]));
+ int i = conv_num(st, &AARGO2(3));
if (i > 127 || i < 0)
{
PRINTF("script: getelementofarray (operator[]): param2 illegal number %d\n",
i);
- push_val(st->stack, ScriptCode::INT, 0);
+ push_val(st->stack, ByteCode::INT, 0);
}
else
{
- push_val(st->stack, ScriptCode::NAME,
- (i << 24) | st->stack->stack_data[st->start + 2].u.num);
+ push_val(st->stack, ByteCode::VARIABLE,
+ (i << 24) | AARGO2(2).u.num);
}
}
else
{
PRINTF("script: getelementofarray (operator[]): param1 not name !\n");
- push_val(st->stack, ScriptCode::INT, 0);
+ push_val(st->stack, ByteCode::INT, 0);
}
}
@@ -2000,8 +1792,8 @@ void builtin_getelementofarray(ScriptState *st)
static
void builtin_setlook(ScriptState *st)
{
- LOOK type = LOOK(conv_num(st, &(st->stack->stack_data[st->start + 2])));
- int val = conv_num(st, &(st->stack->stack_data[st->start + 3]));
+ LOOK type = LOOK(conv_num(st, &AARGO2(2)));
+ int val = conv_num(st, &AARGO2(3));
pc_changelook(script_rid2sd(st), type, val);
@@ -2021,13 +1813,13 @@ void builtin_countitem(ScriptState *st)
sd = script_rid2sd(st);
- data = &(st->stack->stack_data[st->start + 2]);
+ data = &AARGO2(2);
get_val(st, data);
- if (data->type == ScriptCode::STR || data->type == ScriptCode::CONSTSTR)
+ if (data->type == ByteCode::STR || data->type == ByteCode::CONSTSTR)
{
- const char *name = conv_str(st, data);
- struct item_data *item_data;
- if ((item_data = itemdb_searchname(name)) != NULL)
+ dumb_string name = conv_str(st, data);
+ struct item_data *item_data = itemdb_searchname(name.c_str());
+ if (item_data != NULL)
nameid = item_data->nameid;
}
else
@@ -2044,7 +1836,7 @@ void builtin_countitem(ScriptState *st)
if (battle_config.error_log)
PRINTF("wrong item ID : countitem (%i)\n", nameid);
}
- push_val(st->stack, ScriptCode::INT, count);
+ push_val(st->stack, ByteCode::INT, count);
}
@@ -2061,33 +1853,33 @@ void builtin_checkweight(ScriptState *st)
sd = script_rid2sd(st);
- data = &(st->stack->stack_data[st->start + 2]);
+ data = &AARGO2(2);
get_val(st, data);
- if (data->type == ScriptCode::STR || data->type == ScriptCode::CONSTSTR)
+ if (data->type == ByteCode::STR || data->type == ByteCode::CONSTSTR)
{
- const char *name = conv_str(st, data);
- struct item_data *item_data = itemdb_searchname(name);
+ dumb_string name = conv_str(st, data);
+ struct item_data *item_data = itemdb_searchname(name.c_str());
if (item_data)
nameid = item_data->nameid;
}
else
nameid = conv_num(st, data);
- amount = conv_num(st, &(st->stack->stack_data[st->start + 3]));
+ amount = conv_num(st, &AARGO2(3));
if (amount <= 0 || nameid < 500)
{
//if get wrong item ID or amount<=0, don't count weight of non existing items
- push_val(st->stack, ScriptCode::INT, 0);
+ push_val(st->stack, ByteCode::INT, 0);
return;
}
if (itemdb_weight(nameid) * amount + sd->weight > sd->max_weight)
{
- push_val(st->stack, ScriptCode::INT, 0);
+ push_val(st->stack, ByteCode::INT, 0);
}
else
{
- push_val(st->stack, ScriptCode::INT, 1);
+ push_val(st->stack, ByteCode::INT, 1);
}
}
@@ -2106,12 +1898,12 @@ void builtin_getitem(ScriptState *st)
sd = script_rid2sd(st);
- data = &(st->stack->stack_data[st->start + 2]);
+ data = &AARGO2(2);
get_val(st, data);
- if (data->type == ScriptCode::STR || data->type == ScriptCode::CONSTSTR)
+ if (data->type == ByteCode::STR || data->type == ByteCode::CONSTSTR)
{
- const char *name = conv_str(st, data);
- struct item_data *item_data = itemdb_searchname(name);
+ dumb_string name = conv_str(st, data);
+ struct item_data *item_data = itemdb_searchname(name.c_str());
nameid = 727; //Default to iten
if (item_data != NULL)
nameid = item_data->nameid;
@@ -2120,7 +1912,7 @@ void builtin_getitem(ScriptState *st)
nameid = conv_num(st, data);
if ((amount =
- conv_num(st, &(st->stack->stack_data[st->start + 3]))) <= 0)
+ conv_num(st, &AARGO2(3))) <= 0)
{
return; //return if amount <=0, skip the useles iteration
}
@@ -2130,8 +1922,8 @@ void builtin_getitem(ScriptState *st)
memset(&item_tmp, 0, sizeof(item_tmp));
item_tmp.nameid = nameid;
item_tmp.identify = 1;
- if (st->end > st->start + 5) //アイテムを指定したIDに渡す
- sd = map_id2sd(conv_num(st, &(st->stack->stack_data[st->start + 5])));
+ if (HARGO2(5)) //アイテムを指定したIDに渡す
+ sd = map_id2sd(conv_num(st, &AARGO2(5)));
if (sd == NULL) //アイテムを渡す相手がいなかったらお帰り
return;
PickupFail flag;
@@ -2154,19 +1946,19 @@ static
void builtin_makeitem(ScriptState *st)
{
int nameid, amount, flag = 0;
- int x, y, m;
+ int x, y;
struct item item_tmp;
dumb_ptr<map_session_data> sd;
struct script_data *data;
sd = script_rid2sd(st);
- data = &(st->stack->stack_data[st->start + 2]);
+ data = &AARGO2(2);
get_val(st, data);
- if (data->type == ScriptCode::STR || data->type == ScriptCode::CONSTSTR)
+ if (data->type == ByteCode::STR || data->type == ByteCode::CONSTSTR)
{
- const char *name = conv_str(st, data);
- struct item_data *item_data = itemdb_searchname(name);
+ dumb_string name = conv_str(st, data);
+ struct item_data *item_data = itemdb_searchname(name.c_str());
nameid = 512; //Apple Item ID
if (item_data)
nameid = item_data->nameid;
@@ -2174,15 +1966,17 @@ void builtin_makeitem(ScriptState *st)
else
nameid = conv_num(st, data);
- amount = conv_num(st, &(st->stack->stack_data[st->start + 3]));
- const char *mapname = conv_str(st, &(st->stack->stack_data[st->start + 4]));
- x = conv_num(st, &(st->stack->stack_data[st->start + 5]));
- y = conv_num(st, &(st->stack->stack_data[st->start + 6]));
+ amount = conv_num(st, &AARGO2(3));
+ dumb_string mapname = conv_str(st, &AARGO2(4));
+ x = conv_num(st, &AARGO2(5));
+ y = conv_num(st, &AARGO2(6));
- if (sd && strcmp(mapname, "this") == 0)
+ map_local *m;
+ using namespace operators;
+ if (sd && mapname == "this")
m = sd->bl_m;
else
- m = map_mapname2mapid(mapname);
+ m = map_mapname2mapid(mapname.c_str());
if (nameid > 0)
{
@@ -2211,12 +2005,12 @@ void builtin_delitem(ScriptState *st)
sd = script_rid2sd(st);
- data = &(st->stack->stack_data[st->start + 2]);
+ data = &AARGO2(2);
get_val(st, data);
- if (data->type == ScriptCode::STR || data->type == ScriptCode::CONSTSTR)
+ if (data->type == ByteCode::STR || data->type == ByteCode::CONSTSTR)
{
- const char *name = conv_str(st, data);
- struct item_data *item_data = itemdb_searchname(name);
+ dumb_string name = conv_str(st, data);
+ struct item_data *item_data = itemdb_searchname(name.c_str());
//nameid=512;
if (item_data)
nameid = item_data->nameid;
@@ -2224,7 +2018,7 @@ void builtin_delitem(ScriptState *st)
else
nameid = conv_num(st, data);
- amount = conv_num(st, &(st->stack->stack_data[st->start + 3]));
+ amount = conv_num(st, &AARGO2(3));
if (nameid < 500 || amount <= 0)
{
@@ -2272,19 +2066,19 @@ void builtin_readparam(ScriptState *st)
{
dumb_ptr<map_session_data> sd;
- SP type = SP(conv_num(st, &(st->stack->stack_data[st->start + 2])));
- if (st->end > st->start + 3)
- sd = map_nick2sd(conv_str(st, &(st->stack->stack_data[st->start + 3])));
+ SP type = SP(conv_num(st, &AARGO2(2)));
+ if (HARGO2(3))
+ sd = map_nick2sd(conv_str(st, &AARGO2(3)).c_str());
else
sd = script_rid2sd(st);
if (sd == NULL)
{
- push_val(st->stack, ScriptCode::INT, -1);
+ push_val(st->stack, ByteCode::INT, -1);
return;
}
- push_val(st->stack, ScriptCode::INT, pc_readparam(sd, type));
+ push_val(st->stack, ByteCode::INT, pc_readparam(sd, type));
}
@@ -2298,24 +2092,24 @@ void builtin_getcharid(ScriptState *st)
int num;
dumb_ptr<map_session_data> sd;
- num = conv_num(st, &(st->stack->stack_data[st->start + 2]));
- if (st->end > st->start + 3)
- sd = map_nick2sd(conv_str(st, &(st->stack->stack_data[st->start + 3])));
+ num = conv_num(st, &AARGO2(2));
+ if (HARGO2(3))
+ sd = map_nick2sd(conv_str(st, &AARGO2(3)).c_str());
else
sd = script_rid2sd(st);
if (sd == NULL)
{
- push_val(st->stack, ScriptCode::INT, -1);
+ push_val(st->stack, ByteCode::INT, -1);
return;
}
if (num == 0)
- push_val(st->stack, ScriptCode::INT, sd->status.char_id);
+ push_val(st->stack, ByteCode::INT, sd->status.char_id);
if (num == 1)
- push_val(st->stack, ScriptCode::INT, sd->status.party_id);
+ push_val(st->stack, ByteCode::INT, sd->status.party_id);
if (num == 2)
- push_val(st->stack, ScriptCode::INT, 0/*guild_id*/);
+ push_val(st->stack, ByteCode::INT, 0/*guild_id*/);
if (num == 3)
- push_val(st->stack, ScriptCode::INT, sd->status.account_id);
+ push_val(st->stack, ByteCode::INT, sd->status.account_id);
}
/*==========================================
@@ -2323,22 +2117,14 @@ void builtin_getcharid(ScriptState *st)
*------------------------------------------
*/
static
-char *builtin_getpartyname_sub(int party_id)
+dumb_string builtin_getpartyname_sub(int party_id)
{
- struct party *p;
-
- p = NULL;
- p = party_search(party_id);
+ struct party *p = party_search(party_id);
- if (p != NULL)
- {
- char *buf;
- buf = (char *) calloc(24, 1);
- strcpy(buf, p->name);
- return buf;
- }
+ if (p)
+ return dumb_string::copy(p->name);
- return 0;
+ return dumb_string();
}
/*==========================================
@@ -2352,27 +2138,24 @@ void builtin_strcharinfo(ScriptState *st)
int num;
sd = script_rid2sd(st);
- num = conv_num(st, &(st->stack->stack_data[st->start + 2]));
+ num = conv_num(st, &AARGO2(2));
if (num == 0)
{
- char *buf;
- buf = (char *) calloc(24, 1);
- strncpy(buf, sd->status.name, 23);
- push_str(st->stack, ScriptCode::STR, buf);
+ dumb_string buf = dumb_string::copy(sd->status.name);
+ push_str(st->stack, ByteCode::STR, buf);
}
if (num == 1)
{
- char *buf;
- buf = builtin_getpartyname_sub(sd->status.party_id);
- if (buf != 0)
- push_str(st->stack, ScriptCode::STR, buf);
+ dumb_string buf = builtin_getpartyname_sub(sd->status.party_id);
+ if (buf)
+ push_str(st->stack, ByteCode::STR, buf);
else
- push_str(st->stack, ScriptCode::CONSTSTR, "");
+ push_str(st->stack, ByteCode::CONSTSTR, dumb_string::fake(""));
}
if (num == 2)
{
// was: guild name
- push_str(st->stack, ScriptCode::CONSTSTR, "");
+ push_str(st->stack, ByteCode::CONSTSTR, dumb_string::fake(""));
}
}
@@ -2411,19 +2194,19 @@ void builtin_getequipid(ScriptState *st)
PRINTF("getequipid: sd == NULL\n");
return;
}
- num = conv_num(st, &(st->stack->stack_data[st->start + 2]));
+ num = conv_num(st, &AARGO2(2));
i = pc_checkequip(sd, equip[num - 1]);
if (i >= 0)
{
item = sd->inventory_data[i];
if (item)
- push_val(st->stack, ScriptCode::INT, item->nameid);
+ push_val(st->stack, ByteCode::INT, item->nameid);
else
- push_val(st->stack, ScriptCode::INT, 0);
+ push_val(st->stack, ByteCode::INT, 0);
}
else
{
- push_val(st->stack, ScriptCode::INT, -1);
+ push_val(st->stack, ByteCode::INT, -1);
}
}
@@ -2437,25 +2220,25 @@ void builtin_getequipname(ScriptState *st)
int i, num;
dumb_ptr<map_session_data> sd;
struct item_data *item;
- char *buf;
- buf = (char *) calloc(64, 1);
+ std::string buf;
+
sd = script_rid2sd(st);
- num = conv_num(st, &(st->stack->stack_data[st->start + 2]));
+ num = conv_num(st, &AARGO2(2));
i = pc_checkequip(sd, equip[num - 1]);
if (i >= 0)
{
item = sd->inventory_data[i];
if (item)
- sprintf(buf, "%s-[%s]", pos[num - 1], item->jname);
+ buf = STRPRINTF("%s-[%s]", pos[num - 1], item->jname);
else
- sprintf(buf, "%s-[%s]", pos[num - 1], pos[10]);
+ buf = STRPRINTF("%s-[%s]", pos[num - 1], pos[10]);
}
else
{
- sprintf(buf, "%s-[%s]", pos[num - 1], pos[10]);
+ buf = STRPRINTF("%s-[%s]", pos[num - 1], pos[10]);
}
- push_str(st->stack, ScriptCode::STR, buf);
+ push_str(st->stack, ByteCode::STR, dumb_string::copys(buf));
}
@@ -2466,8 +2249,8 @@ void builtin_getequipname(ScriptState *st)
static
void builtin_statusup2(ScriptState *st)
{
- SP type = SP(conv_num(st, &(st->stack->stack_data[st->start + 2])));
- int val = conv_num(st, &(st->stack->stack_data[st->start + 3]));
+ SP type = SP(conv_num(st, &AARGO2(2)));
+ int val = conv_num(st, &AARGO2(3));
dumb_ptr<map_session_data> sd = script_rid2sd(st);
pc_statusup2(sd, type, val);
@@ -2480,8 +2263,8 @@ void builtin_statusup2(ScriptState *st)
static
void builtin_bonus(ScriptState *st)
{
- SP type = SP(conv_num(st, &(st->stack->stack_data[st->start + 2])));
- int val = conv_num(st, &(st->stack->stack_data[st->start + 3]));
+ SP type = SP(conv_num(st, &AARGO2(2)));
+ int val = conv_num(st, &AARGO2(3));
dumb_ptr<map_session_data> sd = script_rid2sd(st);
pc_bonus(sd, type, val);
@@ -2494,9 +2277,9 @@ void builtin_bonus(ScriptState *st)
static
void builtin_bonus2(ScriptState *st)
{
- SP type = SP(conv_num(st, &(st->stack->stack_data[st->start + 2])));
- int type2 = conv_num(st, &(st->stack->stack_data[st->start + 3]));
- int val = conv_num(st, &(st->stack->stack_data[st->start + 4]));
+ SP type = SP(conv_num(st, &AARGO2(2)));
+ int type2 = conv_num(st, &AARGO2(3));
+ int val = conv_num(st, &AARGO2(4));
dumb_ptr<map_session_data> sd = script_rid2sd(st);
pc_bonus2(sd, type, type2, val);
@@ -2512,10 +2295,10 @@ void builtin_skill(ScriptState *st)
int level, flag = 1;
dumb_ptr<map_session_data> sd;
- SkillID id = SkillID(conv_num(st, &(st->stack->stack_data[st->start + 2])));
- level = conv_num(st, &(st->stack->stack_data[st->start + 3]));
- if (st->end > st->start + 4)
- flag = conv_num(st, &(st->stack->stack_data[st->start + 4]));
+ SkillID id = SkillID(conv_num(st, &AARGO2(2)));
+ level = conv_num(st, &AARGO2(3));
+ if (HARGO2(4))
+ flag = conv_num(st, &AARGO2(4));
sd = script_rid2sd(st);
pc_skill(sd, id, level, flag);
clif_skillinfoblock(sd);
@@ -2532,8 +2315,8 @@ void builtin_setskill(ScriptState *st)
int level;
dumb_ptr<map_session_data> sd;
- SkillID id = static_cast<SkillID>(conv_num(st, &(st->stack->stack_data[st->start + 2])));
- level = conv_num(st, &(st->stack->stack_data[st->start + 3]));
+ SkillID id = static_cast<SkillID>(conv_num(st, &AARGO2(2)));
+ level = conv_num(st, &AARGO2(3));
sd = script_rid2sd(st);
sd->status.skill[id].lv = level;
@@ -2547,8 +2330,8 @@ void builtin_setskill(ScriptState *st)
static
void builtin_getskilllv(ScriptState *st)
{
- SkillID id = SkillID(conv_num(st, &(st->stack->stack_data[st->start + 2])));
- push_val(st->stack, ScriptCode::INT, pc_checkskill(script_rid2sd(st), id));
+ SkillID id = SkillID(conv_num(st, &AARGO2(2)));
+ push_val(st->stack, ByteCode::INT, pc_checkskill(script_rid2sd(st), id));
}
/*==========================================
@@ -2558,7 +2341,7 @@ void builtin_getskilllv(ScriptState *st)
static
void builtin_getgmlevel(ScriptState *st)
{
- push_val(st->stack, ScriptCode::INT, pc_isGM(script_rid2sd(st)));
+ push_val(st->stack, ByteCode::INT, pc_isGM(script_rid2sd(st)));
}
/*==========================================
@@ -2568,7 +2351,7 @@ void builtin_getgmlevel(ScriptState *st)
static
void builtin_end(ScriptState *st)
{
- st->state = END;
+ st->state = ScriptEndState::END;
}
/*==========================================
@@ -2583,7 +2366,7 @@ void builtin_getopt2(ScriptState *st)
sd = script_rid2sd(st);
- push_val(st->stack, ScriptCode::INT, uint16_t(sd->opt2));
+ push_val(st->stack, ByteCode::INT, uint16_t(sd->opt2));
}
@@ -2597,7 +2380,7 @@ void builtin_setopt2(ScriptState *st)
{
dumb_ptr<map_session_data> sd;
- Opt2 new_opt2 = Opt2(conv_num(st, &(st->stack->stack_data[st->start + 2])));
+ Opt2 new_opt2 = Opt2(conv_num(st, &AARGO2(2)));
sd = script_rid2sd(st);
if (new_opt2 == sd->opt2)
return;
@@ -2616,10 +2399,10 @@ void builtin_savepoint(ScriptState *st)
{
int x, y;
- const char *str = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- x = conv_num(st, &(st->stack->stack_data[st->start + 3]));
- y = conv_num(st, &(st->stack->stack_data[st->start + 4]));
- pc_setsavepoint(script_rid2sd(st), str, x, y);
+ dumb_string str = conv_str(st, &AARGO2(2));
+ x = conv_num(st, &AARGO2(3));
+ y = conv_num(st, &AARGO2(4));
+ pc_setsavepoint(script_rid2sd(st), str.c_str(), x, y);
}
/*==========================================
@@ -2636,7 +2419,7 @@ static
void builtin_gettimetick(ScriptState *st) /* Asgard Version */
{
int type;
- type = conv_num(st, &(st->stack->stack_data[st->start + 2]));
+ type = conv_num(st, &AARGO2(2));
switch (type)
{
@@ -2644,18 +2427,18 @@ void builtin_gettimetick(ScriptState *st) /* Asgard Version */
case 1:
{
struct tm t = TimeT::now();
- push_val(st->stack, ScriptCode::INT,
+ push_val(st->stack, ByteCode::INT,
t.tm_hour * 3600 + t.tm_min * 60 + t.tm_sec);
break;
}
/* Seconds since Unix epoch. */
case 2:
- push_val(st->stack, ScriptCode::INT, static_cast<time_t>(TimeT::now()));
+ push_val(st->stack, ByteCode::INT, static_cast<time_t>(TimeT::now()));
break;
/* System tick(unsigned int, and yes, it will wrap). */
case 0:
default:
- push_val(st->stack, ScriptCode::INT, gettick().time_since_epoch().count());
+ push_val(st->stack, ByteCode::INT, gettick().time_since_epoch().count());
break;
}
}
@@ -2670,58 +2453,40 @@ void builtin_gettimetick(ScriptState *st) /* Asgard Version */
static
void builtin_gettime(ScriptState *st) /* Asgard Version */
{
- int type = conv_num(st, &(st->stack->stack_data[st->start + 2]));
+ int type = conv_num(st, &AARGO2(2));
struct tm t = TimeT::now();
switch (type)
{
case 1: //Sec(0~59)
- push_val(st->stack, ScriptCode::INT, t.tm_sec);
+ push_val(st->stack, ByteCode::INT, t.tm_sec);
break;
case 2: //Min(0~59)
- push_val(st->stack, ScriptCode::INT, t.tm_min);
+ push_val(st->stack, ByteCode::INT, t.tm_min);
break;
case 3: //Hour(0~23)
- push_val(st->stack, ScriptCode::INT, t.tm_hour);
+ push_val(st->stack, ByteCode::INT, t.tm_hour);
break;
case 4: //WeekDay(0~6)
- push_val(st->stack, ScriptCode::INT, t.tm_wday);
+ push_val(st->stack, ByteCode::INT, t.tm_wday);
break;
case 5: //MonthDay(01~31)
- push_val(st->stack, ScriptCode::INT, t.tm_mday);
+ push_val(st->stack, ByteCode::INT, t.tm_mday);
break;
case 6: //Month(01~12)
- push_val(st->stack, ScriptCode::INT, t.tm_mon + 1);
+ push_val(st->stack, ByteCode::INT, t.tm_mon + 1);
break;
case 7: //Year(20xx)
- push_val(st->stack, ScriptCode::INT, t.tm_year + 1900);
+ push_val(st->stack, ByteCode::INT, t.tm_year + 1900);
break;
default: //(format error)
- push_val(st->stack, ScriptCode::INT, -1);
+ push_val(st->stack, ByteCode::INT, -1);
break;
}
}
/*==========================================
- * GetTimeStr("TimeFMT", Length);
- *------------------------------------------
- */
-static
-void builtin_gettimestr(ScriptState *st)
-{
- struct tm now = TimeT::now();
-
- const char *fmtstr = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- int maxlen = conv_num(st, &(st->stack->stack_data[st->start + 3]));
-
- char *tmpstr = (char *) calloc(maxlen + 1, 1);
- strftime(tmpstr, maxlen, fmtstr, &now);
-
- push_str(st->stack, ScriptCode::STR, tmpstr);
-}
-
-/*==========================================
* カプラ倉庫を開く
*------------------------------------------
*/
@@ -2733,9 +2498,9 @@ void builtin_openstorage(ScriptState *st)
dumb_ptr<map_session_data> sd = script_rid2sd(st);
// if (sync) {
- st->state = STOP;
+ st->state = ScriptEndState::STOP;
sd->npc_flags.storage = 1;
-// } else st->state = END;
+// } else st->state = ScriptEndState::END;
storage_storageopen(sd);
}
@@ -2750,8 +2515,8 @@ void builtin_getexp(ScriptState *st)
dumb_ptr<map_session_data> sd = script_rid2sd(st);
int base = 0, job = 0;
- base = conv_num(st, &(st->stack->stack_data[st->start + 2]));
- job = conv_num(st, &(st->stack->stack_data[st->start + 3]));
+ base = conv_num(st, &AARGO2(2));
+ job = conv_num(st, &AARGO2(3));
if (base < 0 || job < 0)
return;
if (sd)
@@ -2769,16 +2534,16 @@ void builtin_monster(ScriptState *st)
int mob_class, amount, x, y;
const char *event = "";
- const char *mapname = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- x = conv_num(st, &(st->stack->stack_data[st->start + 3]));
- y = conv_num(st, &(st->stack->stack_data[st->start + 4]));
- const char *str = conv_str(st, &(st->stack->stack_data[st->start + 5]));
- mob_class = conv_num(st, &(st->stack->stack_data[st->start + 6]));
- amount = conv_num(st, &(st->stack->stack_data[st->start + 7]));
- if (st->end > st->start + 8)
- event = conv_str(st, &(st->stack->stack_data[st->start + 8]));
+ dumb_string mapname = conv_str(st, &AARGO2(2));
+ x = conv_num(st, &AARGO2(3));
+ y = conv_num(st, &AARGO2(4));
+ dumb_string str = conv_str(st, &AARGO2(5));
+ mob_class = conv_num(st, &AARGO2(6));
+ amount = conv_num(st, &AARGO2(7));
+ if (HARGO2(8))
+ event = conv_str(st, &AARGO2(8)).c_str();
- mob_once_spawn(map_id2sd(st->rid), mapname, x, y, str, mob_class, amount,
+ mob_once_spawn(map_id2sd(st->rid), mapname.c_str(), x, y, str.c_str(), mob_class, amount,
event);
}
@@ -2792,18 +2557,18 @@ void builtin_areamonster(ScriptState *st)
int mob_class, amount, x0, y0, x1, y1;
const char *event = "";
- const char *mapname = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- x0 = conv_num(st, &(st->stack->stack_data[st->start + 3]));
- y0 = conv_num(st, &(st->stack->stack_data[st->start + 4]));
- x1 = conv_num(st, &(st->stack->stack_data[st->start + 5]));
- y1 = conv_num(st, &(st->stack->stack_data[st->start + 6]));
- const char *str = conv_str(st, &(st->stack->stack_data[st->start + 7]));
- mob_class = conv_num(st, &(st->stack->stack_data[st->start + 8]));
- amount = conv_num(st, &(st->stack->stack_data[st->start + 9]));
- if (st->end > st->start + 10)
- event = conv_str(st, &(st->stack->stack_data[st->start + 10]));
-
- mob_once_spawn_area(map_id2sd(st->rid), mapname, x0, y0, x1, y1, str, mob_class,
+ dumb_string mapname = conv_str(st, &AARGO2(2));
+ x0 = conv_num(st, &AARGO2(3));
+ y0 = conv_num(st, &AARGO2(4));
+ x1 = conv_num(st, &AARGO2(5));
+ y1 = conv_num(st, &AARGO2(6));
+ dumb_string str = conv_str(st, &AARGO2(7));
+ mob_class = conv_num(st, &AARGO2(8));
+ amount = conv_num(st, &AARGO2(9));
+ if (HARGO2(10))
+ event = conv_str(st, &AARGO2(10)).c_str();
+
+ mob_once_spawn_area(map_id2sd(st->rid), mapname.c_str(), x0, y0, x1, y1, str.c_str(), mob_class,
amount, event);
}
@@ -2812,19 +2577,20 @@ void builtin_areamonster(ScriptState *st)
*------------------------------------------
*/
static
-void builtin_killmonster_sub(dumb_ptr<block_list> bl, const char *event, int allflag)
+void builtin_killmonster_sub(dumb_ptr<block_list> bl, dumb_string event, int allflag)
{
dumb_ptr<mob_data> md = bl->as_mob();
if (!allflag)
{
- if (strcmp(event, md->npc_event) == 0)
+ using namespace operators;
+ if (event == md->npc_event)
mob_delete(md);
return;
}
else if (allflag)
{
- if (md->spawndelay1 == static_cast<interval_t>(-1)
- && md->spawndelay2 == static_cast<interval_t>(-1))
+ if (md->spawn.delay1 == static_cast<interval_t>(-1)
+ && md->spawn.delay2 == static_cast<interval_t>(-1))
mob_delete(md);
return;
}
@@ -2833,16 +2599,21 @@ void builtin_killmonster_sub(dumb_ptr<block_list> bl, const char *event, int all
static
void builtin_killmonster(ScriptState *st)
{
- int m, allflag = 0;
- const char *mapname = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- const char *event = conv_str(st, &(st->stack->stack_data[st->start + 3]));
- if (strcmp(event, "All") == 0)
+ int allflag = 0;
+ dumb_string mapname = conv_str(st, &AARGO2(2));
+ dumb_string event = conv_str(st, &AARGO2(3));
+ using namespace operators;
+ if (event == "All")
allflag = 1;
- if ((m = map_mapname2mapid(mapname)) < 0)
+ map_local *m = map_mapname2mapid(mapname.c_str());
+ if (m == nullptr)
return;
map_foreachinarea(std::bind(builtin_killmonster_sub, ph::_1, event, allflag),
- m, 0, 0, map[m].xs, map[m].ys, BL::MOB);
+ m,
+ 0, 0,
+ m->xs, m->ys,
+ BL::MOB);
}
static
@@ -2854,13 +2625,16 @@ void builtin_killmonsterall_sub(dumb_ptr<block_list> bl)
static
void builtin_killmonsterall(ScriptState *st)
{
- int m;
- const char *mapname = conv_str(st, &(st->stack->stack_data[st->start + 2]));
+ dumb_string mapname = conv_str(st, &AARGO2(2));
- if ((m = map_mapname2mapid(mapname)) < 0)
+ map_local *m = map_mapname2mapid(mapname.c_str());
+ if (m == nullptr)
return;
map_foreachinarea(builtin_killmonsterall_sub,
- m, 0, 0, map[m].xs, map[m].ys, BL::MOB);
+ m,
+ 0, 0,
+ m->xs, m->ys,
+ BL::MOB);
}
/*==========================================
@@ -2870,8 +2644,8 @@ void builtin_killmonsterall(ScriptState *st)
static
void builtin_donpcevent(ScriptState *st)
{
- const char *event = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- npc_event_do(event);
+ dumb_string event = conv_str(st, &AARGO2(2));
+ npc_event_do(event.c_str());
}
/*==========================================
@@ -2881,9 +2655,9 @@ void builtin_donpcevent(ScriptState *st)
static
void builtin_addtimer(ScriptState *st)
{
- interval_t tick = static_cast<interval_t>(conv_num(st, &(st->stack->stack_data[st->start + 2])));
- const char *event = conv_str(st, &(st->stack->stack_data[st->start + 3]));
- pc_addeventtimer(script_rid2sd(st), tick, event);
+ interval_t tick = static_cast<interval_t>(conv_num(st, &AARGO2(2)));
+ dumb_string event = conv_str(st, &AARGO2(3));
+ pc_addeventtimer(script_rid2sd(st), tick, event.c_str());
}
/*==========================================
@@ -2894,8 +2668,8 @@ static
void builtin_initnpctimer(ScriptState *st)
{
dumb_ptr<npc_data> nd_;
- if (st->end > st->start + 2)
- nd_ = npc_name2id(conv_str(st, &(st->stack->stack_data[st->start + 2])));
+ if (HARGO2(2))
+ nd_ = npc_name2id(conv_str(st, &AARGO2(2)).c_str());
else
nd_ = map_id_as_npc(st->oid);
assert (nd_ && nd_->npc_subtype == NpcSubtype::SCRIPT);
@@ -2913,8 +2687,8 @@ static
void builtin_startnpctimer(ScriptState *st)
{
dumb_ptr<npc_data> nd_;
- if (st->end > st->start + 2)
- nd_ = npc_name2id(conv_str(st, &(st->stack->stack_data[st->start + 2])));
+ if (HARGO2(2))
+ nd_ = npc_name2id(conv_str(st, &AARGO2(2)).c_str());
else
nd_ = map_id_as_npc(st->oid);
assert (nd_ && nd_->npc_subtype == NpcSubtype::SCRIPT);
@@ -2931,8 +2705,8 @@ static
void builtin_stopnpctimer(ScriptState *st)
{
dumb_ptr<npc_data> nd_;
- if (st->end > st->start + 2)
- nd_ = npc_name2id(conv_str(st, &(st->stack->stack_data[st->start + 2])));
+ if (HARGO2(2))
+ nd_ = npc_name2id(conv_str(st, &AARGO2(2)).c_str());
else
nd_ = map_id_as_npc(st->oid);
assert (nd_ && nd_->npc_subtype == NpcSubtype::SCRIPT);
@@ -2949,10 +2723,10 @@ static
void builtin_getnpctimer(ScriptState *st)
{
dumb_ptr<npc_data> nd_;
- int type = conv_num(st, &(st->stack->stack_data[st->start + 2]));
+ int type = conv_num(st, &AARGO2(2));
int val = 0;
- if (st->end > st->start + 3)
- nd_ = npc_name2id(conv_str(st, &(st->stack->stack_data[st->start + 3])));
+ if (HARGO2(3))
+ nd_ = npc_name2id(conv_str(st, &AARGO2(3)).c_str());
else
nd_ = map_id_as_npc(st->oid);
assert (nd_ && nd_->npc_subtype == NpcSubtype::SCRIPT);
@@ -2961,16 +2735,16 @@ void builtin_getnpctimer(ScriptState *st)
switch (type)
{
case 0:
- val = (int) npc_gettimerevent_tick(nd).count();
+ val = npc_gettimerevent_tick(nd).count();
break;
case 1:
- val = (nd->scr.nexttimer >= 0);
+ val = nd->scr.nexttimer != nd->scr.timer_eventv.end();
break;
case 2:
- val = nd->scr.timeramount;
+ val = nd->scr.timer_eventv.size();
break;
}
- push_val(st->stack, ScriptCode::INT, val);
+ push_val(st->stack, ByteCode::INT, val);
}
/*==========================================
@@ -2981,9 +2755,9 @@ static
void builtin_setnpctimer(ScriptState *st)
{
dumb_ptr<npc_data> nd_;
- interval_t tick = static_cast<interval_t>(conv_num(st, &(st->stack->stack_data[st->start + 2])));
- if (st->end > st->start + 3)
- nd_ = npc_name2id(conv_str(st, &(st->stack->stack_data[st->start + 3])));
+ interval_t tick = static_cast<interval_t>(conv_num(st, &AARGO2(2)));
+ if (HARGO2(3))
+ nd_ = npc_name2id(conv_str(st, &AARGO2(3)).c_str());
else
nd_ = map_id_as_npc(st->oid);
assert (nd_ && nd_->npc_subtype == NpcSubtype::SCRIPT);
@@ -3000,13 +2774,16 @@ static
void builtin_announce(ScriptState *st)
{
int flag;
- const char *str = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- flag = conv_num(st, &(st->stack->stack_data[st->start + 3]));
+ dumb_string str = conv_str(st, &AARGO2(2));
+ flag = conv_num(st, &AARGO2(3));
if (flag & 0x0f)
{
- dumb_ptr<block_list> bl = (flag & 0x08) ? map_id2bl(st->oid) :
- (dumb_ptr<block_list>) script_rid2sd(st);
+ dumb_ptr<block_list> bl;
+ if (flag & 0x08)
+ bl = map_id2bl(st->oid);
+ else
+ bl = script_rid2sd(st);
clif_GMmessage(bl, str, flag);
}
else
@@ -3018,24 +2795,28 @@ void builtin_announce(ScriptState *st)
*------------------------------------------
*/
static
-void builtin_mapannounce_sub(dumb_ptr<block_list> bl, const char *str, int flag)
+void builtin_mapannounce_sub(dumb_ptr<block_list> bl, dumb_string str, int flag)
{
- clif_GMmessage(bl, str, flag | 3);
+ clif_GMmessage(bl, str.c_str(), flag | 3);
}
static
void builtin_mapannounce(ScriptState *st)
{
- int flag, m;
+ int flag;
- const char *mapname = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- const char *str = conv_str(st, &(st->stack->stack_data[st->start + 3]));
- flag = conv_num(st, &(st->stack->stack_data[st->start + 4]));
+ dumb_string mapname = conv_str(st, &AARGO2(2));
+ dumb_string str = conv_str(st, &AARGO2(3));
+ flag = conv_num(st, &AARGO2(4));
- if ((m = map_mapname2mapid(mapname)) < 0)
+ map_local *m = map_mapname2mapid(mapname.c_str());
+ if (m == nullptr)
return;
map_foreachinarea(std::bind(builtin_mapannounce_sub, ph::_1, str, flag & 0x10),
- m, 0, 0, map[m].xs, map[m].ys, BL::PC);
+ m,
+ 0, 0,
+ m->xs, m->ys,
+ BL::PC);
}
/*==========================================
@@ -3045,19 +2826,19 @@ void builtin_mapannounce(ScriptState *st)
static
void builtin_getusers(ScriptState *st)
{
- int flag = conv_num(st, &(st->stack->stack_data[st->start + 2]));
+ int flag = conv_num(st, &AARGO2(2));
dumb_ptr<block_list> bl = map_id2bl((flag & 0x08) ? st->oid : st->rid);
int val = 0;
switch (flag & 0x07)
{
case 0:
- val = map[bl->bl_m].users;
+ val = bl->bl_m->users;
break;
case 1:
val = map_getusers();
break;
}
- push_val(st->stack, ScriptCode::INT, val);
+ push_val(st->stack, ByteCode::INT, val);
}
/*==========================================
@@ -3067,14 +2848,14 @@ void builtin_getusers(ScriptState *st)
static
void builtin_getmapusers(ScriptState *st)
{
- int m;
- const char *str = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- if ((m = map_mapname2mapid(str)) < 0)
+ dumb_string str = conv_str(st, &AARGO2(2));
+ map_local *m = map_mapname2mapid(str.c_str());
+ if (m == nullptr)
{
- push_val(st->stack, ScriptCode::INT, -1);
+ push_val(st->stack, ByteCode::INT, -1);
return;
}
- push_val(st->stack, ScriptCode::INT, map[m].users);
+ push_val(st->stack, ByteCode::INT, m->users);
}
/*==========================================
@@ -3097,26 +2878,30 @@ void builtin_getareausers_living_sub(dumb_ptr<block_list> bl, int *users)
static
void builtin_getareausers(ScriptState *st)
{
- int m, x0, y0, x1, y1, users = 0;
- const char *str = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- x0 = conv_num(st, &(st->stack->stack_data[st->start + 3]));
- y0 = conv_num(st, &(st->stack->stack_data[st->start + 4]));
- x1 = conv_num(st, &(st->stack->stack_data[st->start + 5]));
- y1 = conv_num(st, &(st->stack->stack_data[st->start + 6]));
+ int x0, y0, x1, y1, users = 0;
+ dumb_string str = conv_str(st, &AARGO2(2));
+ x0 = conv_num(st, &AARGO2(3));
+ y0 = conv_num(st, &AARGO2(4));
+ x1 = conv_num(st, &AARGO2(5));
+ y1 = conv_num(st, &AARGO2(6));
int living = 0;
- if (st->end > st->start + 7)
+ if (HARGO2(7))
{
- living = conv_num(st, &(st->stack->stack_data[st->start + 7]));
+ living = conv_num(st, &AARGO2(7));
}
- if ((m = map_mapname2mapid(str)) < 0)
+ map_local *m = map_mapname2mapid(str.c_str());
+ if (m == nullptr)
{
- push_val(st->stack, ScriptCode::INT, -1);
+ push_val(st->stack, ByteCode::INT, -1);
return;
}
map_foreachinarea(std::bind(living ? builtin_getareausers_living_sub: builtin_getareausers_sub, ph::_1, &users),
- m, x0, y0, x1, y1, BL::PC);
- push_val(st->stack, ScriptCode::INT, users);
+ m,
+ x0, y0,
+ x1, y1,
+ BL::PC);
+ push_val(st->stack, ByteCode::INT, users);
}
/*==========================================
@@ -3149,21 +2934,21 @@ void builtin_getareadropitem_sub_anddelete(dumb_ptr<block_list> bl, int item, in
static
void builtin_getareadropitem(ScriptState *st)
{
- int m, x0, y0, x1, y1, item, amount = 0, delitems = 0;
+ int x0, y0, x1, y1, item, amount = 0, delitems = 0;
struct script_data *data;
- const char *str = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- x0 = conv_num(st, &(st->stack->stack_data[st->start + 3]));
- y0 = conv_num(st, &(st->stack->stack_data[st->start + 4]));
- x1 = conv_num(st, &(st->stack->stack_data[st->start + 5]));
- y1 = conv_num(st, &(st->stack->stack_data[st->start + 6]));
+ dumb_string str = conv_str(st, &AARGO2(2));
+ x0 = conv_num(st, &AARGO2(3));
+ y0 = conv_num(st, &AARGO2(4));
+ x1 = conv_num(st, &AARGO2(5));
+ y1 = conv_num(st, &AARGO2(6));
- data = &(st->stack->stack_data[st->start + 7]);
+ data = &AARGO2(7);
get_val(st, data);
- if (data->type == ScriptCode::STR || data->type == ScriptCode::CONSTSTR)
+ if (data->type == ByteCode::STR || data->type == ByteCode::CONSTSTR)
{
- const char *name = conv_str(st, data);
- struct item_data *item_data = itemdb_searchname(name);
+ dumb_string name = conv_str(st, data);
+ struct item_data *item_data = itemdb_searchname(name.c_str());
item = 512;
if (item_data)
item = item_data->nameid;
@@ -3171,22 +2956,29 @@ void builtin_getareadropitem(ScriptState *st)
else
item = conv_num(st, data);
- if (st->end > st->start + 8)
- delitems = conv_num(st, &(st->stack->stack_data[st->start + 8]));
+ if (HARGO2(8))
+ delitems = conv_num(st, &AARGO2(8));
- if ((m = map_mapname2mapid(str)) < 0)
+ map_local *m = map_mapname2mapid(str.c_str());
+ if (m == nullptr)
{
- push_val(st->stack, ScriptCode::INT, -1);
+ push_val(st->stack, ByteCode::INT, -1);
return;
}
if (delitems)
map_foreachinarea(std::bind(builtin_getareadropitem_sub_anddelete, ph::_1, item, &amount),
- m, x0, y0, x1, y1, BL::ITEM);
+ m,
+ x0, y0,
+ x1, y1,
+ BL::ITEM);
else
map_foreachinarea(std::bind(builtin_getareadropitem_sub, ph::_1, item, &amount),
- m, x0, y0, x1, y1, BL::ITEM);
+ m,
+ x0, y0,
+ x1, y1,
+ BL::ITEM);
- push_val(st->stack, ScriptCode::INT, amount);
+ push_val(st->stack, ByteCode::INT, amount);
}
/*==========================================
@@ -3196,8 +2988,8 @@ void builtin_getareadropitem(ScriptState *st)
static
void builtin_enablenpc(ScriptState *st)
{
- const char *str = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- npc_enable(str, 1);
+ dumb_string str = conv_str(st, &AARGO2(2));
+ npc_enable(str.c_str(), 1);
}
/*==========================================
@@ -3207,8 +2999,8 @@ void builtin_enablenpc(ScriptState *st)
static
void builtin_disablenpc(ScriptState *st)
{
- const char *str = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- npc_enable(str, 0);
+ dumb_string str = conv_str(st, &AARGO2(2));
+ npc_enable(str.c_str(), 0);
}
/*==========================================
@@ -3220,8 +3012,8 @@ void builtin_sc_start(ScriptState *st)
{
dumb_ptr<block_list> bl;
int val1;
- StatusChange type = static_cast<StatusChange>(conv_num(st, &(st->stack->stack_data[st->start + 2])));
- interval_t tick = static_cast<interval_t>(conv_num(st, &(st->stack->stack_data[st->start + 3])));
+ 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))
// work around old behaviour of:
// speed potion
@@ -3231,9 +3023,9 @@ void builtin_sc_start(ScriptState *st)
// which used to use seconds
// all others used milliseconds
tick *= 1000;
- val1 = conv_num(st, &(st->stack->stack_data[st->start + 4]));
- if (st->end > st->start + 5) //指定したキャラを状態異常にする
- bl = map_id2bl(conv_num(st, &(st->stack->stack_data[st->start + 5])));
+ val1 = conv_num(st, &AARGO2(4));
+ if (HARGO2(5)) //指定したキャラを状態異常にする
+ bl = map_id2bl(conv_num(st, &AARGO2(5)));
else
bl = map_id2bl(st->rid);
skill_status_change_start(bl, type, val1, tick);
@@ -3247,7 +3039,7 @@ static
void builtin_sc_end(ScriptState *st)
{
dumb_ptr<block_list> bl;
- StatusChange type = StatusChange(conv_num(st, &(st->stack->stack_data[st->start + 2])));
+ StatusChange type = StatusChange(conv_num(st, &AARGO2(2)));
bl = map_id2bl(st->rid);
skill_status_change_end(bl, type, nullptr);
}
@@ -3256,10 +3048,10 @@ static
void builtin_sc_check(ScriptState *st)
{
dumb_ptr<block_list> bl;
- StatusChange type = StatusChange(conv_num(st, &(st->stack->stack_data[st->start + 2])));
+ StatusChange type = StatusChange(conv_num(st, &AARGO2(2)));
bl = map_id2bl(st->rid);
- push_val(st->stack, ScriptCode::INT, skill_status_change_active(bl, type));
+ push_val(st->stack, ByteCode::INT, skill_status_change_active(bl, type));
}
@@ -3270,9 +3062,9 @@ void builtin_sc_check(ScriptState *st)
static
void builtin_debugmes(ScriptState *st)
{
- conv_str(st, &(st->stack->stack_data[st->start + 2]));
- PRINTF("script debug : %d %d : %s\n", st->rid, st->oid,
- st->stack->stack_data[st->start + 2].u.str);
+ dumb_string mes = conv_str(st, &AARGO2(2));
+ PRINTF("script debug : %d %d : %s\n",
+ st->rid, st->oid, mes);
}
/*==========================================
@@ -3318,8 +3110,8 @@ void builtin_changesex(ScriptState *st)
static
void builtin_attachrid(ScriptState *st)
{
- st->rid = conv_num(st, &(st->stack->stack_data[st->start + 2]));
- push_val(st->stack, ScriptCode::INT, (map_id2sd(st->rid) != NULL));
+ st->rid = conv_num(st, &AARGO2(2));
+ push_val(st->stack, ByteCode::INT, (map_id2sd(st->rid) != NULL));
}
/*==========================================
@@ -3339,9 +3131,9 @@ void builtin_detachrid(ScriptState *st)
static
void builtin_isloggedin(ScriptState *st)
{
- push_val(st->stack, ScriptCode::INT,
+ push_val(st->stack, ByteCode::INT,
map_id2sd(conv_num(st,
- &(st->stack->stack_data[st->start + 2]))) != NULL);
+ &AARGO2(2))) != NULL);
}
/*==========================================
@@ -3376,59 +3168,57 @@ enum
static
void builtin_setmapflag(ScriptState *st)
{
- int m, i;
-
- const char *str = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- i = conv_num(st, &(st->stack->stack_data[st->start + 3]));
- m = map_mapname2mapid(str);
- if (m >= 0)
+ dumb_string str = conv_str(st, &AARGO2(2));
+ int i = conv_num(st, &AARGO2(3));
+ map_local *m = map_mapname2mapid(str.c_str());
+ if (m != nullptr)
{
switch (i)
{
case MF_NOMEMO:
- map[m].flag.nomemo = 1;
+ m->flag.nomemo = 1;
break;
case MF_NOTELEPORT:
- map[m].flag.noteleport = 1;
+ m->flag.noteleport = 1;
break;
case MF_NOBRANCH:
- map[m].flag.nobranch = 1;
+ m->flag.nobranch = 1;
break;
case MF_NOPENALTY:
- map[m].flag.nopenalty = 1;
+ m->flag.nopenalty = 1;
break;
case MF_PVP_NOPARTY:
- map[m].flag.pvp_noparty = 1;
+ m->flag.pvp_noparty = 1;
break;
case MF_NOZENYPENALTY:
- map[m].flag.nozenypenalty = 1;
+ m->flag.nozenypenalty = 1;
break;
case MF_NOTRADE:
- map[m].flag.notrade = 1;
+ m->flag.notrade = 1;
break;
case MF_NOWARP:
- map[m].flag.nowarp = 1;
+ m->flag.nowarp = 1;
break;
case MF_NOPVP:
- map[m].flag.nopvp = 1;
+ m->flag.nopvp = 1;
break;
case MF_NOICEWALL: // [Valaris]
- map[m].flag.noicewall = 1;
+ m->flag.noicewall = 1;
break;
case MF_SNOW: // [Valaris]
- map[m].flag.snow = 1;
+ m->flag.snow = 1;
break;
case MF_FOG: // [Valaris]
- map[m].flag.fog = 1;
+ m->flag.fog = 1;
break;
case MF_SAKURA: // [Valaris]
- map[m].flag.sakura = 1;
+ m->flag.sakura = 1;
break;
case MF_LEAVES: // [Valaris]
- map[m].flag.leaves = 1;
+ m->flag.leaves = 1;
break;
case MF_RAIN: // [Valaris]
- map[m].flag.rain = 1;
+ m->flag.rain = 1;
break;
}
}
@@ -3438,137 +3228,133 @@ void builtin_setmapflag(ScriptState *st)
static
void builtin_removemapflag(ScriptState *st)
{
- int m, i;
-
- const char *str = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- i = conv_num(st, &(st->stack->stack_data[st->start + 3]));
- m = map_mapname2mapid(str);
- if (m >= 0)
+ dumb_string str = conv_str(st, &AARGO2(2));
+ int i = conv_num(st, &AARGO2(3));
+ map_local *m = map_mapname2mapid(str.c_str());
+ if (m != nullptr)
{
switch (i)
{
case MF_NOMEMO:
- map[m].flag.nomemo = 0;
+ m->flag.nomemo = 0;
break;
case MF_NOTELEPORT:
- map[m].flag.noteleport = 0;
+ m->flag.noteleport = 0;
break;
case MF_NOSAVE:
- map[m].flag.nosave = 0;
+ m->flag.nosave = 0;
break;
case MF_NOBRANCH:
- map[m].flag.nobranch = 0;
+ m->flag.nobranch = 0;
break;
case MF_NOPENALTY:
- map[m].flag.nopenalty = 0;
+ m->flag.nopenalty = 0;
break;
case MF_PVP_NOPARTY:
- map[m].flag.pvp_noparty = 0;
+ m->flag.pvp_noparty = 0;
break;
case MF_NOZENYPENALTY:
- map[m].flag.nozenypenalty = 0;
+ m->flag.nozenypenalty = 0;
break;
case MF_NOWARP:
- map[m].flag.nowarp = 0;
+ m->flag.nowarp = 0;
break;
case MF_NOPVP:
- map[m].flag.nopvp = 0;
+ m->flag.nopvp = 0;
break;
case MF_NOICEWALL: // [Valaris]
- map[m].flag.noicewall = 0;
+ m->flag.noicewall = 0;
break;
case MF_SNOW: // [Valaris]
- map[m].flag.snow = 0;
+ m->flag.snow = 0;
break;
case MF_FOG: // [Valaris]
- map[m].flag.fog = 0;
+ m->flag.fog = 0;
break;
case MF_SAKURA: // [Valaris]
- map[m].flag.sakura = 0;
+ m->flag.sakura = 0;
break;
case MF_LEAVES: // [Valaris]
- map[m].flag.leaves = 0;
+ m->flag.leaves = 0;
break;
case MF_RAIN: // [Valaris]
- map[m].flag.rain = 0;
+ m->flag.rain = 0;
break;
-
}
}
-
}
static
void builtin_getmapflag(ScriptState *st)
{
- int m, i, r = -1;
+ int r = -1;
- const char *str = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- i = conv_num(st, &(st->stack->stack_data[st->start + 3]));
- m = map_mapname2mapid(str);
- if (m >= 0)
+ dumb_string str = conv_str(st, &AARGO2(2));
+ int i = conv_num(st, &AARGO2(3));
+ map_local *m = map_mapname2mapid(str.c_str());
+ if (m != nullptr)
{
switch (i)
{
case MF_NOMEMO:
- r = map[m].flag.nomemo;
+ r = m->flag.nomemo;
break;
case MF_NOTELEPORT:
- r = map[m].flag.noteleport;
+ r = m->flag.noteleport;
break;
case MF_NOSAVE:
- r = map[m].flag.nosave;
+ r = m->flag.nosave;
break;
case MF_NOBRANCH:
- r = map[m].flag.nobranch;
+ r = m->flag.nobranch;
break;
case MF_NOPENALTY:
- r = map[m].flag.nopenalty;
+ r = m->flag.nopenalty;
break;
case MF_PVP_NOPARTY:
- r = map[m].flag.pvp_noparty;
+ r = m->flag.pvp_noparty;
break;
case MF_NOZENYPENALTY:
- r = map[m].flag.nozenypenalty;
+ r = m->flag.nozenypenalty;
break;
case MF_NOWARP:
- r = map[m].flag.nowarp;
+ r = m->flag.nowarp;
break;
case MF_NOPVP:
- r = map[m].flag.nopvp;
+ r = m->flag.nopvp;
break;
case MF_NOICEWALL: // [Valaris]
- r = map[m].flag.noicewall;
+ r = m->flag.noicewall;
break;
case MF_SNOW: // [Valaris]
- r = map[m].flag.snow;
+ r = m->flag.snow;
break;
case MF_FOG: // [Valaris]
- r = map[m].flag.fog;
+ r = m->flag.fog;
break;
case MF_SAKURA: // [Valaris]
- r = map[m].flag.sakura;
+ r = m->flag.sakura;
break;
case MF_LEAVES: // [Valaris]
- r = map[m].flag.leaves;
+ r = m->flag.leaves;
break;
case MF_RAIN: // [Valaris]
- r = map[m].flag.rain;
+ r = m->flag.rain;
break;
}
}
- push_val(st->stack, ScriptCode::INT, r);
+ push_val(st->stack, ByteCode::INT, r);
}
static
void builtin_pvpon(ScriptState *st)
{
- const char *str = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- int m = map_mapname2mapid(str);
- if (m >= 0 && !map[m].flag.pvp && !map[m].flag.nopvp)
+ dumb_string str = conv_str(st, &AARGO2(2));
+ map_local *m = map_mapname2mapid(str.c_str());
+ if (m != nullptr && !m->flag.pvp && !m->flag.nopvp)
{
- map[m].flag.pvp = 1;
+ m->flag.pvp = 1;
if (battle_config.pk_mode) // disable ranking functions if pk_mode is on [Valaris]
return;
@@ -3598,11 +3384,11 @@ void builtin_pvpon(ScriptState *st)
static
void builtin_pvpoff(ScriptState *st)
{
- const char *str = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- int m = map_mapname2mapid(str);
- if (m >= 0 && map[m].flag.pvp && map[m].flag.nopvp)
+ dumb_string str = conv_str(st, &AARGO2(2));
+ map_local *m = map_mapname2mapid(str.c_str());
+ if (m != nullptr && m->flag.pvp && m->flag.nopvp)
{
- map[m].flag.pvp = 0;
+ m->flag.pvp = 0;
if (battle_config.pk_mode) // disable ranking options if pk_mode is on [Valaris]
return;
@@ -3633,7 +3419,7 @@ static
void builtin_emotion(ScriptState *st)
{
int type;
- type = conv_num(st, &(st->stack->stack_data[st->start + 2]));
+ type = conv_num(st, &AARGO2(2));
if (type < 0 || type > 100)
return;
clif_emotion(map_id2bl(st->oid), type);
@@ -3642,73 +3428,82 @@ void builtin_emotion(ScriptState *st)
static
void builtin_mapwarp(ScriptState *st) // Added by RoVeRT
{
- int x, y, m;
+ int x, y;
int x0, y0, x1, y1;
- const char *mapname = conv_str(st, &(st->stack->stack_data[st->start + 2]));
+ dumb_string mapname = conv_str(st, &AARGO2(2));
x0 = 0;
y0 = 0;
- x1 = map[map_mapname2mapid(mapname)].xs;
- y1 = map[map_mapname2mapid(mapname)].ys;
- const char *str = conv_str(st, &(st->stack->stack_data[st->start + 3]));
- x = conv_num(st, &(st->stack->stack_data[st->start + 4]));
- y = conv_num(st, &(st->stack->stack_data[st->start + 5]));
-
- if ((m = map_mapname2mapid(mapname)) < 0)
+ map_local *m = map_mapname2mapid(mapname.c_str());
+ x1 = m->xs;
+ y1 = m->ys;
+ dumb_string str = conv_str(st, &AARGO2(3));
+ x = conv_num(st, &AARGO2(4));
+ y = conv_num(st, &AARGO2(5));
+
+ if (m == nullptr)
return;
map_foreachinarea(std::bind(builtin_areawarp_sub, ph::_1, str, x, y),
- m, x0, y0, x1, y1, BL::PC);
+ m,
+ x0, y0,
+ x1, y1,
+ BL::PC);
}
static
void builtin_cmdothernpc(ScriptState *st) // Added by RoVeRT
{
- const char *npc = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- const char *command = conv_str(st, &(st->stack->stack_data[st->start + 3]));
+ dumb_string npc = conv_str(st, &AARGO2(2));
+ dumb_string command = conv_str(st, &AARGO2(3));
- npc_command(map_id2sd(st->rid), npc, command);
+ npc_command(map_id2sd(st->rid), npc.c_str(), command.c_str());
}
static
-void builtin_mobcount_sub(dumb_ptr<block_list> bl, const char *event, int *c)
+void builtin_mobcount_sub(dumb_ptr<block_list> bl, dumb_string event, int *c)
{
- if (strcmp(event, bl->as_mob()->npc_event) == 0)
+ using namespace operators;
+ if (event == bl->as_mob()->npc_event)
(*c)++;
}
static
void builtin_mobcount(ScriptState *st) // Added by RoVeRT
{
- int m, c = 0;
- const char *mapname = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- const char *event = conv_str(st, &(st->stack->stack_data[st->start + 3]));
+ int c = 0;
+ dumb_string mapname = conv_str(st, &AARGO2(2));
+ dumb_string event = conv_str(st, &AARGO2(3));
- if ((m = map_mapname2mapid(mapname)) < 0)
+ map_local *m = map_mapname2mapid(mapname.c_str());
+ if (m == nullptr)
{
- push_val(st->stack, ScriptCode::INT, -1);
+ push_val(st->stack, ByteCode::INT, -1);
return;
}
map_foreachinarea(std::bind(builtin_mobcount_sub, ph::_1, event, &c),
- m, 0, 0, map[m].xs, map[m].ys, BL::MOB);
+ m,
+ 0, 0,
+ m->xs, m->ys,
+ BL::MOB);
- push_val(st->stack, ScriptCode::INT, (c - 1));
+ push_val(st->stack, ByteCode::INT, (c - 1));
}
static
void builtin_marriage(ScriptState *st)
{
- const char *partner = conv_str(st, &(st->stack->stack_data[st->start + 2]));
+ dumb_string partner = conv_str(st, &AARGO2(2));
dumb_ptr<map_session_data> sd = script_rid2sd(st);
- dumb_ptr<map_session_data> p_sd = map_nick2sd(partner);
+ dumb_ptr<map_session_data> p_sd = map_nick2sd(partner.c_str());
if (sd == NULL || p_sd == NULL || pc_marriage(sd, p_sd) < 0)
{
- push_val(st->stack, ScriptCode::INT, 0);
+ push_val(st->stack, ByteCode::INT, 0);
return;
}
- push_val(st->stack, ScriptCode::INT, 1);
+ push_val(st->stack, ByteCode::INT, 1);
}
static
@@ -3716,17 +3511,17 @@ void builtin_divorce(ScriptState *st)
{
dumb_ptr<map_session_data> sd = script_rid2sd(st);
- st->state = STOP; // rely on pc_divorce to restart
+ st->state = ScriptEndState::STOP; // rely on pc_divorce to restart
sd->npc_flags.divorce = 1;
if (sd == NULL || pc_divorce(sd) < 0)
{
- push_val(st->stack, ScriptCode::INT, 0);
+ push_val(st->stack, ByteCode::INT, 0);
return;
}
- push_val(st->stack, ScriptCode::INT, 1);
+ push_val(st->stack, ByteCode::INT, 1);
}
/*==========================================
@@ -3737,15 +3532,14 @@ static
void builtin_getitemname(ScriptState *st)
{
struct item_data *i_data;
- char *item_name;
struct script_data *data;
- data = &(st->stack->stack_data[st->start + 2]);
+ data = &AARGO2(2);
get_val(st, data);
- if (data->type == ScriptCode::STR || data->type == ScriptCode::CONSTSTR)
+ if (data->type == ByteCode::STR || data->type == ByteCode::CONSTSTR)
{
- const char *name = conv_str(st, data);
- i_data = itemdb_searchname(name);
+ dumb_string name = conv_str(st, data);
+ i_data = itemdb_searchname(name.c_str());
}
else
{
@@ -3753,26 +3547,25 @@ void builtin_getitemname(ScriptState *st)
i_data = itemdb_search(item_id);
}
- item_name = (char *) calloc(24, 1);
+ dumb_string item_name;
if (i_data)
- strncpy(item_name, i_data->jname, 23);
+ item_name = dumb_string::copy(i_data->jname);
else
- strncpy(item_name, "Unknown Item", 23);
-
- push_str(st->stack, ScriptCode::STR, item_name);
+ item_name = dumb_string::copy("Unknown Item");
+ push_str(st->stack, ByteCode::STR, item_name);
}
static
void builtin_getspellinvocation(ScriptState *st)
{
- const char *name = conv_str(st, &(st->stack->stack_data[st->start + 2]));
+ dumb_string name = conv_str(st, &AARGO2(2));
- const char *invocation = magic_find_invocation(name);
+ const char *invocation = magic_find_invocation(name.str());
if (!invocation)
invocation = "...";
- push_str(st->stack, ScriptCode::STR, strdup(invocation));
+ push_str(st->stack, ByteCode::STR, dumb_string::copy(invocation));
}
static
@@ -3780,7 +3573,7 @@ void builtin_getpartnerid2(ScriptState *st)
{
dumb_ptr<map_session_data> sd = script_rid2sd(st);
- push_val(st->stack, ScriptCode::INT, sd->status.partner_id);
+ push_val(st->stack, ByteCode::INT, sd->status.partner_id);
}
/*==========================================
@@ -3799,30 +3592,30 @@ void builtin_getinventorylist(ScriptState *st)
if (sd->status.inventory[i].nameid > 0
&& sd->status.inventory[i].amount > 0)
{
- pc_setreg(sd, add_str("@inventorylist_id") + (j << 24),
+ pc_setreg(sd, variable_names.intern("@inventorylist_id") + (j << 24),
sd->status.inventory[i].nameid);
- pc_setreg(sd, add_str("@inventorylist_amount") + (j << 24),
+ pc_setreg(sd, variable_names.intern("@inventorylist_amount") + (j << 24),
sd->status.inventory[i].amount);
- pc_setreg(sd, add_str("@inventorylist_equip") + (j << 24),
+ pc_setreg(sd, variable_names.intern("@inventorylist_equip") + (j << 24),
uint16_t(sd->status.inventory[i].equip));
- pc_setreg(sd, add_str("@inventorylist_refine") + (j << 24),
+ pc_setreg(sd, variable_names.intern("@inventorylist_refine") + (j << 24),
sd->status.inventory[i].refine);
- pc_setreg(sd, add_str("@inventorylist_identify") + (j << 24),
+ pc_setreg(sd, variable_names.intern("@inventorylist_identify") + (j << 24),
sd->status.inventory[i].identify);
- pc_setreg(sd, add_str("@inventorylist_attribute") + (j << 24),
+ pc_setreg(sd, variable_names.intern("@inventorylist_attribute") + (j << 24),
sd->status.inventory[i].attribute);
- pc_setreg(sd, add_str("@inventorylist_card1") + (j << 24),
+ pc_setreg(sd, variable_names.intern("@inventorylist_card1") + (j << 24),
sd->status.inventory[i].card[0]);
- pc_setreg(sd, add_str("@inventorylist_card2") + (j << 24),
+ pc_setreg(sd, variable_names.intern("@inventorylist_card2") + (j << 24),
sd->status.inventory[i].card[1]);
- pc_setreg(sd, add_str("@inventorylist_card3") + (j << 24),
+ pc_setreg(sd, variable_names.intern("@inventorylist_card3") + (j << 24),
sd->status.inventory[i].card[2]);
- pc_setreg(sd, add_str("@inventorylist_card4") + (j << 24),
+ pc_setreg(sd, variable_names.intern("@inventorylist_card4") + (j << 24),
sd->status.inventory[i].card[3]);
j++;
}
}
- pc_setreg(sd, add_str("@inventorylist_count"), j);
+ pc_setreg(sd, variable_names.intern("@inventorylist_count"), j);
}
static
@@ -3842,18 +3635,18 @@ void builtin_getactivatedpoolskilllist(ScriptState *st)
if (sd->status.skill[skill_id].lv)
{
- pc_setreg(sd, add_str("@skilllist_id") + (count << 24),
+ pc_setreg(sd, variable_names.intern("@skilllist_id") + (count << 24),
static_cast<uint16_t>(skill_id));
- pc_setreg(sd, add_str("@skilllist_lv") + (count << 24),
+ pc_setreg(sd, variable_names.intern("@skilllist_lv") + (count << 24),
sd->status.skill[skill_id].lv);
- pc_setreg(sd, add_str("@skilllist_flag") + (count << 24),
+ pc_setreg(sd, variable_names.intern("@skilllist_flag") + (count << 24),
static_cast<uint16_t>(sd->status.skill[skill_id].flags));
- pc_setregstr(sd, add_str("@skilllist_name$") + (count << 24),
- skill_name(skill_id));
+ pc_setregstr(sd, variable_names.intern("@skilllist_name$") + (count << 24),
+ skill_name(skill_id).c_str());
++count;
}
}
- pc_setreg(sd, add_str("@skilllist_count"), count);
+ pc_setreg(sd, variable_names.intern("@skilllist_count"), count);
}
@@ -3873,25 +3666,25 @@ 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, add_str("@skilllist_id") + (count << 24),
+ pc_setreg(sd, variable_names.intern("@skilllist_id") + (count << 24),
static_cast<uint16_t>(skill_id));
- pc_setreg(sd, add_str("@skilllist_lv") + (count << 24),
+ pc_setreg(sd, variable_names.intern("@skilllist_lv") + (count << 24),
sd->status.skill[skill_id].lv);
- pc_setreg(sd, add_str("@skilllist_flag") + (count << 24),
+ pc_setreg(sd, variable_names.intern("@skilllist_flag") + (count << 24),
static_cast<uint16_t>(sd->status.skill[skill_id].flags));
- pc_setregstr(sd, add_str("@skilllist_name$") + (count << 24),
- skill_name(skill_id));
+ pc_setregstr(sd, variable_names.intern("@skilllist_name$") + (count << 24),
+ skill_name(skill_id).c_str());
++count;
}
}
- pc_setreg(sd, add_str("@skilllist_count"), count);
+ pc_setreg(sd, variable_names.intern("@skilllist_count"), count);
}
static
void builtin_poolskill(ScriptState *st)
{
dumb_ptr<map_session_data> sd = script_rid2sd(st);
- SkillID skill_id = SkillID(conv_num(st, &(st->stack->stack_data[st->start + 2])));
+ SkillID skill_id = SkillID(conv_num(st, &AARGO2(2)));
skill_pool_activate(sd, skill_id);
clif_skillinfoblock(sd);
@@ -3902,7 +3695,7 @@ static
void builtin_unpoolskill(ScriptState *st)
{
dumb_ptr<map_session_data> sd = script_rid2sd(st);
- SkillID skill_id = SkillID(conv_num(st, &(st->stack->stack_data[st->start + 2])));
+ SkillID skill_id = SkillID(conv_num(st, &AARGO2(2)));
skill_pool_deactivate(sd, skill_id);
clif_skillinfoblock(sd);
@@ -3925,18 +3718,18 @@ void builtin_misceffect(ScriptState *st)
{
int type;
int id = 0;
- const char *name = NULL;
+ dumb_string name;
dumb_ptr<block_list> bl = NULL;
- type = conv_num(st, &(st->stack->stack_data[st->start + 2]));
+ type = conv_num(st, &AARGO2(2));
- if (st->end > st->start + 3)
+ if (HARGO2(3))
{
- struct script_data *sdata = &(st->stack->stack_data[st->start + 3]);
+ struct script_data *sdata = &AARGO2(3);
get_val(st, sdata);
- if (sdata->type == ScriptCode::STR || sdata->type == ScriptCode::CONSTSTR)
+ if (sdata->type == ByteCode::STR || sdata->type == ByteCode::CONSTSTR)
name = conv_str(st, sdata);
else
id = conv_num(st, sdata);
@@ -3944,7 +3737,7 @@ void builtin_misceffect(ScriptState *st)
if (name)
{
- dumb_ptr<map_session_data> sd = map_nick2sd(name);
+ dumb_ptr<map_session_data> sd = map_nick2sd(name.c_str());
if (sd)
bl = sd;
}
@@ -3978,7 +3771,7 @@ void builtin_specialeffect(ScriptState *st)
clif_specialeffect(bl,
conv_num(st,
- &(st->stack->stack_data[st->start + 2])),
+ &AARGO2(2)),
0);
}
@@ -3993,7 +3786,7 @@ void builtin_specialeffect2(ScriptState *st)
clif_specialeffect(sd,
conv_num(st,
- &(st->stack->stack_data[st->start + 2])),
+ &AARGO2(2)),
0);
}
@@ -4030,7 +3823,7 @@ void builtin_unequipbyid(ScriptState *st)
if (sd == NULL)
return;
- EQUIP slot_id = EQUIP(conv_num(st, &(st->stack->stack_data[st->start + 2])));
+ EQUIP slot_id = EQUIP(conv_num(st, &AARGO2(2)));
if (slot_id >= EQUIP() && slot_id < EQUIP::COUNT
&& sd->equip_index[slot_id] >= 0)
@@ -4053,9 +3846,9 @@ void builtin_gmcommand(ScriptState *st)
dumb_ptr<map_session_data> sd;
sd = script_rid2sd(st);
- const char *cmd = conv_str(st, &(st->stack->stack_data[st->start + 2]));
+ dumb_string cmd = conv_str(st, &AARGO2(2));
- is_atcommand(sd->fd, sd, cmd, 99);
+ is_atcommand(sd->fd, sd, cmd.c_str(), 99);
}
@@ -4070,28 +3863,28 @@ void builtin_npcwarp(ScriptState *st)
int x, y;
dumb_ptr<npc_data> nd = NULL;
- x = conv_num(st, &(st->stack->stack_data[st->start + 2]));
- y = conv_num(st, &(st->stack->stack_data[st->start + 3]));
- const char *npc = conv_str(st, &(st->stack->stack_data[st->start + 4]));
- nd = npc_name2id(npc);
+ x = conv_num(st, &AARGO2(2));
+ y = conv_num(st, &AARGO2(3));
+ dumb_string npc = conv_str(st, &AARGO2(4));
+ nd = npc_name2id(npc.c_str());
if (!nd)
return;
- short m = nd->bl_m;
+ map_local *m = nd->bl_m;
/* Crude sanity checks. */
- if (m < 0 || !nd->bl_prev
- || x < 0 || x > map[m].xs -1
- || y < 0 || y > map[m].ys - 1)
+ if (m == nullptr || !nd->bl_prev
+ || x < 0 || x > m->xs -1
+ || y < 0 || y > m->ys - 1)
return;
- npc_enable(npc, 0);
+ npc_enable(npc.c_str(), 0);
map_delblock(nd); /* [Freeyorp] */
nd->bl_x = x;
nd->bl_y = y;
map_addblock(nd);
- npc_enable(npc, 1);
+ npc_enable(npc.c_str(), 1);
}
@@ -4103,12 +3896,11 @@ void builtin_npcwarp(ScriptState *st)
static
void builtin_message(ScriptState *st)
{
- dumb_ptr<map_session_data> pl_sd = NULL;
+ dumb_string player = conv_str(st, &AARGO2(2));
+ dumb_string msg = conv_str(st, &AARGO2(3));
- const char *player = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- const char *msg = conv_str(st, &(st->stack->stack_data[st->start + 3]));
-
- if ((pl_sd = map_nick2sd(player)) == NULL)
+ dumb_ptr<map_session_data> pl_sd = map_nick2sd(player.c_str());
+ if (pl_sd == NULL)
return;
clif_displaymessage(pl_sd->fd, msg);
@@ -4123,19 +3915,14 @@ void builtin_message(ScriptState *st)
static
void builtin_npctalk(ScriptState *st)
{
- char message[255];
-
dumb_ptr<npc_data> nd = map_id_as_npc(st->oid);
- const char *str = conv_str(st, &(st->stack->stack_data[st->start + 2]));
+ dumb_string str = conv_str(st, &AARGO2(2));
if (nd)
{
- memcpy(message, nd->name, 24);
- strcat(message, " : ");
- strcat(message, str);
- clif_message(nd, message);
+ std::string message = std::string(nd->name) + " : " + str.c_str();
+ clif_message(nd, message.c_str());
}
-
}
/*==========================================
@@ -4147,7 +3934,7 @@ void builtin_getlook(ScriptState *st)
{
dumb_ptr<map_session_data> sd = script_rid2sd(st);
- LOOK type = LOOK(conv_num(st, &(st->stack->stack_data[st->start + 2])));
+ LOOK type = LOOK(conv_num(st, &AARGO2(2)));
int val = -1;
switch (type)
{
@@ -4179,7 +3966,7 @@ void builtin_getlook(ScriptState *st)
break;
}
- push_val(st->stack, ScriptCode::INT, val);
+ push_val(st->stack, ByteCode::INT, val);
}
/*==========================================
@@ -4190,27 +3977,27 @@ static
void builtin_getsavepoint(ScriptState *st)
{
int x, y, type;
- char *mapname;
dumb_ptr<map_session_data> sd;
sd = script_rid2sd(st);
- type = conv_num(st, &(st->stack->stack_data[st->start + 2]));
+ type = conv_num(st, &AARGO2(2));
x = sd->status.save_point.x;
y = sd->status.save_point.y;
switch (type)
{
case 0:
- mapname = (char*)calloc(24, 1);
- strncpy(mapname, sd->status.save_point.map, 23);
- push_str(st->stack, ScriptCode::STR, mapname);
+ {
+ dumb_string mapname = dumb_string::copy(sd->status.save_point.map);
+ push_str(st->stack, ByteCode::STR, mapname);
+ }
break;
case 1:
- push_val(st->stack, ScriptCode::INT, x);
+ push_val(st->stack, ByteCode::INT, x);
break;
case 2:
- push_val(st->stack, ScriptCode::INT, y);
+ push_val(st->stack, ByteCode::INT, y);
break;
}
}
@@ -4220,30 +4007,33 @@ void builtin_getsavepoint(ScriptState *st)
*------------------------------------------
*/
static
-void builtin_areatimer_sub(dumb_ptr<block_list> bl, interval_t tick, const char *event)
+void builtin_areatimer_sub(dumb_ptr<block_list> bl, interval_t tick, dumb_string event)
{
- pc_addeventtimer(bl->as_player(), tick, event);
+ pc_addeventtimer(bl->as_player(), tick, event.c_str());
}
static
void builtin_areatimer(ScriptState *st)
{
- int m;
int x0, y0, x1, y1;
- const char *mapname = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- x0 = conv_num(st, &(st->stack->stack_data[st->start + 3]));
- y0 = conv_num(st, &(st->stack->stack_data[st->start + 4]));
- x1 = conv_num(st, &(st->stack->stack_data[st->start + 5]));
- y1 = conv_num(st, &(st->stack->stack_data[st->start + 6]));
- interval_t tick = static_cast<interval_t>(conv_num(st, &(st->stack->stack_data[st->start + 7])));
- const char *event = conv_str(st, &(st->stack->stack_data[st->start + 8]));
+ dumb_string mapname = conv_str(st, &AARGO2(2));
+ x0 = conv_num(st, &AARGO2(3));
+ y0 = conv_num(st, &AARGO2(4));
+ x1 = conv_num(st, &AARGO2(5));
+ y1 = conv_num(st, &AARGO2(6));
+ interval_t tick = static_cast<interval_t>(conv_num(st, &AARGO2(7)));
+ dumb_string event = conv_str(st, &AARGO2(8));
- if ((m = map_mapname2mapid(mapname)) < 0)
+ map_local *m = map_mapname2mapid(mapname.c_str());
+ if (m == nullptr)
return;
map_foreachinarea(std::bind(builtin_areatimer_sub, ph::_1, tick, event),
- m, x0, y0, x1, y1, BL::PC);
+ m,
+ x0, y0,
+ x1, y1,
+ BL::PC);
}
/*==========================================
@@ -4256,20 +4046,20 @@ void builtin_isin(ScriptState *st)
int x1, y1, x2, y2;
dumb_ptr<map_session_data> sd = script_rid2sd(st);
- const char *str = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- x1 = conv_num(st, &(st->stack->stack_data[st->start + 3]));
- y1 = conv_num(st, &(st->stack->stack_data[st->start + 4]));
- x2 = conv_num(st, &(st->stack->stack_data[st->start + 5]));
- y2 = conv_num(st, &(st->stack->stack_data[st->start + 6]));
+ dumb_string str = conv_str(st, &AARGO2(2));
+ x1 = conv_num(st, &AARGO2(3));
+ y1 = conv_num(st, &AARGO2(4));
+ x2 = conv_num(st, &AARGO2(5));
+ y2 = conv_num(st, &AARGO2(6));
if (!sd)
return;
- push_val(st->stack, ScriptCode::INT,
+ using namespace operators;
+ push_val(st->stack, ByteCode::INT,
(sd->bl_x >= x1 && sd->bl_x <= x2)
&& (sd->bl_y >= y1 && sd->bl_y <= y2)
- && (!strcmp(str, map[sd->bl_m].name)));
-
+ && (str == sd->bl_m->name));
}
// Trigger the shop on a (hopefully) nearby shop NPC
@@ -4282,7 +4072,7 @@ void builtin_shop(ScriptState *st)
if (!sd)
return;
- nd = npc_name2id(conv_str(st, &(st->stack->stack_data[st->start + 2])));
+ nd = npc_name2id(conv_str(st, &AARGO2(2)).c_str());
if (!nd)
return;
@@ -4299,7 +4089,7 @@ void builtin_isdead(ScriptState *st)
{
dumb_ptr<map_session_data> sd = script_rid2sd(st);
- push_val(st->stack, ScriptCode::INT, pc_isdead(sd));
+ push_val(st->stack, ByteCode::INT, pc_isdead(sd));
}
/*========================================
@@ -4309,18 +4099,18 @@ void builtin_isdead(ScriptState *st)
static
void builtin_fakenpcname(ScriptState *st)
{
- const char *name = conv_str(st, &(st->stack->stack_data[st->start + 2]));
- const char *newname = conv_str(st, &(st->stack->stack_data[st->start + 3]));
- int newsprite = conv_num(st, &(st->stack->stack_data[st->start + 4]));
- dumb_ptr<npc_data> nd = npc_name2id(name);
+ dumb_string name = conv_str(st, &AARGO2(2));
+ dumb_string newname = conv_str(st, &AARGO2(3));
+ int newsprite = conv_num(st, &AARGO2(4));
+ dumb_ptr<npc_data> nd = npc_name2id(name.c_str());
if (!nd)
return;
- strzcpy(nd->name, newname, sizeof(nd->name));
+ strzcpy(nd->name, newname.c_str(), sizeof(nd->name));
nd->npc_class = newsprite;
// Refresh this npc
- npc_enable(name, 0);
- npc_enable(name, 1);
+ npc_enable(name.c_str(), 0);
+ npc_enable(name.c_str(), 1);
}
@@ -4333,7 +4123,7 @@ void builtin_getx(ScriptState *st)
{
dumb_ptr<map_session_data> sd = script_rid2sd(st);
- push_val(st->stack, ScriptCode::INT, sd->bl_x);
+ push_val(st->stack, ByteCode::INT, sd->bl_x);
}
/*============================
@@ -4345,7 +4135,7 @@ void builtin_gety(ScriptState *st)
{
dumb_ptr<map_session_data> sd = script_rid2sd(st);
- push_val(st->stack, ScriptCode::INT, sd->bl_y);
+ push_val(st->stack, ByteCode::INT, sd->bl_y);
}
/*
@@ -4357,7 +4147,7 @@ void builtin_getmap(ScriptState *st)
dumb_ptr<map_session_data> sd = script_rid2sd(st);
// A map_data lives essentially forever.
- push_str(st->stack, ScriptCode::CONSTSTR, map[sd->bl_m].name);
+ push_str(st->stack, ByteCode::CONSTSTR, dumb_string::fake(sd->bl_m->name));
}
//
@@ -4368,13 +4158,14 @@ void builtin_getmap(ScriptState *st)
*------------------------------------------
*/
static
-ScriptCode get_com(const ScriptCode *script, int *pos_)
+ByteCode get_com(ScriptPointer *script)
{
- if (static_cast<uint8_t>(script[*pos_]) >= 0x80)
+ if (static_cast<uint8_t>(script->peek()) >= 0x80)
{
- return ScriptCode::INT;
+ // synthetic! Does not advance pos yet.
+ return ByteCode::INT;
}
- return script[(*pos_)++];
+ return script->pop();
}
/*==========================================
@@ -4382,18 +4173,19 @@ ScriptCode get_com(const ScriptCode *script, int *pos_)
*------------------------------------------
*/
static
-int get_num(const ScriptCode *scr, int *pos_)
+int get_num(ScriptPointer *scr)
{
- const uint8_t *script = reinterpret_cast<const uint8_t *>(scr);
- int i, j;
- i = 0;
- j = 0;
- while (script[*pos_] >= 0xc0)
+ int i = 0;
+ int j = 0;
+ uint8_t val;
+ do
{
- i += (script[(*pos_)++] & 0x7f) << j;
+ val = static_cast<uint8_t>(scr->pop());
+ i += (val & 0x7f) << j;
j += 6;
}
- return i + ((script[(*pos_)++] & 0x7f) << j);
+ while (val >= 0xc0);
+ return i;
}
/*==========================================
@@ -4403,20 +4195,22 @@ int get_num(const ScriptCode *scr, int *pos_)
static
int pop_val(ScriptState *st)
{
- if (st->stack->sp <= 0)
+ if (st->stack->stack_datav.empty())
return 0;
- st->stack->sp--;
- get_val(st, &(st->stack->stack_data[st->stack->sp]));
- if (st->stack->stack_data[st->stack->sp].type == ScriptCode::INT)
- return st->stack->stack_data[st->stack->sp].u.num;
- return 0;
+ script_data& back = st->stack->stack_datav.back();
+ get_val(st, &back);
+ int rv = 0;
+ if (back.type == ByteCode::INT)
+ rv = back.u.num;
+ st->stack->stack_datav.pop_back();
+ return rv;
}
static
bool isstr(struct script_data& c)
{
- return c.type == ScriptCode::STR
- || c.type == ScriptCode::CONSTSTR;
+ return c.type == ByteCode::STR
+ || c.type == ByteCode::CONSTSTR;
}
/*==========================================
@@ -4426,36 +4220,29 @@ bool isstr(struct script_data& c)
static
void op_add(ScriptState *st)
{
- st->stack->sp--;
- get_val(st, &(st->stack->stack_data[st->stack->sp]));
- get_val(st, &(st->stack->stack_data[st->stack->sp - 1]));
+ get_val(st, &st->stack->stack_datav.back());
+ script_data back = st->stack->stack_datav.back();
+ st->stack->stack_datav.pop_back();
+ get_val(st, &st->stack->stack_datav.back());
+ script_data& back1 = st->stack->stack_datav.back();
+ st->stack->stack_datav.pop_back();
- if (isstr(st->stack->stack_data[st->stack->sp])
- || isstr(st->stack->stack_data[st->stack->sp - 1]))
+ if (!(isstr(back) || isstr(back1)))
{
- conv_str(st, &(st->stack->stack_data[st->stack->sp]));
- conv_str(st, &(st->stack->stack_data[st->stack->sp - 1]));
- }
- if (st->stack->stack_data[st->stack->sp].type == ScriptCode::INT)
- { // ii
- st->stack->stack_data[st->stack->sp - 1].u.num +=
- st->stack->stack_data[st->stack->sp].u.num;
+ back1.u.num += back.u.num;
}
else
- { // ssの予定
- char *buf;
- buf = (char *)
- calloc(strlen(st->stack->stack_data[st->stack->sp - 1].u.str) +
- strlen(st->stack->stack_data[st->stack->sp].u.str) + 1,
- 1);
- strcpy(buf, st->stack->stack_data[st->stack->sp - 1].u.str);
- strcat(buf, st->stack->stack_data[st->stack->sp].u.str);
- if (st->stack->stack_data[st->stack->sp - 1].type == ScriptCode::STR)
- free(const_cast<char *>(st->stack->stack_data[st->stack->sp - 1].u.str));
- if (st->stack->stack_data[st->stack->sp].type == ScriptCode::STR)
- free(const_cast<char *>(st->stack->stack_data[st->stack->sp].u.str));
- st->stack->stack_data[st->stack->sp - 1].type = ScriptCode::STR;
- st->stack->stack_data[st->stack->sp - 1].u.str = buf;
+ {
+ dumb_string sb = conv_str(st, &back);
+ dumb_string sb1 = conv_str(st, &back1);
+ // ssの予定
+ std::string buf = sb1.str() + sb.str();
+ if (back1.type == ByteCode::STR)
+ back1.u.str.delete_();
+ if (back.type == ByteCode::STR)
+ back.u.str.delete_();
+ back1.type = ByteCode::STR;
+ back1.u.str = dumb_string::copys(buf);
}
}
@@ -4464,43 +4251,37 @@ void op_add(ScriptState *st)
*------------------------------------------
*/
static
-void op_2str(ScriptState *st, ScriptCode op, int sp1, int sp2)
+void op_2str(ScriptState *st, ByteCode op, dumb_string s1, dumb_string s2)
{
- const char *s1 = st->stack->stack_data[sp1].u.str;
- const char *s2 = st->stack->stack_data[sp2].u.str;
int a = 0;
+ using namespace operators;
switch (op)
{
- case ScriptCode::EQ:
- a = (strcmp(s1, s2) == 0);
+ case ByteCode::EQ:
+ a = s1 == s2;
break;
- case ScriptCode::NE:
- a = (strcmp(s1, s2) != 0);
+ case ByteCode::NE:
+ a = s1 != s2;
break;
- case ScriptCode::GT:
- a = (strcmp(s1, s2) > 0);
+ case ByteCode::GT:
+ a = s1 > s2;
break;
- case ScriptCode::GE:
- a = (strcmp(s1, s2) >= 0);
+ case ByteCode::GE:
+ a = s1 >= s2;
break;
- case ScriptCode::LT:
- a = (strcmp(s1, s2) < 0);
+ case ByteCode::LT:
+ a = s1 < s2;
break;
- case ScriptCode::LE:
- a = (strcmp(s1, s2) <= 0);
+ case ByteCode::LE:
+ a = s1 <= s2;
break;
default:
PRINTF("illegal string operater\n");
break;
}
- push_val(st->stack, ScriptCode::INT, a);
-
- if (st->stack->stack_data[sp1].type == ScriptCode::STR)
- free(const_cast<char *>(s1));
- if (st->stack->stack_data[sp2].type == ScriptCode::STR)
- free(const_cast<char *>(s2));
+ push_val(st->stack, ByteCode::INT, a);
}
/*==========================================
@@ -4508,63 +4289,63 @@ void op_2str(ScriptState *st, ScriptCode op, int sp1, int sp2)
*------------------------------------------
*/
static
-void op_2num(ScriptState *st, ScriptCode op, int i1, int i2)
+void op_2num(ScriptState *st, ByteCode op, int i1, int i2)
{
switch (op)
{
- case ScriptCode::SUB:
+ case ByteCode::SUB:
i1 -= i2;
break;
- case ScriptCode::MUL:
+ case ByteCode::MUL:
i1 *= i2;
break;
- case ScriptCode::DIV:
+ case ByteCode::DIV:
i1 /= i2;
break;
- case ScriptCode::MOD:
+ case ByteCode::MOD:
i1 %= i2;
break;
- case ScriptCode::AND:
+ case ByteCode::AND:
i1 &= i2;
break;
- case ScriptCode::OR:
+ case ByteCode::OR:
i1 |= i2;
break;
- case ScriptCode::XOR:
+ case ByteCode::XOR:
i1 ^= i2;
break;
- case ScriptCode::LAND:
+ case ByteCode::LAND:
i1 = i1 && i2;
break;
- case ScriptCode::LOR:
+ case ByteCode::LOR:
i1 = i1 || i2;
break;
- case ScriptCode::EQ:
+ case ByteCode::EQ:
i1 = i1 == i2;
break;
- case ScriptCode::NE:
+ case ByteCode::NE:
i1 = i1 != i2;
break;
- case ScriptCode::GT:
+ case ByteCode::GT:
i1 = i1 > i2;
break;
- case ScriptCode::GE:
+ case ByteCode::GE:
i1 = i1 >= i2;
break;
- case ScriptCode::LT:
+ case ByteCode::LT:
i1 = i1 < i2;
break;
- case ScriptCode::LE:
+ case ByteCode::LE:
i1 = i1 <= i2;
break;
- case ScriptCode::R_SHIFT:
+ case ByteCode::R_SHIFT:
i1 = i1 >> i2;
break;
- case ScriptCode::L_SHIFT:
+ case ByteCode::L_SHIFT:
i1 = i1 << i2;
break;
}
- push_val(st->stack, ScriptCode::INT, i1);
+ push_val(st->stack, ByteCode::INT, i1);
}
/*==========================================
@@ -4572,34 +4353,35 @@ void op_2num(ScriptState *st, ScriptCode op, int i1, int i2)
*------------------------------------------
*/
static
-void op_2(ScriptState *st, ScriptCode op)
+void op_2(ScriptState *st, ByteCode op)
{
- int i1, i2;
- const char *s1 = NULL, *s2 = NULL;
+ // pop_val has unfortunate implications here
+ script_data d2 = st->stack->stack_datav.back();
+ st->stack->stack_datav.pop_back();
+ get_val(st, &d2);
+ script_data d1 = st->stack->stack_datav.back();
+ st->stack->stack_datav.pop_back();
+ get_val(st, &d1);
- i2 = pop_val(st);
- if (isstr(st->stack->stack_data[st->stack->sp]))
- s2 = st->stack->stack_data[st->stack->sp].u.str;
-
- i1 = pop_val(st);
- if (isstr(st->stack->stack_data[st->stack->sp]))
- s1 = st->stack->stack_data[st->stack->sp].u.str;
-
- if (s1 != NULL && s2 != NULL)
+ if (isstr(d1) && isstr(d2))
{
// ss => op_2str
- op_2str(st, op, st->stack->sp, st->stack->sp + 1);
+ op_2str(st, op, d1.u.str, d2.u.str);
+ if (d1.type == ByteCode::STR)
+ d1.u.str.delete_();
+ if (d2.type == ByteCode::STR)
+ d2.u.str.delete_();
}
- else if (s1 == NULL && s2 == NULL)
+ else if (!(isstr(d1) || isstr(d2)))
{
// ii => op_2num
- op_2num(st, op, i1, i2);
+ op_2num(st, op, d1.u.num, d2.u.num);
}
else
{
// si,is => error
- PRINTF("script: op_2: int&str, str&int not allow.");
- push_val(st->stack, ScriptCode::INT, 0);
+ PRINTF("script: op_2: int&str, str&int not allow.\n");
+ push_val(st->stack, ByteCode::INT, 0);
}
}
@@ -4608,23 +4390,23 @@ void op_2(ScriptState *st, ScriptCode op)
*------------------------------------------
*/
static
-void op_1num(ScriptState *st, ScriptCode op)
+void op_1num(ScriptState *st, ByteCode op)
{
int i1;
i1 = pop_val(st);
switch (op)
{
- case ScriptCode::NEG:
+ case ByteCode::NEG:
i1 = -i1;
break;
- case ScriptCode::NOT:
+ case ByteCode::NOT:
i1 = ~i1;
break;
- case ScriptCode::LNOT:
+ case ByteCode::LNOT:
i1 = !i1;
break;
}
- push_val(st->stack, ScriptCode::INT, i1);
+ push_val(st->stack, ByteCode::INT, i1);
}
/*==========================================
@@ -4633,102 +4415,94 @@ void op_1num(ScriptState *st, ScriptCode op)
*/
void run_func(ScriptState *st)
{
- int i, start_sp, end_sp, func;
-
- end_sp = st->stack->sp;
- for (i = end_sp - 1; i >= 0 && st->stack->stack_data[i].type != ScriptCode::ARG;
- i--);
- if (i == 0)
+ size_t end_sp = st->stack->stack_datav.size();
+ size_t start_sp = end_sp - 1;
+ while (st->stack->stack_datav[start_sp].type != ByteCode::ARG)
{
- if (battle_config.error_log)
- PRINTF("function not found\n");
-// st->stack->sp=0;
- st->state = END;
- return;
+ start_sp--;
+ if (start_sp == 0)
+ {
+ if (battle_config.error_log)
+ PRINTF("function not found\n");
+ st->state = ScriptEndState::END;
+ return;
+ }
}
- start_sp = i - 1;
- st->start = i - 1;
+ // the func is before the arg
+ start_sp--;
+ st->start = start_sp;
st->end = end_sp;
- func = st->stack->stack_data[st->start].u.num;
- if (st->stack->stack_data[st->start].type != ScriptCode::NAME
- || str_data[func].type != ScriptCode::FUNC)
+ size_t func = st->stack->stack_datav[st->start].u.num;
+ if (st->stack->stack_datav[st->start].type != ByteCode::FUNC_REF)
{
PRINTF("run_func: not function and command! \n");
-// st->stack->sp=0;
- st->state = END;
+ st->state = ScriptEndState::END;
return;
}
-#ifdef DEBUG_RUN
- if (battle_config.etc_log)
+
+ if (DEBUG_RUN && battle_config.etc_log)
{
- PRINTF("run_func : %s? (%d(%d))\n", str_buf + str_data[func].str,
- func, str_data[func].type);
+ PRINTF("run_func : %s\n",
+ builtin_functions[func].name);
PRINTF("stack dump :");
- for (i = 0; i < end_sp; i++)
+ for (script_data& d : st->stack->stack_datav)
{
- switch (st->stack->stack_data[i].type)
+ // this is not *nearly* complete enough to be useful ...
+ switch (d.type)
{
- case ScriptCode::INT:
- PRINTF(" int(%d)", st->stack->stack_data[i].u.num);
+ case ByteCode::INT:
+ PRINTF(" int(%d)", d.u.num);
+ break;
+ case ByteCode::RETINFO:
+ PRINTF(" retinfo(%p)", static_cast<const void *>(d.u.script));
+ break;
+ case ByteCode::PARAM_:
+ PRINTF(" param(%d)", d.u.num);
break;
- case ScriptCode::NAME:
- PRINTF(" name(%s)",
- str_buf +
- str_data[st->stack->stack_data[i].u.num].str);
+ case ByteCode::VARIABLE:
+ PRINTF(" name(%s)", variable_names.outtern(d.u.num));
break;
- case ScriptCode::ARG:
+ case ByteCode::ARG:
PRINTF(" arg");
break;
- case ScriptCode::POS:
- PRINTF(" pos(%d)", st->stack->stack_data[i].u.num);
+ case ByteCode::POS:
+ PRINTF(" pos(%d)", d.u.num);
break;
default:
- PRINTF(" %d,%d", st->stack->stack_data[i].type,
- st->stack->stack_data[i].u.num);
+ PRINTF(" %d,%d", d.type, d.u.num);
}
}
PRINTF("\n");
}
-#endif
- if (str_data[func].func)
- {
- str_data[func].func(st);
- }
- else
- {
- if (battle_config.error_log)
- PRINTF("run_func : %s? (%d(%d))\n", str_buf + str_data[func].str,
- func, str_data[func].type);
- push_val(st->stack, ScriptCode::INT, 0);
- }
+ builtin_functions[func].func(st);
pop_stack(st->stack, start_sp, end_sp);
- if (st->state == RETFUNC)
+ if (st->state == ScriptEndState::RETFUNC)
{
// ユーザー定義関数からの復帰
int olddefsp = st->defsp;
pop_stack(st->stack, st->defsp, start_sp); // 復帰に邪魔なスタック削除
if (st->defsp < 4
- || st->stack->stack_data[st->defsp - 1].type != ScriptCode::RETINFO)
+ || st->stack->stack_datav[st->defsp - 1].type != ByteCode::RETINFO)
{
PRINTF("script:run_func (return) return without callfunc or callsub!\n");
- st->state = END;
+ st->state = ScriptEndState::END;
return;
}
assert (olddefsp == st->defsp); // pretty sure it hasn't changed yet
- st->script = conv_script(st, &(st->stack->stack_data[olddefsp - 1])); // スクリプトを復元
- st->pos = conv_num(st, &(st->stack->stack_data[olddefsp - 2])); // スクリプト位置の復元
- st->defsp = conv_num(st, &(st->stack->stack_data[olddefsp - 3])); // 基準スタックポインタを復元
+ st->scriptp.code = conv_script(st, &st->stack->stack_datav[olddefsp - 1]); // スクリプトを復元
+ st->scriptp.pos = conv_num(st, &st->stack->stack_datav[olddefsp - 2]); // スクリプト位置の復元
+ st->defsp = conv_num(st, &st->stack->stack_datav[olddefsp - 3]); // 基準スタックポインタを復元
// Number of arguments.
- i = conv_num(st, &(st->stack->stack_data[olddefsp - 4])); // 引数の数所得
+ int i = conv_num(st, &st->stack->stack_datav[olddefsp - 4]); // 引数の数所得
assert (i == 0);
pop_stack(st->stack, olddefsp - 4 - i, olddefsp); // 要らなくなったスタック(引数と復帰用データ)削除
- st->state = GOTO;
+ st->state = ScriptEndState::GOTO;
}
}
@@ -4737,205 +4511,190 @@ void run_func(ScriptState *st)
*------------------------------------------
*/
static
-void run_script_main(const ScriptCode *script, int pos_, int, int,
- ScriptState *st, const ScriptCode *rootscript)
+void run_script_main(ScriptState *st, const ScriptBuffer *rootscript)
{
- int rerun_pos;
int cmdcount = script_config.check_cmdcount;
int gotocount = script_config.check_gotocount;
struct script_stack *stack = st->stack;
- st->defsp = stack->sp;
- st->script = script;
+ st->defsp = stack->stack_datav.size();
- rerun_pos = st->pos;
- for (st->state = 0; st->state == 0;)
+ int rerun_pos = st->scriptp.pos;
+ st->state = ScriptEndState::ZERO;
+ while (st->state == ScriptEndState::ZERO)
{
- switch (ScriptCode c = get_com(script, &st->pos))
+ switch (ByteCode c = get_com(&st->scriptp))
{
- case ScriptCode::EOL:
- if (stack->sp != st->defsp)
+ case ByteCode::EOL:
+ if (stack->stack_datav.size() != st->defsp)
{
if (battle_config.error_log)
- PRINTF("stack.sp (%d) != default (%d)\n", stack->sp,
+ PRINTF("stack.sp (%zu) != default (%d)\n",
+ stack->stack_datav.size(),
st->defsp);
- stack->sp = st->defsp;
+ stack->stack_datav.resize(st->defsp);
}
- rerun_pos = st->pos;
+ rerun_pos = st->scriptp.pos;
break;
- case ScriptCode::INT:
- push_val(stack, ScriptCode::INT, get_num(script, &st->pos));
+ case ByteCode::INT:
+ // synthesized!
+ push_val(stack, ByteCode::INT, get_num(&st->scriptp));
break;
- case ScriptCode::POS:
- case ScriptCode::NAME:
- push_val(stack, c, (*(const int *)(script + st->pos)) & 0xffffff);
- st->pos += 3;
+
+ case ByteCode::POS:
+ case ByteCode::VARIABLE:
+ case ByteCode::FUNC_REF:
+ // Note that these 3 have *very* different meanings,
+ // despite being encoded similarly.
+ {
+ int arg = 0;
+ arg |= static_cast<uint8_t>(st->scriptp.pop()) << 0;
+ arg |= static_cast<uint8_t>(st->scriptp.pop()) << 8;
+ arg |= static_cast<uint8_t>(st->scriptp.pop()) << 16;
+ push_val(stack, c, arg);
+ }
break;
- case ScriptCode::ARG:
+ case ByteCode::ARG:
push_val(stack, c, 0);
break;
- case ScriptCode::STR:
- push_str(stack, ScriptCode::CONSTSTR, reinterpret_cast<const char *>(script + st->pos));
- while (script[st->pos++] != ScriptCode::NOP);
+ case ByteCode::STR:
+ // ScriptPointer.pops() leaves it .pos pointing to the \0.
+ push_str(stack, ByteCode::CONSTSTR, dumb_string::fake(st->scriptp.pops()));
break;
- case ScriptCode::FUNC:
+ case ByteCode::FUNC_:
run_func(st);
- if (st->state == GOTO)
+ if (st->state == ScriptEndState::GOTO)
{
- rerun_pos = st->pos;
- script = st->script;
- st->state = 0;
+ rerun_pos = st->scriptp.pos;
+ st->state = ScriptEndState::ZERO;
if (gotocount > 0 && (--gotocount) <= 0)
{
PRINTF("run_script: infinity loop !\n");
- st->state = END;
+ st->state = ScriptEndState::END;
}
}
break;
- case ScriptCode::ADD:
+ case ByteCode::ADD:
op_add(st);
break;
- case ScriptCode::SUB:
- case ScriptCode::MUL:
- case ScriptCode::DIV:
- case ScriptCode::MOD:
- case ScriptCode::EQ:
- case ScriptCode::NE:
- case ScriptCode::GT:
- case ScriptCode::GE:
- case ScriptCode::LT:
- case ScriptCode::LE:
- case ScriptCode::AND:
- case ScriptCode::OR:
- case ScriptCode::XOR:
- case ScriptCode::LAND:
- case ScriptCode::LOR:
- case ScriptCode::R_SHIFT:
- case ScriptCode::L_SHIFT:
+ case ByteCode::SUB:
+ case ByteCode::MUL:
+ case ByteCode::DIV:
+ case ByteCode::MOD:
+ case ByteCode::EQ:
+ case ByteCode::NE:
+ case ByteCode::GT:
+ case ByteCode::GE:
+ case ByteCode::LT:
+ case ByteCode::LE:
+ case ByteCode::AND:
+ case ByteCode::OR:
+ case ByteCode::XOR:
+ case ByteCode::LAND:
+ case ByteCode::LOR:
+ case ByteCode::R_SHIFT:
+ case ByteCode::L_SHIFT:
op_2(st, c);
break;
- case ScriptCode::NEG:
- case ScriptCode::NOT:
- case ScriptCode::LNOT:
+ case ByteCode::NEG:
+ case ByteCode::NOT:
+ case ByteCode::LNOT:
op_1num(st, c);
break;
- case ScriptCode::NOP:
- st->state = END;
+ case ByteCode::NOP:
+ st->state = ScriptEndState::END;
break;
default:
if (battle_config.error_log)
- PRINTF("unknown command : %d @ %d\n", c, pos_);
- st->state = END;
+ PRINTF("unknown command : %d @ %zu\n",
+ c, st->scriptp.pos);
+ st->state = ScriptEndState::END;
break;
}
if (cmdcount > 0 && (--cmdcount) <= 0)
{
PRINTF("run_script: infinity loop !\n");
- st->state = END;
+ st->state = ScriptEndState::END;
}
}
switch (st->state)
{
- case STOP:
+ case ScriptEndState::STOP:
break;
- case END:
+ case ScriptEndState::END:
{
dumb_ptr<map_session_data> sd = map_id2sd(st->rid);
- st->pos = -1;
+ st->scriptp.code = nullptr;
+ st->scriptp.pos = -1;
if (sd && sd->npc_id == st->oid)
npc_event_dequeue(sd);
}
break;
- case RERUNLINE:
- {
- st->pos = rerun_pos;
- }
+ case ScriptEndState::RERUNLINE:
+ st->scriptp.pos = rerun_pos;
break;
}
- if (st->state != END)
+ if (st->state != ScriptEndState::END)
{
// 再開するためにスタック情報を保存
dumb_ptr<map_session_data> sd = map_id2sd(st->rid);
- if (sd /* && sd->npc_stackbuf==NULL */ )
+ if (sd)
{
- if (sd->npc_stackbuf)
- free(sd->npc_stackbuf);
- sd->npc_stackbuf = (struct script_data *)
- calloc(sizeof(stack->stack_data[0]) * stack->sp_max, 1);
- memcpy(sd->npc_stackbuf, stack->stack_data,
- sizeof(stack->stack_data[0]) * stack->sp_max);
- sd->npc_stack = stack->sp;
- sd->npc_stackmax = stack->sp_max;
- sd->npc_script = script;
+ sd->npc_stackbuf = stack->stack_datav;
+ sd->npc_script = st->scriptp.code;
+ // sd->npc_pos is set later ... ???
sd->npc_scriptroot = rootscript;
}
}
-
}
/*==========================================
* スクリプトの実行
*------------------------------------------
*/
-int run_script(const ScriptCode *script, int pos_, int rid, int oid)
+int run_script(ScriptPointer sp, int rid, int oid)
{
- return run_script_l(script, pos_, rid, oid, 0, NULL);
+ return run_script_l(sp, rid, oid, 0, NULL);
}
-int run_script_l(const ScriptCode *script, int pos_, int rid, int oid,
+int run_script_l(ScriptPointer sp, int rid, int oid,
int args_nr, argrec_t *args)
{
struct script_stack stack;
ScriptState st;
dumb_ptr<map_session_data> sd = map_id2sd(rid);
- const ScriptCode *rootscript = script;
+ const ScriptBuffer *rootscript = sp.code;
int i;
- if (script == NULL || pos_ < 0)
+ if (sp.code == NULL || sp.pos >> 24)
return -1;
- if (sd && sd->npc_stackbuf && sd->npc_scriptroot == rootscript)
+ if (sd && !sd->npc_stackbuf.empty() && sd->npc_scriptroot == rootscript)
{
// 前回のスタックを復帰
- script = sd->npc_script;
- stack.sp = sd->npc_stack;
- stack.sp_max = sd->npc_stackmax;
- stack.stack_data = (struct script_data *)
- calloc(stack.sp_max, sizeof(stack.stack_data[0]));
- memcpy(stack.stack_data, sd->npc_stackbuf,
- sizeof(stack.stack_data[0]) * stack.sp_max);
- free(sd->npc_stackbuf);
- sd->npc_stackbuf = NULL;
- }
- else
- {
- // スタック初期化
- stack.sp = 0;
- stack.sp_max = 64;
- stack.stack_data = (struct script_data *)
- calloc(stack.sp_max, sizeof(stack.stack_data[0]));
+ sp.code = sd->npc_script;
+ stack.stack_datav = std::move(sd->npc_stackbuf);
}
st.stack = &stack;
- st.pos = pos_;
+ st.scriptp = sp;
st.rid = rid;
st.oid = oid;
for (i = 0; i < args_nr; i++)
{
if (args[i].name[strlen(args[i].name) - 1] == '$')
- pc_setregstr(sd, add_str(args[i].name), args[i].v.s);
+ pc_setregstr(sd, variable_names.intern(args[i].name), args[i].v.s);
else
- pc_setreg(sd, add_str(args[i].name), args[i].v.i);
+ pc_setreg(sd, variable_names.intern(args[i].name), args[i].v.i);
}
- run_script_main(script, pos_, rid, oid, &st, rootscript);
+ run_script_main(&st, rootscript);
- free(stack.stack_data);
- stack.stack_data = NULL;
- return st.pos;
+ stack.stack_datav.clear();
+ return st.scriptp.pos;
}
/*==========================================
@@ -4955,16 +4714,11 @@ void mapreg_setreg(int num, int val)
*/
void mapreg_setregstr(int num, const char *str)
{
- char *p = mapregstr_db.get(num);
- if (p)
- free(p);
-
if (!str || !*str)
- p = NULL;
+ mapregstr_db.erase(num);
else
- p = strdup(str);
+ mapregstr_db.insert(num, str);
- mapregstr_db.put(num, p);
mapreg_dirty = 1;
}
@@ -4994,12 +4748,11 @@ void script_load_mapreg(void)
record<','>(&buf1),
&buf2)))
{
- int s = add_str(buf1.c_str());
+ int s = variable_names.intern(buf1);
int key = (index << 24) | s;
if (buf1.back() == '$')
{
- char *p = strdup(buf2.c_str());
- mapregstr_db.put(key, p);
+ mapregstr_db.insert(key, buf2);
}
else
{
@@ -5027,7 +4780,7 @@ static
void script_save_mapreg_intsub(int key, int data, FILE *fp)
{
int num = key & 0x00ffffff, i = key >> 24;
- char *name = str_buf + str_data[num].str;
+ const std::string& name = variable_names.outtern(num);
if (name[1] != '@')
{
if (i == 0)
@@ -5038,10 +4791,10 @@ void script_save_mapreg_intsub(int key, int data, FILE *fp)
}
static
-void script_save_mapreg_strsub(int key, char *data, FILE *fp)
+void script_save_mapreg_strsub(int key, const std::string& data, FILE *fp)
{
int num = key & 0x00ffffff, i = key >> 24;
- char *name = str_buf + str_data[num].str;
+ const std::string& name = variable_names.outtern(num);
if (name[1] != '@')
{
if (i == 0)
@@ -5084,49 +4837,21 @@ void script_config_read()
script_config.check_gotocount = 512;
}
-/*==========================================
- * 終了
- *------------------------------------------
- */
-
-static
-void mapregstr_db_final(char *data)
-{
- free(data);
-}
-
-static
-void userfunc_db_final(const ScriptCode *data)
-{
- free(const_cast<ScriptCode *>(data));
-}
-
void do_final_script(void)
{
if (mapreg_dirty >= 0)
script_save_mapreg();
-#if 0
- // labels are allocated just out of this
- // (so it's a leak ...)
- // this is disabled because it leads to a crash
- // due to double-free
- if (script_buf)
- free(script_buf);
-#endif
mapreg_db.clear();
for (auto& pair : mapregstr_db)
- mapregstr_db_final(pair.second);
+ pair.second.clear();
mapregstr_db.clear();
scriptlabel_db.clear();
for (auto& pair : userfunc_db)
- userfunc_db_final(pair.second);
+ pair.second.reset();
userfunc_db.clear();
- if (str_data)
- free(str_data);
- if (str_buf)
- free(str_buf);
+ str_datam.clear();
}
/*==========================================
@@ -5196,7 +4921,6 @@ BuiltinFunction builtin_functions[] =
BUILTIN(savepoint, "Mxy"),
BUILTIN(gettimetick, "i"),
BUILTIN(gettime, "i"),
- BUILTIN(gettimestr, "si"),
BUILTIN(openstorage, "*"),
BUILTIN(monster, "Mxysmi*"),
BUILTIN(areamonster, "Mxyxysmi*"),
diff --git a/src/map/script.hpp b/src/map/script.hpp
index 4caf58e..171f8a3 100644
--- a/src/map/script.hpp
+++ b/src/map/script.hpp
@@ -2,43 +2,105 @@
#define SCRIPT_HPP
#include <cstdint>
+#include <cstring> // for inlined get_str - TODO remove
#include <string>
+#include <vector>
#include "../common/db.hpp"
+#include "../common/dumb_ptr.hpp"
-enum class ScriptCode : uint8_t;
+enum class ByteCode : uint8_t;
+struct str_data_t;
+
+class ScriptBuffer
+{
+ std::vector<ByteCode> script_buf;
+public:
+ // construction methods used only by script.cpp
+ void add_scriptc(ByteCode a);
+ void add_scriptb(uint8_t a);
+ void add_scripti(uint32_t a);
+ void add_scriptl(str_data_t *a);
+ void set_label(str_data_t *ld, int pos_);
+ const char *parse_simpleexpr(const char *p);
+ const char *parse_subexpr(const char *p, int limit);
+ const char *parse_expr(const char *p);
+ const char *parse_line(const char *p);
+ void parse_script(const char *src, int line);
+
+ // consumption methods used only by script.cpp
+ ByteCode operator[](size_t i) const { return script_buf[i]; }
+ const char *get_str(size_t i) const
+ {
+ return reinterpret_cast<const char *>(&script_buf[i]);
+ }
+
+ // method used elsewhere
+};
+
+struct ScriptPointer
+{
+ const ScriptBuffer *code;
+ size_t pos;
+
+ ScriptPointer()
+ : code()
+ , pos()
+ {}
+
+ ScriptPointer(const ScriptBuffer *c, size_t p)
+ : code(c)
+ , pos(p)
+ {}
+
+ ByteCode peek() const { return (*code)[pos]; }
+ ByteCode pop() { return (*code)[pos++]; }
+ const char *pops()
+ {
+ const char *rv = code->get_str(pos);
+ pos += strlen(rv);
+ return rv;
+ }
+};
struct script_data
{
- ScriptCode type;
- union
+ ByteCode type;
+ union uu
{
int num;
- const char *str;
- const ScriptCode *script;
+ dumb_string str;
+ // Not a ScriptPointer - pos is stored in a separate slot,
+ // to avoid exploding the struct for everyone.
+ const ScriptBuffer *script;
+
+ uu() { memset(this, '\0', sizeof(*this)); }
+ ~uu() = default;
+ uu(const uu&) = default;
+ uu& operator = (const uu&) = default;
} u;
};
struct script_stack
{
- int sp, sp_max;
- struct script_data *stack_data;
+ std::vector<struct script_data> stack_datav;
};
+enum class ScriptEndState;
// future improvements coming!
class ScriptState
{
public:
struct script_stack *stack;
int start, end;
- int pos, state;
+ ScriptEndState state;
int rid, oid;
- const ScriptCode *script, *new_script;
- int defsp, new_pos, new_defsp;
+ ScriptPointer scriptp, new_scriptp;
+ int defsp, new_defsp;
};
-const ScriptCode *parse_script(const char *, int);
+std::unique_ptr<const ScriptBuffer> parse_script(const char *, int);
typedef struct argrec
{
const char *name;
@@ -52,13 +114,13 @@ typedef struct argrec
_aru(const char *z) : s(z) {}
} v;
} argrec_t;
-int run_script_l(const ScriptCode *, int, int, int, int, argrec_t *args);
-int run_script(const ScriptCode *, int, int, int);
+int run_script_l(ScriptPointer, int, int, int, argrec_t *args);
+int run_script(ScriptPointer, int, int);
extern
Map<std::string, int> scriptlabel_db;
extern
-DMap<std::string, const ScriptCode *> userfunc_db;
+UPMap<std::string, const ScriptBuffer> userfunc_db;
void script_config_read();
void do_init_script(void);
diff --git a/src/map/skill.cpp b/src/map/skill.cpp
index 4f71f06..4e195be 100644
--- a/src/map/skill.cpp
+++ b/src/map/skill.cpp
@@ -427,8 +427,10 @@ int skill_castend_damage_id(dumb_ptr<block_list> src, dumb_ptr<block_list> bl,
skill_area_temp_hp = battle_get_hp(src);
map_foreachinarea(std::bind(skill_area_sub, ph::_1, src, skillid, skilllv,
tick, flag | BCT_ENEMY | BCT_lo_x01, skill_castend_damage_id),
- bl->bl_m, bl->bl_x - 5, bl->bl_y - 5,
- bl->bl_x + 5, bl->bl_y + 5, BL::NUL);
+ bl->bl_m,
+ bl->bl_x - 5, bl->bl_y - 5,
+ bl->bl_x + 5, bl->bl_y + 5,
+ BL::NUL);
battle_damage(src, src, md->hp, 0);
}
}
@@ -450,8 +452,10 @@ int skill_castend_damage_id(dumb_ptr<block_list> src, dumb_ptr<block_list> bl,
skill_area_temp_id = bl->bl_id;
map_foreachinarea(std::bind(skill_area_sub, ph::_1, src, skillid, skilllv,
tick, flag | BCT_ENEMY | BCT_lo_x01, skill_castend_damage_id),
- bl->bl_m, bl->bl_x - 0, bl->bl_y - 0,
- bl->bl_x + 0, bl->bl_y + 0, BL::NUL);
+ bl->bl_m,
+ bl->bl_x - 0, bl->bl_y - 0,
+ bl->bl_x + 0, bl->bl_y + 0,
+ BL::NUL);
}
}
break;
@@ -1342,18 +1346,14 @@ int skill_readdb(void)
skill_db[i].stat = scan_stat(split[16]);
- char *tmp = strdup(split[17]);
- {
- // replace "_" by " "
- char *s = tmp;
- while ((s = strchr(s, '_')))
- *s = ' ';
- if ((s = strchr(tmp, '\t'))
- || (s = strchr(tmp, ' '))
- || (s = strchr(tmp, '\n')))
- *s = '\000';
- }
- skill_lookup_by_id(i).desc = tmp;
+ std::string tmp = split[17];
+ size_t space = tmp.find_first_of(" \t\n");
+ if (space != std::string::npos)
+ tmp.resize(space);
+ for (char& c : tmp)
+ if (c == '_')
+ c = ' ';
+ skill_lookup_by_id(i).desc = std::move(tmp);
}
fclose_(fp);
PRINTF("read db/skill_db.txt done\n");
@@ -1397,7 +1397,7 @@ skill_name_db& skill_lookup_by_id(SkillID id)
skill_name_db& skill_lookup_by_name(const char *name)
{
for (skill_name_db& ner : skill_names)
- if (!strcasecmp(name, ner.name) || !strcasecmp(name, ner.desc))
+ if (!strcasecmp(name, ner.name.c_str()) || !strcasecmp(name, ner.desc.c_str()))
return ner;
return skill_names[num_names - 1];
}
diff --git a/src/map/skill.hpp b/src/map/skill.hpp
index ec354e2..42caf0b 100644
--- a/src/map/skill.hpp
+++ b/src/map/skill.hpp
@@ -33,8 +33,8 @@ extern earray<struct skill_db, SkillID, SkillID::MAX_SKILL_DB> skill_db;
struct skill_name_db
{
SkillID id; // skill id
- const char *name; // search strings
- const char *desc; // description that shows up for search's
+ std::string name; // search strings
+ std::string desc; // description that shows up for searches
};
// used only by @skillid for iteration - should be depublicized
@@ -122,7 +122,7 @@ bool skill_pool_is_activated(dumb_ptr<map_session_data> sd, SkillID skill);
int skill_pool_deactivate(dumb_ptr<map_session_data> sd, SkillID skill);
// Yield configurable skill name
inline
-const char *skill_name(SkillID skill)
+const std::string& skill_name(SkillID skill)
{
return skill_lookup_by_id(skill).desc;
}
diff --git a/src/map/storage.cpp b/src/map/storage.cpp
index 463dd7c..5145b80 100644
--- a/src/map/storage.cpp
+++ b/src/map/storage.cpp
@@ -21,33 +21,6 @@
static
Map<int, struct storage> storage_db;
-/*==========================================
- * 倉庫内アイテムソート
- *------------------------------------------
- */
-static
-int storage_comp_item(const void *_i1, const void *_i2)
-{
- const struct item *i1 = (const struct item *) _i1;
- const struct item *i2 = (const struct item *) _i2;
-
- if (i1->nameid == i2->nameid)
- return 0;
- else if (!(i1->nameid) || !(i1->amount))
- return 1;
- else if (!(i2->nameid) || !(i2->amount))
- return -1;
- return i1->nameid - i2->nameid;
-}
-
-static
-void sortage_sortitem(struct storage *stor)
-{
- nullpo_retv(stor);
- qsort(stor->storage_, MAX_STORAGE, sizeof(struct item),
- storage_comp_item);
-}
-
void do_init_storage(void)
{
}
@@ -328,14 +301,15 @@ 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)
{
- struct storage *stor;
+ struct storage *stor = account2storage2(account_id);
- if ((stor = account2storage2(account_id)) != NULL)
- { //Only mark it clean if it's not in use. [Skotlex]
+ if (stor)
+ {
+ //Only mark it clean if it's not in use. [Skotlex]
if (stor->dirty && stor->storage_status == 0)
{
stor->dirty = 0;
- sortage_sortitem(stor);
+ // sortage_sortitem(stor);
}
return 1;
}
diff --git a/src/map/tmw.cpp b/src/map/tmw.cpp
index 9740ad8..955ea74 100644
--- a/src/map/tmw.cpp
+++ b/src/map/tmw.cpp
@@ -63,7 +63,7 @@ int tmw_CheckChatSpam(dumb_ptr<map_session_data> sd, const char *message)
if (tmw_CheckChatLameness(sd, message))
sd->chat_lines_in += battle_config.chat_lame_penalty;
- strncpy((char *) sd->chat_lastmsg, message, battle_config.chat_maxline);
+ strncpy(sd->chat_lastmsg, message, battle_config.chat_maxline);
if (sd->chat_lines_in >= battle_config.chat_spam_flood
|| sd->chat_total_repeats >= battle_config.chat_spam_flood)
diff --git a/src/map/trade.cpp b/src/map/trade.cpp
index ff54caa..c0f8c46 100644
--- a/src/map/trade.cpp
+++ b/src/map/trade.cpp
@@ -108,7 +108,7 @@ void trade_tradeadditem(dumb_ptr<map_session_data> sd, int index, int amount)
struct item_data *id;
int trade_i;
int trade_weight = 0;
- int free = 0;
+ int free_ = 0;
int c;
int i;
@@ -133,7 +133,7 @@ void trade_tradeadditem(dumb_ptr<map_session_data> sd, int index, int amount)
{
if (target_sd->status.inventory[i].nameid == 0
&& target_sd->inventory_data[i] == NULL)
- free++;
+ free_++;
}
for (trade_i = 0; trade_i < 10; trade_i++)
{
@@ -156,7 +156,7 @@ void trade_tradeadditem(dumb_ptr<map_session_data> sd, int index, int amount)
&& id->type != ItemType::_7
&& id->type != ItemType::_8)
{
- free++;
+ free_++;
break;
}
}
@@ -167,7 +167,7 @@ void trade_tradeadditem(dumb_ptr<map_session_data> sd, int index, int amount)
{
clif_tradeitemok(sd, index, 0, 1); //fail to add item -- the player was over weighted.
}
- else if (free <= 0)
+ else if (free_ <= 0)
{
clif_tradeitemok(sd, index, 0, 2); //fail to add item -- no free slots at receiver
}
@@ -210,14 +210,14 @@ void trade_tradeadditem(dumb_ptr<map_session_data> sd, int index, int amount)
&& id->type != ItemType::_7
&& id->type != ItemType::_8)
{
- free++;
+ free_++;
break;
}
}
}
}
// used a slot, but might be cancelled out by stackable checks above
- free--;
+ free_--;
}
}
}