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:
parent
1c9439e4fd
commit
361ec4dba4
53 changed files with 958 additions and 833 deletions
|
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
|
||||||
using Server.Network;
|
using Server.Network;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -7,6 +6,21 @@ namespace Server.Tests.Network
|
||||||
{
|
{
|
||||||
public class EffectPackets
|
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]
|
[Fact]
|
||||||
public void TestParticleEffect()
|
public void TestParticleEffect()
|
||||||
{
|
{
|
||||||
|
|
@ -29,56 +43,21 @@ namespace Server.Tests.Network
|
||||||
byte layer = 9;
|
byte layer = 9;
|
||||||
ushort unknown = 0;
|
ushort unknown = 0;
|
||||||
|
|
||||||
var data = new ParticleEffect(
|
var expected = new ParticleEffect(
|
||||||
effectType,
|
effectType, from, to, itemId, fromPoint, toPoint, speed, duration, direction,
|
||||||
from,
|
explode, hue, renderMode, effect, explodeEffect, explodeSound, serial, layer,
|
||||||
to,
|
|
||||||
itemId,
|
|
||||||
fromPoint,
|
|
||||||
toPoint,
|
|
||||||
speed,
|
|
||||||
duration,
|
|
||||||
direction,
|
|
||||||
explode,
|
|
||||||
hue,
|
|
||||||
renderMode,
|
|
||||||
effect,
|
|
||||||
explodeEffect,
|
|
||||||
explodeSound,
|
|
||||||
serial,
|
|
||||||
layer,
|
|
||||||
unknown
|
unknown
|
||||||
).Compile();
|
).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;
|
AssertThat.Equal(actual, expected);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -97,74 +76,33 @@ namespace Server.Tests.Network
|
||||||
var hue = 0x1024;
|
var hue = 0x1024;
|
||||||
var renderMode = 1;
|
var renderMode = 1;
|
||||||
|
|
||||||
var data = new HuedEffect(
|
var expected = new HuedEffect(
|
||||||
effectType,
|
effectType, from, to, itemId, fromPoint, toPoint, speed,
|
||||||
from,
|
duration, direction, explode, hue, renderMode
|
||||||
to,
|
|
||||||
itemId,
|
|
||||||
fromPoint,
|
|
||||||
toPoint,
|
|
||||||
speed,
|
|
||||||
duration,
|
|
||||||
direction,
|
|
||||||
explode,
|
|
||||||
hue,
|
|
||||||
renderMode
|
|
||||||
).Compile();
|
).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;
|
AssertThat.Equal(actual, expected);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public void TestScreenEffect()
|
[InlineData(ScreenEffectType.DarkFlash)]
|
||||||
|
[InlineData(ScreenEffectType.FadeInOut)]
|
||||||
|
public void TestScreenEffect(ScreenEffectType screenType)
|
||||||
{
|
{
|
||||||
var type = ScreenEffectType.FadeOut;
|
var expected = new ScreenEffect(screenType).Compile();
|
||||||
var data = new ScreenEffect(type).Compile();
|
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[28];
|
using var ns = PacketTestUtilities.CreateTestNetState();
|
||||||
var pos = 0;
|
ns.SendScreenEffect(screenType);
|
||||||
|
|
||||||
expectedData.Write(ref pos, (byte)0x70); // Packet ID
|
var result = ns.SendPipe.Reader.TryRead();
|
||||||
expectedData.Write(ref pos, (byte)0x04); // Effect
|
AssertThat.Equal(result.Buffer[0].AsSpan(0), expected);
|
||||||
#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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -172,32 +110,15 @@ namespace Server.Tests.Network
|
||||||
{
|
{
|
||||||
IEntity entity = new Entity(0x1000, new Point3D(1000, 100, -10), Map.Felucca);
|
IEntity entity = new Entity(0x1000, new Point3D(1000, 100, -10), Map.Felucca);
|
||||||
var hue = 0x1024;
|
var hue = 0x1024;
|
||||||
var data = new BoltEffect(entity, hue).Compile();
|
var expected = new BoltEffect(entity, hue).Compile();
|
||||||
|
|
||||||
Span<byte> expectedData = stackalloc byte[36];
|
Span<byte> actual = stackalloc byte[OutgoingEffectPackets.BoltEffectLength];
|
||||||
var pos = 0;
|
OutgoingEffectPackets.CreateBoltEffect(
|
||||||
expectedData.Write(ref pos, (byte)0xC0); // Packet ID
|
ref actual,
|
||||||
expectedData.Write(ref pos, (byte)0x01); // Effect
|
entity, hue
|
||||||
|
);
|
||||||
|
|
||||||
|
AssertThat.Equal(actual, expected);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,48 +15,21 @@
|
||||||
|
|
||||||
namespace Server.Network
|
namespace Server.Network
|
||||||
{
|
{
|
||||||
public enum EffectType
|
public sealed class PlaySound : Packet
|
||||||
{
|
{
|
||||||
Moving,
|
public PlaySound(int soundID, IPoint3D target) : base(0x54, 12)
|
||||||
Lightning,
|
{
|
||||||
FixedXYZ,
|
Stream.Write((byte)1); // flags
|
||||||
FixedFrom
|
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 class ParticleEffect : Packet
|
||||||
{
|
{
|
||||||
public ParticleEffect(
|
|
||||||
EffectType type, Serial from, Serial to, int itemID, Point3D fromPoint, Point3D 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.m_X);
|
|
||||||
Stream.Write((short)fromPoint.m_Y);
|
|
||||||
Stream.Write((sbyte)fromPoint.m_Z);
|
|
||||||
Stream.Write((short)toPoint.m_X);
|
|
||||||
Stream.Write((short)toPoint.m_Y);
|
|
||||||
Stream.Write((sbyte)toPoint.m_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 ParticleEffect(
|
public ParticleEffect(
|
||||||
EffectType type, Serial from, Serial to, int itemID, IPoint3D fromPoint, IPoint3D toPoint,
|
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 speed, int duration, bool fixedDirection, bool explode, int hue, int renderMode, int effect,
|
||||||
|
|
@ -92,31 +65,6 @@ namespace Server.Network
|
||||||
|
|
||||||
public class HuedEffect : Packet
|
public class HuedEffect : Packet
|
||||||
{
|
{
|
||||||
public HuedEffect(
|
|
||||||
EffectType type, Serial from, Serial to, int itemID, Point3D fromPoint, Point3D 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.m_X);
|
|
||||||
Stream.Write((short)fromPoint.m_Y);
|
|
||||||
Stream.Write((sbyte)fromPoint.m_Z);
|
|
||||||
Stream.Write((short)toPoint.m_X);
|
|
||||||
Stream.Write((short)toPoint.m_Y);
|
|
||||||
Stream.Write((sbyte)toPoint.m_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 HuedEffect(
|
public HuedEffect(
|
||||||
EffectType type, Serial from, Serial to, int itemID, IPoint3D fromPoint, IPoint3D toPoint,
|
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 speed, int duration, bool fixedDirection, bool explode, int hue, int renderMode
|
||||||
|
|
@ -294,15 +242,6 @@ namespace Server.Network
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ScreenEffectType
|
|
||||||
{
|
|
||||||
FadeOut = 0x00,
|
|
||||||
FadeIn = 0x01,
|
|
||||||
LightFlash = 0x02,
|
|
||||||
FadeInOut = 0x03,
|
|
||||||
DarkFlash = 0x04
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ScreenEffect : Packet
|
public class ScreenEffect : Packet
|
||||||
{
|
{
|
||||||
public ScreenEffect(ScreenEffectType type)
|
public ScreenEffect(ScreenEffectType type)
|
||||||
|
|
@ -315,56 +254,6 @@ namespace Server.Network
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class ScreenFadeOut : ScreenEffect
|
|
||||||
{
|
|
||||||
public static readonly Packet Instance = SetStatic(new ScreenFadeOut());
|
|
||||||
|
|
||||||
public ScreenFadeOut()
|
|
||||||
: base(ScreenEffectType.FadeOut)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class ScreenFadeIn : ScreenEffect
|
|
||||||
{
|
|
||||||
public static readonly Packet Instance = SetStatic(new ScreenFadeIn());
|
|
||||||
|
|
||||||
public ScreenFadeIn()
|
|
||||||
: base(ScreenEffectType.FadeIn)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class ScreenFadeInOut : ScreenEffect
|
|
||||||
{
|
|
||||||
public static readonly Packet Instance = SetStatic(new ScreenFadeInOut());
|
|
||||||
|
|
||||||
public ScreenFadeInOut()
|
|
||||||
: base(ScreenEffectType.FadeInOut)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class ScreenLightFlash : ScreenEffect
|
|
||||||
{
|
|
||||||
public static readonly Packet Instance = SetStatic(new ScreenLightFlash());
|
|
||||||
|
|
||||||
public ScreenLightFlash()
|
|
||||||
: base(ScreenEffectType.LightFlash)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class ScreenDarkFlash : ScreenEffect
|
|
||||||
{
|
|
||||||
public static readonly Packet Instance = SetStatic(new ScreenDarkFlash());
|
|
||||||
|
|
||||||
public ScreenDarkFlash()
|
|
||||||
: base(ScreenEffectType.DarkFlash)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class BoltEffect : Packet
|
public sealed class BoltEffect : Packet
|
||||||
{
|
{
|
||||||
public BoltEffect(IEntity target, int hue) : base(0xC0, 36)
|
public BoltEffect(IEntity target, int hue) : base(0xC0, 36)
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
* ModernUO *
|
* ModernUO *
|
||||||
* Copyright 2019-2020 - ModernUO Development Team *
|
* Copyright 2019-2020 - ModernUO Development Team *
|
||||||
* Email: hi@modernuo.com *
|
* Email: hi@modernuo.com *
|
||||||
* File: DisplayHuePicker.cs *
|
* File: MobilePackets.cs *
|
||||||
* *
|
* *
|
||||||
* This program is free software: you can redistribute it and/or modify *
|
* 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 *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
|
@ -13,17 +13,20 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
using Server.HuePickers;
|
using Server.Network;
|
||||||
|
|
||||||
namespace Server.Network
|
namespace Server.Tests.Network
|
||||||
{
|
{
|
||||||
public sealed class DisplayHuePicker : Packet
|
public sealed class BondedStatus : Packet
|
||||||
{
|
{
|
||||||
public DisplayHuePicker(HuePicker huePicker) : base(0x95, 9)
|
public BondedStatus(Serial serial, bool bonded) : base(0xBF)
|
||||||
{
|
{
|
||||||
Stream.Write(huePicker.Serial);
|
EnsureCapacity(11);
|
||||||
Stream.Write((short)0);
|
|
||||||
Stream.Write((short)huePicker.ItemID);
|
Stream.Write((short)0x19);
|
||||||
|
Stream.Write((byte)0);
|
||||||
|
Stream.Write(serial);
|
||||||
|
Stream.Write((byte)(bonded ? 1 : 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -388,35 +388,6 @@ namespace Server.Tests.Network
|
||||||
AssertThat.Equal(data, expectedData);
|
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]
|
[Theory]
|
||||||
[InlineData(MusicName.Approach)]
|
[InlineData(MusicName.Approach)]
|
||||||
[InlineData(MusicName.Combat1)]
|
[InlineData(MusicName.Combat1)]
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,40 @@
|
||||||
|
/*************************************************************************
|
||||||
|
* ModernUO *
|
||||||
|
* Copyright 2019-2020 - ModernUO Development Team *
|
||||||
|
* Email: hi@modernuo.com *
|
||||||
|
* File: Effects.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 System;
|
||||||
using Server.Network;
|
using Server.Network;
|
||||||
|
|
||||||
namespace Server
|
namespace Server
|
||||||
{
|
{
|
||||||
|
public enum EffectType
|
||||||
|
{
|
||||||
|
Moving,
|
||||||
|
Lightning,
|
||||||
|
FixedXYZ,
|
||||||
|
FixedFrom
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ScreenEffectType
|
||||||
|
{
|
||||||
|
FadeOut = 0x00,
|
||||||
|
FadeIn = 0x01,
|
||||||
|
LightFlash = 0x02,
|
||||||
|
FadeInOut = 0x03,
|
||||||
|
DarkFlash = 0x04
|
||||||
|
}
|
||||||
|
|
||||||
public enum EffectLayer
|
public enum EffectLayer
|
||||||
{
|
{
|
||||||
Head = 0,
|
Head = 0,
|
||||||
|
|
@ -28,7 +61,9 @@ namespace Server
|
||||||
ParticleSupportType == ParticleSupportType.Full ||
|
ParticleSupportType == ParticleSupportType.Full ||
|
||||||
ParticleSupportType == ParticleSupportType.Detect && state.IsUOTDClient;
|
ParticleSupportType == ParticleSupportType.Detect && state.IsUOTDClient;
|
||||||
|
|
||||||
public static void PlaySound(IPoint3D p, Map map, int soundID)
|
public static void PlaySound(IEntity e, int soundID) => PlaySound(e.Location, e.Map, soundID);
|
||||||
|
|
||||||
|
public static void PlaySound(Point3D p, Map map, int soundID)
|
||||||
{
|
{
|
||||||
if (soundID <= -1)
|
if (soundID <= -1)
|
||||||
{
|
{
|
||||||
|
|
@ -37,36 +72,22 @@ namespace Server
|
||||||
|
|
||||||
if (map != null)
|
if (map != null)
|
||||||
{
|
{
|
||||||
Packet playSound = null;
|
Span<byte> buffer = stackalloc byte[OutgoingEffectPackets.SoundPacketLength];
|
||||||
|
OutgoingEffectPackets.CreateSoundEffect(ref buffer, soundID, p);
|
||||||
|
|
||||||
var eable = map.GetClientsInRange(new Point3D(p));
|
var eable = map.GetClientsInRange(new Point3D(p));
|
||||||
|
|
||||||
foreach (var state in eable)
|
foreach (var state in eable)
|
||||||
{
|
{
|
||||||
state.Mobile.ProcessDelta();
|
state.Mobile.ProcessDelta();
|
||||||
|
state.Send(buffer);
|
||||||
playSound ??= Packet.Acquire(new PlaySound(soundID, p));
|
|
||||||
|
|
||||||
state.Send(playSound);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Packet.Release(playSound);
|
|
||||||
|
|
||||||
eable.Free();
|
eable.Free();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SendBoltEffect(IEntity e)
|
public static void SendBoltEffect(IEntity e, bool sound = true, int hue = 0)
|
||||||
{
|
|
||||||
SendBoltEffect(e, true, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SendBoltEffect(IEntity e, bool sound)
|
|
||||||
{
|
|
||||||
SendBoltEffect(e, sound, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SendBoltEffect(IEntity e, bool sound, int hue)
|
|
||||||
{
|
{
|
||||||
var map = e.Map;
|
var map = e.Map;
|
||||||
|
|
||||||
|
|
@ -77,7 +98,20 @@ namespace Server
|
||||||
|
|
||||||
e.ProcessDelta();
|
e.ProcessDelta();
|
||||||
|
|
||||||
Packet preEffect = null, boltEffect = null, playSound = null;
|
Span<byte> preEffect = stackalloc byte[OutgoingEffectPackets.ParticleEffectLength];
|
||||||
|
OutgoingEffectPackets.CreateTargetParticleEffect(
|
||||||
|
ref preEffect,
|
||||||
|
e, 0, 10, 5, 0, 0, 5031, 3, 0
|
||||||
|
);
|
||||||
|
|
||||||
|
Span<byte> boltEffect = stackalloc byte[OutgoingEffectPackets.BoltEffectLength];
|
||||||
|
OutgoingEffectPackets.CreateBoltEffect(ref boltEffect, e, hue);
|
||||||
|
|
||||||
|
Span<byte> soundEffect = sound ? stackalloc byte[OutgoingEffectPackets.SoundPacketLength] : null;
|
||||||
|
if (sound)
|
||||||
|
{
|
||||||
|
OutgoingEffectPackets.CreateSoundEffect(ref soundEffect, 0x29, e);
|
||||||
|
}
|
||||||
|
|
||||||
var eable = map.GetClientsInRange(e.Location);
|
var eable = map.GetClientsInRange(e.Location);
|
||||||
|
|
||||||
|
|
@ -87,52 +121,36 @@ namespace Server
|
||||||
{
|
{
|
||||||
if (SendParticlesTo(state))
|
if (SendParticlesTo(state))
|
||||||
{
|
{
|
||||||
preEffect ??= Packet.Acquire(new TargetParticleEffect(e, 0, 10, 5, 0, 0, 5031, 3, 0));
|
|
||||||
|
|
||||||
state.Send(preEffect);
|
state.Send(preEffect);
|
||||||
}
|
}
|
||||||
|
|
||||||
boltEffect ??= Packet.Acquire(new BoltEffect(e, hue));
|
|
||||||
|
|
||||||
state.Send(boltEffect);
|
state.Send(boltEffect);
|
||||||
|
|
||||||
if (sound)
|
if (sound)
|
||||||
{
|
{
|
||||||
playSound ??= Packet.Acquire(new PlaySound(0x29, e));
|
state.Send(soundEffect);
|
||||||
|
|
||||||
state.Send(playSound);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Packet.Release(preEffect);
|
|
||||||
Packet.Release(boltEffect);
|
|
||||||
Packet.Release(playSound);
|
|
||||||
|
|
||||||
eable.Free();
|
eable.Free();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SendLocationEffect(IPoint3D p, Map map, int itemID, int duration)
|
public static void SendLocationEffect(
|
||||||
{
|
IEntity e, int itemID, int duration, int speed = 10, int hue = 0, int renderMode = 0
|
||||||
SendLocationEffect(p, map, itemID, duration, 10, 0, 0);
|
) => SendLocationEffect(e.Location, e.Map, itemID, duration, speed, hue, renderMode);
|
||||||
}
|
|
||||||
|
|
||||||
public static void SendLocationEffect(IPoint3D p, Map map, int itemID, int duration, int speed)
|
|
||||||
{
|
|
||||||
SendLocationEffect(p, map, itemID, duration, speed, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SendLocationEffect(IPoint3D p, Map map, int itemID, int duration, int hue, int renderMode)
|
|
||||||
{
|
|
||||||
SendLocationEffect(p, map, itemID, duration, 10, hue, renderMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SendLocationEffect(
|
public static void SendLocationEffect(
|
||||||
IPoint3D p, Map map, int itemID, int duration, int speed, int hue,
|
Point3D p, Map map, int itemID, int duration, int speed = 10, int hue = 0, int renderMode = 0
|
||||||
int renderMode
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
SendPacket(p, map, new LocationEffect(p, itemID, speed, duration, hue, renderMode));
|
Span<byte> effect = stackalloc byte[OutgoingEffectPackets.HuedEffectLength];
|
||||||
|
OutgoingEffectPackets.CreateLocationHuedEffect(
|
||||||
|
ref effect,
|
||||||
|
p, itemID, speed, duration, hue, renderMode
|
||||||
|
);
|
||||||
|
|
||||||
|
SendPacket(p, map, ref effect);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SendLocationParticles(IEntity e, int itemID, int speed, int duration, int effect)
|
public static void SendLocationParticles(IEntity e, int itemID, int speed, int duration, int effect)
|
||||||
|
|
@ -146,71 +164,61 @@ namespace Server
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SendLocationParticles(
|
public static void SendLocationParticles(
|
||||||
IEntity e, int itemID, int speed, int duration, int hue, int renderMode,
|
IEntity e, int itemID, int speed, int duration, int hue, int renderMode, int effect, int unknown
|
||||||
int effect, int unknown
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
var map = e.Map;
|
var map = e.Map;
|
||||||
|
|
||||||
if (map != null)
|
if (map == null)
|
||||||
{
|
{
|
||||||
Packet particles = null, regular = null;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var eable = map.GetClientsInRange(e.Location);
|
Span<byte> particles = stackalloc byte[OutgoingEffectPackets.ParticleEffectLength];
|
||||||
|
OutgoingEffectPackets.CreateLocationParticleEffect(
|
||||||
|
ref particles,
|
||||||
|
e, itemID, speed, duration, hue, renderMode, effect, unknown
|
||||||
|
);
|
||||||
|
|
||||||
foreach (var state in eable)
|
Span<byte> regular = itemID != 0 ? stackalloc byte[OutgoingEffectPackets.HuedEffectLength] : null;
|
||||||
|
if (itemID != 0)
|
||||||
|
{
|
||||||
|
OutgoingEffectPackets.CreateLocationHuedEffect(
|
||||||
|
ref regular,
|
||||||
|
e.Location, itemID, speed, duration, hue, renderMode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
var eable = map.GetClientsInRange(e.Location);
|
||||||
|
|
||||||
|
foreach (var state in eable)
|
||||||
|
{
|
||||||
|
state.Mobile.ProcessDelta();
|
||||||
|
|
||||||
|
if (SendParticlesTo(state))
|
||||||
{
|
{
|
||||||
state.Mobile.ProcessDelta();
|
state.Send(particles);
|
||||||
|
}
|
||||||
if (SendParticlesTo(state))
|
else if (itemID != 0)
|
||||||
{
|
{
|
||||||
particles ??=
|
state.Send(regular);
|
||||||
Packet.Acquire(
|
|
||||||
new LocationParticleEffect(e, itemID, speed, duration, hue, renderMode, effect, unknown)
|
|
||||||
);
|
|
||||||
|
|
||||||
state.Send(particles);
|
|
||||||
}
|
|
||||||
else if (itemID != 0)
|
|
||||||
{
|
|
||||||
regular ??= Packet.Acquire(new LocationEffect(e, itemID, speed, duration, hue, renderMode));
|
|
||||||
|
|
||||||
state.Send(regular);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Packet.Release(particles);
|
|
||||||
Packet.Release(regular);
|
|
||||||
|
|
||||||
eable.Free();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendPacket( e.Location, e.Map, new LocationParticleEffect( e, itemID, speed, duration, hue, renderMode, effect, unknown ) );
|
eable.Free();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SendTargetEffect(IEntity target, int itemID, int duration)
|
public static void SendTargetEffect(IEntity target, int itemID, int speed, int duration, int hue = 0, int renderMode = 0)
|
||||||
{
|
{
|
||||||
SendTargetEffect(target, itemID, duration, 0, 0);
|
(target as Mobile)?.ProcessDelta();
|
||||||
}
|
|
||||||
|
|
||||||
public static void SendTargetEffect(IEntity target, int itemID, int speed, int duration)
|
Span<byte> effect = stackalloc byte[OutgoingEffectPackets.HuedEffectLength];
|
||||||
{
|
OutgoingEffectPackets.CreateTargetHuedEffect(
|
||||||
SendTargetEffect(target, itemID, speed, duration, 0, 0);
|
ref effect,
|
||||||
}
|
target, itemID, speed, duration, hue, renderMode
|
||||||
|
);
|
||||||
|
|
||||||
public static void SendTargetEffect(IEntity target, int itemID, int duration, int hue, int renderMode)
|
SendPacket(target.Location, target.Map, ref effect);
|
||||||
{
|
|
||||||
SendTargetEffect(target, itemID, 10, duration, hue, renderMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SendTargetEffect(IEntity target, int itemID, int speed, int duration, int hue, int renderMode)
|
|
||||||
{
|
|
||||||
if (target is Mobile mobile)
|
|
||||||
{
|
|
||||||
mobile.ProcessDelta();
|
|
||||||
}
|
|
||||||
|
|
||||||
SendPacket(target.Location, target.Map, new TargetEffect(target, itemID, speed, duration, hue, renderMode));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SendTargetParticles(
|
public static void SendTargetParticles(
|
||||||
|
|
@ -218,121 +226,184 @@ namespace Server
|
||||||
EffectLayer layer
|
EffectLayer layer
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
SendTargetParticles(target, itemID, speed, duration, 0, 0, effect, layer, 0);
|
SendTargetParticles(target, itemID, speed, duration, 0, 0, effect, layer);
|
||||||
}
|
|
||||||
|
|
||||||
public static void SendTargetParticles(
|
|
||||||
IEntity target, int itemID, int speed, int duration, int effect,
|
|
||||||
EffectLayer layer, int unknown
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SendTargetParticles(target, itemID, speed, duration, 0, 0, effect, layer, unknown);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SendTargetParticles(
|
public static void SendTargetParticles(
|
||||||
IEntity target, int itemID, int speed, int duration, int hue, int renderMode,
|
IEntity target, int itemID, int speed, int duration, int hue, int renderMode,
|
||||||
int effect, EffectLayer layer, int unknown
|
int effect, EffectLayer layer, int unknown = 0
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (target is Mobile mobile)
|
(target as Mobile)?.ProcessDelta();
|
||||||
{
|
|
||||||
mobile.ProcessDelta();
|
|
||||||
}
|
|
||||||
|
|
||||||
var map = target.Map;
|
var map = target.Map;
|
||||||
|
|
||||||
if (map != null)
|
if (map == null)
|
||||||
{
|
{
|
||||||
Packet particles = null, regular = null;
|
return;
|
||||||
|
|
||||||
var eable = map.GetClientsInRange(target.Location);
|
|
||||||
|
|
||||||
foreach (var state in eable)
|
|
||||||
{
|
|
||||||
state.Mobile.ProcessDelta();
|
|
||||||
|
|
||||||
if (SendParticlesTo(state))
|
|
||||||
{
|
|
||||||
particles ??= Packet.Acquire(
|
|
||||||
new TargetParticleEffect(
|
|
||||||
target,
|
|
||||||
itemID,
|
|
||||||
speed,
|
|
||||||
duration,
|
|
||||||
hue,
|
|
||||||
renderMode,
|
|
||||||
effect,
|
|
||||||
(int)layer,
|
|
||||||
unknown
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
state.Send(particles);
|
|
||||||
}
|
|
||||||
else if (itemID != 0)
|
|
||||||
{
|
|
||||||
regular ??= Packet.Acquire(new TargetEffect(target, itemID, speed, duration, hue, renderMode));
|
|
||||||
|
|
||||||
state.Send(regular);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Packet.Release(particles);
|
|
||||||
Packet.Release(regular);
|
|
||||||
|
|
||||||
eable.Free();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendPacket( target.Location, target.Map, new TargetParticleEffect( target, itemID, speed, duration, hue, renderMode, effect, (int)layer, unknown ) );
|
Span<byte> particles = stackalloc byte[OutgoingEffectPackets.ParticleEffectLength];
|
||||||
|
OutgoingEffectPackets.CreateTargetParticleEffect(
|
||||||
|
ref particles,
|
||||||
|
target, itemID, speed, duration, hue, renderMode, effect, (int)layer, unknown
|
||||||
|
);
|
||||||
|
|
||||||
|
Span<byte> regular = itemID != 0 ? stackalloc byte[OutgoingEffectPackets.HuedEffectLength] : null;
|
||||||
|
if (itemID != 0)
|
||||||
|
{
|
||||||
|
OutgoingEffectPackets.CreateTargetHuedEffect(ref regular, target, itemID, speed, duration, hue, renderMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
var eable = map.GetClientsInRange(target.Location);
|
||||||
|
|
||||||
|
foreach (var state in eable)
|
||||||
|
{
|
||||||
|
state.Mobile.ProcessDelta();
|
||||||
|
|
||||||
|
if (SendParticlesTo(state))
|
||||||
|
{
|
||||||
|
state.Send(particles);
|
||||||
|
}
|
||||||
|
else if (itemID != 0)
|
||||||
|
{
|
||||||
|
state.Send(regular);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
eable.Free();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SendMovingEffect(
|
public static void SendMovingEffect(
|
||||||
IEntity from, IEntity to, int itemID, int speed, int duration,
|
Map map, int itemID, Point3D from, Point3D to, int speed, int duration,
|
||||||
bool fixedDirection, bool explodes, int hue = 0, int renderMode = 0
|
bool fixedDirection = false, bool explodes = false, int hue = 0, int renderMode = 0
|
||||||
|
) => SendMovingEffect(
|
||||||
|
Serial.Zero,
|
||||||
|
Serial.Zero,
|
||||||
|
from,
|
||||||
|
map,
|
||||||
|
itemID,
|
||||||
|
from,
|
||||||
|
to,
|
||||||
|
speed,
|
||||||
|
duration,
|
||||||
|
fixedDirection,
|
||||||
|
explodes,
|
||||||
|
hue,
|
||||||
|
renderMode
|
||||||
|
);
|
||||||
|
|
||||||
|
public static void SendMovingEffect(
|
||||||
|
Point3D origin, Map map, int itemID, Point3D from, Point3D to, int speed, int duration,
|
||||||
|
bool fixedDirection = false, bool explodes = false, int hue = 0, int renderMode = 0
|
||||||
|
) => SendMovingEffect(
|
||||||
|
Serial.Zero,
|
||||||
|
Serial.Zero,
|
||||||
|
origin,
|
||||||
|
map,
|
||||||
|
itemID,
|
||||||
|
from,
|
||||||
|
to,
|
||||||
|
speed,
|
||||||
|
duration,
|
||||||
|
fixedDirection,
|
||||||
|
explodes,
|
||||||
|
hue,
|
||||||
|
renderMode
|
||||||
|
);
|
||||||
|
|
||||||
|
public static void SendMovingEffect(
|
||||||
|
IEntity from, Point3D to, int itemID,
|
||||||
|
int speed, int duration, bool fixedDirection = false, bool explodes = false, int hue = 0, int renderMode = 0
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (from is Mobile mobile)
|
(from as Mobile)?.ProcessDelta();
|
||||||
{
|
|
||||||
mobile.ProcessDelta();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (to is Mobile mobile1)
|
SendMovingEffect(
|
||||||
{
|
from.Serial,
|
||||||
mobile1.ProcessDelta();
|
Serial.Zero,
|
||||||
}
|
|
||||||
|
|
||||||
SendPacket(
|
|
||||||
from.Location,
|
from.Location,
|
||||||
from.Map,
|
from.Map,
|
||||||
new MovingEffect(from, to, itemID, speed, duration, fixedDirection, explodes, hue, renderMode)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SendMovingParticles(
|
|
||||||
IEntity from, IEntity to, int itemID, int speed, int duration,
|
|
||||||
bool fixedDirection, bool explodes, int effect, int explodeEffect, int explodeSound
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SendMovingParticles(
|
|
||||||
from,
|
|
||||||
to,
|
|
||||||
itemID,
|
itemID,
|
||||||
|
from.Location,
|
||||||
|
to,
|
||||||
speed,
|
speed,
|
||||||
duration,
|
duration,
|
||||||
fixedDirection,
|
fixedDirection,
|
||||||
explodes,
|
explodes,
|
||||||
0,
|
hue,
|
||||||
0,
|
renderMode
|
||||||
effect,
|
|
||||||
explodeEffect,
|
|
||||||
explodeSound,
|
|
||||||
0
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void SendMovingEffect(
|
||||||
|
IEntity from, IEntity to, int itemID,
|
||||||
|
int speed, int duration, bool fixedDirection = false, bool explodes = false, int hue = 0, int renderMode = 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
(from as Mobile)?.ProcessDelta();
|
||||||
|
(to as Mobile)?.ProcessDelta();
|
||||||
|
|
||||||
|
SendMovingEffect(
|
||||||
|
from,
|
||||||
|
to,
|
||||||
|
from.Location,
|
||||||
|
from.Map,
|
||||||
|
itemID,
|
||||||
|
from.Location,
|
||||||
|
to.Location,
|
||||||
|
speed,
|
||||||
|
duration,
|
||||||
|
fixedDirection,
|
||||||
|
explodes,
|
||||||
|
hue,
|
||||||
|
renderMode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SendMovingEffect(
|
||||||
|
IEntity from, IEntity to, Point3D origin, Map map, int itemID, Point3D fromLocation, Point3D toLocation,
|
||||||
|
int speed, int duration, bool fixedDirection = false, bool explodes = false, int hue = 0, int renderMode = 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
(from as Mobile)?.ProcessDelta();
|
||||||
|
(to as Mobile)?.ProcessDelta();
|
||||||
|
|
||||||
|
SendMovingEffect(
|
||||||
|
from.Serial,
|
||||||
|
to.Serial,
|
||||||
|
origin,
|
||||||
|
map,
|
||||||
|
itemID,
|
||||||
|
fromLocation,
|
||||||
|
toLocation,
|
||||||
|
speed,
|
||||||
|
duration,
|
||||||
|
fixedDirection,
|
||||||
|
explodes,
|
||||||
|
hue,
|
||||||
|
renderMode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SendMovingEffect(
|
||||||
|
Serial from, Serial to, Point3D origin, Map map, int itemID, Point3D fromLocation, Point3D toLocation,
|
||||||
|
int speed, int duration, bool fixedDirection = false, bool explodes = false, int hue = 0, int renderMode = 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Span<byte> effect = stackalloc byte[OutgoingEffectPackets.HuedEffectLength];
|
||||||
|
OutgoingEffectPackets.CreateMovingHuedEffect(
|
||||||
|
ref effect,
|
||||||
|
from, to, itemID, fromLocation, toLocation, speed, duration, fixedDirection,
|
||||||
|
explodes, hue, renderMode
|
||||||
|
);
|
||||||
|
|
||||||
|
SendPacket(origin, map, ref effect);
|
||||||
|
}
|
||||||
|
|
||||||
public static void SendMovingParticles(
|
public static void SendMovingParticles(
|
||||||
IEntity from, IEntity to, int itemID, int speed, int duration,
|
IEntity from, IEntity to, int itemID, int speed, int duration,
|
||||||
bool fixedDirection, bool explodes, int effect, int explodeEffect, int explodeSound, int unknown
|
bool fixedDirection, bool explodes, int effect, int explodeEffect, int explodeSound, int unknown = 0
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
SendMovingParticles(
|
SendMovingParticles(
|
||||||
|
|
@ -382,103 +453,52 @@ namespace Server
|
||||||
EffectLayer layer, int unknown
|
EffectLayer layer, int unknown
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (from is Mobile fromMob)
|
(from as Mobile)?.ProcessDelta();
|
||||||
{
|
(to as Mobile)?.ProcessDelta();
|
||||||
fromMob.ProcessDelta();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (to is Mobile toMob)
|
|
||||||
{
|
|
||||||
toMob.ProcessDelta();
|
|
||||||
}
|
|
||||||
|
|
||||||
var map = from.Map;
|
var map = from.Map;
|
||||||
|
|
||||||
if (map != null)
|
|
||||||
{
|
|
||||||
Packet particles = null, regular = null;
|
|
||||||
|
|
||||||
var eable = map.GetClientsInRange(from.Location);
|
|
||||||
|
|
||||||
foreach (var state in eable)
|
|
||||||
{
|
|
||||||
state.Mobile.ProcessDelta();
|
|
||||||
|
|
||||||
if (SendParticlesTo(state))
|
|
||||||
{
|
|
||||||
particles ??= Packet.Acquire(
|
|
||||||
new MovingParticleEffect(
|
|
||||||
from,
|
|
||||||
to,
|
|
||||||
itemID,
|
|
||||||
speed,
|
|
||||||
duration,
|
|
||||||
fixedDirection,
|
|
||||||
explodes,
|
|
||||||
hue,
|
|
||||||
renderMode,
|
|
||||||
effect,
|
|
||||||
explodeEffect,
|
|
||||||
explodeSound,
|
|
||||||
layer,
|
|
||||||
unknown
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
state.Send(particles);
|
|
||||||
}
|
|
||||||
else if (itemID > 1)
|
|
||||||
{
|
|
||||||
regular ??= Packet.Acquire(
|
|
||||||
new MovingEffect(
|
|
||||||
from,
|
|
||||||
to,
|
|
||||||
itemID,
|
|
||||||
speed,
|
|
||||||
duration,
|
|
||||||
fixedDirection,
|
|
||||||
explodes,
|
|
||||||
hue,
|
|
||||||
renderMode
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
state.Send(regular);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Packet.Release(particles);
|
|
||||||
Packet.Release(regular);
|
|
||||||
|
|
||||||
eable.Free();
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendPacket( from.Location, from.Map, new MovingParticleEffect( from, to, itemID, speed, duration, fixedDirection, explodes, hue, renderMode, effect, explodeEffect, explodeSound, unknown ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SendPacket(Point3D origin, Map map, Packet p)
|
|
||||||
{
|
|
||||||
if (map == null)
|
if (map == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var eable = map.GetClientsInRange(origin);
|
Span<byte> particles = stackalloc byte[OutgoingEffectPackets.ParticleEffectLength];
|
||||||
|
OutgoingEffectPackets.CreateMovingParticleEffect(
|
||||||
|
ref particles,
|
||||||
|
from, to, itemID, speed, duration, fixedDirection, explodes, hue, renderMode, effect,
|
||||||
|
explodeEffect, explodeSound, layer, unknown
|
||||||
|
);
|
||||||
|
|
||||||
p.Acquire();
|
Span<byte> regular = itemID != 0 ? stackalloc byte[OutgoingEffectPackets.HuedEffectLength] : null;
|
||||||
|
if (itemID != 0)
|
||||||
|
{
|
||||||
|
OutgoingEffectPackets.CreateMovingHuedEffect(
|
||||||
|
ref regular,
|
||||||
|
from, to, itemID, speed, duration, fixedDirection, explodes, hue, renderMode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
var eable = map.GetClientsInRange(from.Location);
|
||||||
|
|
||||||
foreach (var state in eable)
|
foreach (var state in eable)
|
||||||
{
|
{
|
||||||
state.Mobile.ProcessDelta();
|
state.Mobile.ProcessDelta();
|
||||||
state.Send(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
p.Release();
|
if (SendParticlesTo(state))
|
||||||
|
{
|
||||||
|
state.Send(particles);
|
||||||
|
}
|
||||||
|
else if (itemID > 1)
|
||||||
|
{
|
||||||
|
state.Send(regular);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
eable.Free();
|
eable.Free();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SendPacket(IPoint3D origin, Map map, Packet p)
|
public static void SendPacket(Point3D origin, Map map, ref Span<byte> effectBuffer)
|
||||||
{
|
{
|
||||||
if (map == null)
|
if (map == null)
|
||||||
{
|
{
|
||||||
|
|
@ -487,16 +507,12 @@ namespace Server
|
||||||
|
|
||||||
var eable = map.GetClientsInRange(new Point3D(origin));
|
var eable = map.GetClientsInRange(new Point3D(origin));
|
||||||
|
|
||||||
p.Acquire();
|
|
||||||
|
|
||||||
foreach (var state in eable)
|
foreach (var state in eable)
|
||||||
{
|
{
|
||||||
state.Mobile.ProcessDelta();
|
state.Mobile.ProcessDelta();
|
||||||
state.Send(p);
|
state.Send(effectBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Release();
|
|
||||||
|
|
||||||
eable.Free();
|
eable.Free();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Server.Accounting;
|
using Server.Accounting;
|
||||||
|
|
@ -3374,12 +3375,14 @@ namespace Server
|
||||||
Packet hitsPacket = null;
|
Packet hitsPacket = null;
|
||||||
Packet statPacketTrue = null;
|
Packet statPacketTrue = null;
|
||||||
Packet statPacketFalse = null;
|
Packet statPacketFalse = null;
|
||||||
Packet deadPacket = null;
|
|
||||||
Packet hairPacket = null;
|
Packet hairPacket = null;
|
||||||
Packet facialhairPacket = null;
|
Packet facialhairPacket = null;
|
||||||
Packet hbpPacket = null;
|
Packet hbpPacket = null;
|
||||||
Packet hbyPacket = null;
|
Packet hbyPacket = null;
|
||||||
|
|
||||||
|
Span<byte> deadBuffer = stackalloc byte[OutgoingMobilePackets.BondedStatusPacketLength];
|
||||||
|
OutgoingMobilePackets.CreateBondedStatus(ref deadBuffer, m.Serial, true);
|
||||||
|
|
||||||
var eable = m.Map.GetClientsInRange(m.m_Location);
|
var eable = m.Map.GetClientsInRange(m.m_Location);
|
||||||
|
|
||||||
foreach (var state in eable)
|
foreach (var state in eable)
|
||||||
|
|
@ -3399,9 +3402,7 @@ namespace Server
|
||||||
|
|
||||||
if (m.IsDeadBondedPet)
|
if (m.IsDeadBondedPet)
|
||||||
{
|
{
|
||||||
deadPacket ??= Packet.Acquire(new BondedStatus(m.Serial, true));
|
state.Send(deadBuffer);
|
||||||
|
|
||||||
state.Send(deadPacket);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3502,7 +3503,6 @@ namespace Server
|
||||||
Packet.Release(hitsPacket);
|
Packet.Release(hitsPacket);
|
||||||
Packet.Release(statPacketTrue);
|
Packet.Release(statPacketTrue);
|
||||||
Packet.Release(statPacketFalse);
|
Packet.Release(statPacketFalse);
|
||||||
Packet.Release(deadPacket);
|
|
||||||
Packet.Release(hairPacket);
|
Packet.Release(hairPacket);
|
||||||
Packet.Release(facialhairPacket);
|
Packet.Release(facialhairPacket);
|
||||||
Packet.Release(hbpPacket);
|
Packet.Release(hbpPacket);
|
||||||
|
|
@ -5383,7 +5383,7 @@ namespace Server
|
||||||
|
|
||||||
if (sound >= 0)
|
if (sound >= 0)
|
||||||
{
|
{
|
||||||
Effects.PlaySound(this, Map, sound);
|
Effects.PlaySound(this, sound);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_Player)
|
if (!m_Player)
|
||||||
|
|
@ -5660,12 +5660,7 @@ namespace Server
|
||||||
|
|
||||||
from.Holding = item;
|
from.Holding = item;
|
||||||
|
|
||||||
var liftSound = item.GetLiftSound(from);
|
from.SendSound(item.GetLiftSound(from));
|
||||||
|
|
||||||
if (liftSound != -1)
|
|
||||||
{
|
|
||||||
from.Send(new PlaySound(liftSound, from));
|
|
||||||
}
|
|
||||||
|
|
||||||
from.NextActionTime = Core.TickCount + ActionDelay;
|
from.NextActionTime = Core.TickCount + ActionDelay;
|
||||||
|
|
||||||
|
|
@ -7319,22 +7314,21 @@ namespace Server
|
||||||
eable.Free();
|
eable.Free();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void SendSound(int soundID)
|
public void SendSound(int soundID)
|
||||||
{
|
{
|
||||||
if (soundID != -1 && m_NetState != null)
|
m_NetState?.SendSoundEffect(soundID, this);
|
||||||
{
|
|
||||||
Send(new PlaySound(soundID, this));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void SendSound(int soundID, IPoint3D p)
|
public void SendSound(int soundID, IPoint3D p)
|
||||||
{
|
{
|
||||||
if (soundID != -1 && m_NetState != null)
|
m_NetState?.SendSoundEffect(soundID, p);
|
||||||
{
|
|
||||||
Send(new PlaySound(soundID, p));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plays a sound to netstates that can see this mobile
|
||||||
|
*/
|
||||||
public void PlaySound(int soundID)
|
public void PlaySound(int soundID)
|
||||||
{
|
{
|
||||||
if (soundID == -1 || m_Map == null)
|
if (soundID == -1 || m_Map == null)
|
||||||
|
|
@ -7342,7 +7336,8 @@ namespace Server
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var p = Packet.Acquire(new PlaySound(soundID, this));
|
Span<byte> buffer = stackalloc byte[OutgoingEffectPackets.SoundPacketLength];
|
||||||
|
OutgoingEffectPackets.CreateSoundEffect(ref buffer, soundID, this);
|
||||||
|
|
||||||
var eable = m_Map.GetClientsInRange(m_Location);
|
var eable = m_Map.GetClientsInRange(m_Location);
|
||||||
|
|
||||||
|
|
@ -7350,12 +7345,10 @@ namespace Server
|
||||||
{
|
{
|
||||||
if (state.Mobile.CanSee(this))
|
if (state.Mobile.CanSee(this))
|
||||||
{
|
{
|
||||||
state.Send(p);
|
state.Send(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Packet.Release(p);
|
|
||||||
|
|
||||||
eable.Free();
|
eable.Free();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -7382,12 +7375,7 @@ namespace Server
|
||||||
DisruptiveAction(); // Anything that unhides you will also distrupt meditation
|
DisruptiveAction(); // Anything that unhides you will also distrupt meditation
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendRemovePacket()
|
public void SendRemovePacket(bool everyone = true)
|
||||||
{
|
|
||||||
SendRemovePacket(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendRemovePacket(bool everyone)
|
|
||||||
{
|
{
|
||||||
if (m_Map == null)
|
if (m_Map == null)
|
||||||
{
|
{
|
||||||
|
|
@ -7530,7 +7518,7 @@ namespace Server
|
||||||
|
|
||||||
if (m.IsDeadBondedPet)
|
if (m.IsDeadBondedPet)
|
||||||
{
|
{
|
||||||
ns.Send(new BondedStatus(m.Serial, true));
|
ns.SendBondedStatus(m.Serial, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ObjectPropertyList.Enabled)
|
if (ObjectPropertyList.Enabled)
|
||||||
|
|
@ -7690,7 +7678,7 @@ namespace Server
|
||||||
|
|
||||||
if (IsDeadBondedPet)
|
if (IsDeadBondedPet)
|
||||||
{
|
{
|
||||||
state.Send(new BondedStatus(Serial, true));
|
state.SendBondedStatus(Serial, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ObjectPropertyList.Enabled)
|
if (ObjectPropertyList.Enabled)
|
||||||
|
|
@ -7976,7 +7964,7 @@ namespace Server
|
||||||
|
|
||||||
if (IsDeadBondedPet)
|
if (IsDeadBondedPet)
|
||||||
{
|
{
|
||||||
m.m_NetState.Send(new BondedStatus(Serial, true));
|
m.m_NetState.SendBondedStatus(Serial, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ObjectPropertyList.Enabled)
|
if (ObjectPropertyList.Enabled)
|
||||||
|
|
@ -8003,7 +7991,7 @@ namespace Server
|
||||||
|
|
||||||
if (m.IsDeadBondedPet)
|
if (m.IsDeadBondedPet)
|
||||||
{
|
{
|
||||||
ourState.Send(new BondedStatus(m.Serial, true));
|
ourState.SendBondedStatus(m.Serial, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ObjectPropertyList.Enabled)
|
if (ObjectPropertyList.Enabled)
|
||||||
|
|
@ -8038,7 +8026,7 @@ namespace Server
|
||||||
|
|
||||||
if (IsDeadBondedPet)
|
if (IsDeadBondedPet)
|
||||||
{
|
{
|
||||||
ns.Send(new BondedStatus(Serial, true));
|
ns.SendBondedStatus(Serial, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ObjectPropertyList.Enabled)
|
if (ObjectPropertyList.Enabled)
|
||||||
|
|
@ -8126,7 +8114,7 @@ namespace Server
|
||||||
|
|
||||||
if (IsDeadBondedPet)
|
if (IsDeadBondedPet)
|
||||||
{
|
{
|
||||||
state.Send(new BondedStatus(Serial, true));
|
state.SendBondedStatus(Serial, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ObjectPropertyList.Enabled)
|
if (ObjectPropertyList.Enabled)
|
||||||
|
|
|
||||||
|
|
@ -377,7 +377,34 @@ namespace Server.Network
|
||||||
return !(result.IsClosed || result.Length <= 0);
|
return !(result.IsClosed || result.Length <= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Send(ref CircularBuffer<byte> buffer, int length)
|
public void Send(ReadOnlySpan<byte> span)
|
||||||
|
{
|
||||||
|
var length = span.Length;
|
||||||
|
if (Connection == null || BlockAllPackets || length <= 0 || !GetSendBuffer(out var buffer))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
buffer.CopyFrom(span);
|
||||||
|
_packetEncoder?.Invoke(ref buffer, ref length);
|
||||||
|
SendPipe.Writer.Advance((uint)length);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
Console.WriteLine(ex);
|
||||||
|
TraceException(ex);
|
||||||
|
#endif
|
||||||
|
Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send data using a circular buffer from SendPipe
|
||||||
|
*/
|
||||||
|
public void Send(ref CircularBuffer<byte> buffer, int length)
|
||||||
{
|
{
|
||||||
if (Connection == null || BlockAllPackets || length <= 0)
|
if (Connection == null || BlockAllPackets || length <= 0)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -27,19 +27,6 @@ namespace Server.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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class MobileMoving : Packet
|
public sealed class MobileMoving : Packet
|
||||||
{
|
{
|
||||||
public MobileMoving(Mobile m, int noto) : base(0x77, 17)
|
public MobileMoving(Mobile m, int noto) : base(0x77, 17)
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ namespace Server.Network
|
||||||
writer.Write(attacker);
|
writer.Write(attacker);
|
||||||
writer.Write(defender);
|
writer.Write(defender);
|
||||||
|
|
||||||
ns.Send(ref buffer, 10);
|
ns.Send(ref buffer, writer.Position);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SendSetWarMode(this NetState ns, bool warmode)
|
public static void SendSetWarMode(this NetState ns, bool warmode)
|
||||||
|
|
@ -47,7 +47,7 @@ namespace Server.Network
|
||||||
// Warmode, 0x00, 0x32, 0x00
|
// Warmode, 0x00, 0x32, 0x00
|
||||||
writer.Write(warmode ? 0x01003200 : 0x00003200);
|
writer.Write(warmode ? 0x01003200 : 0x00003200);
|
||||||
|
|
||||||
ns.Send(ref buffer, 5);
|
ns.Send(ref buffer, writer.Position);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SendChangeCombatant(this NetState ns, Serial combatant)
|
public static void SendChangeCombatant(this NetState ns, Serial combatant)
|
||||||
|
|
@ -61,7 +61,7 @@ namespace Server.Network
|
||||||
writer.Write((byte)0xAA); // Packet ID
|
writer.Write((byte)0xAA); // Packet ID
|
||||||
writer.Write(combatant);
|
writer.Write(combatant);
|
||||||
|
|
||||||
ns.Send(ref buffer, 5);
|
ns.Send(ref buffer, writer.Position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
331
Projects/Server/Network/Packets/OutgoingEffectPackets.cs
Normal file
331
Projects/Server/Network/Packets/OutgoingEffectPackets.cs
Normal file
|
|
@ -0,0 +1,331 @@
|
||||||
|
/*************************************************************************
|
||||||
|
* ModernUO *
|
||||||
|
* Copyright 2019-2020 - ModernUO Development Team *
|
||||||
|
* Email: hi@modernuo.com *
|
||||||
|
* File: OutgoingEffectPackets.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 System;
|
||||||
|
using System.Buffers;
|
||||||
|
|
||||||
|
namespace Server.Network
|
||||||
|
{
|
||||||
|
public static class OutgoingEffectPackets
|
||||||
|
{
|
||||||
|
public const int SoundPacketLength = 12;
|
||||||
|
public const int ParticleEffectLength = 49;
|
||||||
|
public const int HuedEffectLength = 36;
|
||||||
|
public const int BoltEffectLength = 36;
|
||||||
|
|
||||||
|
public static void CreateSoundEffect(ref Span<byte> buffer, int soundID, IPoint3D target)
|
||||||
|
{
|
||||||
|
var writer = new SpanWriter(buffer);
|
||||||
|
writer.Write((byte)0x54); // Packet ID
|
||||||
|
writer.Write((byte)1); // flags
|
||||||
|
writer.Write((short)soundID);
|
||||||
|
writer.Write((short)0); // volume
|
||||||
|
writer.Write((short)target.X);
|
||||||
|
writer.Write((short)target.Y);
|
||||||
|
writer.Write((short)target.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SendSoundEffect(this NetState ns, int soundID, IPoint3D target)
|
||||||
|
{
|
||||||
|
if (ns == null || !ns.GetSendBuffer(out var buffer))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var writer = new CircularBufferWriter(buffer);
|
||||||
|
writer.Write((byte)0x54); // Packet ID
|
||||||
|
writer.Write((byte)1); // flags
|
||||||
|
writer.Write((short)soundID);
|
||||||
|
writer.Write((short)0); // volume
|
||||||
|
writer.Write((short)target.X);
|
||||||
|
writer.Write((short)target.Y);
|
||||||
|
writer.Write((short)target.Z);
|
||||||
|
|
||||||
|
ns.Send(ref buffer, writer.Position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CreateParticleEffect(
|
||||||
|
ref Span<byte> buffer,
|
||||||
|
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
|
||||||
|
)
|
||||||
|
{
|
||||||
|
var writer = new SpanWriter(buffer);
|
||||||
|
writer.Write((byte)0xC7); // Packet ID
|
||||||
|
writer.Write((byte)type);
|
||||||
|
writer.Write(from);
|
||||||
|
writer.Write(to);
|
||||||
|
writer.Write((short)itemID);
|
||||||
|
writer.Write((short)fromPoint.X);
|
||||||
|
writer.Write((short)fromPoint.Y);
|
||||||
|
writer.Write((sbyte)fromPoint.Z);
|
||||||
|
writer.Write((short)toPoint.X);
|
||||||
|
writer.Write((short)toPoint.Y);
|
||||||
|
writer.Write((sbyte)toPoint.Z);
|
||||||
|
writer.Write((byte)speed);
|
||||||
|
writer.Write((byte)duration);
|
||||||
|
writer.Write((byte)0);
|
||||||
|
writer.Write((byte)0);
|
||||||
|
writer.Write(fixedDirection);
|
||||||
|
writer.Write(explode);
|
||||||
|
writer.Write(hue);
|
||||||
|
writer.Write(renderMode);
|
||||||
|
writer.Write((short)effect);
|
||||||
|
writer.Write((short)explodeEffect);
|
||||||
|
writer.Write((short)explodeSound);
|
||||||
|
writer.Write(serial);
|
||||||
|
writer.Write((byte)layer);
|
||||||
|
writer.Write((short)unknown);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CreateTargetParticleEffect(
|
||||||
|
ref Span<byte> buffer,
|
||||||
|
IEntity e, int itemID, int speed, int duration, int hue, int renderMode, int effect, int layer, int unknown
|
||||||
|
) => CreateParticleEffect(
|
||||||
|
ref buffer,
|
||||||
|
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 static void CreateLocationParticleEffect(
|
||||||
|
ref Span<byte> buffer,
|
||||||
|
IEntity e, int itemID, int speed, int duration, int hue, int renderMode, int effect, int unknown
|
||||||
|
) => CreateParticleEffect(
|
||||||
|
ref buffer,
|
||||||
|
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 static void CreateMovingParticleEffect(
|
||||||
|
ref Span<byte> buffer,
|
||||||
|
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
|
||||||
|
) => CreateParticleEffect(
|
||||||
|
ref buffer,
|
||||||
|
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 static void CreateHuedEffect(
|
||||||
|
ref Span<byte> buffer,
|
||||||
|
EffectType type, Serial from, Serial to, int itemID, Point3D fromPoint, Point3D toPoint,
|
||||||
|
int speed, int duration, bool fixedDirection, bool explode, int hue, int renderMode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
var writer = new SpanWriter(buffer);
|
||||||
|
writer.Write((byte)0xC0); // Packet ID
|
||||||
|
writer.Write((byte)type);
|
||||||
|
writer.Write(from);
|
||||||
|
writer.Write(to);
|
||||||
|
writer.Write((short)itemID);
|
||||||
|
writer.Write((short)fromPoint.X);
|
||||||
|
writer.Write((short)fromPoint.Y);
|
||||||
|
writer.Write((sbyte)fromPoint.Z);
|
||||||
|
writer.Write((short)toPoint.X);
|
||||||
|
writer.Write((short)toPoint.Y);
|
||||||
|
writer.Write((sbyte)toPoint.Z);
|
||||||
|
writer.Write((byte)speed);
|
||||||
|
writer.Write((byte)duration);
|
||||||
|
writer.Write((byte)0);
|
||||||
|
writer.Write((byte)0);
|
||||||
|
writer.Write(fixedDirection);
|
||||||
|
writer.Write(explode);
|
||||||
|
writer.Write(hue);
|
||||||
|
writer.Write(renderMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CreateTargetHuedEffect(
|
||||||
|
ref Span<byte> buffer,
|
||||||
|
IEntity e, int itemID, int speed, int duration, int hue, int renderMode
|
||||||
|
) => CreateHuedEffect(
|
||||||
|
ref buffer,
|
||||||
|
EffectType.FixedFrom,
|
||||||
|
e.Serial,
|
||||||
|
Serial.Zero,
|
||||||
|
itemID,
|
||||||
|
e.Location,
|
||||||
|
e.Location,
|
||||||
|
speed,
|
||||||
|
duration,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
hue,
|
||||||
|
renderMode
|
||||||
|
);
|
||||||
|
|
||||||
|
public static void CreateLocationHuedEffect(
|
||||||
|
ref Span<byte> buffer,
|
||||||
|
Point3D p, int itemID, int speed, int duration, int hue, int renderMode
|
||||||
|
) => CreateHuedEffect(
|
||||||
|
ref buffer,
|
||||||
|
EffectType.FixedXYZ,
|
||||||
|
Serial.Zero,
|
||||||
|
Serial.Zero,
|
||||||
|
itemID,
|
||||||
|
p,
|
||||||
|
p,
|
||||||
|
speed,
|
||||||
|
duration,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
hue,
|
||||||
|
renderMode
|
||||||
|
);
|
||||||
|
|
||||||
|
public static void CreateMovingHuedEffect(
|
||||||
|
ref Span<byte> buffer,
|
||||||
|
IEntity from, IEntity to, int itemID, int speed, int duration, bool fixedDirection,
|
||||||
|
bool explodes, int hue, int renderMode
|
||||||
|
) => CreateHuedEffect(
|
||||||
|
ref buffer,
|
||||||
|
EffectType.Moving,
|
||||||
|
from.Serial,
|
||||||
|
to.Serial,
|
||||||
|
itemID,
|
||||||
|
from.Location,
|
||||||
|
to.Location,
|
||||||
|
speed,
|
||||||
|
duration,
|
||||||
|
fixedDirection,
|
||||||
|
explodes,
|
||||||
|
hue,
|
||||||
|
renderMode
|
||||||
|
);
|
||||||
|
|
||||||
|
public static void CreateMovingHuedEffect(
|
||||||
|
ref Span<byte> buffer,
|
||||||
|
int itemID, Point3D fromLocation, Point3D toLocation, int speed, int duration,
|
||||||
|
bool fixedDirection, bool explodes, int hue, int renderMode
|
||||||
|
) => CreateHuedEffect(
|
||||||
|
ref buffer,
|
||||||
|
EffectType.Moving,
|
||||||
|
Serial.Zero,
|
||||||
|
Serial.Zero,
|
||||||
|
itemID,
|
||||||
|
fromLocation,
|
||||||
|
toLocation,
|
||||||
|
speed,
|
||||||
|
duration,
|
||||||
|
fixedDirection,
|
||||||
|
explodes,
|
||||||
|
hue,
|
||||||
|
renderMode
|
||||||
|
);
|
||||||
|
|
||||||
|
public static void CreateMovingHuedEffect(
|
||||||
|
ref Span<byte> buffer,
|
||||||
|
Serial from, Serial to, int itemID, Point3D fromLocation, Point3D toLocation, int speed, int duration,
|
||||||
|
bool fixedDirection, bool explodes, int hue, int renderMode
|
||||||
|
) => CreateHuedEffect(
|
||||||
|
ref buffer,
|
||||||
|
EffectType.Moving,
|
||||||
|
from,
|
||||||
|
to,
|
||||||
|
itemID,
|
||||||
|
fromLocation,
|
||||||
|
toLocation,
|
||||||
|
speed,
|
||||||
|
duration,
|
||||||
|
fixedDirection,
|
||||||
|
explodes,
|
||||||
|
hue,
|
||||||
|
renderMode
|
||||||
|
);
|
||||||
|
|
||||||
|
public static void CreateBoltEffect(ref Span<byte> buffer, IEntity target, int hue) => CreateHuedEffect(
|
||||||
|
ref buffer,
|
||||||
|
EffectType.Lightning,
|
||||||
|
target.Serial,
|
||||||
|
Serial.Zero,
|
||||||
|
0,
|
||||||
|
target.Location,
|
||||||
|
target.Location,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
hue,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
public static void SendScreenEffect(this NetState ns, ScreenEffectType type)
|
||||||
|
{
|
||||||
|
if (ns == null || !ns.GetSendBuffer(out var buffer))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var writer = new CircularBufferWriter(buffer);
|
||||||
|
|
||||||
|
writer.Write((byte)0x70); // Packet ID
|
||||||
|
writer.Write((byte)0x4);
|
||||||
|
writer.Clear(8);
|
||||||
|
writer.Write((ushort)type);
|
||||||
|
writer.Clear(16);
|
||||||
|
|
||||||
|
ns.Send(ref buffer, writer.Position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
54
Projects/Server/Network/Packets/OutgoingMobilePackets.cs
Normal file
54
Projects/Server/Network/Packets/OutgoingMobilePackets.cs
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*************************************************************************
|
||||||
|
* ModernUO *
|
||||||
|
* Copyright 2019-2020 - ModernUO Development Team *
|
||||||
|
* Email: hi@modernuo.com *
|
||||||
|
* File: OutgoingMobilePackets.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 System;
|
||||||
|
using System.Buffers;
|
||||||
|
|
||||||
|
namespace Server.Network
|
||||||
|
{
|
||||||
|
public static class OutgoingMobilePackets
|
||||||
|
{
|
||||||
|
public const int BondedStatusPacketLength = 11;
|
||||||
|
|
||||||
|
public static void CreateBondedStatus(ref Span<byte> buffer, Serial serial, bool bonded)
|
||||||
|
{
|
||||||
|
var writer = new SpanWriter(buffer);
|
||||||
|
writer.Write((byte)0xBF); // Packet ID
|
||||||
|
writer.Write((ushort)11); // Length
|
||||||
|
writer.Write((ushort)0x19); // Subpacket ID
|
||||||
|
writer.Write((byte)0); // Command
|
||||||
|
writer.Write(serial);
|
||||||
|
writer.Write(bonded);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SendBondedStatus(this NetState ns, Serial serial, bool bonded)
|
||||||
|
{
|
||||||
|
if (ns == null || !ns.GetSendBuffer(out var buffer))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var writer = new CircularBufferWriter(buffer);
|
||||||
|
writer.Write((byte)0xBF); // Packet ID
|
||||||
|
writer.Write((ushort)11); // Length
|
||||||
|
writer.Write((ushort)0x19); // Subpacket ID
|
||||||
|
writer.Write((byte)0); // Command
|
||||||
|
writer.Write(serial);
|
||||||
|
writer.Write(bonded);
|
||||||
|
|
||||||
|
ns.Send(ref buffer, writer.Position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using Server.HuePickers;
|
||||||
|
|
||||||
namespace Server.Network
|
namespace Server.Network
|
||||||
{
|
{
|
||||||
|
|
@ -305,19 +306,6 @@ 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 sealed class PlayMusic : Packet
|
public sealed class PlayMusic : Packet
|
||||||
{
|
{
|
||||||
public static readonly Packet InvalidInstance = SetStatic(new PlayMusic(MusicName.Invalid));
|
public static readonly Packet InvalidInstance = SetStatic(new PlayMusic(MusicName.Invalid));
|
||||||
|
|
@ -430,4 +418,14 @@ namespace Server.Network
|
||||||
Stream.Write((short)0x21);
|
Stream.Write((short)0x21);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sealed class DisplayHuePicker : Packet
|
||||||
|
{
|
||||||
|
public DisplayHuePicker(HuePicker huePicker) : base(0x95, 9)
|
||||||
|
{
|
||||||
|
Stream.Write(huePicker.Serial);
|
||||||
|
Stream.Write((short)0);
|
||||||
|
Stream.Write((short)huePicker.ItemID);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -394,7 +394,7 @@ namespace Server.Commands.Generic
|
||||||
index,
|
index,
|
||||||
CommandLogging.Format(mob)
|
CommandLogging.Format(mob)
|
||||||
);
|
);
|
||||||
mob.Send(new PlaySound(index, mob.Location));
|
mob.SendSound(index);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Server.Commands.Generic;
|
using Server.Commands.Generic;
|
||||||
|
|
@ -420,19 +421,16 @@ namespace Server.Commands
|
||||||
toAll
|
toAll
|
||||||
);
|
);
|
||||||
|
|
||||||
Packet p = new PlaySound(index, m.Location);
|
Span<byte> buffer = stackalloc byte[OutgoingEffectPackets.SoundPacketLength];
|
||||||
|
OutgoingEffectPackets.CreateSoundEffect(ref buffer, index, m);
|
||||||
p.Acquire();
|
|
||||||
|
|
||||||
foreach (var state in m.GetClientsInRange(12))
|
foreach (var state in m.GetClientsInRange(12))
|
||||||
{
|
{
|
||||||
if (toAll || state.Mobile.CanSee(m))
|
if (toAll || state.Mobile.CanSee(m))
|
||||||
{
|
{
|
||||||
state.Send(p);
|
state.Send(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Usage("Echo <text>")]
|
[Usage("Echo <text>")]
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,7 @@ namespace Server.ContextMenus
|
||||||
book.Content |= (ulong)1 << val;
|
book.Content |= (ulong)1 << val;
|
||||||
|
|
||||||
m_Scroll.Consume();
|
m_Scroll.Consume();
|
||||||
|
from.SendSound(0x249, book.GetWorldLocation());
|
||||||
from.Send(new PlaySound(0x249, book.GetWorldLocation()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -476,14 +476,14 @@ namespace Server.Engines.Doom
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void PlayEffect(IEntity from, IEntity to, int itemid, int speed, bool explodes)
|
private static void PlayEffect(IEntity from, IEntity to, int itemid, int speed, bool explodes)
|
||||||
{
|
{
|
||||||
Effects.SendMovingParticles(from, to, itemid, speed, 0, true, explodes, 2, 0, 0);
|
Effects.SendMovingParticles(from, to, itemid, speed, 0, true, explodes, 2, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SendLocationEffect(IPoint3D p, int itemID, int speed, int duration, int hue)
|
private static void SendLocationEffect(Point3D p, int itemID, int speed, int duration, int hue)
|
||||||
{
|
{
|
||||||
Effects.SendPacket(p, Map.Malas, new LocationEffect(p, itemID, speed, duration, hue, 0));
|
Effects.SendLocationEffect(p, Map.Malas, itemID, speed, duration, hue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void PlayerSendASCII(Mobile player, int index)
|
public static void PlayerSendASCII(Mobile player, int index)
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ namespace Server.Ethics.Evil
|
||||||
{
|
{
|
||||||
SpellHelper.Turn(from.Mobile, p);
|
SpellHelper.Turn(from.Mobile, p);
|
||||||
|
|
||||||
Effects.PlaySound(p, from.Mobile.Map, 0x1FB);
|
Effects.PlaySound(new Point3D(p), from.Mobile.Map, 0x1FB);
|
||||||
|
|
||||||
from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You curse the area.");
|
from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You curse the area.");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ namespace Server.Ethics.Hero
|
||||||
{
|
{
|
||||||
SpellHelper.Turn(from.Mobile, p);
|
SpellHelper.Turn(from.Mobile, p);
|
||||||
|
|
||||||
Effects.PlaySound(p, from.Mobile.Map, 0x299);
|
Effects.PlaySound(new Point3D(p), from.Mobile.Map, 0x299);
|
||||||
|
|
||||||
from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You consecrate the area.");
|
from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You consecrate the area.");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -330,7 +330,7 @@ namespace Server.Items
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
Effects.SendLocationEffect(to, to.Map, 0x113A, 20, 10);
|
Effects.SendLocationEffect(to, 0x113A, 20);
|
||||||
to.PlaySound(0x231);
|
to.PlaySound(0x231);
|
||||||
to.LocalOverheadMessage(MessageType.Regular, 0x44, 1010523); // A toxic vapor envelops thee.
|
to.LocalOverheadMessage(MessageType.Regular, 0x44, 1010523); // A toxic vapor envelops thee.
|
||||||
|
|
||||||
|
|
@ -340,7 +340,7 @@ namespace Server.Items
|
||||||
}
|
}
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
Effects.SendLocationEffect(to, to.Map, 0x3709, 30);
|
Effects.SendLocationEffect(to, 0x3709, 30);
|
||||||
to.PlaySound(0x54);
|
to.PlaySound(0x54);
|
||||||
to.LocalOverheadMessage(MessageType.Regular, 0xEE, 1010524); // Searing heat scorches thy skin.
|
to.LocalOverheadMessage(MessageType.Regular, 0xEE, 1010524); // Searing heat scorches thy skin.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -157,24 +157,7 @@ namespace Server.Engines.Quests.Necro
|
||||||
|
|
||||||
var hue = Utility.RandomList(0x481, 0x482, 0x489, 0x497, 0x66D);
|
var hue = Utility.RandomList(0x481, 0x482, 0x489, 0x497, 0x66D);
|
||||||
|
|
||||||
Effects.SendPacket(
|
Effects.SendMovingEffect(map, 0x36D4, from, to,0, 0, false, true, hue);
|
||||||
from,
|
|
||||||
map,
|
|
||||||
new HuedEffect(
|
|
||||||
EffectType.Moving,
|
|
||||||
Serial.Zero,
|
|
||||||
Serial.Zero,
|
|
||||||
0x36D4,
|
|
||||||
from,
|
|
||||||
to,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
hue,
|
|
||||||
0
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ namespace Server.Engines.Quests.Haven
|
||||||
|
|
||||||
public override bool HandlesOnMovement => Canoneer?.Deleted == false && Canoneer.Active;
|
public override bool HandlesOnMovement => Canoneer?.Deleted == false && Canoneer.Active;
|
||||||
|
|
||||||
public void DoFireEffect(IPoint3D target)
|
public void DoFireEffect(Point3D target)
|
||||||
{
|
{
|
||||||
var from = CannonDirection switch
|
var from = CannonDirection switch
|
||||||
{
|
{
|
||||||
|
|
@ -85,7 +85,7 @@ namespace Server.Engines.Quests.Haven
|
||||||
|
|
||||||
public void Fire(Mobile from, Mobile target)
|
public void Fire(Mobile from, Mobile target)
|
||||||
{
|
{
|
||||||
DoFireEffect(target);
|
DoFireEffect(target.Location);
|
||||||
|
|
||||||
target.Damage(9999, from);
|
target.Damage(9999, from);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ namespace Server.Items
|
||||||
Location = new Point3D(X - Offset.X, Y - Offset.Y, Z - Offset.Z);
|
Location = new Point3D(X - Offset.X, Y - Offset.Y, Z - Offset.Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
Effects.PlaySound(this, Map, m_Open ? OpenedSound : ClosedSound);
|
Effects.PlaySound(this, m_Open ? OpenedSound : ClosedSound);
|
||||||
|
|
||||||
if (m_Open)
|
if (m_Open)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -81,24 +81,21 @@ namespace Server.Items
|
||||||
{
|
{
|
||||||
if (dropped is BasePiece piece && piece.Board == this && base.OnDragDropInto(from, dropped, point))
|
if (dropped is BasePiece piece && piece.Board == this && base.OnDragDropInto(from, dropped, point))
|
||||||
{
|
{
|
||||||
Packet p = new PlaySound(0x127, GetWorldLocation());
|
|
||||||
|
|
||||||
p.Acquire();
|
|
||||||
|
|
||||||
if (RootParent == from)
|
if (RootParent == from)
|
||||||
{
|
{
|
||||||
from.Send(p);
|
from.SendSound(0x127, GetWorldLocation());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Span<byte> buffer = stackalloc byte[OutgoingEffectPackets.SoundPacketLength];
|
||||||
|
OutgoingEffectPackets.CreateSoundEffect(ref buffer, 0x127, GetWorldLocation());
|
||||||
|
|
||||||
foreach (var state in GetClientsInRange(2))
|
foreach (var state in GetClientsInRange(2))
|
||||||
{
|
{
|
||||||
state.Send(p);
|
state.Send(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Release();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -886,7 +886,7 @@ namespace Server.Items
|
||||||
m_Chest.Z++;
|
m_Chest.Z++;
|
||||||
}
|
}
|
||||||
|
|
||||||
Effects.PlaySound(m_Chest, m_Map, 0x33B);
|
Effects.PlaySound(m_Chest.Location, m_Map, 0x33B);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_Chest?.Location.Z >= m_Location.Z)
|
if (m_Chest?.Location.Z >= m_Location.Z)
|
||||||
|
|
|
||||||
|
|
@ -180,7 +180,7 @@ namespace Server.Items
|
||||||
{
|
{
|
||||||
if (from.AccessLevel == AccessLevel.Player || !from.Hidden)
|
if (from.AccessLevel == AccessLevel.Player || !from.Hidden)
|
||||||
{
|
{
|
||||||
from.Send(new PlaySound(0x20E, from.Location));
|
from.SendSound(0x20E, from);
|
||||||
}
|
}
|
||||||
|
|
||||||
from.CloseGump<MoongateConfirmGump>();
|
from.CloseGump<MoongateConfirmGump>();
|
||||||
|
|
|
||||||
|
|
@ -414,7 +414,7 @@ namespace Server.Items
|
||||||
|
|
||||||
rune.Delete();
|
rune.Delete();
|
||||||
|
|
||||||
from.Send(new PlaySound(0x42, GetWorldLocation()));
|
from.SendSound(0x42, GetWorldLocation());
|
||||||
|
|
||||||
from.SendMessage((rune.Description?.Trim()).DefaultIfNullOrEmpty("(indescript)"));
|
from.SendMessage((rune.Description?.Trim()).DefaultIfNullOrEmpty("(indescript)"));
|
||||||
|
|
||||||
|
|
@ -432,7 +432,7 @@ namespace Server.Items
|
||||||
{
|
{
|
||||||
if (CurCharges < MaxCharges)
|
if (CurCharges < MaxCharges)
|
||||||
{
|
{
|
||||||
from.Send(new PlaySound(0x249, GetWorldLocation()));
|
from.SendSound(0x249, GetWorldLocation());
|
||||||
|
|
||||||
var amount = dropped.Amount;
|
var amount = dropped.Amount;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -591,7 +591,7 @@ namespace Server.Items
|
||||||
|
|
||||||
scroll.Delete();
|
scroll.Delete();
|
||||||
|
|
||||||
from.Send(new PlaySound(0x249, GetWorldLocation()));
|
from.SendSound(0x249, GetWorldLocation());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ namespace Server.Items
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Use(Mobile from, IPoint3D loc)
|
public void Use(Mobile from, Point3D loc)
|
||||||
{
|
{
|
||||||
if (!CheckUse(from))
|
if (!CheckUse(from))
|
||||||
{
|
{
|
||||||
|
|
@ -84,23 +84,14 @@ namespace Server.Items
|
||||||
from.Backpack.ConsumeUpTo(typeof(SulfurousAsh), sulfAsh);
|
from.Backpack.ConsumeUpTo(typeof(SulfurousAsh), sulfAsh);
|
||||||
|
|
||||||
from.PlaySound(0x15F);
|
from.PlaySound(0x15F);
|
||||||
Effects.SendPacket(
|
Effects.SendMovingEffect(
|
||||||
from,
|
from,
|
||||||
from.Map,
|
loc,
|
||||||
new HuedEffect(
|
0x36D4,
|
||||||
EffectType.Moving,
|
5,
|
||||||
from.Serial,
|
0,
|
||||||
Serial.Zero,
|
false,
|
||||||
0x36D4,
|
true
|
||||||
from.Location,
|
|
||||||
loc,
|
|
||||||
5,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
var eable = from.Map.GetMobilesInRange(new Point3D(loc), 2);
|
var eable = from.Map.GetMobilesInRange(new Point3D(loc), 2);
|
||||||
|
|
@ -241,14 +232,14 @@ namespace Server.Items
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
IPoint3D loc;
|
Point3D loc;
|
||||||
if (targeted is Item item)
|
if (targeted is Item item)
|
||||||
{
|
{
|
||||||
loc = item.GetWorldLocation();
|
loc = item.GetWorldLocation();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
loc = targeted as IPoint3D;
|
loc = new Point3D(targeted as IPoint3D);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Horn.Use(from, loc);
|
m_Horn.Use(from, loc);
|
||||||
|
|
|
||||||
|
|
@ -214,11 +214,11 @@ namespace Server.Items
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DoFireEffect(IPoint3D target)
|
public void DoFireEffect(Point3D target)
|
||||||
{
|
{
|
||||||
var map = Map;
|
var map = Map;
|
||||||
|
|
||||||
if (target == null || map == null)
|
if (map == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -228,7 +228,7 @@ namespace Server.Items
|
||||||
|
|
||||||
for (var count = Utility.Random(3); count > 0; count--)
|
for (var count = Utility.Random(3); count > 0; count--)
|
||||||
{
|
{
|
||||||
IPoint3D location = new Point3D(
|
Point3D location = new Point3D(
|
||||||
target.X + Utility.RandomMinMax(-1, 1),
|
target.X + Utility.RandomMinMax(-1, 1),
|
||||||
target.Y + Utility.RandomMinMax(-1, 1),
|
target.Y + Utility.RandomMinMax(-1, 1),
|
||||||
target.Z
|
target.Z
|
||||||
|
|
@ -320,9 +320,11 @@ namespace Server.Items
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allow && Utility.InRange(new Point3D(p), m_Cannon.Location, 14))
|
var loc = new Point3D(p);
|
||||||
|
|
||||||
|
if (allow && Utility.InRange(loc, m_Cannon.Location, 14))
|
||||||
{
|
{
|
||||||
m_Cannon.DoFireEffect(p);
|
m_Cannon.DoFireEffect(loc);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -408,7 +408,7 @@ namespace Server.Items
|
||||||
20,
|
20,
|
||||||
5042
|
5042
|
||||||
);
|
);
|
||||||
Effects.PlaySound(m_Creature, m_Creature.Map, 0x201);
|
Effects.PlaySound(m_Creature, 0x201);
|
||||||
|
|
||||||
m_Creature.Delete();
|
m_Creature.Delete();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,8 @@ namespace Server.Mobiles
|
||||||
20,
|
20,
|
||||||
5042
|
5042
|
||||||
);
|
);
|
||||||
Effects.PlaySound(m_Mobile, m_Mobile.Map, 0x201);
|
|
||||||
|
Effects.PlaySound(m_Mobile,0x201);
|
||||||
|
|
||||||
m_Mobile.Delete();
|
m_Mobile.Delete();
|
||||||
}
|
}
|
||||||
|
|
@ -405,13 +406,13 @@ namespace Server.Mobiles
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// An area attack that only damages staff, wtf?
|
// An area attack that only damages staff, wtf?
|
||||||
|
|
||||||
private DateTime m_NextWave;
|
private DateTime m_NextWave;
|
||||||
|
|
||||||
public void AreaHeatDamage()
|
public void AreaHeatDamage()
|
||||||
{
|
{
|
||||||
Mobile mob = ControlMaster;
|
Mobile mob = ControlMaster;
|
||||||
|
|
||||||
if (mob != null)
|
if (mob != null)
|
||||||
{
|
{
|
||||||
if (mob.InRange( Location, 2 ))
|
if (mob.InRange( Location, 2 ))
|
||||||
|
|
@ -422,9 +423,9 @@ namespace Server.Mobiles
|
||||||
mob.SendLocalizedMessage( 1008112 ); // The intense heat is damaging you!
|
mob.SendLocalizedMessage( 1008112 ); // The intense heat is damaging you!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GuardedRegion r = Region as GuardedRegion;
|
GuardedRegion r = Region as GuardedRegion;
|
||||||
|
|
||||||
if (r != null && mob.Alive)
|
if (r != null && mob.Alive)
|
||||||
{
|
{
|
||||||
foreach ( Mobile m in GetMobilesInRange( 2 ) )
|
foreach ( Mobile m in GetMobilesInRange( 2 ) )
|
||||||
|
|
@ -434,7 +435,7 @@ namespace Server.Mobiles
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_NextWave = DateTime.UtcNow + TimeSpan.FromSeconds( 3 );
|
m_NextWave = DateTime.UtcNow + TimeSpan.FromSeconds( 3 );
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -3550,7 +3550,7 @@ namespace Server.Items
|
||||||
20,
|
20,
|
||||||
5042
|
5042
|
||||||
);
|
);
|
||||||
Effects.PlaySound(defender, defender.Map, 0x201);
|
Effects.PlaySound(defender, 0x201);
|
||||||
|
|
||||||
defender.Delete();
|
defender.Delete();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2278,7 +2278,7 @@ namespace Server.Mobiles
|
||||||
20,
|
20,
|
||||||
5042
|
5042
|
||||||
);
|
);
|
||||||
Effects.PlaySound(m, m.Map, 0x201);
|
Effects.PlaySound(m, 0x201);
|
||||||
|
|
||||||
m.Delete();
|
m.Delete();
|
||||||
}
|
}
|
||||||
|
|
@ -3216,12 +3216,7 @@ namespace Server.Mobiles
|
||||||
|
|
||||||
if (IsBonded)
|
if (IsBonded)
|
||||||
{
|
{
|
||||||
var sound = GetDeathSound();
|
Effects.PlaySound(this, GetDeathSound());
|
||||||
|
|
||||||
if (sound >= 0)
|
|
||||||
{
|
|
||||||
Effects.PlaySound(this, Map, sound);
|
|
||||||
}
|
|
||||||
|
|
||||||
Warmode = false;
|
Warmode = false;
|
||||||
|
|
||||||
|
|
@ -3845,7 +3840,9 @@ namespace Server.Mobiles
|
||||||
|
|
||||||
IsDeadPet = false;
|
IsDeadPet = false;
|
||||||
|
|
||||||
Effects.SendPacket(Location, Map, new BondedStatus(Serial, false));
|
Span<byte> buffer = stackalloc byte[OutgoingMobilePackets.BondedStatusPacketLength];
|
||||||
|
OutgoingMobilePackets.CreateBondedStatus(ref buffer, Serial, false);
|
||||||
|
Effects.SendPacket(Location, Map, ref buffer);
|
||||||
|
|
||||||
SendIncomingPacket();
|
SendIncomingPacket();
|
||||||
SendIncomingPacket();
|
SendIncomingPacket();
|
||||||
|
|
|
||||||
|
|
@ -103,8 +103,8 @@ namespace Server.Mobiles
|
||||||
LootPack.FilthyRich.Generate(this, rm.Backpack, false, LootPack.GetLuckChanceForKiller(this));
|
LootPack.FilthyRich.Generate(this, rm.Backpack, false, LootPack.GetLuckChanceForKiller(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
Effects.PlaySound(this, Map, GetDeathSound());
|
Effects.PlaySound(this, GetDeathSound());
|
||||||
Effects.SendLocationEffect(Location, Map, 0x3709, 30, 10, 0x835, 0);
|
Effects.SendLocationEffect(Location, Map, 0x3709, 30, 10, 0x835);
|
||||||
rm.MoveToWorld(Location, Map);
|
rm.MoveToWorld(Location, Map);
|
||||||
|
|
||||||
Delete();
|
Delete();
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ namespace Server.Mobiles
|
||||||
LootPack.FilthyRich.Generate(this, rm.Backpack, false, LootPack.GetLuckChanceForKiller(this));
|
LootPack.FilthyRich.Generate(this, rm.Backpack, false, LootPack.GetLuckChanceForKiller(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
Effects.PlaySound(this, Map, GetDeathSound());
|
Effects.PlaySound(this, GetDeathSound());
|
||||||
Effects.SendLocationEffect(Location, Map, 0x3709, 30, 10, 0x835, 0);
|
Effects.SendLocationEffect(Location, Map, 0x3709, 30, 10, 0x835, 0);
|
||||||
rm.MoveToWorld(Location, Map);
|
rm.MoveToWorld(Location, Map);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,68 +78,42 @@ namespace Server.Mobiles
|
||||||
* Effect: damage is dealt to the attacker, no damage is taken by the fan dancer
|
* Effect: damage is dealt to the attacker, no damage is taken by the fan dancer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
private void ThrowFan(Mobile to)
|
||||||
|
{
|
||||||
|
if (!(Utility.RandomDouble() < 0.8) || to.InRange(this, 1))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fan Throw
|
||||||
|
* Effect: - To: "0x57D4F5B" - ItemId: "0x27A3" - ItemIdName: "Tessen" - FromLocation: "(992 299, 24)" - ToLocation: "(992 308, 22)" - Speed: "10" - Duration: "0" - FixedDirection: "False" - Explode: "False" - Hue: "0x0" - Render: "0x0"
|
||||||
|
* Damage: 50-65
|
||||||
|
*/
|
||||||
|
Effects.SendMovingEffect(
|
||||||
|
to.Location,
|
||||||
|
to.Map,
|
||||||
|
0x27A3,
|
||||||
|
Location,
|
||||||
|
to.Location,
|
||||||
|
10,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
AOS.Damage(to, this, Utility.RandomMinMax(50, 65), 100, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnDamagedBySpell(Mobile attacker)
|
public override void OnDamagedBySpell(Mobile attacker)
|
||||||
{
|
{
|
||||||
base.OnDamagedBySpell(attacker);
|
base.OnDamagedBySpell(attacker);
|
||||||
|
ThrowFan(attacker);
|
||||||
if (Utility.RandomDouble() < 0.8 && !attacker.InRange(this, 1))
|
|
||||||
{
|
|
||||||
/* Fan Throw
|
|
||||||
* Effect: - To: "0x57D4F5B" - ItemId: "0x27A3" - ItemIdName: "Tessen" - FromLocation: "(992 299, 24)" - ToLocation: "(992 308, 22)" - Speed: "10" - Duration: "0" - FixedDirection: "False" - Explode: "False" - Hue: "0x0" - Render: "0x0"
|
|
||||||
* Damage: 50-65
|
|
||||||
*/
|
|
||||||
Effects.SendPacket(
|
|
||||||
attacker,
|
|
||||||
attacker.Map,
|
|
||||||
new HuedEffect(
|
|
||||||
EffectType.Moving,
|
|
||||||
Serial.Zero,
|
|
||||||
Serial.Zero,
|
|
||||||
0x27A3,
|
|
||||||
Location,
|
|
||||||
attacker.Location,
|
|
||||||
10,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
)
|
|
||||||
);
|
|
||||||
AOS.Damage(attacker, this, Utility.RandomMinMax(50, 65), 100, 0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnGotMeleeAttack(Mobile attacker)
|
public override void OnGotMeleeAttack(Mobile attacker)
|
||||||
{
|
{
|
||||||
base.OnGotMeleeAttack(attacker);
|
base.OnGotMeleeAttack(attacker);
|
||||||
|
ThrowFan(attacker);
|
||||||
if (Utility.RandomDouble() < 0.8 && !attacker.InRange(this, 1))
|
|
||||||
{
|
|
||||||
/* Fan Throw
|
|
||||||
* Effect: - To: "0x57D4F5B" - ItemId: "0x27A3" - ItemIdName: "Tessen" - FromLocation: "(992 299, 24)" - ToLocation: "(992 308, 22)" - Speed: "10" - Duration: "0" - FixedDirection: "False" - Explode: "False" - Hue: "0x0" - Render: "0x0"
|
|
||||||
* Damage: 50-65
|
|
||||||
*/
|
|
||||||
Effects.SendPacket(
|
|
||||||
attacker,
|
|
||||||
attacker.Map,
|
|
||||||
new HuedEffect(
|
|
||||||
EffectType.Moving,
|
|
||||||
Serial.Zero,
|
|
||||||
Serial.Zero,
|
|
||||||
0x27A3,
|
|
||||||
Location,
|
|
||||||
attacker.Location,
|
|
||||||
10,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
)
|
|
||||||
);
|
|
||||||
AOS.Damage(attacker, this, Utility.RandomMinMax(50, 65), 100, 0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnGaveMeleeAttack(Mobile defender)
|
public override void OnGaveMeleeAttack(Mobile defender)
|
||||||
|
|
@ -158,9 +132,8 @@ namespace Server.Mobiles
|
||||||
* Effect does not stack
|
* Effect does not stack
|
||||||
*/
|
*/
|
||||||
|
|
||||||
defender.SendLocalizedMessage(
|
// The creature fans you with fire, reducing your resistance to fire attacks.
|
||||||
1070833
|
defender.SendLocalizedMessage(1070833);
|
||||||
); // The creature fans you with fire, reducing your resistance to fire attacks.
|
|
||||||
|
|
||||||
var effect = -(defender.FireResistance / 10);
|
var effect = -(defender.FireResistance / 10);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -355,7 +355,7 @@ namespace Server.Mobiles
|
||||||
30,
|
30,
|
||||||
5052
|
5052
|
||||||
);
|
);
|
||||||
Effects.PlaySound(g, g.Map, 0x208);
|
Effects.PlaySound(g, 0x208);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -368,7 +368,7 @@ namespace Server.Mobiles
|
||||||
10,
|
10,
|
||||||
5044
|
5044
|
||||||
);
|
);
|
||||||
Effects.PlaySound(g, g.Map, 0x307);
|
Effects.PlaySound(g, 0x307);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -687,7 +687,7 @@ namespace Server.Mobiles
|
||||||
30,
|
30,
|
||||||
5052
|
5052
|
||||||
);
|
);
|
||||||
Effects.PlaySound(g, g.Map, 0x208);
|
Effects.PlaySound(g, 0x208);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -700,7 +700,7 @@ namespace Server.Mobiles
|
||||||
10,
|
10,
|
||||||
5044
|
5044
|
||||||
);
|
);
|
||||||
Effects.PlaySound(g, g.Map, 0x307);
|
Effects.PlaySound(g, 0x307);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ namespace Server.Spells.Chivalry
|
||||||
20,
|
20,
|
||||||
5042
|
5042
|
||||||
);
|
);
|
||||||
Effects.PlaySound(m, m.Map, 0x201);
|
Effects.PlaySound(m, 0x201);
|
||||||
|
|
||||||
m.Delete();
|
m.Delete();
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ namespace Server.Spells.Fifth
|
||||||
eastToWest = false;
|
eastToWest = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Effects.PlaySound(p, Caster.Map, 0x20B);
|
Effects.PlaySound(new Point3D(p), Caster.Map, 0x20B);
|
||||||
|
|
||||||
var itemID = eastToWest ? 0x3915 : 0x3922;
|
var itemID = eastToWest ? 0x3915 : 0x3922;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ namespace Server.Spells.Fourth
|
||||||
|
|
||||||
var map = Caster.Map;
|
var map = Caster.Map;
|
||||||
var directTarget = p as Mobile;
|
var directTarget = p as Mobile;
|
||||||
|
var loc = new Point3D(p);
|
||||||
|
|
||||||
if (map != null)
|
if (map != null)
|
||||||
{
|
{
|
||||||
|
|
@ -54,13 +55,13 @@ namespace Server.Spells.Fourth
|
||||||
targets.Add(directTarget);
|
targets.Add(directTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
var eable = map.GetMobilesInRange(new Point3D(p), 2);
|
var eable = map.GetMobilesInRange(loc, 2);
|
||||||
targets.AddRange(eable.Where(m => m != directTarget).Where(m => AreaCanTarget(m, feluccaRules)));
|
targets.AddRange(eable.Where(m => m != directTarget).Where(m => AreaCanTarget(m, feluccaRules)));
|
||||||
|
|
||||||
eable.Free();
|
eable.Free();
|
||||||
}
|
}
|
||||||
|
|
||||||
Effects.PlaySound(p, Caster.Map, 0x299);
|
Effects.PlaySound(loc, Caster.Map, 0x299);
|
||||||
|
|
||||||
if (targets.Count > 0)
|
if (targets.Count > 0)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -40,9 +40,11 @@ namespace Server.Spells.Fourth
|
||||||
|
|
||||||
SpellHelper.GetSurfaceTop(ref p);
|
SpellHelper.GetSurfaceTop(ref p);
|
||||||
|
|
||||||
|
var loc = new Point3D(p);
|
||||||
|
|
||||||
if (!Core.AOS)
|
if (!Core.AOS)
|
||||||
{
|
{
|
||||||
Effects.PlaySound(p, Caster.Map, 0x299);
|
Effects.PlaySound(loc, Caster.Map, 0x299);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Caster.Map == null)
|
if (Caster.Map == null)
|
||||||
|
|
@ -51,7 +53,7 @@ namespace Server.Spells.Fourth
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var targets = Caster.Map.GetMobilesInRange(new Point3D(p), Core.AOS ? 2 : 3)
|
var targets = Caster.Map.GetMobilesInRange(loc, Core.AOS ? 2 : 3)
|
||||||
.Where(m => Caster.CanBeBeneficial(m, false));
|
.Where(m => Caster.CanBeBeneficial(m, false));
|
||||||
|
|
||||||
if (Core.AOS)
|
if (Core.AOS)
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ namespace Server.Spells.Fourth
|
||||||
eastToWest = false;
|
eastToWest = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Effects.PlaySound(p, Caster.Map, 0x20C);
|
Effects.PlaySound(new Point3D(p), Caster.Map, 0x20C);
|
||||||
|
|
||||||
var itemID = eastToWest ? 0x398C : 0x3996;
|
var itemID = eastToWest ? 0x398C : 0x3996;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,9 +51,11 @@ namespace Server.Spells.Mysticism
|
||||||
|
|
||||||
if (map != null)
|
if (map != null)
|
||||||
{
|
{
|
||||||
PlayEffect(p, Caster.Map);
|
var loc = new Point3D(p);
|
||||||
|
|
||||||
foreach (var m in map.GetMobilesInRange(new Point3D(p), 2))
|
PlayEffect(loc, Caster.Map);
|
||||||
|
|
||||||
|
foreach (var m in map.GetMobilesInRange(loc, 2))
|
||||||
{
|
{
|
||||||
if (m == Caster)
|
if (m == Caster)
|
||||||
{
|
{
|
||||||
|
|
@ -94,7 +96,7 @@ namespace Server.Spells.Mysticism
|
||||||
Caster.Target = new SpellTargetPoint3D(this);
|
Caster.Target = new SpellTargetPoint3D(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void PlayEffect(IPoint3D p, Map map)
|
private static void PlayEffect(Point3D p, Map map)
|
||||||
{
|
{
|
||||||
Effects.PlaySound(p, map, 0x64F);
|
Effects.PlaySound(p, map, 0x64F);
|
||||||
|
|
||||||
|
|
@ -105,7 +107,7 @@ namespace Server.Spells.Mysticism
|
||||||
PlaySingleEffect(p, map, -1, 1, 1, 3);
|
PlaySingleEffect(p, map, -1, 1, 1, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void PlaySingleEffect(IPoint3D p, Map map, int a, int b, int c, int d)
|
private static void PlaySingleEffect(Point3D p, Map map, int a, int b, int c, int d)
|
||||||
{
|
{
|
||||||
int x = p.X, y = p.Y, z = p.Z + 18;
|
int x = p.X, y = p.Y, z = p.Z + 18;
|
||||||
|
|
||||||
|
|
@ -120,25 +122,20 @@ namespace Server.Spells.Mysticism
|
||||||
SendEffectPacket(p, map, new Point3D(x + a, y + c, z), new Point3D(x + a, y + d, z));
|
SendEffectPacket(p, map, new Point3D(x + a, y + c, z), new Point3D(x + a, y + d, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SendEffectPacket(IPoint3D p, Map map, Point3D orig, Point3D dest)
|
private static void SendEffectPacket(Point3D p, Map map, Point3D orig, Point3D dest)
|
||||||
{
|
{
|
||||||
Effects.SendPacket(
|
Effects.SendMovingEffect(
|
||||||
p,
|
p,
|
||||||
map,
|
map,
|
||||||
new HuedEffect(
|
0x36D4,
|
||||||
EffectType.Moving,
|
orig,
|
||||||
Serial.Zero,
|
dest,
|
||||||
Serial.Zero,
|
0,
|
||||||
0x36D4,
|
0,
|
||||||
orig,
|
false,
|
||||||
dest,
|
false,
|
||||||
0,
|
0x63,
|
||||||
0,
|
0x4
|
||||||
false,
|
|
||||||
false,
|
|
||||||
0x63,
|
|
||||||
0x4
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,9 +54,11 @@ namespace Server.Spells.Mysticism
|
||||||
|
|
||||||
if (map != null)
|
if (map != null)
|
||||||
{
|
{
|
||||||
PlayEffect(p, Caster.Map);
|
var loc = new Point3D(p);
|
||||||
|
|
||||||
foreach (var m in map.GetMobilesInRange(new Point3D(p), 2))
|
PlayEffect(loc, Caster.Map);
|
||||||
|
|
||||||
|
foreach (var m in map.GetMobilesInRange(loc, 2))
|
||||||
{
|
{
|
||||||
if (m == Caster)
|
if (m == Caster)
|
||||||
{
|
{
|
||||||
|
|
@ -103,7 +105,7 @@ namespace Server.Spells.Mysticism
|
||||||
Caster.Target = new SpellTargetPoint3D(this);
|
Caster.Target = new SpellTargetPoint3D(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void PlayEffect(IPoint3D p, Map map)
|
private static void PlayEffect(Point3D p, Map map)
|
||||||
{
|
{
|
||||||
Effects.PlaySound(p, map, 0x64F);
|
Effects.PlaySound(p, map, 0x64F);
|
||||||
|
|
||||||
|
|
@ -114,7 +116,7 @@ namespace Server.Spells.Mysticism
|
||||||
PlaySingleEffect(p, map, -1, 1, 1, 3);
|
PlaySingleEffect(p, map, -1, 1, 1, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void PlaySingleEffect(IPoint3D p, Map map, int a, int b, int c, int d)
|
private static void PlaySingleEffect(Point3D p, Map map, int a, int b, int c, int d)
|
||||||
{
|
{
|
||||||
int x = p.X, y = p.Y, z = p.Z + 18;
|
int x = p.X, y = p.Y, z = p.Z + 18;
|
||||||
|
|
||||||
|
|
@ -129,25 +131,20 @@ namespace Server.Spells.Mysticism
|
||||||
SendEffectPacket(p, map, new Point3D(x + a, y + c, z), new Point3D(x + a, y + d, z));
|
SendEffectPacket(p, map, new Point3D(x + a, y + c, z), new Point3D(x + a, y + d, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SendEffectPacket(IPoint3D p, Map map, Point3D orig, Point3D dest)
|
private static void SendEffectPacket(Point3D p, Map map, Point3D orig, Point3D dest)
|
||||||
{
|
{
|
||||||
Effects.SendPacket(
|
Effects.SendMovingEffect(
|
||||||
p,
|
p,
|
||||||
map,
|
map,
|
||||||
new HuedEffect(
|
0x375A,
|
||||||
EffectType.Moving,
|
orig,
|
||||||
Serial.Zero,
|
dest,
|
||||||
Serial.Zero,
|
0,
|
||||||
0x375A,
|
0,
|
||||||
orig,
|
false,
|
||||||
dest,
|
false,
|
||||||
0,
|
0x49A,
|
||||||
0,
|
0x4
|
||||||
false,
|
|
||||||
false,
|
|
||||||
0x49A,
|
|
||||||
0x4
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ namespace Server.Spells.Seventh
|
||||||
eastToWest = false;
|
eastToWest = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Effects.PlaySound(p, Caster.Map, 0x20B);
|
Effects.PlaySound(new Point3D(p), Caster.Map, 0x20B);
|
||||||
|
|
||||||
TimeSpan duration;
|
TimeSpan duration;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ namespace Server.Spells.Seventh
|
||||||
20,
|
20,
|
||||||
5042
|
5042
|
||||||
);
|
);
|
||||||
Effects.PlaySound(bc, bc.Map, 0x201);
|
Effects.PlaySound(bc, 0x201);
|
||||||
|
|
||||||
bc.Delete();
|
bc.Delete();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,10 +46,11 @@ namespace Server.Spells.Seventh
|
||||||
var map = Caster.Map;
|
var map = Caster.Map;
|
||||||
|
|
||||||
var playerVsPlayer = false;
|
var playerVsPlayer = false;
|
||||||
|
var loc = new Point3D(p);
|
||||||
|
|
||||||
if (map != null)
|
if (map != null)
|
||||||
{
|
{
|
||||||
var eable = map.GetMobilesInRange(new Point3D(p), 2);
|
var eable = map.GetMobilesInRange(loc, 2);
|
||||||
|
|
||||||
targets = eable.Where(
|
targets = eable.Where(
|
||||||
m =>
|
m =>
|
||||||
|
|
@ -86,7 +87,7 @@ namespace Server.Spells.Seventh
|
||||||
|
|
||||||
if (targets.Count > 0)
|
if (targets.Count > 0)
|
||||||
{
|
{
|
||||||
Effects.PlaySound(p, Caster.Map, 0x160);
|
Effects.PlaySound(loc, Caster.Map, 0x160);
|
||||||
|
|
||||||
if (Core.AOS && targets.Count > 2)
|
if (Core.AOS && targets.Count > 2)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ namespace Server.Spells.Sixth
|
||||||
20,
|
20,
|
||||||
5042
|
5042
|
||||||
);
|
);
|
||||||
Effects.PlaySound(m, m.Map, 0x201);
|
Effects.PlaySound(m, 0x201);
|
||||||
|
|
||||||
m.Delete();
|
m.Delete();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ namespace Server.Spells.Sixth
|
||||||
rune.Mark(Caster);
|
rune.Mark(Caster);
|
||||||
|
|
||||||
Caster.PlaySound(0x1FA);
|
Caster.PlaySound(0x1FA);
|
||||||
Effects.SendLocationEffect(Caster, Caster.Map, 14201, 16);
|
Effects.SendLocationEffect(Caster, 14201, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
FinishSequence();
|
FinishSequence();
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ namespace Server.Spells.Sixth
|
||||||
eastToWest = false;
|
eastToWest = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Effects.PlaySound(p, Caster.Map, 0x20B);
|
Effects.PlaySound(new Point3D(p), Caster.Map, 0x20B);
|
||||||
|
|
||||||
var itemID = eastToWest ? 0x3967 : 0x3979;
|
var itemID = eastToWest ? 0x3967 : 0x3979;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,16 +27,17 @@ namespace Server.Spells.Third
|
||||||
if (CheckSequence())
|
if (CheckSequence())
|
||||||
{
|
{
|
||||||
SpellHelper.Turn(Caster, p);
|
SpellHelper.Turn(Caster, p);
|
||||||
|
var loc = new Point3D(p);
|
||||||
|
|
||||||
Effects.SendLocationParticles(
|
Effects.SendLocationParticles(
|
||||||
EffectItem.Create(new Point3D(p), Caster.Map, EffectItem.DefaultDuration),
|
EffectItem.Create(loc, Caster.Map, EffectItem.DefaultDuration),
|
||||||
0x376A,
|
0x376A,
|
||||||
9,
|
9,
|
||||||
32,
|
32,
|
||||||
5024
|
5024
|
||||||
);
|
);
|
||||||
|
|
||||||
Effects.PlaySound(p, Caster.Map, 0x1FF);
|
Effects.PlaySound(loc, Caster.Map, 0x1FF);
|
||||||
|
|
||||||
if (p is Mobile)
|
if (p is Mobile)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ namespace Server.Spells.Third
|
||||||
eastToWest = false;
|
eastToWest = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Effects.PlaySound(p, Caster.Map, 0x1F6);
|
Effects.PlaySound(new Point3D(p), Caster.Map, 0x1F6);
|
||||||
|
|
||||||
for (var i = -1; i <= 1; ++i)
|
for (var i = -1; i <= 1; ++i)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue