Effects packets (#308)

- [X] Changes effect packets
- [X] Updates playing sounds
- [X] Updates Effects class to have more options so there are less direct calls to building the packets
- [X] Changes bonding status packet
This commit is contained in:
Kamron Batman 2020-11-12 00:52:38 -08:00 committed by GitHub
parent 1c9439e4fd
commit 361ec4dba4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
53 changed files with 958 additions and 833 deletions

View file

@ -1,5 +1,4 @@
using System;
using System.Buffers;
using Server.Network;
using Xunit;
@ -7,6 +6,21 @@ namespace Server.Tests.Network
{
public class EffectPackets
{
[Theory]
[InlineData(10, 1000, 10, 5)]
public void TestSoundEffect(ushort soundID, int x, int y, int z)
{
var p = new Point3D(x, y, z);
var expected = new PlaySound(soundID, p).Compile();
using var ns = PacketTestUtilities.CreateTestNetState();
ns.SendSoundEffect(soundID, p);
var result = ns.SendPipe.Reader.TryRead();
AssertThat.Equal(result.Buffer[0].AsSpan(0), expected);
}
[Fact]
public void TestParticleEffect()
{
@ -29,56 +43,21 @@ namespace Server.Tests.Network
byte layer = 9;
ushort unknown = 0;
var data = new ParticleEffect(
effectType,
from,
to,
itemId,
fromPoint,
toPoint,
speed,
duration,
direction,
explode,
hue,
renderMode,
effect,
explodeEffect,
explodeSound,
serial,
layer,
var expected = new ParticleEffect(
effectType, from, to, itemId, fromPoint, toPoint, speed, duration, direction,
explode, hue, renderMode, effect, explodeEffect, explodeSound, serial, layer,
unknown
).Compile();
Span<byte> expectedData = stackalloc byte[49];
Span<byte> actual = stackalloc byte[OutgoingEffectPackets.ParticleEffectLength];
OutgoingEffectPackets.CreateParticleEffect(
ref actual,
effectType, from, to, itemId, fromPoint, toPoint, speed, duration, direction,
explode, hue, renderMode, effect, explodeEffect, explodeSound, serial, layer,
unknown
);
var pos = 0;
expectedData.Write(ref pos, (byte)0xC7); // Packet ID
expectedData.Write(ref pos, (byte)effectType);
expectedData.Write(ref pos, from);
expectedData.Write(ref pos, to);
expectedData.Write(ref pos, (ushort)itemId);
expectedData.Write(ref pos, fromPoint);
expectedData.Write(ref pos, toPoint);
expectedData.Write(ref pos, speed);
expectedData.Write(ref pos, duration);
#if NO_LOCAL_INIT
expectedData.Write(ref pos, (ushort)0);
#else
pos += 2;
#endif
expectedData.Write(ref pos, direction);
expectedData.Write(ref pos, explode);
expectedData.Write(ref pos, hue);
expectedData.Write(ref pos, renderMode);
expectedData.Write(ref pos, effect);
expectedData.Write(ref pos, explodeEffect);
expectedData.Write(ref pos, explodeSound);
expectedData.Write(ref pos, serial);
expectedData.Write(ref pos, layer);
expectedData.Write(ref pos, unknown);
AssertThat.Equal(data, expectedData);
AssertThat.Equal(actual, expected);
}
[Fact]
@ -97,74 +76,33 @@ namespace Server.Tests.Network
var hue = 0x1024;
var renderMode = 1;
var data = new HuedEffect(
effectType,
from,
to,
itemId,
fromPoint,
toPoint,
speed,
duration,
direction,
explode,
hue,
renderMode
var expected = new HuedEffect(
effectType, from, to, itemId, fromPoint, toPoint, speed,
duration, direction, explode, hue, renderMode
).Compile();
Span<byte> expectedData = stackalloc byte[36];
Span<byte> actual = stackalloc byte[OutgoingEffectPackets.HuedEffectLength];
OutgoingEffectPackets.CreateHuedEffect(
ref actual,
effectType, from, to, itemId, fromPoint, toPoint, speed,
duration, direction, explode, hue, renderMode
);
var pos = 0;
expectedData.Write(ref pos, (byte)0xC0); // Packet ID
expectedData.Write(ref pos, (byte)effectType);
expectedData.Write(ref pos, from);
expectedData.Write(ref pos, to);
expectedData.Write(ref pos, (ushort)itemId);
expectedData.Write(ref pos, fromPoint);
expectedData.Write(ref pos, toPoint);
expectedData.Write(ref pos, speed);
expectedData.Write(ref pos, duration);
#if NO_LOCAL_INIT
expectedData.Write(ref pos, (ushort)0);
#else
pos += 2;
#endif
expectedData.Write(ref pos, direction);
expectedData.Write(ref pos, explode);
expectedData.Write(ref pos, hue);
expectedData.Write(ref pos, renderMode);
AssertThat.Equal(data, expectedData);
AssertThat.Equal(actual, expected);
}
[Fact]
public void TestScreenEffect()
[Theory]
[InlineData(ScreenEffectType.DarkFlash)]
[InlineData(ScreenEffectType.FadeInOut)]
public void TestScreenEffect(ScreenEffectType screenType)
{
var type = ScreenEffectType.FadeOut;
var data = new ScreenEffect(type).Compile();
var expected = new ScreenEffect(screenType).Compile();
Span<byte> expectedData = stackalloc byte[28];
var pos = 0;
using var ns = PacketTestUtilities.CreateTestNetState();
ns.SendScreenEffect(screenType);
expectedData.Write(ref pos, (byte)0x70); // Packet ID
expectedData.Write(ref pos, (byte)0x04); // Effect
#if NO_LOCAL_INIT
expectedData.Write(ref pos, 0);
expectedData.Write(ref pos, 0);
#else
pos += 8;
#endif
expectedData.Write(ref pos, (ushort)type); // Screen Effect Type
#if NO_LOCAL_INIT
expectedData.Write(ref pos, 0);
expectedData.Write(ref pos, 0);
expectedData.Write(ref pos, 0);
expectedData.Write(ref pos, 0);
#endif
AssertThat.Equal(data, expectedData);
var result = ns.SendPipe.Reader.TryRead();
AssertThat.Equal(result.Buffer[0].AsSpan(0), expected);
}
[Fact]
@ -172,32 +110,15 @@ namespace Server.Tests.Network
{
IEntity entity = new Entity(0x1000, new Point3D(1000, 100, -10), Map.Felucca);
var hue = 0x1024;
var data = new BoltEffect(entity, hue).Compile();
var expected = new BoltEffect(entity, hue).Compile();
Span<byte> expectedData = stackalloc byte[36];
var pos = 0;
expectedData.Write(ref pos, (byte)0xC0); // Packet ID
expectedData.Write(ref pos, (byte)0x01); // Effect
Span<byte> actual = stackalloc byte[OutgoingEffectPackets.BoltEffectLength];
OutgoingEffectPackets.CreateBoltEffect(
ref actual,
entity, hue
);
expectedData.Write(ref pos, entity.Serial);
#if NO_LOCAL_INIT
expectedData.Write(ref pos, 0);
expectedData.Write(ref pos, (ushort)0);
#else
pos += 6;
#endif
expectedData.Write(ref pos, entity.Location);
expectedData.Write(ref pos, entity.Location);
#if NO_LOCAL_INIT
expectedData.Write(ref pos, 0);
expectedData.Write(ref pos, (ushort)0);
#else
pos += 6;
#endif
expectedData.Write(ref pos, hue);
AssertThat.Equal(data, expectedData);
AssertThat.Equal(actual, expected);
}
}
}

View file

@ -0,0 +1,280 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2020 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: EffectPackets.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
namespace Server.Network
{
public sealed class PlaySound : Packet
{
public PlaySound(int soundID, IPoint3D target) : base(0x54, 12)
{
Stream.Write((byte)1); // flags
Stream.Write((short)soundID);
Stream.Write((short)0); // volume
Stream.Write((short)target.X);
Stream.Write((short)target.Y);
Stream.Write((short)target.Z);
}
}
public class ParticleEffect : Packet
{
public ParticleEffect(
EffectType type, Serial from, Serial to, int itemID, IPoint3D fromPoint, IPoint3D toPoint,
int speed, int duration, bool fixedDirection, bool explode, int hue, int renderMode, int effect,
int explodeEffect, int explodeSound, Serial serial, int layer, int unknown
) : base(0xC7, 49)
{
Stream.Write((byte)type);
Stream.Write(from);
Stream.Write(to);
Stream.Write((short)itemID);
Stream.Write((short)fromPoint.X);
Stream.Write((short)fromPoint.Y);
Stream.Write((sbyte)fromPoint.Z);
Stream.Write((short)toPoint.X);
Stream.Write((short)toPoint.Y);
Stream.Write((sbyte)toPoint.Z);
Stream.Write((byte)speed);
Stream.Write((byte)duration);
Stream.Write((byte)0);
Stream.Write((byte)0);
Stream.Write(fixedDirection);
Stream.Write(explode);
Stream.Write(hue);
Stream.Write(renderMode);
Stream.Write((short)effect);
Stream.Write((short)explodeEffect);
Stream.Write((short)explodeSound);
Stream.Write(serial);
Stream.Write((byte)layer);
Stream.Write((short)unknown);
}
}
public class HuedEffect : Packet
{
public HuedEffect(
EffectType type, Serial from, Serial to, int itemID, IPoint3D fromPoint, IPoint3D toPoint,
int speed, int duration, bool fixedDirection, bool explode, int hue, int renderMode
) : base(0xC0, 36)
{
Stream.Write((byte)type);
Stream.Write(from);
Stream.Write(to);
Stream.Write((short)itemID);
Stream.Write((short)fromPoint.X);
Stream.Write((short)fromPoint.Y);
Stream.Write((sbyte)fromPoint.Z);
Stream.Write((short)toPoint.X);
Stream.Write((short)toPoint.Y);
Stream.Write((sbyte)toPoint.Z);
Stream.Write((byte)speed);
Stream.Write((byte)duration);
Stream.Write((byte)0);
Stream.Write((byte)0);
Stream.Write(fixedDirection);
Stream.Write(explode);
Stream.Write(hue);
Stream.Write(renderMode);
}
}
public sealed class TargetParticleEffect : ParticleEffect
{
public TargetParticleEffect(
IEntity e, int itemID, int speed, int duration, int hue, int renderMode, int effect,
int layer, int unknown
) : base(
EffectType.FixedFrom,
e.Serial,
Serial.Zero,
itemID,
e.Location,
e.Location,
speed,
duration,
true,
false,
hue,
renderMode,
effect,
1,
0,
e.Serial,
layer,
unknown
)
{
}
}
public sealed class TargetEffect : HuedEffect
{
public TargetEffect(IEntity e, int itemID, int speed, int duration, int hue, int renderMode) : base(
EffectType.FixedFrom,
e.Serial,
Serial.Zero,
itemID,
e.Location,
e.Location,
speed,
duration,
true,
false,
hue,
renderMode
)
{
}
}
public sealed class LocationParticleEffect : ParticleEffect
{
public LocationParticleEffect(
IEntity e, int itemID, int speed, int duration, int hue, int renderMode, int effect,
int unknown
) : base(
EffectType.FixedXYZ,
e.Serial,
Serial.Zero,
itemID,
e.Location,
e.Location,
speed,
duration,
true,
false,
hue,
renderMode,
effect,
1,
0,
e.Serial,
255,
unknown
)
{
}
}
public sealed class LocationEffect : HuedEffect
{
public LocationEffect(IPoint3D p, int itemID, int speed, int duration, int hue, int renderMode) : base(
EffectType.FixedXYZ,
Serial.Zero,
Serial.Zero,
itemID,
p,
p,
speed,
duration,
true,
false,
hue,
renderMode
)
{
}
}
public sealed class MovingParticleEffect : ParticleEffect
{
public MovingParticleEffect(
IEntity from, IEntity to, int itemID, int speed, int duration, bool fixedDirection,
bool explodes, int hue, int renderMode, int effect, int explodeEffect, int explodeSound, EffectLayer layer,
int unknown
) : base(
EffectType.Moving,
from.Serial,
to.Serial,
itemID,
from.Location,
to.Location,
speed,
duration,
fixedDirection,
explodes,
hue,
renderMode,
effect,
explodeEffect,
explodeSound,
Serial.Zero,
(int)layer,
unknown
)
{
}
}
public sealed class MovingEffect : HuedEffect
{
public MovingEffect(
IEntity from, IEntity to, int itemID, int speed, int duration, bool fixedDirection,
bool explodes, int hue, int renderMode
) : base(
EffectType.Moving,
from.Serial,
to.Serial,
itemID,
from.Location,
to.Location,
speed,
duration,
fixedDirection,
explodes,
hue,
renderMode
)
{
}
}
public class ScreenEffect : Packet
{
public ScreenEffect(ScreenEffectType type)
: base(0x70, 28)
{
Stream.Write((byte)0x04);
Stream.Fill(8);
Stream.Write((short)type);
Stream.Fill(16);
}
}
public sealed class BoltEffect : Packet
{
public BoltEffect(IEntity target, int hue) : base(0xC0, 36)
{
Stream.Write((byte)0x01); // type
Stream.Write(target.Serial);
Stream.Write(Serial.Zero);
Stream.Write((short)0); // itemID
Stream.Write((short)target.X);
Stream.Write((short)target.Y);
Stream.Write((sbyte)target.Z);
Stream.Write((short)target.X);
Stream.Write((short)target.Y);
Stream.Write((sbyte)target.Z);
Stream.Write((byte)0); // speed
Stream.Write((byte)0); // duration
Stream.Write((short)0); // unk
Stream.Write(false); // fixed direction
Stream.Write(false); // explode
Stream.Write(hue);
Stream.Write(0); // render mode
}
}
}

View file

@ -0,0 +1,32 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2020 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: MobilePackets.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
using Server.Network;
namespace Server.Tests.Network
{
public sealed class BondedStatus : Packet
{
public BondedStatus(Serial serial, bool bonded) : base(0xBF)
{
EnsureCapacity(11);
Stream.Write((short)0x19);
Stream.Write((byte)0);
Stream.Write(serial);
Stream.Write((byte)(bonded ? 1 : 0));
}
}
}

View file

@ -388,35 +388,6 @@ namespace Server.Tests.Network
AssertThat.Equal(data, expectedData);
}
[Theory]
[InlineData(10, 1000, 10, 5)]
public void TestPlaySound(ushort soundID, int x, int y, int z)
{
var p = new Point3D(x, y, z);
var data = new PlaySound(soundID, p).Compile();
Span<byte> expectedData = stackalloc byte[12];
var pos = 0;
expectedData.Write(ref pos, (byte)0x54); // Packet ID
expectedData.Write(ref pos, (byte)1); // Flags
expectedData.Write(ref pos, soundID);
#if NO_LOCAL_INIT
expectedData.Write(ref pos, (ushort)0); // Volume
#else
pos += 2;
#endif
expectedData.Write(ref pos, (ushort)p.X);
expectedData.Write(ref pos, (ushort)p.Y);
expectedData.Write(ref pos, (short)p.Z);
AssertThat.Equal(data, expectedData);
}
[Theory]
[InlineData(MusicName.Approach)]
[InlineData(MusicName.Combat1)]