diff --git a/Scripts/Misc/CharacterCreation.cs b/Scripts/Misc/CharacterCreation.cs index 2d473e600..34222d428 100644 --- a/Scripts/Misc/CharacterCreation.cs +++ b/Scripts/Misc/CharacterCreation.cs @@ -615,11 +615,16 @@ namespace Server.Misc if ( !VerifyProfession( args.Profession ) ) args.Profession = 0; + NetState state = args.State; + + if ( state == null ) + return; + Mobile newChar = CreateMobile( args.Account as Account ); if ( newChar == null ) { - Console.WriteLine( "Login: {0}: Character creation failed, account full", args.State ); + Console.WriteLine( "Login: {0}: Character creation failed, account full", state ); return; } @@ -657,7 +662,7 @@ namespace Server.Misc AddBackpack( newChar ); - SetStats( newChar, args.Str, args.Dex, args.Int ); + SetStats( newChar, state, args.Str, args.Dex, args.Int ); SetSkills( newChar, args.Skills, args.Profession ); Race race = newChar.Race; @@ -695,7 +700,7 @@ namespace Server.Misc newChar.MoveToWorld( city.Location, city.Map ); - Console.WriteLine( "Login: {0}: New character being created (account={1})", args.State, args.Account.Username ); + Console.WriteLine( "Login: {0}: New character being created (account={1})", state, args.Account.Username ); Console.WriteLine( " - Character: {0} (serial={1})", newChar.Name, newChar.Serial ); Console.WriteLine( " - Started: {0} {1} in {2}", city.City, city.Location, city.Map.ToString() ); @@ -830,7 +835,7 @@ namespace Server.Misc return args.City; } - private static void FixStats( ref int str, ref int dex, ref int intel ) + private static void FixStats( ref int str, ref int dex, ref int intel, int max ) { int vStr = str - 10; int vDex = dex - 10; @@ -847,39 +852,42 @@ namespace Server.Misc int total = vStr + vDex + vInt; - if ( total == 0 || total == 50 ) + if ( total == 0 || total == max ) return; - double scalar = 50 / (double)total; + double scalar = max / (double)total; vStr = (int)(vStr * scalar); vDex = (int)(vDex * scalar); vInt = (int)(vInt * scalar); - FixStat( ref vStr, (vStr + vDex + vInt) - 50 ); - FixStat( ref vDex, (vStr + vDex + vInt) - 50 ); - FixStat( ref vInt, (vStr + vDex + vInt) - 50 ); + FixStat( ref vStr, (vStr + vDex + vInt) - max, max ); + FixStat( ref vDex, (vStr + vDex + vInt) - max, max ); + FixStat( ref vInt, (vStr + vDex + vInt) - max, max ); str = vStr + 10; dex = vDex + 10; intel = vInt + 10; } - private static void FixStat( ref int stat, int diff ) + private static void FixStat( ref int stat, int diff, int max ) { stat += diff; if ( stat < 0 ) stat = 0; - else if ( stat > 50 ) - stat = 50; + else if ( stat > max ) + stat = max; } - private static void SetStats( Mobile m, int str, int dex, int intel ) + private static void SetStats( Mobile m, NetState state, int str, int dex, int intel ) { - FixStats( ref str, ref dex, ref intel ); + int max = state.NewCharacterCreation ? 60 : 50; + int total = state.NewCharacterCreation ? 90 : 80; - if ( str < 10 || str > 60 || dex < 10 || dex > 60 || intel < 10 || intel > 60 || (str + dex + intel) != 80 ) + FixStats( ref str, ref dex, ref intel, max ); + + if ( str < 10 || str > max || dex < 10 || dex > max || intel < 10 || intel > max || (str + dex + intel) != total ) { str = 10; dex = 10; @@ -917,7 +925,7 @@ namespace Server.Misc } } - return ( total == 100 ); + return ( total == 100 || total == 120 ); } private static Mobile m_Mobile; diff --git a/Server/Network/NetState.cs b/Server/Network/NetState.cs index e994818c0..299cdf957 100644 --- a/Server/Network/NetState.cs +++ b/Server/Network/NetState.cs @@ -165,7 +165,9 @@ namespace Server.Network { set { m_Version = value; - if ( value >= m_Version70130 ) { + if ( value >= m_Version70160 ) { + _ProtocolChanges = ProtocolChanges.Version70160; + } else if ( value >= m_Version70130 ) { _ProtocolChanges = ProtocolChanges.Version70130; } else if ( value >= m_Version7090 ) { _ProtocolChanges = ProtocolChanges.Version7090; @@ -199,6 +201,7 @@ namespace Server.Network { private static ClientVersion m_Version7000 = new ClientVersion( "7.0.0.0" ); private static ClientVersion m_Version7090 = new ClientVersion( "7.0.9.0" ); private static ClientVersion m_Version70130 = new ClientVersion( "7.0.13.0" ); + private static ClientVersion m_Version70160 = new ClientVersion( "7.0.16.0" ); private ProtocolChanges _ProtocolChanges; @@ -213,6 +216,7 @@ namespace Server.Network { StygianAbyss = 0x00000080, HighSeas = 0x00000100, NewCharacterList = 0x00000200, + NewCharacterCreation = 0x00000400, Version400a = NewSpellbook, Version407a = Version400a | DamagePacket, @@ -223,7 +227,8 @@ namespace Server.Network { Version60142 = Version6017 | ExtendedSupportedFeatures, Version7000 = Version60142 | StygianAbyss, Version7090 = Version7000 | HighSeas, - Version70130 = Version7090 | NewCharacterList + Version70130 = Version7090 | NewCharacterList, + Version70160 = Version70130 | NewCharacterCreation } public bool NewSpellbook { get { return ((_ProtocolChanges & ProtocolChanges.NewSpellbook) != 0); } } @@ -236,6 +241,7 @@ namespace Server.Network { public bool StygianAbyss { get { return ((_ProtocolChanges & ProtocolChanges.StygianAbyss) != 0); } } public bool HighSeas { get { return ((_ProtocolChanges & ProtocolChanges.HighSeas) != 0); } } public bool NewCharacterList { get { return ((_ProtocolChanges & ProtocolChanges.NewCharacterList) != 0); } } + public bool NewCharacterCreation { get { return ((_ProtocolChanges & ProtocolChanges.NewCharacterCreation) != 0); } } public bool IsUOTDClient { get { diff --git a/Server/Network/PacketHandlers.cs b/Server/Network/PacketHandlers.cs index dd008596f..a4635f291 100644 --- a/Server/Network/PacketHandlers.cs +++ b/Server/Network/PacketHandlers.cs @@ -149,6 +149,7 @@ namespace Server.Network Register( 0xD7, 0, true, new OnPacketReceive( EncodedCommand ) ); Register( 0xE1, 0, false, new OnPacketReceive( ClientType ) ); Register( 0xEF, 21, false, new OnPacketReceive( LoginServerSeed ) ); + Register( 0xF8, 106, false, new OnPacketReceive( CreateCharacter70160 ) ); Register6017( 0x08, 15, true, new OnPacketReceive( DropReq6017 ) ); @@ -2161,6 +2162,128 @@ namespace Server.Network } } + public static void CreateCharacter70160( NetState state, PacketReader pvSrc ) + { + int unk1 = pvSrc.ReadInt32(); + int unk2 = pvSrc.ReadInt32(); + int unk3 = pvSrc.ReadByte(); + string name = pvSrc.ReadString( 30 ); + + pvSrc.Seek( 2, SeekOrigin.Current ); + int flags = pvSrc.ReadInt32(); + pvSrc.Seek( 8, SeekOrigin.Current ); + int prof = pvSrc.ReadByte(); + pvSrc.Seek( 15, SeekOrigin.Current ); + + int genderRace = pvSrc.ReadByte(); + + int str = pvSrc.ReadByte(); + int dex = pvSrc.ReadByte(); + int intl= pvSrc.ReadByte(); + int is1 = pvSrc.ReadByte(); + int vs1 = pvSrc.ReadByte(); + int is2 = pvSrc.ReadByte(); + int vs2 = pvSrc.ReadByte(); + int is3 = pvSrc.ReadByte(); + int vs3 = pvSrc.ReadByte(); + int is4 = pvSrc.ReadByte(); + int vs4 = pvSrc.ReadByte(); + + int hue = pvSrc.ReadUInt16(); + int hairVal = pvSrc.ReadInt16(); + int hairHue = pvSrc.ReadInt16(); + int hairValf= pvSrc.ReadInt16(); + int hairHuef= pvSrc.ReadInt16(); + pvSrc.ReadByte(); + int cityIndex = pvSrc.ReadByte(); + int charSlot = pvSrc.ReadInt32(); + int clientIP = pvSrc.ReadInt32(); + int shirtHue = pvSrc.ReadInt16(); + int pantsHue = pvSrc.ReadInt16(); + + /* + 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 = null; + + byte raceID = (byte)(genderRace < 4 ? 0 : ((genderRace / 2) - 1)); + race = Race.Races[raceID]; + + if( race == null ) + race = Race.DefaultRace; + + CityInfo[] info = state.CityInfo; + IAccount a = state.Account; + + if ( info == null || a == null || cityIndex < 0 || cityIndex >= info.Length ) + { + state.Dispose(); + } + else + { + // Check if anyone is using this account + for ( int i = 0; i < a.Length; ++i ) + { + Mobile check = a[i]; + + if ( check != null && check.Map != Map.Internal ) + { + Console.WriteLine( "Login: {0}: Account in use", state ); + state.Send( new PopupMessage( PMMessage.CharInWorld ) ); + return; + } + } + + state.Flags = (ClientFlags)flags; + + CharacterCreatedEventArgs args = new CharacterCreatedEventArgs( + state, a, + name, female, hue, + str, dex, intl, + info[cityIndex], + new SkillNameValue[4] + { + new SkillNameValue( (SkillName)is1, vs1 ), + new SkillNameValue( (SkillName)is2, vs2 ), + new SkillNameValue( (SkillName)is3, vs3 ), + new SkillNameValue( (SkillName)is4, vs4 ), + }, + shirtHue, pantsHue, + hairVal, hairHue, + hairValf, hairHuef, + prof, + race + ); + + state.Send( new ClientVersionReq() ); + + state.BlockAllPackets = true; + + EventSink.InvokeCharacterCreated( args ); + + Mobile m = args.Mobile; + + if ( m != null ) + { + state.Mobile = m; + m.NetState = state; + new LoginTimer( state, m ).Start(); + } + else + { + state.BlockAllPackets = false; + state.Dispose(); + } + } + } + + private static bool m_ClientVerification = true; public static bool ClientVerification