From 20bd6bdb685af11548c35d3a48e5aa33f4222397 Mon Sep 17 00:00:00 2001 From: Lexi Hale <5723574+velartrill@users.noreply.github.com> Date: Wed, 13 Jul 2022 11:57:12 +0200 Subject: Animated particlespawners and more (#11545) Co-authored-by: Lars Mueller Co-authored-by: sfan5 Co-authored-by: Dmitry Kostenko --- src/network/clientpackethandler.cpp | 89 +++++++++++++++++++++++++++++----- src/network/networkprotocol.h | 95 ++++++++++++++++++++++++++++++------- 2 files changed, 156 insertions(+), 28 deletions(-) (limited to 'src/network') diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 1901c6675..25c1d2690 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -994,18 +994,18 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt) p.amount = readU16(is); p.time = readF32(is); - p.minpos = readV3F32(is); - p.maxpos = readV3F32(is); - p.minvel = readV3F32(is); - p.maxvel = readV3F32(is); - p.minacc = readV3F32(is); - p.maxacc = readV3F32(is); - p.minexptime = readF32(is); - p.maxexptime = readF32(is); - p.minsize = readF32(is); - p.maxsize = readF32(is); + + // older protocols do not support tweening, and send only + // static ranges, so we can't just use the normal serialization + // functions for the older values. + p.pos.start.legacyDeSerialize(is); + p.vel.start.legacyDeSerialize(is); + p.acc.start.legacyDeSerialize(is); + p.exptime.start.legacyDeSerialize(is); + p.size.start.legacyDeSerialize(is); + p.collisiondetection = readU8(is); - p.texture = deSerializeString32(is); + p.texture.string = deSerializeString32(is); server_id = readU32(is); @@ -1018,6 +1018,8 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt) p.glow = readU8(is); p.object_collision = readU8(is); + bool legacy_format = true; + // This is kinda awful do { u16 tmp_param0 = readU16(is); @@ -1026,7 +1028,70 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt) p.node.param0 = tmp_param0; p.node.param2 = readU8(is); p.node_tile = readU8(is); - } while (0); + + // v >= 5.6.0 + f32 tmp_sbias = readF32(is); + if (is.eof()) + break; + + // initial bias must be stored separately in the stream to preserve + // backwards compatibility with older clients, which do not support + // a bias field in their range "format" + p.pos.start.bias = tmp_sbias; + p.vel.start.bias = readF32(is); + p.acc.start.bias = readF32(is); + p.exptime.start.bias = readF32(is); + p.size.start.bias = readF32(is); + + p.pos.end.deSerialize(is); + p.vel.end.deSerialize(is); + p.acc.end.deSerialize(is); + p.exptime.end.deSerialize(is); + p.size.end.deSerialize(is); + + // properties for legacy texture field + p.texture.deSerialize(is, m_proto_ver, true); + + p.drag.deSerialize(is); + p.jitter.deSerialize(is); + p.bounce.deSerialize(is); + ParticleParamTypes::deSerializeParameterValue(is, p.attractor_kind); + using ParticleParamTypes::AttractorKind; + if (p.attractor_kind != AttractorKind::none) { + p.attract.deSerialize(is); + p.attractor_origin.deSerialize(is); + p.attractor_attachment = readU16(is); + /* we only check the first bit, in order to allow this value + * to be turned into a bit flag field later if needed */ + p.attractor_kill = !!(readU8(is) & 1); + if (p.attractor_kind != AttractorKind::point) { + p.attractor_direction.deSerialize(is); + p.attractor_direction_attachment = readU16(is); + } + } + p.radius.deSerialize(is); + + u16 texpoolsz = readU16(is); + p.texpool.reserve(texpoolsz); + for (u16 i = 0; i < texpoolsz; ++i) { + ServerParticleTexture newtex; + newtex.deSerialize(is, m_proto_ver); + p.texpool.push_back(newtex); + } + + legacy_format = false; + } while(0); + + if (legacy_format) { + // there's no tweening data to be had, so we need to set the + // legacy params to constant values, otherwise everything old + // will tween to zero + p.pos.end = p.pos.start; + p.vel.end = p.vel.start; + p.acc.end = p.acc.start; + p.exptime.end = p.exptime.start; + p.size.end = p.size.start; + } auto event = new ClientEvent(); event->type = CE_ADD_PARTICLESPAWNER; diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h index 33e49afa4..e3fd32866 100644 --- a/src/network/networkprotocol.h +++ b/src/network/networkprotocol.h @@ -207,6 +207,7 @@ with this program; if not, write to the Free Software Foundation, Inc., Minimap modes PROTOCOL VERSION 40: TOCLIENT_MEDIA_PUSH changed, TOSERVER_HAVE_MEDIA added + Added new particlespawner parameters (5.6.0) */ #define LATEST_PROTOCOL_VERSION 40 @@ -511,11 +512,12 @@ enum ToClientCommand TOCLIENT_SPAWN_PARTICLE = 0x46, /* - v3f1000 pos - v3f1000 velocity - v3f1000 acceleration - f1000 expirationtime - f1000 size + -- struct range { T min, T max, f32 bias }; + v3f pos + v3f velocity + v3f acceleration + f32 expirationtime + f32 size u8 bool collisiondetection u32 len u8[len] texture @@ -524,22 +526,26 @@ enum ToClientCommand TileAnimation animation u8 glow u8 object_collision + v3f drag + range bounce */ TOCLIENT_ADD_PARTICLESPAWNER = 0x47, /* + -- struct range { T min, T max, f32 bias }; + -- struct tween { T start, T end }; u16 amount - f1000 spawntime - v3f1000 minpos - v3f1000 maxpos - v3f1000 minvel - v3f1000 maxvel - v3f1000 minacc - v3f1000 maxacc - f1000 minexptime - f1000 maxexptime - f1000 minsize - f1000 maxsize + f32 spawntime + v3f minpos + v3f maxpos + v3f minvel + v3f maxvel + v3f minacc + v3f maxacc + f32 minexptime + f32 maxexptime + f32 minsize + f32 maxsize u8 bool collisiondetection u32 len u8[len] texture @@ -549,6 +555,63 @@ enum ToClientCommand TileAnimation animation u8 glow u8 object_collision + + f32 pos_start_bias + f32 vel_start_bias + f32 acc_start_bias + f32 exptime_start_bias + f32 size_start_bias + + range pos_end + -- i.e v3f pos_end_min + -- v3f pos_end_max + -- f32 pos_end_bias + range vel_end + range acc_end + + tween> drag + -- i.e. v3f drag_start_min + -- v3f drag_start_max + -- f32 drag_start_bias + -- v3f drag_end_min + -- v3f drag_end_max + -- f32 drag_end_bias + tween> jitter + tween> bounce + + u8 attraction_kind + none = 0 + point = 1 + line = 2 + plane = 3 + + if attraction_kind > none { + tween> attract_strength + tween attractor_origin + u16 attractor_origin_attachment_object_id + u8 spawner_flags + bit 1: attractor_kill (particles dies on contact) + if attraction_mode > point { + tween attractor_angle + u16 attractor_origin_attachment_object_id + } + } + + tween> radius + tween> drag + + u16 texpool_sz + texpool_sz.times { + u8 flags + -- bit 0: animated + -- other bits free & ignored as of proto v40 + tween alpha + tween scale + if flags.animated { + TileAnimation animation + } + } + */ TOCLIENT_DELETE_PARTICLESPAWNER_LEGACY = 0x48, // Obsolete -- cgit v1.2.3