fix(core): Converts mobile stats packets (#360)

- [X] Converts mobile stats packets
- [X] Removes human racial from non-players
This commit is contained in:
Kamron Batman 2020-12-27 14:44:03 -08:00 • committed by GitHub
parent d73afdba8e
commit 5b69f1d389
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 413 additions and 423 deletions

View file

@ -622,7 +622,7 @@ namespace Server
[CommandProperty(AccessLevel.GameMaster)]
public Race Race
{
get => m_Race ?? (m_Race = Race.DefaultRace);
get => m_Race ??= Race.DefaultRace;
set
{
var oldRace = Race;
@ -1322,15 +1322,7 @@ namespace Server
[Hue, CommandProperty(AccessLevel.GameMaster)]
public virtual int Hue
{
get
{
if (m_HueMod != -1)
{
return m_HueMod;
}
return m_Hue;
}
get => m_HueMod != -1 ? m_HueMod : m_Hue;
set
{
var oldHue = m_Hue;
@ -2100,7 +2092,6 @@ namespace Server
if (Hits < HitsMax)
{
m_HitsTimer ??= new HitsTimer(this);
m_HitsTimer.Start();
}
else if (Hits > HitsMax)
@ -2290,7 +2281,6 @@ namespace Server
if (CanRegenHits)
{
m_HitsTimer ??= new HitsTimer(this);
m_HitsTimer.Start();
}
else
@ -2850,7 +2840,7 @@ namespace Server
ns.Send(new MobileIncoming(ns, this, this));
ns.SendSupportedFeature();
ns.Send(new MobileUpdate(this, ns.StygianAbyss));
ns.Send(new MobileAttributes(this));
ns.SendMobileAttributes(this);
}
OnMapChange(oldMap);
@ -3091,23 +3081,23 @@ namespace Server
}
else if (sendAll)
{
ourState.Send(new MobileAttributes(m));
ourState.SendMobileAttributes(m);
}
else if (sendAny)
{
if (sendHits)
{
ourState.Send(new MobileHits(m));
}
if (sendStam)
{
ourState.Send(new MobileStam(m));
ourState.SendMobileHits(m);
}
if (sendMana)
{
ourState.Send(new MobileMana(m));
ourState.SendMobileMana(m);
}
if (sendStam)
{
ourState.SendMobileStam(m);
}
}
@ -3115,15 +3105,15 @@ namespace Server
{
if (Party is IParty ip)
{
if (sendStam)
{
ip.OnStamChanged(this);
}
if (sendMana)
{
ip.OnManaChanged(this);
}
if (sendStam)
{
ip.OnStamChanged(this);
}
}
}
@ -3165,9 +3155,6 @@ namespace Server
sendOPLUpdate || sendHair || sendFacialHair || sendHealthbarPoison ||
sendHealthbarYellow))
{
Mobile beholder;
Packet hitsPacket = null;
Packet statPacketTrue = null;
Packet statPacketFalse = null;
Packet hairPacket = null;
@ -3183,104 +3170,111 @@ namespace Server
Span<byte> removeEntity = stackalloc byte[OutgoingEntityPackets.RemoveEntityLength];
removeEntity.InitializePacket();
Span<byte> hitsPacket = stackalloc byte[OutgoingMobilePackets.MobileAttributePacketLength];
hitsPacket.InitializePacket();
foreach (var state in eable)
{
beholder = state.Mobile;
var beholder = state.Mobile;
if (beholder != m && beholder.CanSee(m))
if (beholder == m || !beholder.CanSee(m))
{
if (sendRemove)
{
if (removeEntity[0] == 0)
{
OutgoingEntityPackets.CreateRemoveEntity(removeEntity, Serial);
}
state.Send(removeEntity);
}
if (sendIncoming)
{
state.Send(new MobileIncoming(state, beholder, m));
if (m.IsDeadBondedPet)
{
if (deadBuffer[0] == 0)
{
OutgoingMobilePackets.CreateBondedStatus(deadBuffer, m.Serial, true);
}
state.Send(deadBuffer);
}
}
if (sendMoving || !state.StygianAbyss && (sendHealthbarPoison || sendHealthbarYellow))
{
state.SendMobileMovingUsingCache(mobileMovingPackets, beholder, m);
}
if (state.StygianAbyss)
{
if (sendHealthbarPoison)
{
hbpPacket ??= Packet.Acquire(new HealthbarPoison(m));
state.Send(hbpPacket);
}
if (sendHealthbarYellow)
{
hbyPacket ??= Packet.Acquire(new HealthbarYellow(m));
state.Send(hbyPacket);
}
}
if (sendPublicStats)
{
if (m.CanBeRenamedBy(beholder))
{
statPacketTrue ??= Packet.Acquire(new MobileStatusCompact(true, m));
state.Send(statPacketTrue);
}
else
{
statPacketFalse ??= Packet.Acquire(new MobileStatusCompact(false, m));
state.Send(statPacketFalse);
}
}
else if (sendHits)
{
hitsPacket ??= Packet.Acquire(new MobileHitsN(m));
state.Send(hitsPacket);
}
if (sendHair)
{
hairPacket ??= removeHair
? Packet.Acquire(new RemoveHair(m))
: Packet.Acquire(new HairEquipUpdate(m));
state.Send(hairPacket);
}
if (sendFacialHair)
{
facialhairPacket ??= removeFacialHair
? Packet.Acquire(new RemoveFacialHair(m))
: Packet.Acquire(new FacialHairEquipUpdate(m));
state.Send(facialhairPacket);
}
SendOPLPacketTo(state);
continue;
}
if (sendRemove)
{
if (removeEntity[0] == 0)
{
OutgoingEntityPackets.CreateRemoveEntity(removeEntity, Serial);
}
state.Send(removeEntity);
}
if (sendIncoming)
{
state.Send(new MobileIncoming(state, beholder, m));
if (m.IsDeadBondedPet)
{
if (deadBuffer[0] == 0)
{
OutgoingMobilePackets.CreateBondedStatus(deadBuffer, m.Serial, true);
}
state.Send(deadBuffer);
}
}
if (sendMoving || !state.StygianAbyss && (sendHealthbarPoison || sendHealthbarYellow))
{
state.SendMobileMovingUsingCache(mobileMovingPackets, beholder, m);
}
if (state.StygianAbyss)
{
if (sendHealthbarPoison)
{
hbpPacket ??= Packet.Acquire(new HealthbarPoison(m));
state.Send(hbpPacket);
}
if (sendHealthbarYellow)
{
hbyPacket ??= Packet.Acquire(new HealthbarYellow(m));
state.Send(hbyPacket);
}
}
if (sendPublicStats)
{
if (m.CanBeRenamedBy(beholder))
{
statPacketTrue ??= Packet.Acquire(new MobileStatusCompact(true, m));
state.Send(statPacketTrue);
}
else
{
statPacketFalse ??= Packet.Acquire(new MobileStatusCompact(false, m));
state.Send(statPacketFalse);
}
}
else if (sendHits)
{
if (hitsPacket[0] == 0)
{
OutgoingMobilePackets.CreateMobileHits(ref hitsPacket, m, true);
}
state.Send(hitsPacket);
}
if (sendHair)
{
hairPacket ??= removeHair
? Packet.Acquire(new RemoveHair(m))
: Packet.Acquire(new HairEquipUpdate(m));
state.Send(hairPacket);
}
if (sendFacialHair)
{
facialhairPacket ??= removeFacialHair
? Packet.Acquire(new RemoveFacialHair(m))
: Packet.Acquire(new FacialHairEquipUpdate(m));
state.Send(facialhairPacket);
}
SendOPLPacketTo(state);
}
Packet.Release(hitsPacket);
Packet.Release(statPacketTrue);
Packet.Release(statPacketFalse);
Packet.Release(hairPacket);
@ -6652,7 +6646,6 @@ namespace Server
if (CanRegenHits)
{
m_HitsTimer ??= new HitsTimer(this);
m_HitsTimer.Start();
}
else

View file

@ -1,23 +1,8 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2020 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: AttributeNormalizer.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 static class AttributeNormalizer
{
public static int Maximum { get; set; } = 25;
public static int Maximum { get; set; } = 100;
public static bool Enabled { get; set; } = true;

View file

@ -17,92 +17,6 @@ using System.Threading;
namespace Server.Network
{
public sealed class MobileHits : Packet
{
public MobileHits(Mobile m) : base(0xA1, 9)
{
Stream.Write(m.Serial);
Stream.Write((short)m.HitsMax);
Stream.Write((short)m.Hits);
}
}
public sealed class MobileHitsN : Packet
{
public MobileHitsN(Mobile m) : base(0xA1, 9)
{
Stream.Write(m.Serial);
AttributeNormalizer.Write(Stream, m.Hits, m.HitsMax);
}
}
public sealed class MobileMana : Packet
{
public MobileMana(Mobile m) : base(0xA2, 9)
{
Stream.Write(m.Serial);
Stream.Write((short)m.ManaMax);
Stream.Write((short)m.Mana);
}
}
public sealed class MobileManaN : Packet
{
public MobileManaN(Mobile m) : base(0xA2, 9)
{
Stream.Write(m.Serial);
AttributeNormalizer.Write(Stream, m.Mana, m.ManaMax);
}
}
public sealed class MobileStam : Packet
{
public MobileStam(Mobile m) : base(0xA3, 9)
{
Stream.Write(m.Serial);
Stream.Write((short)m.StamMax);
Stream.Write((short)m.Stam);
}
}
public sealed class MobileStamN : Packet
{
public MobileStamN(Mobile m) : base(0xA3, 9)
{
Stream.Write(m.Serial);
AttributeNormalizer.Write(Stream, m.Stam, m.StamMax);
}
}
public sealed class MobileAttributes : Packet
{
public MobileAttributes(Mobile m) : base(0x2D, 17)
{
Stream.Write(m.Serial);
Stream.Write((short)m.HitsMax);
Stream.Write((short)m.Hits);
Stream.Write((short)m.ManaMax);
Stream.Write((short)m.Mana);
Stream.Write((short)m.StamMax);
Stream.Write((short)m.Stam);
}
}
public sealed class MobileAttributesN : Packet
{
public MobileAttributesN(Mobile m) : base(0x2D, 17)
{
Stream.Write(m.Serial);
AttributeNormalizer.Write(Stream, m.Hits, m.HitsMax);
AttributeNormalizer.Write(Stream, m.Mana, m.ManaMax);
AttributeNormalizer.Write(Stream, m.Stam, m.StamMax);
}
}
public sealed class MobileName : Packet
{
public MobileName(Mobile m) : base(0x98)

View file

@ -25,6 +25,9 @@ namespace Server.Network
public const int DeathAnimationPacketLength = 13;
public const int MobileMovingPacketLength = 17;
public const int MobileMovingPacketCacheLength = MobileMovingPacketLength * 8 * 2; // 8 notoriety, 2 client versions
public const int AttributeMaximum = 100;
public const int MobileAttributePacketLength = 9;
public const int MobileAttributesPacketLength = 17;
public static void CreateBondedStatus(Span<byte> buffer, Serial serial, bool bonded)
{
@ -135,5 +138,119 @@ namespace Server.Network
ns.Send(buffer);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void WriteAttribute(this ref SpanWriter writer, int max, int cur, bool normalize = false, bool reverse = false)
{
if (normalize && max != 0)
{
if (reverse)
{
writer.Write((short)(cur * AttributeMaximum / max));
writer.Write((short)AttributeMaximum);
}
else
{
writer.Write((short)AttributeMaximum);
writer.Write((short)(cur * AttributeMaximum / max));
}
}
else
{
if (reverse)
{
writer.Write((short)cur);
writer.Write((short)max);
}
else
{
writer.Write((short)max);
writer.Write((short)cur);
}
}
}
public static void SendMobileHits(this NetState ns, Mobile m, bool normalize = false)
{
if (ns == null)
{
return;
}
Span<byte> span = stackalloc byte[MobileAttributePacketLength];
CreateMobileHits(ref span, m, normalize);
ns.Send(span);
}
public static void CreateMobileHits(ref Span<byte> buffer, Mobile m, bool normalize = false)
{
var writer = new SpanWriter(buffer);
writer.Write((byte)0xA1); // Packet ID
writer.Write(m.Serial);
writer.WriteAttribute(m.HitsMax, m.Hits, normalize);
}
public static void SendMobileMana(this NetState ns, Mobile m, bool normalize = false)
{
if (ns == null)
{
return;
}
Span<byte> span = stackalloc byte[MobileAttributePacketLength];
CreateMobileMana(ref span, m, normalize);
ns.Send(span);
}
public static void CreateMobileMana(ref Span<byte> buffer, Mobile m, bool normalize = false)
{
var writer = new SpanWriter(buffer);
writer.Write((byte)0xA2); // Packet ID
writer.Write(m.Serial);
writer.WriteAttribute(m.ManaMax, m.Mana, normalize);
}
public static void SendMobileStam(this NetState ns, Mobile m, bool normalize = false)
{
if (ns == null)
{
return;
}
Span<byte> span = stackalloc byte[MobileAttributePacketLength];
CreateMobileStam(ref span, m, normalize);
ns.Send(span);
}
public static void CreateMobileStam(ref Span<byte> buffer, Mobile m, bool normalize = false)
{
var writer = new SpanWriter(buffer);
writer.Write((byte)0xA3); // Packet ID
writer.Write(m.Serial);
writer.WriteAttribute(m.StamMax, m.Stam, normalize);
}
public static void SendMobileAttributes(this NetState ns, Mobile m, bool normalize = false)
{
if (ns == null)
{
return;
}
Span<byte> span = stackalloc byte[MobileAttributesPacketLength];
CreateMobileAttributes(ref span, m, normalize);
ns.Send(span);
}
public static void CreateMobileAttributes(ref Span<byte> buffer, Mobile m, bool normalize = false)
{
var writer = new SpanWriter(buffer);
writer.Write((byte)0x2D); // Packet ID
writer.Write(m.Serial);
writer.WriteAttribute(m.HitsMax, m.Hits, normalize);
writer.WriteAttribute(m.ManaMax, m.Mana, normalize);
writer.WriteAttribute(m.StamMax, m.Stam, normalize);
}
}
}