Effects packets (#308)

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

View file

@ -1,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;
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
{
Head = 0,
@ -28,7 +61,9 @@ namespace Server
ParticleSupportType == ParticleSupportType.Full ||
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)
{
@ -37,36 +72,22 @@ namespace Server
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));
foreach (var state in eable)
{
state.Mobile.ProcessDelta();
playSound ??= Packet.Acquire(new PlaySound(soundID, p));
state.Send(playSound);
state.Send(buffer);
}
Packet.Release(playSound);
eable.Free();
}
}
public static void SendBoltEffect(IEntity e)
{
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)
public static void SendBoltEffect(IEntity e, bool sound = true, int hue = 0)
{
var map = e.Map;
@ -77,7 +98,20 @@ namespace Server
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);
@ -87,52 +121,36 @@ namespace Server
{
if (SendParticlesTo(state))
{
preEffect ??= Packet.Acquire(new TargetParticleEffect(e, 0, 10, 5, 0, 0, 5031, 3, 0));
state.Send(preEffect);
}
boltEffect ??= Packet.Acquire(new BoltEffect(e, hue));
state.Send(boltEffect);
if (sound)
{
playSound ??= Packet.Acquire(new PlaySound(0x29, e));
state.Send(playSound);
state.Send(soundEffect);
}
}
}
Packet.Release(preEffect);
Packet.Release(boltEffect);
Packet.Release(playSound);
eable.Free();
}
public static void SendLocationEffect(IPoint3D p, Map map, int itemID, int duration)
{
SendLocationEffect(p, map, itemID, duration, 10, 0, 0);
}
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(
IEntity e, int itemID, int duration, int speed = 10, int hue = 0, int renderMode = 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, int hue,
int renderMode
Point3D p, Map map, int itemID, int duration, int speed = 10, int hue = 0, int renderMode = 0
)
{
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)
@ -146,71 +164,61 @@ namespace Server
}
public static void SendLocationParticles(
IEntity e, int itemID, int speed, int duration, int hue, int renderMode,
int effect, int unknown
IEntity e, int itemID, int speed, int duration, int hue, int renderMode, int effect, int unknown
)
{
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();
if (SendParticlesTo(state))
{
particles ??=
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);
}
state.Send(particles);
}
else if (itemID != 0)
{
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)
{
SendTargetEffect(target, itemID, speed, duration, 0, 0);
}
Span<byte> effect = stackalloc byte[OutgoingEffectPackets.HuedEffectLength];
OutgoingEffectPackets.CreateTargetHuedEffect(
ref effect,
target, itemID, speed, duration, hue, renderMode
);
public static void SendTargetEffect(IEntity target, int itemID, int duration, int hue, int renderMode)
{
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));
SendPacket(target.Location, target.Map, ref effect);
}
public static void SendTargetParticles(
@ -218,121 +226,184 @@ namespace Server
EffectLayer layer
)
{
SendTargetParticles(target, itemID, speed, duration, 0, 0, effect, layer, 0);
}
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);
SendTargetParticles(target, itemID, speed, duration, 0, 0, effect, layer);
}
public static void SendTargetParticles(
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)
{
mobile.ProcessDelta();
}
(target as Mobile)?.ProcessDelta();
var map = target.Map;
if (map != null)
if (map == null)
{
Packet particles = null, regular = null;
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();
return;
}
// 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(
IEntity from, IEntity to, int itemID, int speed, int duration,
bool fixedDirection, bool explodes, int hue = 0, int renderMode = 0
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,
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)
{
mobile.ProcessDelta();
}
(from as Mobile)?.ProcessDelta();
if (to is Mobile mobile1)
{
mobile1.ProcessDelta();
}
SendPacket(
SendMovingEffect(
from.Serial,
Serial.Zero,
from.Location,
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,
from.Location,
to,
speed,
duration,
fixedDirection,
explodes,
0,
0,
effect,
explodeEffect,
explodeSound,
0
hue,
renderMode
);
}
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(
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(
@ -382,103 +453,52 @@ namespace Server
EffectLayer layer, int unknown
)
{
if (from is Mobile fromMob)
{
fromMob.ProcessDelta();
}
if (to is Mobile toMob)
{
toMob.ProcessDelta();
}
(from as Mobile)?.ProcessDelta();
(to as Mobile)?.ProcessDelta();
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)
{
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)
{
state.Mobile.ProcessDelta();
state.Send(p);
}
p.Release();
if (SendParticlesTo(state))
{
state.Send(particles);
}
else if (itemID > 1)
{
state.Send(regular);
}
}
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)
{
@ -487,16 +507,12 @@ namespace Server
var eable = map.GetClientsInRange(new Point3D(origin));
p.Acquire();
foreach (var state in eable)
{
state.Mobile.ProcessDelta();
state.Send(p);
state.Send(effectBuffer);
}
p.Release();
eable.Free();
}
}

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Text;
using Server.Accounting;
@ -3374,12 +3375,14 @@ namespace Server
Packet hitsPacket = null;
Packet statPacketTrue = null;
Packet statPacketFalse = null;
Packet deadPacket = null;
Packet hairPacket = null;
Packet facialhairPacket = null;
Packet hbpPacket = 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);
foreach (var state in eable)
@ -3399,9 +3402,7 @@ namespace Server
if (m.IsDeadBondedPet)
{
deadPacket ??= Packet.Acquire(new BondedStatus(m.Serial, true));
state.Send(deadPacket);
state.Send(deadBuffer);
}
}
@ -3502,7 +3503,6 @@ namespace Server
Packet.Release(hitsPacket);
Packet.Release(statPacketTrue);
Packet.Release(statPacketFalse);
Packet.Release(deadPacket);
Packet.Release(hairPacket);
Packet.Release(facialhairPacket);
Packet.Release(hbpPacket);
@ -5383,7 +5383,7 @@ namespace Server
if (sound >= 0)
{
Effects.PlaySound(this, Map, sound);
Effects.PlaySound(this, sound);
}
if (!m_Player)
@ -5660,12 +5660,7 @@ namespace Server
from.Holding = item;
var liftSound = item.GetLiftSound(from);
if (liftSound != -1)
{
from.Send(new PlaySound(liftSound, from));
}
from.SendSound(item.GetLiftSound(from));
from.NextActionTime = Core.TickCount + ActionDelay;
@ -7319,22 +7314,21 @@ namespace Server
eable.Free();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SendSound(int soundID)
{
if (soundID != -1 && m_NetState != null)
{
Send(new PlaySound(soundID, this));
}
m_NetState?.SendSoundEffect(soundID, this);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SendSound(int soundID, IPoint3D p)
{
if (soundID != -1 && m_NetState != null)
{
Send(new PlaySound(soundID, p));
}
m_NetState?.SendSoundEffect(soundID, p);
}
/**
* Plays a sound to netstates that can see this mobile
*/
public void PlaySound(int soundID)
{
if (soundID == -1 || m_Map == null)
@ -7342,7 +7336,8 @@ namespace Server
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);
@ -7350,12 +7345,10 @@ namespace Server
{
if (state.Mobile.CanSee(this))
{
state.Send(p);
state.Send(buffer);
}
}
Packet.Release(p);
eable.Free();
}
@ -7382,12 +7375,7 @@ namespace Server
DisruptiveAction(); // Anything that unhides you will also distrupt meditation
}
public void SendRemovePacket()
{
SendRemovePacket(true);
}
public void SendRemovePacket(bool everyone)
public void SendRemovePacket(bool everyone = true)
{
if (m_Map == null)
{
@ -7530,7 +7518,7 @@ namespace Server
if (m.IsDeadBondedPet)
{
ns.Send(new BondedStatus(m.Serial, true));
ns.SendBondedStatus(m.Serial, true);
}
if (ObjectPropertyList.Enabled)
@ -7690,7 +7678,7 @@ namespace Server
if (IsDeadBondedPet)
{
state.Send(new BondedStatus(Serial, true));
state.SendBondedStatus(Serial, true);
}
if (ObjectPropertyList.Enabled)
@ -7976,7 +7964,7 @@ namespace Server
if (IsDeadBondedPet)
{
m.m_NetState.Send(new BondedStatus(Serial, true));
m.m_NetState.SendBondedStatus(Serial, true);
}
if (ObjectPropertyList.Enabled)
@ -8003,7 +7991,7 @@ namespace Server
if (m.IsDeadBondedPet)
{
ourState.Send(new BondedStatus(m.Serial, true));
ourState.SendBondedStatus(m.Serial, true);
}
if (ObjectPropertyList.Enabled)
@ -8038,7 +8026,7 @@ namespace Server
if (IsDeadBondedPet)
{
ns.Send(new BondedStatus(Serial, true));
ns.SendBondedStatus(Serial, true);
}
if (ObjectPropertyList.Enabled)
@ -8126,7 +8114,7 @@ namespace Server
if (IsDeadBondedPet)
{
state.Send(new BondedStatus(Serial, true));
state.SendBondedStatus(Serial, true);
}
if (ObjectPropertyList.Enabled)

View file

@ -377,7 +377,34 @@ namespace Server.Network
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)
{

View file

@ -1,29 +0,0 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2020 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: DisplayHuePicker.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
using Server.HuePickers;
namespace Server.Network
{
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);
}
}
}

View file

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

View file

@ -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 MobileMoving(Mobile m, int noto) : base(0x77, 17)

View file

@ -32,7 +32,7 @@ namespace Server.Network
writer.Write(attacker);
writer.Write(defender);
ns.Send(ref buffer, 10);
ns.Send(ref buffer, writer.Position);
}
public static void SendSetWarMode(this NetState ns, bool warmode)
@ -47,7 +47,7 @@ namespace Server.Network
// Warmode, 0x00, 0x32, 0x00
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)
@ -61,7 +61,7 @@ namespace Server.Network
writer.Write((byte)0xAA); // Packet ID
writer.Write(combatant);
ns.Send(ref buffer, 5);
ns.Send(ref buffer, writer.Position);
}
}
}

View 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);
}
}
}

View 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);
}
}
}

View file

@ -14,6 +14,7 @@
*************************************************************************/
using System;
using Server.HuePickers;
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 static readonly Packet InvalidInstance = SetStatic(new PlayMusic(MusicName.Invalid));
@ -430,4 +418,14 @@ namespace Server.Network
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);
}
}
}