Allow looped animation to be used safely with old clients

fixes #12657
This commit is contained in:
sfan5 2022-09-04 16:22:12 +02:00
parent adb03ccc6d
commit c607bee19e
4 changed files with 15 additions and 8 deletions

View File

@ -555,6 +555,7 @@ void ParticleSpawner::spawnParticle(ClientEnvironment *env, float radius,
// synchronize animation length with particle life if desired // synchronize animation length with particle life if desired
if (pp.animation.type != TAT_NONE) { if (pp.animation.type != TAT_NONE) {
// FIXME: this should be moved into a TileAnimationParams class method
if (pp.animation.type == TAT_VERTICAL_FRAMES && if (pp.animation.type == TAT_VERTICAL_FRAMES &&
pp.animation.vertical_frames.length < 0) { pp.animation.vertical_frames.length < 0) {
auto& a = pp.animation.vertical_frames; auto& a = pp.animation.vertical_frames;

View File

@ -127,7 +127,7 @@ void ParticleParameters::serialize(std::ostream &os, u16 protocol_ver) const
os << serializeString32(texture.string); os << serializeString32(texture.string);
writeU8(os, vertical); writeU8(os, vertical);
writeU8(os, collision_removal); writeU8(os, collision_removal);
animation.serialize(os, 6); /* NOT the protocol ver */ animation.serialize(os, protocol_ver);
writeU8(os, glow); writeU8(os, glow);
writeU8(os, object_collision); writeU8(os, object_collision);
writeU16(os, node.param0); writeU16(os, node.param0);
@ -160,7 +160,7 @@ void ParticleParameters::deSerialize(std::istream &is, u16 protocol_ver)
texture.string = deSerializeString32(is); texture.string = deSerializeString32(is);
vertical = readU8(is); vertical = readU8(is);
collision_removal = readU8(is); collision_removal = readU8(is);
animation.deSerialize(is, 6); /* NOT the protocol ver */ animation.deSerialize(is, protocol_ver);
glow = readU8(is); glow = readU8(is);
object_collision = readU8(is); object_collision = readU8(is);

View File

@ -19,21 +19,27 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "tileanimation.h" #include "tileanimation.h"
#include "util/serialize.h" #include "util/serialize.h"
void TileAnimationParams::serialize(std::ostream &os, u16 protocol_version) const void TileAnimationParams::serialize(std::ostream &os, u16 protocol_ver) const
{ {
// The particle code overloads the length parameter so that negative numbers
// indicate an extra feature which old clients don't understand (crash).
// In hindsight it would have been better to use an extra parameter for this
// but we're stuck with this now.
const bool need_abs = protocol_ver < 40;
writeU8(os, type); writeU8(os, type);
if (type == TAT_VERTICAL_FRAMES) { if (type == TAT_VERTICAL_FRAMES) {
writeU16(os, vertical_frames.aspect_w); writeU16(os, vertical_frames.aspect_w);
writeU16(os, vertical_frames.aspect_h); writeU16(os, vertical_frames.aspect_h);
writeF32(os, vertical_frames.length); writeF32(os, need_abs ? fabs(vertical_frames.length) : vertical_frames.length);
} else if (type == TAT_SHEET_2D) { } else if (type == TAT_SHEET_2D) {
writeU8(os, sheet_2d.frames_w); writeU8(os, sheet_2d.frames_w);
writeU8(os, sheet_2d.frames_h); writeU8(os, sheet_2d.frames_h);
writeF32(os, sheet_2d.frame_length); writeF32(os, need_abs ? fabs(sheet_2d.frame_length) : sheet_2d.frame_length);
} }
} }
void TileAnimationParams::deSerialize(std::istream &is, u16 protocol_version) void TileAnimationParams::deSerialize(std::istream &is, u16 protocol_ver)
{ {
type = (TileAnimationType) readU8(is); type = (TileAnimationType) readU8(is);

View File

@ -50,8 +50,8 @@ struct TileAnimationParams
} sheet_2d; } sheet_2d;
}; };
void serialize(std::ostream &os, u16 protocol_version) const; void serialize(std::ostream &os, u16 protocol_ver) const;
void deSerialize(std::istream &is, u16 protocol_version); void deSerialize(std::istream &is, u16 protocol_ver);
void determineParams(v2u32 texture_size, int *frame_count, int *frame_length_ms, void determineParams(v2u32 texture_size, int *frame_count, int *frame_length_ms,
v2u32 *frame_size) const; v2u32 *frame_size) const;
void getTextureModifer(std::ostream &os, v2u32 texture_size, int frame) const; void getTextureModifer(std::ostream &os, v2u32 texture_size, int frame) const;