summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThorbjørn Lindeijer <bjorn@lindeijer.nl>2025-02-26 10:35:48 +0100
committerThorbjørn Lindeijer <bjorn@lindeijer.nl>2025-02-26 10:39:56 +0100
commitbc9a68bd584e572386ef8d21179d1c1eac513775 (patch)
tree2869a9836e25af4d4817b94e9938eb2d76b52857
parent2d32c37a5639d76f34f83d3a929677efa46962a5 (diff)
downloadtmwa-being-spawn-message.tar.gz
tmwa-being-spawn-message.tar.bz2
tmwa-being-spawn-message.tar.xz
tmwa-being-spawn-message.zip
Re-enable SMSG_BEING_SPAWN (0x007c) with additional fieldsbeing-spawn-message
This packet was disabled with the comment "manaplus is skipping this packet". In fact, that isn't entirely true: M+ uses this packet to set a "spawn ID" so that it can later trigger the spawn action after the being is created. Rather than just re-enabling this packet, I've added some additional data (hp, max_hp, attack_range and sex) using previously unused fields, which makes sending SMSG_BEING_VISIBLE (0x0078) obsolete. Starting with client version 9 (M+ and Mana are currently on version 8), we now send either SMSG_BEING_SPAWN or SMSG_BEING_VISIBLE.
-rw-r--r--src/map/clif.cpp109
-rw-r--r--src/map/npc.hpp1
-rwxr-xr-xtools/protocol.py13
3 files changed, 62 insertions, 61 deletions
diff --git a/src/map/clif.cpp b/src/map/clif.cpp
index 1b77be6..cc3d8f8 100644
--- a/src/map/clif.cpp
+++ b/src/map/clif.cpp
@@ -849,7 +849,7 @@ static
void clif_mob0078(dumb_ptr<mob_data> md, Buffer& buf)
{
nullpo_retv(md);
- int max_hp = md->stats[mob_stat::MAX_HP];
+ int max_hp = battle_get_max_hp(md);
int hp = md->hp;
Packet_Fixed<0x0078> fixed_78;
@@ -897,7 +897,7 @@ static
void clif_mob007b(dumb_ptr<mob_data> md, Buffer& buf)
{
nullpo_retv(md);
- int max_hp = md->stats[mob_stat::MAX_HP];
+ int max_hp = battle_get_max_hp(md);
int hp = md->hp;
Packet_Fixed<0x007b> fixed_7b;
@@ -1039,26 +1039,25 @@ int clif_spawnnpc(dumb_ptr<npc_data> nd)
if (nd->flag & 1 || nd->npc_class == INVISIBLE_CLASS)
return 0;
- /* manaplus is skipping this packet
+
Packet_Fixed<0x007c> fixed_7c;
fixed_7c.block_id = nd->bl_id;
fixed_7c.speed = nd->speed;
fixed_7c.species = nd->npc_class;
+ fixed_7c.sex = nd->sex;
fixed_7c.pos.x = nd->bl_x;
fixed_7c.pos.y = nd->bl_y;
-
+ fixed_7c.pos.dir = nd->dir;
Buffer buf = create_fpacket<0x007c, 41>(fixed_7c);
- clif_send(buf, nd, SendWho::AREA);
- */
- Buffer buf;
- clif_npc0078(nd, buf);
- clif_send(buf, nd, SendWho::AREA);
- if(nd->sit == DamageType::SIT)
+ Buffer elseBuf;
+ clif_npc0078(nd, elseBuf);
+ clif_send(buf, nd, SendWho::AREA, wrap<ClientVersion>(9), elseBuf);
+
+ if (nd->sit == DamageType::SIT)
{
- Buffer buff;
- clif_sitnpc_sub(buff, nd, nd->sit);
- clif_send(buff, nd, SendWho::AREA);
+ clif_sitnpc_sub(buf, nd, nd->sit);
+ clif_send(buf, nd, SendWho::AREA);
}
return 0;
@@ -1073,28 +1072,32 @@ int clif_spawn_fake_npc_for_player(dumb_ptr<map_session_data> sd, BlockId fake_n
if (!s)
return 0;
- /* manaplus skips this packet
- Packet_Fixed<0x007c> fixed_7c;
- fixed_7c.block_id = fake_npc_id;
- fixed_7c.speed = interval_t();
- fixed_7c.opt1 = Opt1::ZERO;
- fixed_7c.opt2 = Opt2::ZERO;
- fixed_7c.option = Opt0::ZERO;
- fixed_7c.species = FAKE_NPC_CLASS;
- fixed_7c.pos.x = sd->bl_x;
- fixed_7c.pos.y = sd->bl_y;
- send_fpacket<0x007c, 41>(s, fixed_7c);*/
-
- Packet_Fixed<0x0078> fixed_78;
- fixed_78.block_id = fake_npc_id;
- fixed_78.speed = interval_t();
- fixed_78.opt1 = Opt1::ZERO;
- fixed_78.opt2 = Opt2::ZERO;
- fixed_78.option = Opt0::ZERO;
- fixed_78.species = FAKE_NPC_CLASS;
- fixed_78.pos.x = sd->bl_x;
- fixed_78.pos.y = sd->bl_y;
- send_fpacket<0x0078, 54>(s, fixed_78);
+ if (sd->client_version >= wrap<ClientVersion>(9))
+ {
+ Packet_Fixed<0x007c> fixed_7c;
+ fixed_7c.block_id = fake_npc_id;
+ fixed_7c.speed = interval_t();
+ fixed_7c.opt1 = Opt1::ZERO;
+ fixed_7c.opt2 = Opt2::ZERO;
+ fixed_7c.option = Opt0::ZERO;
+ fixed_7c.species = FAKE_NPC_CLASS;
+ fixed_7c.pos.x = sd->bl_x;
+ fixed_7c.pos.y = sd->bl_y;
+ send_fpacket<0x007c, 41>(s, fixed_7c);
+ }
+ else
+ {
+ Packet_Fixed<0x0078> fixed_78;
+ fixed_78.block_id = fake_npc_id;
+ fixed_78.speed = interval_t();
+ fixed_78.opt1 = Opt1::ZERO;
+ fixed_78.opt2 = Opt2::ZERO;
+ fixed_78.option = Opt0::ZERO;
+ fixed_78.species = FAKE_NPC_CLASS;
+ fixed_78.pos.x = sd->bl_x;
+ fixed_78.pos.y = sd->bl_y;
+ send_fpacket<0x0078, 54>(s, fixed_78);
+ }
return 0;
}
@@ -1107,24 +1110,24 @@ int clif_spawnmob(dumb_ptr<mob_data> md)
{
nullpo_retz(md);
- /*{ manaplus skips this packet
- Packet_Fixed<0x007c> fixed_7c;
- fixed_7c.block_id = md->bl_id;
- fixed_7c.speed = interval_t(md->stats[mob_stat::SPEED]);
- fixed_7c.opt1 = md->opt1;
- fixed_7c.opt2 = md->opt2;
- fixed_7c.option = md->option;
- fixed_7c.species = md->mob_class;
- fixed_7c.pos.x = md->bl_x;
- fixed_7c.pos.y = md->bl_y;
- Buffer buf = create_fpacket<0x007c, 41>(fixed_7c);
- clif_send(buf, md, SendWho::AREA);
- }*/
- {
- Buffer buf;
- clif_mob0078(md, buf);
- clif_send(buf, md, SendWho::AREA);
- }
+ Packet_Fixed<0x007c> fixed_7c;
+ fixed_7c.block_id = md->bl_id;
+ fixed_7c.speed = battle_get_speed(md);
+ fixed_7c.opt1 = md->opt1;
+ fixed_7c.opt2 = md->opt2;
+ fixed_7c.option = md->option;
+ fixed_7c.species = md->mob_class;
+ fixed_7c.hp = md->hp;
+ fixed_7c.max_hp = battle_get_max_hp(md);
+ fixed_7c.attack_range = battle_get_range(md);
+ fixed_7c.pos.x = md->bl_x;
+ fixed_7c.pos.y = md->bl_y;
+ fixed_7c.pos.dir = md->dir;
+ Buffer buf = create_fpacket<0x007c, 41>(fixed_7c);
+
+ Buffer elseBuf;
+ clif_mob0078(md, elseBuf);
+ clif_send(buf, md, SendWho::AREA, wrap<ClientVersion>(9), elseBuf);
// custom mob names
if (md->name != MobName() && md->name != get_mob_db(md->mob_class).name && md->name.size() >= 4)
diff --git a/src/map/npc.hpp b/src/map/npc.hpp
index e230ffe..9f3650c 100644
--- a/src/map/npc.hpp
+++ b/src/map/npc.hpp
@@ -38,7 +38,6 @@ namespace map
{
constexpr BlockId START_NPC_NUM = wrap<BlockId>(110000000);
-// TODO make these species, see npc_class in npc_data
constexpr Species WARP_CLASS = wrap<Species>(45);
constexpr Species FAKE_NPC_CLASS = wrap<Species>(127);
constexpr Species INVISIBLE_CLASS = wrap<Species>(32767);
diff --git a/tools/protocol.py b/tools/protocol.py
index c4c8657..0c84b2a 100755
--- a/tools/protocol.py
+++ b/tools/protocol.py
@@ -2391,14 +2391,13 @@ def build_context():
at(18, u16, 'unknown 3'),
at(20, species, 'species'),
at(22, u16, 'unknown 4'),
- at(24, u16, 'unknown 5'),
- at(26, u16, 'unknown 6'),
- at(28, u16, 'unknown 7'),
- at(30, u16, 'unknown 8'),
- at(32, u16, 'unknown 9'),
- at(34, u16, 'unknown 10'),
+ at(24, u32, 'hp'),
+ at(28, u32, 'max hp'),
+ at(32, u16, 'unknown 5'),
+ at(34, u8, 'attack range'),
+ at(35, sex, 'sex'),
at(36, pos1, 'pos'),
- at(39, u16, 'unknown 11'),
+ at(39, u16, 'unknown 6'),
],
fixed_size=41,
pre=[BOOT, FINISH, GM, MAGIC, SCRIPT, TIMER, 0x0089, 0x008c, 0x00b8, 0x00b9, 0x00e6, 0x00f7, 0x0143, 0x0146, 0x01d5],