diff options
author | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2025-02-26 10:35:48 +0100 |
---|---|---|
committer | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2025-02-26 10:39:56 +0100 |
commit | bc9a68bd584e572386ef8d21179d1c1eac513775 (patch) | |
tree | 2869a9836e25af4d4817b94e9938eb2d76b52857 | |
parent | 2d32c37a5639d76f34f83d3a929677efa46962a5 (diff) | |
download | tmwa-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.cpp | 109 | ||||
-rw-r--r-- | src/map/npc.hpp | 1 | ||||
-rwxr-xr-x | tools/protocol.py | 13 |
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], |