BritainKnights/Scripts/Misc/CharacterCreation.cs

495 lines
No EOL
12 KiB
C#

using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Network;
using Server.Accounting;
namespace Server.Misc
{
public class CharacterCreation
{
public static void Initialize()
{
// Register our event handler
EventSink.CharacterCreated += new CharacterCreatedEventHandler( EventSink_CharacterCreated );
}
private static void AddBackpack( Mobile m )
{
Container pack = m.Backpack;
if ( pack == null )
{
pack = new Backpack();
pack.Movable = false;
m.AddItem( pack );
}
PackItem( new RedBook( "a book", m.Name, 20, true ) );
PackItem( new Gold( Server.Misc.Settings.StartGold() ) );
PackItem( new Dagger() );
PackItem( new Candle() );
}
private static void AddShirt( Mobile m )
{
switch ( Utility.Random( 5 ) )
{
case 0: EquipItem( new FancyShirt( Utility.RandomHue() ), true ); break;
case 1: EquipItem( new Doublet( Utility.RandomHue() ), true ); break;
case 2: EquipItem( new Shirt( Utility.RandomHue() ), true ); break;
case 3: EquipItem( new Tunic( Utility.RandomHue() ), true ); break;
case 4: EquipItem( new Surcoat( Utility.RandomHue() ), true ); break;
}
}
private static void AddPants( Mobile m )
{
if ( m.Female )
{
switch ( Utility.Random( 4 ) )
{
case 0: EquipItem( new Skirt( Utility.RandomHue() ), true ); break;
case 1: EquipItem( new Kilt( Utility.RandomHue() ), true ); break;
case 2: EquipItem( new LongPants( Utility.RandomHue() ), true ); break;
case 3: EquipItem( new ShortPants( Utility.RandomHue() ), true ); break;
}
}
else
{
switch ( Utility.Random( 3 ) )
{
case 0: EquipItem( new LongPants( Utility.RandomHue() ), true ); break;
case 1: EquipItem( new ShortPants( Utility.RandomHue() ), true ); break;
case 2: EquipItem( new Kilt( Utility.RandomHue() ), true ); break;
}
}
}
private static void AddShoes( Mobile m )
{
switch ( Utility.Random( 4 ) )
{
case 0: EquipItem( new Shoes( Utility.RandomNeutralHue() ), true ); break;
case 1: EquipItem( new Boots( Utility.RandomNeutralHue() ), true ); break;
case 2: EquipItem( new Sandals( Utility.RandomNeutralHue() ), true ); break;
case 3: EquipItem( new ThighBoots( Utility.RandomNeutralHue() ), true ); break;
}
}
private static void AddHat( Mobile m, int color )
{
switch ( Utility.Random( 7 ) )
{
case 0: EquipItem( new FloppyHat( Utility.RandomHue() ), true ); break;
case 1: EquipItem( new Hood( color ), true ); break;
case 2: EquipItem( new WideBrimHat( Utility.RandomHue() ), true ); break;
case 3: EquipItem( new Cap( Utility.RandomHue() ), true ); break;
case 4: EquipItem( new SkullCap( Utility.RandomHue() ), true ); break;
case 5: EquipItem( new Bandana( Utility.RandomHue() ), true ); break;
case 6: EquipItem( new FeatheredHat( Utility.RandomHue() ), true ); break;
}
}
private static Mobile CreateMobile( Account a )
{
if ( a.Count >= a.Limit )
return null;
for ( int i = 0; i < a.Length; ++i )
{
if ( a[i] == null )
return (a[i] = new PlayerMobile());
}
return null;
}
private static void EventSink_CharacterCreated( CharacterCreatedEventArgs args )
{
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", state );
return;
}
args.Mobile = newChar;
m_Mobile = newChar;
newChar.Player = true;
newChar.StatCap = 200;
newChar.Skills.Cap = 7000;
newChar.AccessLevel = args.Account.AccessLevel;
newChar.Female = args.Female;
newChar.Race = Race.Human;
newChar.Hue = newChar.Race.ClipSkinHue( args.Hue & 0x3FFF ) | 0x8000;
newChar.Hunger = 20;
newChar.Thirst = 20;
if ( newChar is PlayerMobile )
{
PlayerMobile pm = (PlayerMobile) newChar;
pm.Profession = args.Profession;
}
SetName( newChar, args.Name );
AddBackpack( newChar );
SetStats( newChar, state, args.Str, args.Dex, args.Int, args.Profession );
SetSkills( newChar, args.Skills, args.Profession );
newChar.HairItemID = args.HairID;
newChar.HairHue = ClipHairHue( args.HairHue & 0x3FFF );
newChar.FacialHairItemID = args.BeardID;
newChar.FacialHairHue = ClipHairHue( args.BeardHue & 0x3FFF );
newChar.RecordHair = newChar.HairItemID;;
newChar.RecordBeard = newChar.FacialHairItemID;;
AddShirt( newChar );
AddPants( newChar );
AddShoes( newChar );
int hatColor = 0;
int robeColor = 0;
if ( Utility.RandomBool() )
{
hatColor = Utility.RandomHue();
EquipItem( new Cloak( hatColor ), true );
}
if ( Utility.RandomBool() )
{
robeColor = Utility.RandomHue();
EquipItem( new Robe( robeColor ), true );
if ( hatColor > 0 && Utility.RandomBool() ){ hatColor = robeColor; }
else if ( hatColor == 0 ){ hatColor = robeColor; }
}
if ( Utility.RandomBool() ){ AddHat( newChar, hatColor ); }
CityInfo city = GetStartLocation( args );
newChar.MoveToWorld( city.Location, city.Map );
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() );
new WelcomeTimer( newChar ).Start();
}
public static int ClipHairHue( int hue )
{
if( hue < 1102 )
return 1102;
else if( hue > 1149 )
return 1149;
else
return hue;
}
public static bool VerifyProfession( int profession )
{
if ( profession < 8 )
return true;
else
return false;
}
private class BadStartMessage : Timer
{
Mobile m_Mobile;
int m_Message;
public BadStartMessage( Mobile m, int message ) : base( TimeSpan.FromSeconds ( 3.5 ) )
{
m_Mobile = m;
m_Message = message;
this.Start();
}
protected override void OnTick()
{
m_Mobile.SendLocalizedMessage( m_Message );
}
}
private static CityInfo GetStartLocation( CharacterCreatedEventArgs args )
{
return args.City;
}
private static void FixStats( ref int str, ref int dex, ref int intel, int max )
{
int vMax = max - 30;
int vStr = str - 10;
int vDex = dex - 10;
int vInt = intel - 10;
if ( vStr < 0 )
vStr = 0;
if ( vDex < 0 )
vDex = 0;
if ( vInt < 0 )
vInt = 0;
int total = vStr + vDex + vInt;
if ( total == 0 || total == vMax )
return;
double scalar = vMax / (double)total;
vStr = (int)(vStr * scalar);
vDex = (int)(vDex * scalar);
vInt = (int)(vInt * scalar);
FixStat( ref vStr, (vStr + vDex + vInt) - vMax, vMax );
FixStat( ref vDex, (vStr + vDex + vInt) - vMax, vMax );
FixStat( ref vInt, (vStr + vDex + vInt) - vMax, vMax );
str = vStr + 10;
dex = vDex + 10;
intel = vInt + 10;
}
private static void FixStat( ref int stat, int diff, int max )
{
stat += diff;
if ( stat < 0 )
stat = 0;
else if ( stat > max )
stat = max;
}
private static void SetStats( Mobile m, NetState state, int str, int dex, int intel, int prof )
{
int max = state.NewCharacterCreation ? 90 : 80;
FixStats( ref str, ref dex, ref intel, max );
if ( str < 10 || str > 60 || dex < 10 || dex > 60 || intel < 10 || intel > 60 || (str + dex + intel) != max )
{
str = 10;
dex = 10;
intel = 10;
}
if ( prof > 0 )
{
switch ( prof )
{
case 1: // Swordsman
{
m.InitStats( 45, 25, 10 ); break;
}
case 2: // Magician
{
m.InitStats( 15, 20, 45 ); break;
}
case 3: // Thief
{
m.InitStats( 20, 45, 15 ); break;
}
case 4: // Fencer
{
m.InitStats( 30, 40, 10 ); break;
}
case 5: // Mace Fighter
{
m.InitStats( 45, 25, 10 ); break;
}
case 6: // Archer
{
m.InitStats( 25, 45, 10 ); break;
}
case 7: // Bard
{
m.InitStats( 25, 35, 20 ); break;
}
}
}
else
m.InitStats( str, dex, intel );
}
private static void SetName( Mobile m, string name )
{
name = name.Trim();
if ( !NameVerification.Validate( name, 2, 16, true, false, true, 1, NameVerification.SpaceDashPeriodQuote ) )
name = "Generic Player";
m.Name = name;
}
private static bool ValidSkills( SkillNameValue[] skills )
{
int total = 0;
for ( int i = 0; i < skills.Length; ++i )
{
if ( skills[i].Value < 0 || skills[i].Value > 50 )
return false;
total += skills[i].Value;
for ( int j = i + 1; j < skills.Length; ++j )
{
if ( skills[j].Value > 0 && skills[j].Name == skills[i].Name )
return false;
}
}
return ( total == 100 || total == 120 );
}
private static Mobile m_Mobile;
private static void SetSkills( Mobile m, SkillNameValue[] skills, int prof )
{
switch ( prof )
{
case 1: // Swordsman
{
skills = new SkillNameValue[]
{
new SkillNameValue( SkillName.Healing, 30 ),
new SkillNameValue( SkillName.Swords, 40 ),
new SkillNameValue( SkillName.Tactics, 30 )
};
break;
}
case 2: // Magician
{
skills = new SkillNameValue[]
{
new SkillNameValue( SkillName.Magery, 50 ),
new SkillNameValue( SkillName.Meditation, 50 )
};
break;
}
case 3: // Thief
{
skills = new SkillNameValue[]
{
new SkillNameValue( SkillName.Hiding, 50 ),
new SkillNameValue( SkillName.Stealing, 50 )
};
break;
}
case 4: // Fencer
{
skills = new SkillNameValue[]
{
new SkillNameValue( SkillName.Healing, 30 ),
new SkillNameValue( SkillName.Fencing, 40 ),
new SkillNameValue( SkillName.Tactics, 30 )
};
break;
}
case 5: // Mace Fighter
{
skills = new SkillNameValue[]
{
new SkillNameValue( SkillName.Healing, 30 ),
new SkillNameValue( SkillName.Bludgeoning, 40 ),
new SkillNameValue( SkillName.Tactics, 30 )
};
break;
}
case 6: // Archer
{
skills = new SkillNameValue[]
{
new SkillNameValue( SkillName.Archery, 50 ),
new SkillNameValue( SkillName.Tactics, 50 )
};
break;
}
case 7: // Bard
{
skills = new SkillNameValue[]
{
new SkillNameValue( SkillName.Musicianship, 40 ),
new SkillNameValue( SkillName.Discordance, 30 ),
new SkillNameValue( SkillName.Peacemaking, 30 )
};
break;
}
default:
{
if ( !ValidSkills( skills ) )
return;
break;
}
}
for ( int i = 0; i < skills.Length; ++i )
{
SkillNameValue snv = skills[i];
if ( snv.Value > 0 )
{
Skill skill = m.Skills[snv.Name];
if ( skill != null )
{
skill.BaseFixedPoint = snv.Value * 10;
}
}
}
}
private static void EquipItem( Item item )
{
EquipItem( item, false );
}
private static void EquipItem( Item item, bool mustEquip )
{
if ( m_Mobile != null && m_Mobile.EquipItem( item ) )
return;
Container pack = m_Mobile.Backpack;
if ( !mustEquip && pack != null )
pack.DropItem( item );
else
item.Delete();
}
private static void PackItem( Item item )
{
Container pack = m_Mobile.Backpack;
if ( pack != null )
pack.DropItem( item );
else
item.Delete();
}
}
}