fix: Fixes boat movement & moves weapon ability out of core (#750)
* Fixes boats only moving once. * Removes event sink for weapon ability * Moves weapon ability packets out of the core.
This commit is contained in:
parent
c789a7f78a
commit
fd59b080f4
12 changed files with 142 additions and 130 deletions
|
|
@ -56,22 +56,6 @@ namespace Server.Tests.Network
|
|||
AssertThat.Equal(result.Buffer[0].AsSpan(0), expected);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(0, true)]
|
||||
[InlineData(0, false)]
|
||||
[InlineData(100, true)]
|
||||
[InlineData(1000, false)]
|
||||
public void TestSpecialAbility(int abilityId, bool active)
|
||||
{
|
||||
var expected = new ToggleSpecialAbility(abilityId, active).Compile();
|
||||
|
||||
var ns = PacketTestUtilities.CreateTestNetState();
|
||||
ns.SendToggleSpecialAbility(abilityId, active);
|
||||
|
||||
var result = ns.SendPipe.Reader.TryRead();
|
||||
AssertThat.Equal(result.Buffer[0].AsSpan(0), expected);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(0x1000u, "This is a header", "This is a body", "This is a footer")]
|
||||
[InlineData(0x1000u, null, null, null)]
|
||||
|
|
@ -338,18 +322,6 @@ namespace Server.Tests.Network
|
|||
AssertThat.Equal(result.Buffer[0].AsSpan(0), expected);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestClearAbility()
|
||||
{
|
||||
var expected = new ClearWeaponAbility().Compile();
|
||||
|
||||
var ns = PacketTestUtilities.CreateTestNetState();
|
||||
ns.SendClearWeaponAbility();
|
||||
|
||||
var result = ns.SendPipe.Reader.TryRead();
|
||||
AssertThat.Equal(result.Buffer[0].AsSpan(0), expected);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(0xFF01)]
|
||||
public void TestDisplayHuePicker(int itemID)
|
||||
|
|
|
|||
|
|
@ -57,19 +57,6 @@ namespace Server.Network
|
|||
public static Packet Instantiate(bool dead) => dead ? Dead : Alive;
|
||||
}
|
||||
|
||||
public sealed class ToggleSpecialAbility : Packet
|
||||
{
|
||||
public ToggleSpecialAbility(int abilityID, bool active) : base(0xBF)
|
||||
{
|
||||
EnsureCapacity(7);
|
||||
|
||||
Stream.Write((short)0x25);
|
||||
|
||||
Stream.Write((short)abilityID);
|
||||
Stream.Write(active);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class DisplayProfile : Packet
|
||||
{
|
||||
public DisplayProfile(Serial m, string header, string body, string footer) : base(0xB8)
|
||||
|
|
@ -374,18 +361,6 @@ namespace Server.Network
|
|||
}
|
||||
}
|
||||
|
||||
public sealed class ClearWeaponAbility : Packet
|
||||
{
|
||||
public static readonly Packet Instance = SetStatic(new ClearWeaponAbility());
|
||||
|
||||
public ClearWeaponAbility() : base(0xBF)
|
||||
{
|
||||
EnsureCapacity(5);
|
||||
|
||||
Stream.Write((short)0x21);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class DisplayHuePicker : Packet
|
||||
{
|
||||
public DisplayHuePicker(HuePicker huePicker) : base(0x95, 9)
|
||||
|
|
|
|||
|
|
@ -106,9 +106,6 @@ namespace Server
|
|||
public static event Action<NetState, int> DeleteRequest;
|
||||
public static void InvokeDeleteRequest(NetState state, int index) => DeleteRequest?.Invoke(state, index);
|
||||
|
||||
public static event Action<Mobile, int> SetAbility;
|
||||
public static void InvokeSetAbility(Mobile mobile, int index) => SetAbility?.Invoke(mobile, index);
|
||||
|
||||
public static event Action ServerStarted;
|
||||
public static void InvokeServerStarted() => ServerStarted?.Invoke();
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@ namespace Server.Network
|
|||
IncomingPackets.Register(0xD7, 0, true, EncodedCommand);
|
||||
IncomingPackets.Register(0xF4, 0, false, CrashReport);
|
||||
|
||||
IncomingPackets.RegisterEncoded(0x19, true, SetAbility);
|
||||
IncomingPackets.RegisterEncoded(0x28, true, GuildGumpRequest);
|
||||
IncomingPackets.RegisterEncoded(0x32, true, QuestGumpRequest);
|
||||
}
|
||||
|
|
@ -584,17 +583,12 @@ namespace Server.Network
|
|||
}
|
||||
}
|
||||
|
||||
public static void SetAbility(this NetState state, IEntity e, EncodedReader reader)
|
||||
{
|
||||
EventSink.InvokeSetAbility(state.Mobile, reader.ReadInt32());
|
||||
}
|
||||
|
||||
public static void GuildGumpRequest(this NetState state, IEntity e, EncodedReader reader)
|
||||
public static void GuildGumpRequest(NetState state, IEntity e, EncodedReader reader)
|
||||
{
|
||||
EventSink.InvokeGuildGumpRequest(state.Mobile);
|
||||
}
|
||||
|
||||
public static void QuestGumpRequest(this NetState state, IEntity e, EncodedReader reader)
|
||||
public static void QuestGumpRequest(NetState state, IEntity e, EncodedReader reader)
|
||||
{
|
||||
EventSink.InvokeQuestGumpRequest(state.Mobile);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,23 +63,6 @@ namespace Server.Network
|
|||
public static void SendDeathStatus(this NetState ns, bool dead) =>
|
||||
ns?.Send(stackalloc byte[] { 0x2C, dead ? (byte)0 : (byte)2 });
|
||||
|
||||
public static void SendToggleSpecialAbility(this NetState ns, int abilityId, bool active)
|
||||
{
|
||||
if (ns == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var writer = new SpanWriter(stackalloc byte[8]);
|
||||
writer.Write((byte)0xBF); // Packet ID
|
||||
writer.Write((ushort)8);
|
||||
writer.Write((short)0x25);
|
||||
writer.Write((short)abilityId);
|
||||
writer.Write(active);
|
||||
|
||||
ns.Send(writer.Span);
|
||||
}
|
||||
|
||||
public static void SendDisplayProfile(this NetState ns, Serial m, string header, string body, string footer)
|
||||
{
|
||||
if (ns == null)
|
||||
|
|
@ -352,10 +335,6 @@ namespace Server.Network
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void SendPingAck(this NetState ns, byte ping) => ns?.Send(stackalloc byte[] { 0x73, ping });
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void SendClearWeaponAbility(this NetState ns) =>
|
||||
ns?.Send(stackalloc byte[] { 0xBF, 0x00, 0x5, 0x00, 0x21 });
|
||||
|
||||
public static void SendDisplayHuePicker(this NetState ns, Serial huePickerSerial, int huePickerItemID)
|
||||
{
|
||||
if (ns == null)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
using System;
|
||||
using Server.Items;
|
||||
using Server.Tests;
|
||||
using Server.Tests.Network;
|
||||
using Xunit;
|
||||
|
||||
namespace UOContent.Tests
|
||||
{
|
||||
public class WeaponAbilityPacketTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(0, true)]
|
||||
[InlineData(0, false)]
|
||||
[InlineData(100, true)]
|
||||
[InlineData(1000, false)]
|
||||
public void TestSpecialAbility(int abilityId, bool active)
|
||||
{
|
||||
var expected = new ToggleSpecialAbility(abilityId, active).Compile();
|
||||
|
||||
var ns = PacketTestUtilities.CreateTestNetState();
|
||||
ns.SendToggleSpecialAbility(abilityId, active);
|
||||
|
||||
var result = ns.SendPipe.Reader.TryRead();
|
||||
AssertThat.Equal(result.Buffer[0].AsSpan(0), expected);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestClearAbility()
|
||||
{
|
||||
var expected = new ClearWeaponAbility().Compile();
|
||||
|
||||
var ns = PacketTestUtilities.CreateTestNetState();
|
||||
ns.SendClearWeaponAbility();
|
||||
|
||||
var result = ns.SendPipe.Reader.TryRead();
|
||||
AssertThat.Equal(result.Buffer[0].AsSpan(0), expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
using Server.Network;
|
||||
|
||||
namespace UOContent.Tests
|
||||
{
|
||||
public sealed class ToggleSpecialAbility : Packet
|
||||
{
|
||||
public ToggleSpecialAbility(int abilityID, bool active) : base(0xBF)
|
||||
{
|
||||
EnsureCapacity(7);
|
||||
|
||||
Stream.Write((short)0x25);
|
||||
|
||||
Stream.Write((short)abilityID);
|
||||
Stream.Write(active);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ClearWeaponAbility : Packet
|
||||
{
|
||||
public static readonly Packet Instance = SetStatic(new ClearWeaponAbility());
|
||||
|
||||
public ClearWeaponAbility() : base(0xBF)
|
||||
{
|
||||
EnsureCapacity(5);
|
||||
|
||||
Stream.Write((short)0x21);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,9 +3,8 @@ using System;
|
|||
namespace Server.Items
|
||||
{
|
||||
/// <summary>
|
||||
/// This devastating strike is most effective against those who are in good health and whose reserves of mana are low, or
|
||||
/// vice
|
||||
/// versa.
|
||||
/// This devastating strike is most effective against those who are in good health and whose reserves
|
||||
/// of mana are low, or vice versa.
|
||||
/// </summary>
|
||||
public class ConcussionBlow : WeaponAbility
|
||||
{
|
||||
|
|
|
|||
|
|
@ -132,15 +132,17 @@ namespace Server.Items
|
|||
{
|
||||
var mana = BaseMana;
|
||||
|
||||
var skillTotal = GetSkill(from, SkillName.Swords) + GetSkill(from, SkillName.Macing)
|
||||
+ GetSkill(from, SkillName.Fencing) +
|
||||
GetSkill(from, SkillName.Archery) +
|
||||
GetSkill(from, SkillName.Parry)
|
||||
+ GetSkill(from, SkillName.Lumberjacking) +
|
||||
GetSkill(from, SkillName.Stealth)
|
||||
+ GetSkill(from, SkillName.Poisoning) +
|
||||
GetSkill(from, SkillName.Bushido) +
|
||||
GetSkill(from, SkillName.Ninjitsu);
|
||||
var skillTotal =
|
||||
GetSkill(from, SkillName.Swords) +
|
||||
GetSkill(from, SkillName.Macing) +
|
||||
GetSkill(from, SkillName.Fencing) +
|
||||
GetSkill(from, SkillName.Archery) +
|
||||
GetSkill(from, SkillName.Parry) +
|
||||
GetSkill(from, SkillName.Lumberjacking) +
|
||||
GetSkill(from, SkillName.Stealth) +
|
||||
GetSkill(from, SkillName.Poisoning) +
|
||||
GetSkill(from, SkillName.Bushido) +
|
||||
GetSkill(from, SkillName.Ninjitsu);
|
||||
|
||||
if (skillTotal >= 300.0)
|
||||
{
|
||||
|
|
@ -196,9 +198,11 @@ namespace Server.Items
|
|||
}
|
||||
|
||||
/* <UBWS> */
|
||||
if (weapon.WeaponAttributes.UseBestSkill > 0 && (from.Skills.Swords.Base >= reqSkill ||
|
||||
from.Skills.Macing.Base >= reqSkill ||
|
||||
from.Skills.Fencing.Base >= reqSkill))
|
||||
if (weapon.WeaponAttributes.UseBestSkill > 0 &&
|
||||
(from.Skills.Swords.Base >= reqSkill ||
|
||||
from.Skills.Macing.Base >= reqSkill ||
|
||||
from.Skills.Fencing.Base >= reqSkill)
|
||||
)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -394,23 +398,6 @@ namespace Server.Items
|
|||
}
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
EventSink.SetAbility += EventSink_SetAbility;
|
||||
}
|
||||
|
||||
private static void EventSink_SetAbility(Mobile m, int index)
|
||||
{
|
||||
if (index == 0)
|
||||
{
|
||||
ClearCurrentAbility(m);
|
||||
}
|
||||
else if (index >= 1 && index < Abilities.Length)
|
||||
{
|
||||
SetCurrentAbility(m, Abilities[index]);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddContext(Mobile m, WeaponAbilityContext context)
|
||||
{
|
||||
m_PlayersTable[m] = context;
|
||||
|
|
@ -418,21 +405,12 @@ namespace Server.Items
|
|||
|
||||
private static void RemoveContext(Mobile m)
|
||||
{
|
||||
var context = GetContext(m);
|
||||
|
||||
if (context != null)
|
||||
if (m_PlayersTable.Remove(m, out var context))
|
||||
{
|
||||
RemoveContext(m, context);
|
||||
context.Timer?.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
private static void RemoveContext(Mobile m, WeaponAbilityContext context)
|
||||
{
|
||||
m_PlayersTable.Remove(m);
|
||||
|
||||
context.Timer.Stop();
|
||||
}
|
||||
|
||||
private static WeaponAbilityContext GetContext(Mobile m)
|
||||
{
|
||||
m_PlayersTable.TryGetValue(m, out var context);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
using System.Buffers;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public static class WeaponAbilityPackets
|
||||
{
|
||||
public static void Configure()
|
||||
{
|
||||
IncomingPackets.RegisterEncoded(0x19, true, SetAbility);
|
||||
}
|
||||
|
||||
public static void SetAbility(NetState state, IEntity e, EncodedReader reader)
|
||||
{
|
||||
var m = state.Mobile;
|
||||
var index = reader.ReadInt32();
|
||||
|
||||
if (index >= 1 && index < WeaponAbility.Abilities.Length)
|
||||
{
|
||||
WeaponAbility.SetCurrentAbility(m, WeaponAbility.Abilities[index]);
|
||||
}
|
||||
else
|
||||
{
|
||||
WeaponAbility.ClearCurrentAbility(m);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void SendClearWeaponAbility(this NetState ns) =>
|
||||
ns?.Send(stackalloc byte[] { 0xBF, 0x00, 0x5, 0x00, 0x21 });
|
||||
|
||||
public static void SendToggleSpecialAbility(this NetState ns, int abilityId, bool active)
|
||||
{
|
||||
if (ns == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var writer = new SpanWriter(stackalloc byte[8]);
|
||||
writer.Write((byte)0xBF); // Packet ID
|
||||
writer.Write((ushort)8);
|
||||
writer.Write((short)0x25);
|
||||
writer.Write((short)abilityId);
|
||||
writer.Write(active);
|
||||
|
||||
ns.Send(writer.Span);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1342,7 +1342,7 @@ namespace Server.Multis
|
|||
Order = BoatOrder.Move;
|
||||
|
||||
_moveTimerToken.Cancel();
|
||||
Timer.StartTimer(interval, StopBoat, out _moveTimerToken);
|
||||
Timer.StartTimer(interval, single ? 1 : 0, StopBoat, out _moveTimerToken);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Spells.Bushido
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue