diff --git a/Scripts/Misc/RaceDefinitions.cs b/Scripts/Misc/RaceDefinitions.cs index b9eeb5c26..45db08ae8 100644 --- a/Scripts/Misc/RaceDefinitions.cs +++ b/Scripts/Misc/RaceDefinitions.cs @@ -48,6 +48,7 @@ namespace Server.Misc return false; } + public override int RandomHair( bool female ) //Random hair doesn't include baldness { switch( Utility.Random( 9 ) ) @@ -80,6 +81,7 @@ namespace Server.Misc return false; } + public override int RandomFacialHair( bool female ) { if( female ) @@ -163,6 +165,7 @@ namespace Server.Misc return false; } + public override int RandomHair( bool female ) //Random hair doesn't include baldness { switch( Utility.Random( 8 ) ) @@ -182,6 +185,7 @@ namespace Server.Misc { return (itemID == 0); } + public override int RandomFacialHair( bool female ) { return 0; diff --git a/Server/Mobile.cs b/Server/Mobile.cs index 811b58e75..504bc1aec 100644 --- a/Server/Mobile.cs +++ b/Server/Mobile.cs @@ -403,32 +403,34 @@ namespace Server [Flags] public enum MobileDelta { - None=0x00000000, - Name=0x00000001, - Flags=0x00000002, - Hits=0x00000004, - Mana=0x00000008, - Stam=0x00000010, - Stat=0x00000020, - Noto=0x00000040, - Gold=0x00000080, - Weight=0x00000100, - Direction=0x00000200, - Hue=0x00000400, - Body=0x00000800, - Armor=0x00001000, - StatCap=0x00002000, - GhostUpdate=0x00004000, - Followers=0x00008000, - Properties=0x00010000, - TithingPoints=0x00020000, - Resistances=0x00040000, - WeaponDamage=0x00080000, - Hair=0x00100000, - FacialHair=0x00200000, - Race=0x00400000, + None= 0x00000000, + Name= 0x00000001, + Flags= 0x00000002, + Hits= 0x00000004, + Mana= 0x00000008, + Stam= 0x00000010, + Stat= 0x00000020, + Noto= 0x00000040, + Gold= 0x00000080, + Weight= 0x00000100, + Direction= 0x00000200, + Hue= 0x00000400, + Body= 0x00000800, + Armor= 0x00001000, + StatCap= 0x00002000, + GhostUpdate= 0x00004000, + Followers= 0x00008000, + Properties= 0x00010000, + TithingPoints= 0x00020000, + Resistances= 0x00040000, + WeaponDamage= 0x00080000, + Hair= 0x00100000, + FacialHair= 0x00200000, + Race= 0x00400000, + HealthbarYellow=0x00800000, + HealthbarPoison=0x01000000, - Attributes=0x0000001C + Attributes= 0x0000001C } public enum AccessLevel @@ -6415,7 +6417,7 @@ namespace Server if( m_Blessed != value ) { m_Blessed = value; - Delta( MobileDelta.Flags ); + Delta( MobileDelta.HealthbarYellow ); } } } @@ -6676,6 +6678,14 @@ namespace Server { ns.Send( new MobileIncoming( this, m ) ); + if ( ns.IsPost7000 ) { + if ( m.Poisoned ) + ns.Send( new HealthbarPoison( m ) ); + + if ( m.Blessed || m.YellowHealthbar ) + ns.Send( new HealthbarYellow( m ) ); + } + if( m.IsDeadBondedPet ) ns.Send( new BondedStatus( 0, m.m_Serial, 1 ) ); @@ -7655,8 +7665,13 @@ namespace Server if( m_Female ) flags |= 0x02; - if( m_Poison != null ) + if( m_NetState.IsPost7000 ) { + if( m_Flying ) { + flags |= 0x04; + } + } else if( m_Poison != null ) { flags |= 0x04; + } if( m_Blessed || m_YellowHealthbar ) flags |= 0x08; @@ -8136,7 +8151,7 @@ namespace Server set { m_YellowHealthbar = value; - Delta( MobileDelta.Flags ); + Delta( MobileDelta.HealthbarYellow ); } } @@ -8277,7 +8292,7 @@ namespace Server /*if ( m_Poison != value && (m_Poison == null || value == null || m_Poison.Level < value.Level) ) {*/ m_Poison = value; - Delta( MobileDelta.Flags ); + Delta( MobileDelta.HealthbarPoison ); if( m_PoisonTimer != null ) { @@ -8913,6 +8928,14 @@ namespace Server { m.m_NetState.Send( new MobileIncoming( m, this ) ); + if ( m.m_NetState.IsPost7000 ) { + if ( m_Poison != null ) + m.m_NetState.Send( new HealthbarPoison( this ) ); + + if ( m_Blessed || m_YellowHealthbar ) + m.m_NetState.Send( new HealthbarYellow( this ) ); + } + if( IsDeadBondedPet ) m.m_NetState.Send( new BondedStatus( 0, m_Serial, 1 ) ); @@ -8929,6 +8952,14 @@ namespace Server { ourState.Send( new MobileIncoming( this, m ) ); + if ( ourState.IsPost7000 ) { + if ( m.Poisoned ) + ourState.Send( new HealthbarPoison( m ) ); + + if ( m.Blessed || m.YellowHealthbar ) + ourState.Send( new HealthbarYellow( m ) ); + } + if( m.IsDeadBondedPet ) ourState.Send( new BondedStatus( 0, m.m_Serial, 1 ) ); @@ -8956,6 +8987,14 @@ namespace Server { ns.Send( new MobileIncoming( ns.Mobile, this ) ); + if ( ns.IsPost7000 ) { + if ( m_Poison != null ) + ns.Send( new HealthbarPoison( this ) ); + + if ( m_Blessed || m_YellowHealthbar ) + ns.Send( new HealthbarYellow( this ) ); + } + if( IsDeadBondedPet ) ns.Send( new BondedStatus( 0, m_Serial, 1 ) ); @@ -9285,6 +9324,14 @@ namespace Server { state.Send( new MobileIncoming( state.Mobile, this ) ); + if ( state.IsPost7000 ) { + if ( m_Poison != null ) + state.Send( new HealthbarPoison( this ) ); + + if ( m_Blessed || m_YellowHealthbar ) + state.Send( new HealthbarYellow( this ) ); + } + if( IsDeadBondedPet ) state.Send( new BondedStatus( 0, m_Serial, 1 ) ); @@ -9708,6 +9755,8 @@ namespace Server bool sendHair = false, sendFacialHair = false, removeHair = false, removeFacialHair = false; + bool sendHealthbarPoison = false, sendHealthbarYellow = false; + if( attrs != MobileDelta.None ) { sendAny = true; @@ -9764,6 +9813,16 @@ namespace Server sendMoving = true; } + if( (delta & (MobileDelta.HealthbarPoison) != 0 ) + { + sendHealthbarPoison = true; + } + + if( (delta & (MobileDelta.HealthbarYellow) != 0 ) + { + sendHealthbarYellow = true; + } + if( (delta & MobileDelta.Name) != 0 ) { sendAll = false; @@ -9815,10 +9874,24 @@ namespace Server if( sendIncoming ) ourState.Send( new MobileIncoming( m, m ) ); - if( sendMoving ) - { - int noto = Notoriety.Compute( m, m ); - ourState.Send( cache[noto] = Packet.Acquire( new MobileMoving( m, noto ) ) ); + if ( state.IsPost7000 ) { + if( sendMoving ) + { + int noto = Notoriety.Compute( m, m ); + ourState.Send( cache[noto] = Packet.Acquire( new MobileMoving( m, noto ) ) ); + } + + if ( sendHealthbarPoison ) + ourState.Send( new HealthbarPoison( m ) ); + + if ( sendHealthbarYellow ) + ourState.Send( new HealthbarYellow( m ) ); + } else { + if( sendMoving || sendHealthbarPoison || sendHealthbarYellow ) + { + int noto = Notoriety.Compute( m, m ); + ourState.Send( cache[noto] = Packet.Acquire( new MobileMoving( m, noto ) ) ); + } } if( sendPublicStats || sendPrivateStats ) @@ -9876,7 +9949,7 @@ namespace Server sendIncoming = sendIncoming || sendNonlocalIncoming; sendHits = sendHits || sendAll; - if( m.m_Map != null && (sendRemove || sendIncoming || sendPublicStats || sendHits || sendMoving || sendOPLUpdate || sendHair || sendFacialHair) ) + if( m.m_Map != null && (sendRemove || sendIncoming || sendPublicStats || sendHits || sendMoving || sendOPLUpdate || sendHair || sendFacialHair || sendHealthbarPoison || sendHealthbarYellow) ) { Mobile beholder; @@ -9886,6 +9959,7 @@ namespace Server Packet statPacketTrue = null, statPacketFalse = null; Packet deadPacket = null; Packet hairPacket = null, facialhairPacket = null; + Packet hbpPacket = null, hbyPacket = null; foreach( NetState state in eable ) { @@ -9909,16 +9983,43 @@ namespace Server } } - if( sendMoving ) - { - int noto = Notoriety.Compute( beholder, m ); + if ( state.IsPost7000 ) { + if( sendMoving ) + { + int noto = Notoriety.Compute( beholder, m ); - Packet p = cache[noto]; + Packet p = cache[noto]; - if( p == null ) - cache[noto] = p = Packet.Acquire( new MobileMoving( m, noto ) ); + if( p == null ) + cache[noto] = p = Packet.Acquire( new MobileMoving( m, noto ) ); - state.Send( p ); + state.Send( p ); + } + + if ( sendHealthbarPoison ) { + if ( hbpPacket == null ) + hbpPacket = Packet.Acquire( new HealthbarPoison( m ) ); + + state.Send( hbpPacket ); + } + + if ( sendHealthbarYellow ) { + if ( hbyPacket == null ) + hbyPacket = Packet.Acquire( new HealthbarYellow( m ) ); + state.Send( hbyPacket ); + } + } else { + if( sendMoving || sendHealthbarPoison || sendHealthbarYellow ) + { + int noto = Notoriety.Compute( beholder, m ); + + Packet p = cache[noto]; + + if( p == null ) + cache[noto] = p = Packet.Acquire( new MobileMoving( m, noto ) ); + + state.Send( p ); + } } if( sendPublicStats ) @@ -9983,11 +10084,13 @@ namespace Server Packet.Release( deadPacket ); Packet.Release( hairPacket ); Packet.Release( facialhairPacket ); + Packet.Release( hbpPacket ); + Packet.Release( hbyPacket ); eable.Free(); } - if( sendMoving || sendNonlocalMoving ) + if( sendMoving || sendNonlocalMoving || sendHealthbarPoison || sendHealthbarYellow ) { for( int i = 0; i < cache.Length; ++i ) Packet.Release( ref cache[i] ); diff --git a/Server/Network/NetState.cs b/Server/Network/NetState.cs index 27ac4100d..86087dc19 100644 --- a/Server/Network/NetState.cs +++ b/Server/Network/NetState.cs @@ -201,7 +201,9 @@ namespace Server.Network { set { m_Version = value; - if ( value >= m_Version60142 ) { + if ( value >= m_Version7000 ) { + m_Post7000 = m_Post60142 = m_Post6017 = true; + } else if ( value >= m_Version60142 ) { m_Post60142 = m_Post6017 = true; } else if ( value >= m_Version6017 ) { m_Post6017 = true; @@ -224,9 +226,11 @@ namespace Server.Network { private static ClientVersion m_Version6017 = new ClientVersion( "6.0.1.7" ); private static ClientVersion m_Version60142 = new ClientVersion( "6.0.14.2" ); + private static ClientVersion m_Version7000 = new ClientVersion( "7.0.0.0" ); private bool m_Post6017; private bool m_Post60142; + private bool m_Post7000; public bool IsPost6017 { get { @@ -240,6 +244,12 @@ namespace Server.Network { } } + public bool IsPost7000 { + get { + return m_Post7000; + } + } + public List Trades { get { return m_Trades; diff --git a/Server/Network/PacketHandlers.cs b/Server/Network/PacketHandlers.cs index 9da6f7e31..5efb2f5b0 100644 --- a/Server/Network/PacketHandlers.cs +++ b/Server/Network/PacketHandlers.cs @@ -147,7 +147,7 @@ namespace Server.Network Register( 0xD1, 2, true, new OnPacketReceive( LogoutReq ) ); Register( 0xD6, 0, true, new OnPacketReceive( BatchQueryProperties ) ); Register( 0xD7, 0, true, new OnPacketReceive( EncodedCommand ) ); - Register( 0xEF, 21, false, new OnPacketReceive( LoginServerSeed ) ); + Register( 0xEF, 21, false, new OnPacketReceive( LoginServerSeed ) ); Register6017( 0x08, 15, true, new OnPacketReceive( DropReq6017 ) ); @@ -2024,9 +2024,28 @@ namespace Server.Network int shirtHue = pvSrc.ReadInt16(); int pantsHue = pvSrc.ReadInt16(); + /* + Pre-7.0.0.0: + 0x00, 0x01 -> Human Male, Human Female + 0x02, 0x03 -> Elf Male, Elf Female + + Post-7.0.0.0: + 0x00, 0x01 + 0x02, 0x03 -> Human Male, Human Female + 0x04, 0x05 -> Elf Male, Elf Female + 0x05, 0x06 -> Gargoyle Male, Gargoyle Female + */ + bool female = ((genderRace % 2) != 0); - Race race = Race.Races[(byte)(genderRace / 2)]; + Race race = null; + + if ( state.IsPost7000 ) { + byte raceID = (byte)(genderRace < 4 ? 0 : ((genderRace / 2) - 1)); + race = Race.Races[raceID]; + } else { + race = Race.Races[(byte)(genderRace / 2)]; + } if( race == null ) race = Race.DefaultRace; diff --git a/Server/Network/Packets.cs b/Server/Network/Packets.cs index 4f7dbb4de..998f8e978 100644 --- a/Server/Network/Packets.cs +++ b/Server/Network/Packets.cs @@ -2734,10 +2734,9 @@ namespace Server.Network string name = m.Name; if ( name == null ) name = ""; - bool sendMaxWeight = (Core.ML && ns != null && ns.SupportsExpansion( Expansion.ML )); + bool sendMLExtended = (Core.ML && ns != null && ns.SupportsExpansion( Expansion.ML )); - - this.EnsureCapacity( sendMaxWeight ? 91 :88 ); + this.EnsureCapacity( sendMLExtended ? 91 : 88 ); m_Stream.Write( (int) m.Serial ); m_Stream.WriteAsciiFixed( name, 30 ); @@ -2747,7 +2746,7 @@ namespace Server.Network m_Stream.Write( m.CanBeRenamedBy( m ) ); - m_Stream.Write( (byte)(sendMaxWeight ? 0x05 : Core.AOS ? 0x04 : 0x03) ); // type + m_Stream.Write( (byte)(sendMLExtended ? 0x05 : Core.AOS ? 0x04 : 0x03) ); // type m_Stream.Write( m.Female ); @@ -2765,7 +2764,7 @@ namespace Server.Network m_Stream.Write( (short) (Core.AOS ? m.PhysicalResistance : (int)(m.ArmorRating + 0.5)) ); m_Stream.Write( (short) (Mobile.BodyWeight + m.TotalWeight) ); - if( sendMaxWeight ) + if( sendMLExtended ) { m_Stream.Write( (short)m.MaxWeight ); m_Stream.Write( (byte)(m.Race.RaceID + 1)); // Would be 0x00 if it's a non-ML enabled account but... @@ -2810,9 +2809,9 @@ namespace Server.Network string name = beheld.Name; if ( name == null ) name = ""; - bool sendMaxWeight = (Core.ML && ns != null && ns.SupportsExpansion( Expansion.ML )); + bool sendMLExtended = (Core.ML && ns != null && ns.SupportsExpansion( Expansion.ML )); - this.EnsureCapacity( 43 + (beholder == beheld ? (sendMaxWeight ? 48 : 45) : 0) ); + this.EnsureCapacity( 43 + (beholder == beheld ? (sendMLExtended ? 48 : 45) : 0) ); m_Stream.Write( beheld.Serial ); @@ -2827,7 +2826,7 @@ namespace Server.Network if ( beholder == beheld ) { - m_Stream.Write( (byte)(sendMaxWeight ? 0x05 : Core.AOS ? 0x04 : 0x03) ); // type + m_Stream.Write( (byte)(sendMLExtended ? 0x05 : Core.AOS ? 0x04 : 0x03) ); // type m_Stream.Write( beheld.Female ); @@ -2842,7 +2841,7 @@ namespace Server.Network m_Stream.Write( (short) (Core.AOS ? beheld.PhysicalResistance : (int)(beheld.ArmorRating + 0.5)) ); m_Stream.Write( (short) (Mobile.BodyWeight + beheld.TotalWeight) ); - if( sendMaxWeight ) + if( sendMLExtended ) { m_Stream.Write( (short)beheld.MaxWeight ); m_Stream.Write( (byte)(beheld.Race.RaceID + 1) ); // Would be 0x00 if it's a non-ML enabled account but... @@ -2892,6 +2891,46 @@ namespace Server.Network } } + public sealed class HealthbarPoison : Packet + { + public HealthbarUpdatePoison( Mobile m ) : base( 0x17 ) + { + EnsureCapacity( 12 ); + + m_Stream.Write( (int) m.Serial ); + m_Stream.Write( (short) 0 ); + + m_Stream.Write( (short) 1 ); + + Poison p = m.Poison; + + if ( p != null ) { + m_Stream.Write( (byte) p.Level + 1 ); + } else { + m_Stream.Write( (byte) 0 ); + } + } + } + + public sealed class HealthbarYellow : Packet + { + public HealthbarUpdateYellow( Mobile m ) : base( 0x17 ) + { + EnsureCapacity( 12 ); + + m_Stream.Write( (int) m.Serial ); + m_Stream.Write( (short) 0 ); + + m_Stream.Write( (short) 2 ); + + if ( m.Blessed || m.YellowHealthbar ) { + m_Stream.Write( (byte) 1 ); + } else { + m_Stream.Write( (byte) 0 ); + } + } + } + public sealed class MobileUpdate : Packet { public MobileUpdate( Mobile m ) : base( 0x20, 19 )