summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ints/wrap.hpp17
-rw-r--r--src/map/atcommand.cpp5
-rw-r--r--src/map/clif.cpp267
-rw-r--r--src/map/clif.hpp7
-rw-r--r--src/map/magic-stmt.cpp10
-rw-r--r--src/map/map.cpp5
-rw-r--r--src/map/map.hpp2
-rw-r--r--src/map/mapflag.cpp2
-rw-r--r--src/map/mapflag.hpp2
-rw-r--r--src/map/mapflag.py2
-rw-r--r--src/map/npc-parse.cpp15
-rw-r--r--src/map/pc.cpp10
-rw-r--r--src/map/script-fun.cpp131
-rw-r--r--src/mmo/version.hpp3
-rw-r--r--src/wire/packets.cpp1
15 files changed, 359 insertions, 120 deletions
diff --git a/src/ints/wrap.hpp b/src/ints/wrap.hpp
index 707c787..25b03c1 100644
--- a/src/ints/wrap.hpp
+++ b/src/ints/wrap.hpp
@@ -64,6 +64,14 @@ namespace ints
}
template<class T>
+ struct Sub : T
+ {
+ constexpr
+ Sub(typename T::wrapped_type v2)
+ : T(v2)
+ {}
+ };
+ template<class T>
constexpr
typename T::wrapped_type unwrap(typename std::enable_if<true, T>::type w)
{
@@ -73,14 +81,7 @@ namespace ints
constexpr
T wrap(typename T::wrapped_type v)
{
- struct Sub : T
- {
- constexpr
- Sub(typename T::wrapped_type v2)
- : T(v2)
- {}
- };
- return Sub(v);
+ return Sub<T>(v);
}
template<class W>
diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp
index 63a1159..5db8288 100644
--- a/src/map/atcommand.cpp
+++ b/src/map/atcommand.cpp
@@ -4108,6 +4108,9 @@ ATCE atcommand_pvp(Session *s, dumb_ptr<map_session_data> sd,
clif_displaymessage(s, "##3PvP : ##BOff"_s);
}
+ sd->state.pvp_rank = 0;
+ clif_pvpstatus(sd); // send my channel to others
+
pc_setpvptimer(sd, battle_config.player_pvp_time);
return ATCE::OKAY;
}
@@ -4127,6 +4130,8 @@ ATCE atcommand_charpvp(Session *, dumb_ptr<map_session_data>,
return ATCE::EXIST;
pl_sd->state.pvpchannel = channel;
+ pl_sd->state.pvp_rank = 0;
+ clif_pvpstatus(pl_sd); // send their channel to others
return ATCE::OKAY;
}
diff --git a/src/map/clif.cpp b/src/map/clif.cpp
index 248f74a..35cc463 100644
--- a/src/map/clif.cpp
+++ b/src/map/clif.cpp
@@ -217,7 +217,7 @@ AString clif_validate_chat(dumb_ptr<map_session_data> sd, ChatType type, XString
*/
static
void clif_send_sub(dumb_ptr<block_list> bl, const Buffer& buf,
- dumb_ptr<block_list> src_bl, SendWho type)
+ dumb_ptr<block_list> src_bl, SendWho type, short min_version)
{
nullpo_retv(bl);
dumb_ptr<map_session_data> sd = bl->is_player();
@@ -246,6 +246,7 @@ void clif_send_sub(dumb_ptr<block_list> bl, const Buffer& buf,
if (sd->sess != nullptr)
{
{
+ if (sd->client_version >= min_version)
{
send_buffer(sd->sess, buf);
}
@@ -258,7 +259,7 @@ void clif_send_sub(dumb_ptr<block_list> bl, const Buffer& buf,
*------------------------------------------
*/
static
-int clif_send(const Buffer& buf, dumb_ptr<block_list> bl, SendWho type)
+int clif_send(const Buffer& buf, dumb_ptr<block_list> bl, SendWho type, short min_version)
{
int x0 = 0, x1 = 0, y0 = 0, y1 = 0;
@@ -323,14 +324,14 @@ int clif_send(const Buffer& buf, dumb_ptr<block_list> bl, SendWho type)
break;
case SendWho::AREA:
case SendWho::AREA_WOS:
- map_foreachinarea(std::bind(clif_send_sub, ph::_1, buf, bl, type),
+ map_foreachinarea(std::bind(clif_send_sub, ph::_1, buf, bl, type, min_version),
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, bl, SendWho::AREA_CHAT_WOC),
+ map_foreachinarea(std::bind(clif_send_sub, ph::_1, buf, bl, SendWho::AREA_CHAT_WOC, min_version),
bl->bl_m,
bl->bl_x - (AREA_SIZE), bl->bl_y - (AREA_SIZE),
bl->bl_x + (AREA_SIZE), bl->bl_y + (AREA_SIZE),
@@ -380,6 +381,7 @@ int clif_send(const Buffer& buf, dumb_ptr<block_list> bl, SendWho type)
(sd->bl_x < x0 || sd->bl_y < y0 ||
sd->bl_x > x1 || sd->bl_y > y1))
continue;
+ if (sd->client_version >= min_version)
{
send_buffer(sd->sess, buf);
}
@@ -395,6 +397,7 @@ int clif_send(const Buffer& buf, dumb_ptr<block_list> bl, SendWho type)
{
if (sd->partyspy == p.party_id)
{
+ if (sd->client_version >= min_version)
{
send_buffer(sd->sess, buf);
}
@@ -410,7 +413,8 @@ int clif_send(const Buffer& buf, dumb_ptr<block_list> bl, SendWho type)
dumb_ptr<map_session_data> sd = bl->is_player();
{
- send_buffer(sd->sess, buf);
+ if (sd->client_version >= min_version)
+ send_buffer(sd->sess, buf);
}
}
break;
@@ -528,7 +532,7 @@ int clif_dropflooritem(dumb_ptr<flooritem_data> fitem)
Buffer buf;
clif_set009e(fitem, buf);
- clif_send(buf, fitem, SendWho::AREA);
+ clif_send(buf, fitem, SendWho::AREA, MIN_CLIENT_VERSION);
return 0;
}
@@ -547,7 +551,7 @@ int clif_clearflooritem(dumb_ptr<flooritem_data> fitem, Session *s)
if (!s)
{
Buffer buf = create_fpacket<0x00a1, 6>(fixed_a1);
- clif_send(buf, fitem, SendWho::AREA);
+ clif_send(buf, fitem, SendWho::AREA, MIN_CLIENT_VERSION);
}
else
{
@@ -572,14 +576,14 @@ int clif_clearchar(dumb_ptr<block_list> bl, BeingRemoveWhy type)
{
fixed_80.type = BeingRemoveWhy::GONE;
Buffer buf = create_fpacket<0x0080, 7>(fixed_80);
- clif_send(buf, bl, SendWho::AREA);
+ clif_send(buf, bl, SendWho::AREA, MIN_CLIENT_VERSION);
}
else
{
fixed_80.type = type;
Buffer buf = create_fpacket<0x0080, 7>(fixed_80);
clif_send(buf, bl,
- type == BeingRemoveWhy::DEAD ? SendWho::AREA : SendWho::AREA_WOS);
+ type == BeingRemoveWhy::DEAD ? SendWho::AREA : SendWho::AREA_WOS, MIN_CLIENT_VERSION);
}
return 0;
@@ -796,6 +800,24 @@ void clif_mob0078(dumb_ptr<mob_data> md, Buffer& buf)
buf = create_fpacket<0x0078, 54>(fixed_78);
}
+void clif_npc_action(dumb_ptr<map_session_data> sd, BlockId npcid,
+ short command, int id, short x, short y)
+{
+ nullpo_retv(sd);
+ if(sd->client_version < 2)
+ return;
+
+ Packet_Fixed<0x0212> fixed_212;
+ fixed_212.npc_id = npcid;
+ fixed_212.command = command;
+ fixed_212.id = id;
+ fixed_212.x = x;
+ fixed_212.y = y;
+
+ Buffer buf = create_fpacket<0x0212, 16>(fixed_212);
+ send_buffer(sd->sess, buf);
+}
+
/*==========================================
* MOB表示2
*------------------------------------------
@@ -835,21 +857,6 @@ void clif_mob007b(dumb_ptr<mob_data> md, Buffer& buf)
*------------------------------------------
*/
static
-void clif_0225_being_move3_sub(dumb_ptr<block_list> bl, const Buffer& buf)
-{
- nullpo_retv(bl);
- dumb_ptr<map_session_data> sd = bl->is_player();
-
- if (sd->sess != nullptr)
- {
- if(sd->client_version >= 3)
- {
- send_buffer(sd->sess, buf);
- }
- }
-}
-
-static
int clif_0225_being_move3(dumb_ptr<mob_data> md)
{
Packet_Head<0x0225> head_225;
@@ -869,11 +876,7 @@ int clif_0225_being_move3(dumb_ptr<mob_data> md)
Buffer buf = create_vpacket<0x0225, 14, 1>(head_225, repeat_225);
- map_foreachinarea(std::bind(clif_0225_being_move3_sub, ph::_1, buf),
- md->bl_m,
- md->bl_x - AREA_SIZE, md->bl_y - AREA_SIZE,
- md->bl_x + AREA_SIZE, md->bl_y + AREA_SIZE,
- BL::PC);
+ clif_send(buf, md, SendWho::AREA, 3);
return 0;
}
@@ -928,7 +931,9 @@ int clif_spawnpc(dumb_ptr<map_session_data> sd)
Buffer buf;
clif_set0078_alt_1d9(sd, buf);
- clif_send(buf, sd, SendWho::AREA_WOS);
+ clif_send(buf, sd, SendWho::AREA_WOS, MIN_CLIENT_VERSION);
+
+ clif_pvpstatus(sd);
if (sd->bl_m->flag.get(MapFlag::SNOW))
clif_specialeffect(sd, 162, 1);
@@ -965,17 +970,17 @@ int clif_spawnnpc(dumb_ptr<npc_data> nd)
fixed_7c.pos.y = nd->bl_y;
Buffer buf = create_fpacket<0x007c, 41>(fixed_7c);
- clif_send(buf, nd, SendWho::AREA);
+ clif_send(buf, nd, SendWho::AREA, MIN_CLIENT_VERSION);
*/
Buffer buf;
clif_npc0078(nd, buf);
- clif_send(buf, nd, SendWho::AREA);
+ clif_send(buf, nd, SendWho::AREA, MIN_CLIENT_VERSION);
if(nd->sit == DamageType::SIT)
{
Buffer buff;
clif_sitnpc_sub(buff, nd, nd->sit);
- clif_send(buff, nd, SendWho::AREA);
+ clif_send(buff, nd, SendWho::AREA, MIN_CLIENT_VERSION);
}
return 0;
@@ -1034,12 +1039,12 @@ int clif_spawnmob(dumb_ptr<mob_data> md)
fixed_7c.pos.x = md->bl_x;
fixed_7c.pos.y = md->bl_y;
Buffer buf = create_fpacket<0x007c, 41>(fixed_7c);
- clif_send(buf, md, SendWho::AREA);
+ clif_send(buf, md, SendWho::AREA, MIN_CLIENT_VERSION);
}
Buffer buf;
clif_mob0078(md, buf);
- clif_send(buf, md, SendWho::AREA);
+ clif_send(buf, md, SendWho::AREA, MIN_CLIENT_VERSION);
return 0;
}
@@ -1093,7 +1098,7 @@ int clif_movechar(dumb_ptr<map_session_data> sd)
Buffer buf;
clif_set007b(sd, buf);
- clif_send(buf, sd, SendWho::AREA_WOS);
+ clif_send(buf, sd, SendWho::AREA_WOS, MIN_CLIENT_VERSION);
if (battle_config.save_clothcolor == 1 && sd->status.clothes_color > 0)
clif_changelook(sd, LOOK::CLOTHES_COLOR,
@@ -1150,6 +1155,9 @@ void clif_changemap(dumb_ptr<map_session_data> sd, MapName mapname, int x, int y
fixed_91.x = x;
fixed_91.y = y;
send_fpacket<0x0091, 22>(s, fixed_91);
+
+ if(sd->bl_m->mask > 0)
+ clif_send_mask(sd, sd->bl_m->mask);
}
/*==========================================
@@ -1185,7 +1193,7 @@ void clif_fixpos(dumb_ptr<block_list> bl)
fixed_88.y = bl->bl_y;
Buffer buf = create_fpacket<0x0088, 10>(fixed_88);
- clif_send(buf, bl, SendWho::AREA);
+ clif_send(buf, bl, SendWho::AREA, MIN_CLIENT_VERSION);
}
/*==========================================
@@ -1863,9 +1871,9 @@ int clif_changelook_towards(dumb_ptr<block_list> bl, LOOK type, int val,
Buffer buf = create_fpacket<0x01d7, 11>(fixed_1d7);
if (dstsd)
- clif_send(buf, dstsd, SendWho::SELF);
+ clif_send(buf, dstsd, SendWho::SELF, MIN_CLIENT_VERSION);
else
- clif_send(buf, bl, SendWho::AREA);
+ clif_send(buf, bl, SendWho::AREA, MIN_CLIENT_VERSION);
}
else
{
@@ -1877,9 +1885,9 @@ int clif_changelook_towards(dumb_ptr<block_list> bl, LOOK type, int val,
Buffer buf = create_fpacket<0x01d7, 11>(fixed_1d7);
if (dstsd)
- clif_send(buf, dstsd, SendWho::SELF);
+ clif_send(buf, dstsd, SendWho::SELF, MIN_CLIENT_VERSION);
else
- clif_send(buf, bl, SendWho::AREA);
+ clif_send(buf, bl, SendWho::AREA, MIN_CLIENT_VERSION);
}
return 0;
}
@@ -2043,11 +2051,42 @@ int clif_misceffect(dumb_ptr<block_list> bl, int type)
fixed_19b.type = type;
Buffer buf = create_fpacket<0x019b, 10>(fixed_19b);
- clif_send(buf, bl, SendWho::AREA);
+ clif_send(buf, bl, SendWho::AREA, MIN_CLIENT_VERSION);
return 0;
}
+void clif_map_pvp(dumb_ptr<map_session_data> sd)
+{
+ nullpo_retv(sd);
+
+ Packet_Fixed<0x0199> fixed_199;
+ fixed_199.status = sd->bl_m->flag.get(MapFlag::PVP)? 1: 0;
+ Buffer buf = create_fpacket<0x0199, 4>(fixed_199);
+
+ clif_send(buf, sd, SendWho::SELF, 2);
+}
+
+static
+void clif_pvpstatus_towards(Buffer& buf, dumb_ptr<map_session_data> sd)
+{
+ nullpo_retv(sd);
+
+ Packet_Fixed<0x019a> fixed_19a;
+ fixed_19a.block_id = sd->bl_id;
+ fixed_19a.rank = sd->state.pvp_rank;
+ fixed_19a.channel = sd->state.pvpchannel;
+ buf = create_fpacket<0x019a, 14>(fixed_19a);
+}
+
+void clif_pvpstatus(dumb_ptr<map_session_data> sd)
+{
+ nullpo_retv(sd);
+ Buffer buf;
+ clif_pvpstatus_towards(buf, sd);
+ clif_send(buf, sd, SendWho::AREA, 2);
+}
+
/*==========================================
* 表示オプション変更
*------------------------------------------
@@ -2069,7 +2108,7 @@ int clif_changeoption(dumb_ptr<block_list> bl)
fixed_119.zero = 0;
Buffer buf = create_fpacket<0x0119, 13>(fixed_119);
- clif_send(buf, bl, SendWho::AREA);
+ clif_send(buf, bl, SendWho::AREA, MIN_CLIENT_VERSION);
return 0;
}
@@ -2101,7 +2140,7 @@ int clif_useitemack(dumb_ptr<map_session_data> sd, IOff0 index, int amount,
fixed_1c8.amount = amount;
fixed_1c8.ok = ok;
Buffer buf = create_fpacket<0x01c8, 13>(fixed_1c8);
- clif_send(buf, sd, SendWho::SELF);
+ clif_send(buf, sd, SendWho::SELF, MIN_CLIENT_VERSION);
}
return 0;
@@ -2356,6 +2395,10 @@ void clif_getareachar_pc(dumb_ptr<map_session_data> sd,
}
send_buffer(sd->sess, buf);
+ Buffer buff;
+ clif_pvpstatus_towards(buff, dstsd);
+ clif_send(buff, sd, SendWho::SELF, 2);
+
if (battle_config.save_clothcolor == 1 && dstsd->status.clothes_color > 0)
clif_changelook(dstsd, LOOK::CLOTHES_COLOR,
dstsd->status.clothes_color);
@@ -2399,7 +2442,7 @@ int clif_movemob(dumb_ptr<mob_data> md)
Buffer buf;
clif_mob007b(md, buf);
- clif_send(buf, md, SendWho::AREA);
+ clif_send(buf, md, SendWho::AREA, MIN_CLIENT_VERSION);
clif_0225_being_move3(md);
return 0;
@@ -2417,13 +2460,13 @@ int clif_fixmobpos(dumb_ptr<mob_data> md)
{
Buffer buf;
clif_mob007b(md, buf);
- clif_send(buf, md, SendWho::AREA);
+ clif_send(buf, md, SendWho::AREA, MIN_CLIENT_VERSION);
}
else
{
Buffer buf;
clif_mob0078(md, buf);
- clif_send(buf, md, SendWho::AREA);
+ clif_send(buf, md, SendWho::AREA, MIN_CLIENT_VERSION);
}
return 0;
@@ -2441,13 +2484,13 @@ int clif_fixpcpos(dumb_ptr<map_session_data> sd)
{
Buffer buf;
clif_set007b(sd, buf);
- clif_send(buf, sd, SendWho::AREA);
+ clif_send(buf, sd, SendWho::AREA, MIN_CLIENT_VERSION);
}
else
{
Buffer buf;
clif_set0078_main_1d8(sd, buf);
- clif_send(buf, sd, SendWho::AREA);
+ clif_send(buf, sd, SendWho::AREA, MIN_CLIENT_VERSION);
}
clif_changelook_accessories(sd, nullptr);
@@ -2480,7 +2523,7 @@ int clif_damage(dumb_ptr<block_list> src, dumb_ptr<block_list> dst,
fixed_8a.damage_type = type;
fixed_8a.damage2 = 0;
Buffer buf = create_fpacket<0x008a, 29>(fixed_8a);
- clif_send(buf, src, SendWho::AREA);
+ clif_send(buf, src, SendWho::AREA, MIN_CLIENT_VERSION);
return 0;
}
@@ -2687,7 +2730,7 @@ void clif_skillinfoblock(dumb_ptr<map_session_data> sd)
std::vector<Packet_Repeat<0x010f>> repeat_10f;
for (SkillID i : erange(SkillID(), MAX_SKILL))
{
- if (sd->status.skill[i].lv && sd->client_version >= 1)
+ if (sd->status.skill[i].lv)
{
Packet_Repeat<0x010f> info;
// [Fate] Version 1 and later don't crash because of bad skill IDs anymore
@@ -2802,7 +2845,7 @@ int clif_skill_damage(dumb_ptr<block_list> src, dumb_ptr<block_list> dst,
fixed_1de.div = div;
fixed_1de.type_or_hit = (type > 0) ? type : skill_get_hit(skill_id);
Buffer buf = create_fpacket<0x01de, 33>(fixed_1de);
- clif_send(buf, src, SendWho::AREA);
+ clif_send(buf, src, SendWho::AREA, MIN_CLIENT_VERSION);
return 0;
}
@@ -2820,7 +2863,7 @@ int clif_status_change(dumb_ptr<block_list> bl, StatusChange type, int flag)
fixed_196.block_id = bl->bl_id;
fixed_196.flag = flag;
Buffer buf = create_fpacket<0x0196, 9>(fixed_196);
- clif_send(buf, bl, SendWho::AREA);
+ clif_send(buf, bl, SendWho::AREA, MIN_CLIENT_VERSION);
return 0;
}
@@ -2850,7 +2893,7 @@ void clif_GMmessage(dumb_ptr<block_list> bl, XString mes, int flag)
(flag == 1) ? SendWho::ALL_SAMEMAP :
(flag == 2) ? SendWho::AREA :
(flag == 3) ? SendWho::SELF :
- SendWho::ALL_CLIENT);
+ SendWho::ALL_CLIENT, MIN_CLIENT_VERSION);
}
/*==========================================
@@ -2867,7 +2910,7 @@ void clif_resurrection(dumb_ptr<block_list> bl, int type)
Buffer buf = create_fpacket<0x0148, 8>(fixed_148);
clif_send(buf, bl,
- type == 1 ? SendWho::AREA : SendWho::AREA_WOS);
+ type == 1 ? SendWho::AREA : SendWho::AREA_WOS, MIN_CLIENT_VERSION);
}
/*==========================================
@@ -2954,7 +2997,7 @@ int clif_party_info(PartyPair p, Session *s)
if (sd != nullptr)
{
Buffer buf = create_vpacket<0x00fb, 28, 46>(head_fb, repeat_fb);
- clif_send(buf, sd, SendWho::PARTY);
+ clif_send(buf, sd, SendWho::PARTY, MIN_CLIENT_VERSION);
}
return 0;
}
@@ -3031,7 +3074,7 @@ void clif_party_option(PartyPair p, dumb_ptr<map_session_data> sd, int flag)
if (flag == 0)
{
Buffer buf = create_fpacket<0x0101, 6>(fixed_101);
- clif_send(buf, sd, SendWho::PARTY);
+ clif_send(buf, sd, SendWho::PARTY, MIN_CLIENT_VERSION);
}
else
{
@@ -3065,7 +3108,7 @@ void clif_party_leaved(PartyPair p, dumb_ptr<map_session_data> sd,
if (sd != nullptr)
{
Buffer buf = create_fpacket<0x0105, 31>(fixed_105);
- clif_send(buf, sd, SendWho::PARTY);
+ clif_send(buf, sd, SendWho::PARTY, MIN_CLIENT_VERSION);
}
}
else if (sd != nullptr)
@@ -3095,7 +3138,7 @@ void clif_party_message(PartyPair p, AccountId account_id, XString mes)
Packet_Head<0x0109> head_109;
head_109.account_id = account_id;
Buffer buf = create_vpacket<0x0109, 8, 1>(head_109, mes);
- clif_send(buf, sd, SendWho::PARTY);
+ clif_send(buf, sd, SendWho::PARTY, MIN_CLIENT_VERSION);
}
}
@@ -3112,7 +3155,7 @@ int clif_party_xy(PartyPair , dumb_ptr<map_session_data> sd)
fixed_107.x = sd->bl_x;
fixed_107.y = sd->bl_y;
Buffer buf = create_fpacket<0x0107, 10>(fixed_107);
- clif_send(buf, sd, SendWho::PARTY_SAMEMAP_WOS);
+ clif_send(buf, sd, SendWho::PARTY_SAMEMAP_WOS, MIN_CLIENT_VERSION);
return 0;
}
@@ -3130,7 +3173,7 @@ int clif_party_hp(PartyPair , dumb_ptr<map_session_data> sd)
fixed_106.max_hp =
(sd->status.max_hp > 0x7fff) ? 0x7fff : sd->status.max_hp;
Buffer buf = create_fpacket<0x0106, 10>(fixed_106);
- clif_send(buf, sd, SendWho::PARTY_AREA_WOS);
+ clif_send(buf, sd, SendWho::PARTY_AREA_WOS, MIN_CLIENT_VERSION);
return 0;
}
@@ -3167,7 +3210,7 @@ void clif_emotion(dumb_ptr<block_list> bl, int type)
fixed_c0.block_id = bl->bl_id;
fixed_c0.type = type;
Buffer buf = create_fpacket<0x00c0, 7>(fixed_c0);
- clif_send(buf, bl, SendWho::AREA);
+ clif_send(buf, bl, SendWho::AREA, MIN_CLIENT_VERSION);
}
void clif_emotion_towards(dumb_ptr<block_list> bl,
@@ -3200,7 +3243,7 @@ void clif_sitting(Session *, dumb_ptr<map_session_data> sd)
fixed_8a.src_id = sd->bl_id;
fixed_8a.damage_type = DamageType::SIT;
Buffer buf = create_fpacket<0x008a, 29>(fixed_8a);
- clif_send(buf, sd, SendWho::AREA);
+ clif_send(buf, sd, SendWho::AREA, MIN_CLIENT_VERSION);
}
static
@@ -3224,7 +3267,7 @@ void clif_sitnpc_towards(dumb_ptr<map_session_data> sd, dumb_ptr<npc_data> nd, D
Buffer buf;
clif_sitnpc_sub(buf, nd, dmg);
- clif_send(buf, sd, SendWho::SELF);
+ clif_send(buf, sd, SendWho::SELF, MIN_CLIENT_VERSION);
}
void clif_sitnpc(dumb_ptr<npc_data> nd, DamageType dmg)
@@ -3233,7 +3276,7 @@ void clif_sitnpc(dumb_ptr<npc_data> nd, DamageType dmg)
Buffer buf;
clif_sitnpc_sub(buf, nd, dmg);
- clif_send(buf, nd, SendWho::AREA);
+ clif_send(buf, nd, SendWho::AREA, MIN_CLIENT_VERSION);
}
static
@@ -3270,7 +3313,7 @@ void clif_setnpcdirection_towards(dumb_ptr<map_session_data> sd, dumb_ptr<npc_da
Buffer buf;
clif_setnpcdirection_sub(buf, nd, direction);
- clif_send(buf, sd, SendWho::SELF);
+ clif_send(buf, sd, SendWho::SELF, MIN_CLIENT_VERSION);
}
void clif_setnpcdirection(dumb_ptr<npc_data> nd, DIR direction)
@@ -3279,7 +3322,7 @@ void clif_setnpcdirection(dumb_ptr<npc_data> nd, DIR direction)
Buffer buf;
clif_setnpcdirection_sub(buf, nd, direction);
- clif_send(buf, nd, SendWho::AREA);
+ clif_send(buf, nd, SendWho::AREA, MIN_CLIENT_VERSION);
}
/*==========================================
@@ -3338,9 +3381,9 @@ int clif_specialeffect(dumb_ptr<block_list> bl, int type, int flag)
}
}
else if (flag == 1)
- clif_send(buf, bl, SendWho::SELF);
+ clif_send(buf, bl, SendWho::SELF, MIN_CLIENT_VERSION);
else if (!flag)
- clif_send(buf, bl, SendWho::AREA);
+ clif_send(buf, bl, SendWho::AREA, MIN_CLIENT_VERSION);
return 0;
@@ -3455,6 +3498,8 @@ RecvResult clif_parse_LoadEndAck(Session *s, dumb_ptr<map_session_data> sd)
map_addblock(sd); // ブロック登録
clif_spawnpc(sd); // spawn
+ clif_map_pvp(sd); // send map pvp status
+
// weight max , now
clif_updatestatus(sd, SP::MAXWEIGHT);
clif_updatestatus(sd, SP::WEIGHT);
@@ -3758,7 +3803,7 @@ RecvResult clif_parse_GlobalMessage(Session *s, dumb_ptr<map_session_data> sd)
XString repeat_8d = mbuf;
Buffer sendbuf = create_vpacket<0x008d, 8, 1>(head_8d, repeat_8d);
- clif_send(sendbuf, sd, SendWho::AREA_CHAT_WOC);
+ clif_send(sendbuf, sd, SendWho::AREA_CHAT_WOC, MIN_CLIENT_VERSION);
}
/* Send the message back to the speaker. */
@@ -3767,19 +3812,81 @@ RecvResult clif_parse_GlobalMessage(Session *s, dumb_ptr<map_session_data> sd)
return rv;
}
-void clif_message(dumb_ptr<block_list> bl, XString msg)
+static
+void clif_message_sub(Buffer& buf, dumb_ptr<block_list> bl, XString msg)
{
size_t msg_len = msg.size() + 1;
if (msg_len + 16 > 512)
return;
- nullpo_retv(bl);
-
Packet_Head<0x008d> head_8d;
head_8d.block_id = bl->bl_id;
- Buffer buf = create_vpacket<0x008d, 8, 1>(head_8d, msg);
+ buf = create_vpacket<0x008d, 8, 1>(head_8d, msg);
+}
+
+void clif_npc_send_title(Session *s, BlockId npcid, XString msg)
+{
+ size_t msg_len = msg.size() + 1;
+ if (msg_len > 50)
+ return;
+
+ Packet_Head<0x0228> head_228;
+ head_228.npc_id = npcid;
+ head_228.string_length = msg_len;
+ Buffer buf = create_vpacket<0x0228, 10, 1>(head_228, msg);
+
+ send_buffer(s, buf);
+}
+
+void clif_change_music(dumb_ptr<map_session_data> sd, XString music)
+{
+ nullpo_retv(sd);
+ if(sd->client_version < 2)
+ return;
+
+ size_t msg_len = music.size();
+ if (msg_len > 128)
+ return;
+
+ Packet_Head<0x0227> head_227;
+ Buffer buf = create_vpacket<0x0227, 4, 1>(head_227, music);
+
+ send_buffer(sd->sess, buf);
+}
+
+void clif_message_towards(dumb_ptr<map_session_data> sd, dumb_ptr<block_list> bl, XString msg)
+{
+ nullpo_retv(bl);
+ nullpo_retv(sd);
+
+ if(!sd)
+ return;
+
+ Buffer buf;
+ clif_message_sub(buf, bl, msg);
+ clif_send(buf, sd, SendWho::SELF, MIN_CLIENT_VERSION);
+}
+
+void clif_message(dumb_ptr<block_list> bl, XString msg)
+{
+ nullpo_retv(bl);
- clif_send(buf, bl, SendWho::AREA);
+ Buffer buf;
+ clif_message_sub(buf, bl, msg);
+ clif_send(buf, bl, SendWho::AREA, MIN_CLIENT_VERSION);
+}
+
+void clif_send_mask(dumb_ptr<map_session_data> sd, int map_mask)
+{
+ nullpo_retv(sd);
+ if(sd->client_version < 2)
+ return;
+
+ Packet_Fixed<0x0226> fixed_226;
+ fixed_226.mask = map_mask;
+
+ Buffer buf = create_fpacket<0x0226, 10>(fixed_226);
+ send_buffer(sd->sess, buf);
}
/*==========================================
@@ -3823,7 +3930,7 @@ RecvResult clif_parse_ChangeDir(Session *s, dumb_ptr<map_session_data> sd)
fixed_9c.client_dir = client_dir;
Buffer buf = create_fpacket<0x009c, 9>(fixed_9c);
- clif_send(buf, sd, SendWho::AREA_WOS);
+ clif_send(buf, sd, SendWho::AREA_WOS, MIN_CLIENT_VERSION);
return rv;
}
@@ -3848,7 +3955,7 @@ RecvResult clif_parse_Emotion(Session *s, dumb_ptr<map_session_data> sd)
fixed_c0.block_id = sd->bl_id;
fixed_c0.type = emote;
Buffer buf = create_fpacket<0x00c0, 7>(fixed_c0);
- clif_send(buf, sd, SendWho::AREA);
+ clif_send(buf, sd, SendWho::AREA, MIN_CLIENT_VERSION);
}
else
clif_skill_fail(sd, SkillID::ONE, 0, 1);
@@ -3919,7 +4026,7 @@ RecvResult clif_parse_ActionRequest(Session *s, dumb_ptr<map_session_data> sd)
fixed_8a.src_id = sd->bl_id;
fixed_8a.damage_type = DamageType::STAND;
Buffer buf = create_fpacket<0x008a, 29>(fixed_8a);
- clif_send(buf, sd, SendWho::AREA);
+ clif_send(buf, sd, SendWho::AREA, MIN_CLIENT_VERSION);
break;
}
@@ -4817,7 +4924,7 @@ void clif_sendallquest(dumb_ptr<map_session_data> sd)
if (!sd->sess)
return;
- if(sd->client_version < 2)
+ if(sd->client_version < 2) // require 1.5.5.9 or above
return;
Session *s = sd->sess;
@@ -4854,7 +4961,7 @@ void clif_sendquest(dumb_ptr<map_session_data> sd, QuestId questid, int value)
if (!sd->sess)
return;
- if(sd->client_version < 2)
+ if(sd->client_version < 2) // require 1.5.5.9 or above
return;
Session *s = sd->sess;
diff --git a/src/map/clif.hpp b/src/map/clif.hpp
index 3cc308c..28f58a9 100644
--- a/src/map/clif.hpp
+++ b/src/map/clif.hpp
@@ -72,6 +72,7 @@ void clif_scriptclose(dumb_ptr<map_session_data>, BlockId); //self
void clif_scriptmenu(dumb_ptr<map_session_data>, BlockId, XString); //self
void clif_scriptinput(dumb_ptr<map_session_data>, BlockId); //self
void clif_scriptinputstr(dumb_ptr<map_session_data> sd, BlockId npcid); // self
+void clif_map_pvp(dumb_ptr<map_session_data>); // self
int clif_additem(dumb_ptr<map_session_data>, IOff0, int, PickupFail); //self
void clif_delitem(dumb_ptr<map_session_data>, IOff0, int); //self
@@ -92,6 +93,7 @@ int clif_statusupack(dumb_ptr<map_session_data>, SP, int, int); // self
int clif_equipitemack(dumb_ptr<map_session_data>, IOff0, EPOS, int); // self
int clif_unequipitemack(dumb_ptr<map_session_data>, IOff0, EPOS, int); // self
int clif_misceffect(dumb_ptr<block_list>, int); // area
+void clif_pvpstatus(dumb_ptr<map_session_data>); // area
int clif_changeoption(dumb_ptr<block_list>); // area
int clif_useitemack(dumb_ptr<map_session_data>, IOff0, int, int); // self
@@ -102,6 +104,10 @@ void clif_sitnpc(dumb_ptr<npc_data> nd, DamageType dmg);
void clif_sitnpc_towards(dumb_ptr<map_session_data> sd, dumb_ptr<npc_data> nd, DamageType dmg);
void clif_setnpcdirection(dumb_ptr<npc_data> nd, DIR direction);
void clif_setnpcdirection_towards(dumb_ptr<map_session_data> sd, dumb_ptr<npc_data> nd, DIR direction);
+void clif_npc_send_title(Session *s, BlockId npcid, XString msg);
+void clif_change_music(dumb_ptr<map_session_data> sd, XString music);
+void clif_npc_action(dumb_ptr<map_session_data>, BlockId, short, int, short, short);
+void clif_send_mask(dumb_ptr<map_session_data>, int);
// trade
void clif_traderequest(dumb_ptr<map_session_data> sd, CharName name);
@@ -174,6 +180,7 @@ void clif_resurrection(dumb_ptr<block_list> bl, int type);
int clif_specialeffect(dumb_ptr<block_list> bl, int type, int flag); // special effects [Valaris]
void clif_message(dumb_ptr<block_list> bl, XString msg); // messages (from mobs/npcs) [Valaris]
+void clif_message_towards(dumb_ptr<map_session_data> sd, dumb_ptr<block_list> bl, XString msg);
int clif_GM_kick(dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> tsd,
int type);
diff --git a/src/map/magic-stmt.cpp b/src/map/magic-stmt.cpp
index 4d8330a..1a8085b 100644
--- a/src/map/magic-stmt.cpp
+++ b/src/map/magic-stmt.cpp
@@ -771,10 +771,12 @@ int op_injure(dumb_ptr<env_t> env, Slice<val_t> args)
int target_hp = battle_get_hp(target);
int mdef = battle_get_mdef(target);
- if (target->bl_type == BL::PC
- && !target->bl_m->flag.get(MapFlag::PVP)
- && (caster->bl_type == BL::PC)
- && ((caster->is_player()->state.pvpchannel > 1) && (target->is_player()->state.pvpchannel != caster->is_player()->state.pvpchannel)))
+ if (target->bl_type == BL::PC // target is player
+ && !target->bl_m->flag.get(MapFlag::PVP) // there is no pvpon flag
+ && (caster->bl_type == BL::PC) // caster is player
+ && ((target->is_player()->state.pvpchannel == 0)
+ || ((caster->is_player()->state.pvpchannel > 0)
+ && (target->is_player()->state.pvpchannel != caster->is_player()->state.pvpchannel))))
return 0; /* Cannot damage other players outside of pvp */
if (target != caster)
diff --git a/src/map/map.cpp b/src/map/map.cpp
index 7d219a9..0c73b59 100644
--- a/src/map/map.cpp
+++ b/src/map/map.cpp
@@ -183,7 +183,7 @@ int map_addblock(dumb_ptr<block_list> bl)
if (bl->bl_next)
bl->bl_next->bl_prev = bl;
m->blocks.ref(x / BLOCK_SIZE, y / BLOCK_SIZE).normal = bl;
- if (bl->bl_type == BL::PC)
+ if (bl->bl_type == BL::PC && !bool(bl->is_player()->status.option & Opt0::HIDE))
m->users++;
}
@@ -1237,7 +1237,8 @@ int map_setipport(MapName name, IP4Address ip, int port)
mdos->gat = nullptr;
mdos->ip = ip;
mdos->port = port;
- maps_db.put(mdos->name_, std::move(mdos));
+ MapName mName = mdos->name_;
+ maps_db.put(mName, std::move(mdos));
}
}
OMATCH_END ();
diff --git a/src/map/map.hpp b/src/map/map.hpp
index aac646b..aea35b7 100644
--- a/src/map/map.hpp
+++ b/src/map/map.hpp
@@ -143,6 +143,7 @@ struct map_session_data : block_list, SessionData
unsigned shroud_disappears_on_talk:1;
unsigned seen_motd:1;
unsigned pvpchannel;
+ unsigned pvp_rank;
} state;
struct
{
@@ -504,6 +505,7 @@ struct map_local : map_abstract
MapFlags flag;
Point save;
Point resave;
+ int mask;
Array<dumb_ptr<npc_data>, MAX_NPC_PER_MAP> npc;
};
diff --git a/src/map/mapflag.cpp b/src/map/mapflag.cpp
index 9f3c9ab..22c4878 100644
--- a/src/map/mapflag.cpp
+++ b/src/map/mapflag.cpp
@@ -71,7 +71,7 @@ bool impl_extract(XString str, MapFlag *mf)
{"nowarp"_s, MapFlag::NOWARP},
{"nowarpto"_s, MapFlag::NOWARPTO},
{"nopvp"_s, MapFlag::NOPVP},
- //{"noicewall"_s, MapFlag::NOICEWALL},
+ {"mask"_s, MapFlag::MASK},
{"snow"_s, MapFlag::SNOW},
{"fog"_s, MapFlag::FOG},
{"sakura"_s, MapFlag::SAKURA},
diff --git a/src/map/mapflag.hpp b/src/map/mapflag.hpp
index 3538c56..9223d70 100644
--- a/src/map/mapflag.hpp
+++ b/src/map/mapflag.hpp
@@ -54,7 +54,7 @@ enum class MapFlag
NOWARP = 1 << 13,
NOWARPTO = 1 << 26,
NOPVP = 1 << 14,
- //NOICEWALL = 1 << 15,
+ MASK = 1 << 15,
SNOW = 1 << 16,
FOG = 1 << 17,
SAKURA = 1 << 18,
diff --git a/src/map/mapflag.py b/src/map/mapflag.py
index b0a2f24..728aa81 100644
--- a/src/map/mapflag.py
+++ b/src/map/mapflag.py
@@ -40,7 +40,7 @@ class MapFlags(object):
('NOWARP', 13),
('NOWARPTO', 26),
('NOPVP', 14),
- #('NOICEWALL', 15),
+ ('MASK', 15),
('SNOW', 16),
('FOG', 17),
('SAKURA', 18),
diff --git a/src/map/npc-parse.cpp b/src/map/npc-parse.cpp
index 0a0d682..9ee84d2 100644
--- a/src/map/npc-parse.cpp
+++ b/src/map/npc-parse.cpp
@@ -354,7 +354,7 @@ bool npc_load_mapflag(ast::npc::MapFlag& mapflag)
}
MapName savemap;
- int savex, savey;
+ int savex, savey, mask;
if (mf == MapFlag::NOSAVE)
{
@@ -392,6 +392,19 @@ bool npc_load_mapflag(ast::npc::MapFlag& mapflag)
return false;
}
}
+ else if (mf == MapFlag::MASK)
+ {
+ if (mapflag.vec_extra.data.size() == 1
+ && extract(mapflag.vec_extra.data[0].data, &mask))
+ {
+ m->mask = mask;
+ }
+ else
+ {
+ mapflag.vec_extra.span.error("Unable to extract map mask"_s);
+ return false;
+ }
+ }
else
{
if (mapflag.vec_extra.data.size())
diff --git a/src/map/pc.cpp b/src/map/pc.cpp
index d2b2f44..96233e1 100644
--- a/src/map/pc.cpp
+++ b/src/map/pc.cpp
@@ -796,6 +796,9 @@ int pc_authok(AccountId id, int login_id2,
pc_calcstatus(sd, 1);
+ if(sd->bl_m->mask > 0)
+ clif_send_mask(sd, sd->bl_m->mask);
+
// Init Quest Log
clif_sendallquest(sd);
return 0;
@@ -944,7 +947,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
b_mdef = sd->mdef;
b_mdef2 = sd->mdef2;
b_base_atk = sd->base_atk;
- if (!pc_isdead(sd) && sd->state.pvpchannel == 1)
+ if (sd->state.pvpchannel == 1)
b_pvpchannel = sd->state.pvpchannel;
sd->max_weight = max_weight_base_0 + sd->status.attrs[ATTR::STR] * 300;
@@ -3313,6 +3316,11 @@ int pc_damage(dumb_ptr<block_list> src, dumb_ptr<map_session_data> sd,
};
npc_event_doall_l(stringish<ScriptLabel>("OnPCKilledEvent"_s), sd->bl_id, arg);
npc_event_doall_l(stringish<ScriptLabel>("OnPCKillEvent"_s), src->bl_id, arg);
+
+ sd->state.pvp_rank = 0;
+ src->is_player()->state.pvp_rank++;
+ clif_pvpstatus(sd);
+ clif_pvpstatus(src->is_player());
}
npc_event_doall_l(stringish<ScriptLabel>("OnPCDieEvent"_s), sd->bl_id, nullptr);
diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp
index 3949627..2822550 100644
--- a/src/map/script-fun.cpp
+++ b/src/map/script-fun.cpp
@@ -66,21 +66,6 @@ namespace tmwa
{
namespace map
{
-static
-Array<LString, 11> pos_str //=
-{{
- "Head"_s,
- "Body"_s,
- "Left hand"_s,
- "Right hand"_s,
- "Robe"_s,
- "Shoes"_s,
- "Accessory 1"_s,
- "Accessory 2"_s,
- "Head 2"_s,
- "Head 3"_s,
- "Not Equipped"_s,
-}};
#define AARG(n) (st->stack->stack_datav[st->start + 2 + (n)])
#define HARG(n) (st->end > st->start + 2 + (n))
@@ -1630,6 +1615,30 @@ void builtin_setnpctimer(ScriptState *st)
}
static
+void builtin_npcaction(ScriptState *st)
+{
+ dumb_ptr<map_session_data> sd = script_rid2sd(st);
+ short command = conv_num(st, &AARG(0));
+ int id = 0;
+ short x = HARG(2) ? conv_num(st, &AARG(2)) : 0;
+ short y = HARG(3) ? conv_num(st, &AARG(3)) : 0;
+
+ if(HARG(1))
+ {
+ if(command == 2)
+ {
+ dumb_ptr<npc_data> nd_;
+ nd_ = npc_name2id(stringish<NpcName>(ZString(conv_str(st, &AARG(1)))));
+ id = unwrap<BlockId>(nd_->bl_id);
+ }
+ else
+ id = conv_num(st, &AARG(1));
+ }
+
+ clif_npc_action(sd, st->oid, command, id, x, y);
+}
+
+static
void builtin_setnpcdirection(ScriptState *st)
{
dumb_ptr<npc_data> nd_;
@@ -2675,6 +2684,70 @@ void builtin_message(ScriptState *st)
}
+static
+void builtin_title(ScriptState *st)
+{
+ dumb_ptr<map_session_data> sd = script_rid2sd(st);
+ ZString msg = ZString(conv_str(st, &AARG(0)));
+ if (sd == nullptr)
+ return;
+ clif_npc_send_title(sd->sess, st->oid, msg);
+}
+
+static
+void builtin_music(ScriptState *st)
+{
+ dumb_ptr<map_session_data> sd = script_rid2sd(st);
+ ZString msg = ZString(conv_str(st, &AARG(0)));
+ if (sd == nullptr)
+ return;
+ clif_change_music(sd, msg);
+}
+
+static
+void builtin_mapmask(ScriptState *st)
+{
+ dumb_ptr<npc_data> nd;
+ dumb_ptr<map_session_data> sd;
+ int map_mask = conv_num(st, &AARG(0));
+
+ if(st->oid)
+ nd = map_id_is_npc(st->oid);
+ if(st->rid)
+ sd = script_rid2sd(st);
+
+ if(HARG(1) && sd != nullptr)
+ sd->bl_m->mask = map_mask;
+ else if(HARG(1) && nd)
+ nd->bl_m->mask = map_mask;
+
+ if (sd == nullptr)
+ return;
+ clif_send_mask(sd, map_mask);
+}
+
+static
+void builtin_getmask(ScriptState *st)
+{
+ dumb_ptr<npc_data> nd;
+ dumb_ptr<map_session_data> sd;
+ int map_mask;
+
+ if(st->oid)
+ nd = map_id_is_npc(st->oid);
+ if(st->rid)
+ sd = script_rid2sd(st);
+
+ if(sd != nullptr)
+ map_mask = sd->bl_m->mask;
+ else if(nd)
+ map_mask = nd->bl_m->mask;
+ else
+ map_mask = -1;
+
+ push_int<ScriptDataInt>(st->stack, map_mask);
+}
+
/*==========================================
* npctalk (sends message to surrounding
* area) [Valaris]
@@ -2684,13 +2757,24 @@ void builtin_message(ScriptState *st)
static
void builtin_npctalk(ScriptState *st)
{
- dumb_ptr<npc_data> nd = map_id_is_npc(st->oid);
- RString str = conv_str(st, &AARG(0));
+ dumb_ptr<npc_data> nd;
+ RString str = conv_str(st, &AARG(1));
- if (nd)
- {
- clif_message(nd, str);
+ dumb_ptr<npc_data> nd_ = npc_name2id(stringish<NpcName>(ZString(conv_str(st, &AARG(0)))));
+ assert (nd_ && nd_->npc_subtype == NpcSubtype::SCRIPT);
+ nd = nd_->is_script();
+
+
+ if(HARG(2)){
+ CharName player = stringish<CharName>(ZString(conv_str(st, &AARG(2))));
+ dumb_ptr<map_session_data> pl_sd = map_nick2sd(player);
+ if (pl_sd == nullptr)
+ return;
+ clif_message_towards(pl_sd, nd, str);
}
+
+ else
+ clif_message(nd, str);
}
/*==========================================
@@ -3098,6 +3182,7 @@ BuiltinFunction builtin_functions[] =
BUILTIN(getnpctimer, "i?"_s, 'i'),
BUILTIN(setnpctimer, "i?"_s, '\0'),
BUILTIN(setnpcdirection, "iii?"_s, '\0'),
+ BUILTIN(npcaction, "i???"_s, '\0'),
BUILTIN(announce, "si"_s, '\0'),
BUILTIN(mapannounce, "Msi"_s, '\0'),
BUILTIN(getusers, "i"_s, 'i'),
@@ -3144,7 +3229,11 @@ BuiltinFunction builtin_functions[] =
BUILTIN(npcwarp, "xys"_s, '\0'),
BUILTIN(npcareawarp, "xyxyis"_s, '\0'),
BUILTIN(message, "Ps"_s, '\0'),
- BUILTIN(npctalk, "s"_s, '\0'),
+ BUILTIN(npctalk, "ss?"_s, '\0'),
+ BUILTIN(title, "s"_s, '\0'),
+ BUILTIN(music, "s"_s, '\0'),
+ BUILTIN(mapmask, "i?"_s, '\0'),
+ BUILTIN(getmask, ""_s, 'i'),
BUILTIN(getlook, "i"_s, 'i'),
BUILTIN(getsavepoint, "i"_s, '.'),
BUILTIN(areatimer, "MxyxytE"_s, '\0'),
diff --git a/src/mmo/version.hpp b/src/mmo/version.hpp
index 6de3a9c..20cb1d9 100644
--- a/src/mmo/version.hpp
+++ b/src/mmo/version.hpp
@@ -36,6 +36,9 @@ namespace tmwa
#define TMWA_SERVER_MAP 0x08
// increase the min version when the protocol is incompatible with old m+ versions
+// 1 = latest mana, old manaplus, bots
+// 2 = manaplus 1.5.5.9 and above
+// 3 = manaplus 1.5.5.23 and above
#define MIN_CLIENT_VERSION 1
// TODO now that I generate the protocol, split 'flags' out of the struct
diff --git a/src/wire/packets.cpp b/src/wire/packets.cpp
index be06283..22a996a 100644
--- a/src/wire/packets.cpp
+++ b/src/wire/packets.cpp
@@ -76,6 +76,7 @@ void packet_dump(Session *s)
if ((i & 15) == 0)
FPRINTF(stderr, "%04X "_fmt, i);
Byte rfifob_ib;
+ rfifob_ib.value = 0;
packet_fetch(s, i, &rfifob_ib, 1);
uint8_t rfifob_i = rfifob_ib.value;
FPRINTF(stderr, "%02x "_fmt, rfifob_i);