RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Dynamic Race/Class System.

Echo

Addition 3: Restricted Spellbooks

I did my Best to make this system easily compatible with AllSpells without making it a required system. So here goes:

For Those WITH or WITHOUT AllSpells:

I have provided my SpellBook.cs, it has one very minor addition. If yours is already edited, simply copy and paste this addition into your SpellBook.cs. This Handles All OSI SpellBooks.

For Those WITH AllSpells:

First of all, the UseRestrictions bool in the AllSpells script should be set to False so as not to conflict with this system.

The addition I made to SpellBook.cs needs to be added to all SpellBook files in AllSpells for them to work with the system.

EXAMPLE: Copy and Paste the addition from SpellBook.cs to the OnDoubleClick Method ClericSpellBook.cs this will make Cleric spellbooks work with the system. Repeat this for all AllSpells Books you want to work with this system.

How the System Works:

[Loadsb : This Command loads a SpellbookType into the system, simply type the command and click on a Spellbook. The system starts empty, so any books you want added to the system must be added using this command. The spellbook targeted by [Loadsb WILL BE DELETED. A Spellbooktype can only be loaded into the system once. Once loaded a spellbook cannot be removed from the system.

[restrictsb : This command controls which spellbooks are restricted to which class. Spellbooks can be restricted and unrestricted at ANYTIME. The gumps are fairly straight forward on how to Restrict and Unrestrict Spellbooks.

When a player goes to use a Restricted Spellbook for their class they recieve a message stating the Spellbook is restricted.
Echo I have updated the All Spells System. It now uses Alien's Central Memory which eliminates the need for orbs, titles and PlayerMobile edits. Unfortunately, that means this system is no longer compatible with All Spells. I would suggest that you update this system in the same manner that I have done mine and eliminate the need for orbs. If you need help you are welcome to contact me. Thanks :)
 

Kin-Kran

Wanderer
Titles

EchoEcho said:
UPDATE

- Made the "Young" protection optional
- Removed need to edit PlayerMobile
- Added TITLES!!!!!!


First, let me say i am very impressed by what you have made here.It will do wonders for our shard.

I cannot seem to find where to work the titles. I seen the other script for making it available for players to choose, i would rather have it so it is set. If i missed where this has been mentioned before i apoligise.

*****************Edit******************************************

I found it, i didnt look hard eneough. This is a great system
 
hmmm litle help?

I am Using runuo 1.0.0
ok this is what i did... i put in a custom folder all the scripts. and i had override all others like BaseArmor, BaseWeapon etc...
The server starts great no error... But when I add the stone and i click it my server crash.... and it says nothig, just ''server crash'' :mad: Why? am doing wron? :confused: maybe is becouse am using 1.0.0 version? or maybe i dont have to put the Commands scripts? to update... thx :D
-----------------------
ups i was not following instructions sorry :D..
P/d: IT IS A GREAT SYSTEM!!!!
 

nacrom

Wanderer
run in debug mode and it will put a crash log file into your runuo directory. if you can give us that log we should be able to see what your problem is and see how to fix it for you.
 

Kin-Kran

Wanderer
Powerscrolls

A bug we found was when a skill is restricted and you use a powerscroll it opens up the skill for use on that char. If someone knows a way to code it so the powerscroll.cs checks for a minimum skill level ( like 50 incase they purchase it ) then those restricted skills couldnt be over ridden by powerscrolls. I cannot script this well but if someone else here can please sharse it. ;)

Code:
using System;
using Server;
using Server.Gumps;
using Server.Network;

namespace Server.Items
{
	public class PowerScroll : Item
	{
		private SkillName m_Skill;
		private double m_Value;

		private static SkillName[] m_Skills = new SkillName[]
			{
				SkillName.Blacksmith,
				SkillName.Tailoring,
				SkillName.Swords,
				SkillName.Fencing,
				SkillName.Macing,
				SkillName.Archery,
				SkillName.Wrestling,
				SkillName.Parry,
				SkillName.Tactics,
				SkillName.Anatomy,
				SkillName.Healing,
				SkillName.Magery,
				SkillName.Meditation,
				SkillName.EvalInt,
				SkillName.MagicResist,
				SkillName.AnimalTaming,
				SkillName.AnimalLore,
				SkillName.Veterinary,
				SkillName.Musicianship,
				SkillName.Provocation,
				SkillName.Discordance,
				SkillName.Peacemaking
			};

		private static SkillName[] m_AOSSkills = new SkillName[]
			{
				SkillName.Blacksmith,
				SkillName.Tailoring,
				SkillName.Swords,
				SkillName.Fencing,
				SkillName.Macing,
				SkillName.Archery,
				SkillName.Wrestling,
				SkillName.Parry,
				SkillName.Tactics,
				SkillName.Anatomy,
				SkillName.Healing,
				SkillName.Magery,
				SkillName.Meditation,
				SkillName.EvalInt,
				SkillName.MagicResist,
				SkillName.AnimalTaming,
				SkillName.AnimalLore,
				SkillName.Veterinary,
				SkillName.Musicianship,
				SkillName.Provocation,
				SkillName.Discordance,
				SkillName.Peacemaking,
				SkillName.Chivalry,
				SkillName.Focus,
				SkillName.Necromancy,
				SkillName.Stealing,
				SkillName.Stealth,
				SkillName.SpiritSpeak
			};

		private static SkillName[] m_SESkills = new SkillName[]
			{
				SkillName.Blacksmith,
				SkillName.Tailoring,
				SkillName.Swords,
				SkillName.Fencing,
				SkillName.Macing,
				SkillName.Archery,
				SkillName.Wrestling,
				SkillName.Parry,
				SkillName.Tactics,
				SkillName.Anatomy,
				SkillName.Healing,
				SkillName.Magery,
				SkillName.Meditation,
				SkillName.EvalInt,
				SkillName.MagicResist,
				SkillName.AnimalTaming,
				SkillName.AnimalLore,
				SkillName.Veterinary,
				SkillName.Musicianship,
				SkillName.Provocation,
				SkillName.Discordance,
				SkillName.Peacemaking,
				SkillName.Chivalry,
				SkillName.Focus,
				SkillName.Necromancy,
				SkillName.Stealing,
				SkillName.Stealth,
				SkillName.SpiritSpeak,
				SkillName.Ninjitsu,
				SkillName.Bushido
			};

		public static SkillName[] Skills{ get{ return ( Core.SE ? m_SESkills : Core.AOS ? m_AOSSkills : m_Skills ); } }

		public static PowerScroll CreateRandom( int min, int max )
		{
			min /= 5;
			max /= 5;

			SkillName[] skills = PowerScroll.Skills;

			return new PowerScroll( skills[Utility.Random( skills.Length )], 100 + (Utility.RandomMinMax( min, max ) * 5));
		}

		public static PowerScroll CreateRandomNoCraft( int min, int max )
		{
			min /= 5;
			max /= 5;

			SkillName[] skills = PowerScroll.Skills;
			SkillName skillName;

			do
			{
				skillName = skills[Utility.Random( skills.Length )];
			} while ( skillName == SkillName.Blacksmith || skillName == SkillName.Tailoring );

			return new PowerScroll( skillName, 100 + (Utility.RandomMinMax( min, max ) * 5));
		}

		[Constructable]
		public PowerScroll( SkillName skill, double value ) : base( 0x14F0 )
		{
			base.Hue = 0x481;
			base.Weight = 1.0;

			LootType = LootType.Cursed;

			m_Skill = skill;
			m_Value = value;
		}

		public PowerScroll( Serial serial ) : base( serial )
		{
		}

		[CommandProperty( AccessLevel.GameMaster )]
		public SkillName Skill
		{
			get
			{
				return m_Skill;
			}
			set
			{
				m_Skill = value;
			}
		}

		[CommandProperty( AccessLevel.GameMaster )]
		public double Value
		{
			get
			{
				return m_Value;
			}
			set
			{
				m_Value = value;
			}
		}

		private string GetNameLocalized()
		{
			return String.Concat( "#", (1044060 + (int)m_Skill).ToString() );
		}

		private string GetName()
		{
			int index = (int)m_Skill;
			SkillInfo[] table = SkillInfo.Table;

			if ( index >= 0 && index < table.Length )
				return table[index].Name.ToLower();
			else
				return "???";
		}

		public override void AddNameProperty(ObjectPropertyList list)
		{
			if ( m_Value == 105.0 )
				list.Add( 1049639, GetNameLocalized() ); // a wonderous scroll of ~1_type~ (105 Skill)
			else if ( m_Value == 110.0 )
				list.Add( 1049640, GetNameLocalized() ); // an exalted scroll of ~1_type~ (110 Skill)
			else if ( m_Value == 115.0 )
				list.Add( 1049641, GetNameLocalized() ); // a mythical scroll of ~1_type~ (115 Skill)
			else if ( m_Value == 120.0 )
				list.Add( 1049642, GetNameLocalized() ); // a legendary scroll of ~1_type~ (120 Skill)
			else
				list.Add( "a power scroll of {0} ({1} Skill)", GetName(), m_Value );
		}

		public override void OnSingleClick( Mobile from )
		{
			if ( m_Value == 105.0 )
				base.LabelTo( from, 1049639, GetNameLocalized() ); // a wonderous scroll of ~1_type~ (105 Skill)
			else if ( m_Value == 110.0 )
				base.LabelTo( from, 1049640, GetNameLocalized() ); // an exalted scroll of ~1_type~ (110 Skill)
			else if ( m_Value == 115.0 )
				base.LabelTo( from, 1049641, GetNameLocalized() ); // a mythical scroll of ~1_type~ (115 Skill)
			else if ( m_Value == 120.0 )
				base.LabelTo( from, 1049642, GetNameLocalized() ); // a legendary scroll of ~1_type~ (120 Skill)
			else
				base.LabelTo( from, "a power scroll of {0} ({1} Skill)", GetName(), m_Value );
		}

		public void Use( Mobile from, bool firstStage )
		{
			if ( Deleted )
				return;

			if ( IsChildOf( from.Backpack ) )
			{
				Skill skill = from.Skills[m_Skill];

				if ( skill != null )
				{
					if ( skill.Cap >= m_Value )
					{
						from.SendLocalizedMessage( 1049511, GetNameLocalized() ); // Your ~1_type~ is too high for this power scroll.
					}
					else
					{
						if ( firstStage )
						{
							from.CloseGump( typeof( StatCapScroll.InternalGump ) );
							from.CloseGump( typeof( PowerScroll.InternalGump ) );
							from.SendGump( new InternalGump( from, this ) );
						}
						else
						{
							from.SendLocalizedMessage( 1049513, GetNameLocalized() ); // You feel a surge of magic as the scroll enhances your ~1_type~!

							skill.Cap = m_Value;

							Effects.SendLocationParticles( EffectItem.Create( from.Location, from.Map, EffectItem.DefaultDuration ), 0, 0, 0, 0, 0, 5060, 0 );
							Effects.PlaySound( from.Location, from.Map, 0x243 );

							Effects.SendMovingParticles( new Entity( Serial.Zero, new Point3D( from.X - 6, from.Y - 6, from.Z + 15 ), from.Map ), from, 0x36D4, 7, 0, false, true, 0x497, 0, 9502, 1, 0, (EffectLayer)255, 0x100 );
							Effects.SendMovingParticles( new Entity( Serial.Zero, new Point3D( from.X - 4, from.Y - 6, from.Z + 15 ), from.Map ), from, 0x36D4, 7, 0, false, true, 0x497, 0, 9502, 1, 0, (EffectLayer)255, 0x100 );
							Effects.SendMovingParticles( new Entity( Serial.Zero, new Point3D( from.X - 6, from.Y - 4, from.Z + 15 ), from.Map ), from, 0x36D4, 7, 0, false, true, 0x497, 0, 9502, 1, 0, (EffectLayer)255, 0x100 );

							Effects.SendTargetParticles( from, 0x375A, 35, 90, 0x00, 0x00, 9502, (EffectLayer)255, 0x100 );

							Delete();
						}
					}
				}
			}
			else
			{
				from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
			}
		}

		public override void OnDoubleClick( Mobile from )
		{
			Use( from, true );
		}

		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );

			writer.Write( (int) 0 ); // version

			writer.Write( (int) m_Skill );
			writer.Write( (double) m_Value );
		}

		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );

			int version = reader.ReadInt();

			switch ( version )
			{
				case 0:
				{
					m_Skill = (SkillName)reader.ReadInt();
					m_Value = reader.ReadDouble();

					break;
				}
			}

			if ( LootType != LootType.Cursed )
				LootType = LootType.Cursed;

			if ( Insured )
				Insured = false;
		}

		public class InternalGump : Gump
		{
			private Mobile m_Mobile;
			private PowerScroll m_Scroll;

			public InternalGump( Mobile mobile, PowerScroll scroll ) : base( 25, 50 )
			{
				m_Mobile = mobile;
				m_Scroll = scroll;

				AddPage( 0 );

				AddBackground( 25, 10, 420, 200, 5054 );

				AddImageTiled( 33, 20, 401, 181, 2624 );
				AddAlphaRegion( 33, 20, 401, 181 );

				AddHtmlLocalized( 40, 48, 387, 100, 1049469, true, true ); /* Using a scroll increases the maximum amount of a specific skill or your maximum statistics.
																			* When used, the effect is not immediately seen without a gain of points with that skill or statistics.
																			* You can view your maximum skill values in your skills window.
																			* You can view your maximum statistic value in your statistics window.
																			*/

				AddHtmlLocalized( 125, 148, 200, 20, 1049478, 0xFFFFFF, false, false ); // Do you wish to use this scroll?

				AddButton( 100, 172, 4005, 4007, 1, GumpButtonType.Reply, 0 );
				AddHtmlLocalized( 135, 172, 120, 20, 1046362, 0xFFFFFF, false, false ); // Yes

				AddButton( 275, 172, 4005, 4007, 0, GumpButtonType.Reply, 0 );
				AddHtmlLocalized( 310, 172, 120, 20, 1046363, 0xFFFFFF, false, false ); // No

				double value = scroll.m_Value;

				if ( value == 105.0 )
					AddHtmlLocalized( 40, 20, 260, 20, 1049635, 0xFFFFFF, false, false ); // Wonderous Scroll (105 Skill):
				else if ( value == 110.0 )
					AddHtmlLocalized( 40, 20, 260, 20, 1049636, 0xFFFFFF, false, false ); // Exalted Scroll (110 Skill):
				else if ( value == 115.0 )
					AddHtmlLocalized( 40, 20, 260, 20, 1049637, 0xFFFFFF, false, false ); // Mythical Scroll (115 Skill):
				else if ( value == 120.0 )
					AddHtmlLocalized( 40, 20, 260, 20, 1049638, 0xFFFFFF, false, false ); // Legendary Scroll (120 Skill):
				else
					AddHtml( 40, 20, 260, 20, String.Format( "<basefont color=#FFFFFF>Power Scroll ({0} Skill):</basefont>", value ), false, false );

				AddHtmlLocalized( 310, 20, 120, 20, 1044060 + (int)scroll.m_Skill, 0xFFFFFF, false, false );
			}

			public override void OnResponse( NetState state, RelayInfo info )
			{
				if ( info.ButtonID == 1 )
					m_Scroll.Use( m_Mobile, false );
			}
		}
	}
}
 

xxx007xxx

Sorceror
Power Scroll Restriction

Add The red code

Code:
public void Use(Mobile from, bool firstStage )
		{
			if ( Deleted )
				return;

			if ( IsChildOf( from.Backpack ) )
			{
				Skill skill = from.Skills[m_Skill];

				if ( skill != null )
				{
					if ( skill.Cap >= m_Value )
					{
						from.SendLocalizedMessage( 1049511, GetNameLocalized() ); // Your ~1_type~ is too high for this power scroll.
					}
					[COLOR="Red"]if ( skill.Cap <= 90 )
					{
						from.SendMessage( "You cannot raise secondary SkillsCap!" );
                                                    }[/COLOR]		
					
					else
					{
						if ( firstStage )
						{
							from.CloseGump( typeof( StatCapScroll.InternalGump ) );
							from.CloseGump( typeof( PowerScroll.InternalGump ) );
							from.SendGump( new InternalGump( from, this ) );
						}
						else
						{
							from.SendLocalizedMessage( 1049513, GetNameLocalized() ); // You feel a surge of magic as the scroll enhances your ~1_type~!

							skill.Cap = m_Value;

							Effects.SendLocationParticles( EffectItem.Create( from.Location, from.Map, EffectItem.DefaultDuration ), 0, 0, 0, 0, 0, 5060, 0 );
							Effects.PlaySound( from.Location, from.Map, 0x243 );

							Effects.SendMovingParticles( new Entity( Serial.Zero, new Point3D( from.X - 6, from.Y - 6, from.Z + 15 ), from.Map ), from, 0x36D4, 7, 0, false, true, 0x497, 0, 9502, 1, 0, (EffectLayer)255, 0x100 );
							Effects.SendMovingParticles( new Entity( Serial.Zero, new Point3D( from.X - 4, from.Y - 6, from.Z + 15 ), from.Map ), from, 0x36D4, 7, 0, false, true, 0x497, 0, 9502, 1, 0, (EffectLayer)255, 0x100 );
							Effects.SendMovingParticles( new Entity( Serial.Zero, new Point3D( from.X - 6, from.Y - 4, from.Z + 15 ), from.Map ), from, 0x36D4, 7, 0, false, true, 0x497, 0, 9502, 1, 0, (EffectLayer)255, 0x100 );

							Effects.SendTargetParticles( from, 0x375A, 35, 90, 0x00, 0x00, 9502, (EffectLayer)255, 0x100 );

							Delete();
						}
					}
				}
			}
			else
			{
				from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
			}
		}
 

Kin-Kran

Wanderer
Oh man, that had me excited, this happened though.

Code:
RunUO - [www.runuo.com] Version 1.0.0, Build 36918
Scripts: Compiling C# scripts...failed (6 errors, 0 warnings)
 - Error: scripts\scripts\Scripts\Scripts\Items\Special\Special Scrolls\PowerScr
oll.cs: CS1519: (line 265, column 4) Invalid token 'else' in class, struct, or i
nterface member declaration
 - Error: scripts\scripts\Scripts\Scripts\Items\Special\Special Scrolls\PowerScr
oll.cs: CS1519: (line 267, column 30) Invalid token '(' in class, struct, or int
erface member declaration
 - Error: scripts\scripts\Scripts\Scripts\Items\Special\Special Scrolls\PowerScr
oll.cs: CS1518: (line 271, column 19) Expected class, delegate, enum, interface,
 or struct
 - Error: scripts\scripts\Scripts\Scripts\Items\Special\Special Scrolls\PowerScr
oll.cs: CS1518: (line 276, column 19) Expected class, delegate, enum, interface,
 or struct
 - Error: scripts\scripts\Scripts\Scripts\Items\Special\Special Scrolls\PowerScr
oll.cs: CS1518: (line 286, column 19) Expected class, delegate, enum, interface,
 or struct
 - Error: scripts\scripts\Scripts\Scripts\Items\Special\Special Scrolls\PowerScr
oll.cs: CS1022: (line 363, column 2) Type or namespace definition, or end-of-fil
e expected
Scripts: One or more scripts failed to compile or no script files were found.
 - Press return to exit, or R to try again.
 
got crash :(

hmm when i click the race stone my server crashes do you help it with fix system

heres the my crashlog
Code:
Server Crash Report
===================

RunUO Version 1.0.0, Build 36918
Operating System: Microsoft Windows NT 5.1.2600.0
.NET Framework: 1.1.4322.573
Time: 14.06.2006 10:40
Mobiles: 15149
Items: 138294
Clients:
- Count: 1
+ 127.0.0.1: (account = ******) (mobile = 0x935 '*****)

Exception:
System.NullReferenceException: Object reference not set to an instance of an object.
   at Server.Gumps.RaceGump..ctor(Mobile from)
   at Server.Items.RaceStone.OnDoubleClick(Mobile from)
   at Server.Mobile.Use(Item item)
   at Server.Network.PacketHandlers.UseReq(NetState state, PacketReader pvSrc)
   at Server.Network.MessagePump.HandleReceive(NetState ns)
   at Server.Network.MessagePump.Slice()
   at Server.Core.Main(String[] args)
 

Icedddragon

Wanderer
aww this sucks, the class system works great for current players, but new player tries to create a new char? BOOM server crash...
 

Kin-Kran

Wanderer
Do not place any items in the race bags, when anything is epuipted it causes crashes.

http://www.runuo.com/forums/showthread.php?t=69661

I was put them in there for the races to recieve some items like you can on the classes. I should have looked at it better, been doing alot of things so i over looked that little detail.

We are in developement with this and so far besides finding some small bugs or loopholes ( like the powerscrolls ) it is an awesome script. Cant wait to offer all these option to thre players.
 

Icedddragon

Wanderer
Kin is it just items or equip as well?
the same thing happens for anything being in ANY bags including restricted *goes to delete everything ever*
if echos still around, any chance of a fix?
 

Icedddragon

Wanderer
Figured out what was causing crash :) i had to ctrl+f to delete the edits in base armour and weapon to stop the crash :( otherwise nothing could be equipted
Edit: sorrry for the double post *cries*
 

Icedddragon

Wanderer
Okay here goes ^^ heres the one for armour, the one for weapons pretty much says the same but with weapon file instead :rolleyes:
Edit: didnt realize it doesnt support .logs :p
 

Attachments

  • Crash 15-6-2006-17-57-49.txt
    782 bytes · Views: 5

Icedddragon

Wanderer
Got another problem ;( it crashes on a new player logging in, i think it has something to do with your system lucid=/
Code:
Server Crash Report
===================

RunUO Version 1.0.0, Build 36918
Operating System: Microsoft Windows NT 5.1.2600.0
.NET Framework: 1.1.4322.2032
Time: 15/06/2006 22:20:04
Mobiles: 4815
Items: 123741
Clients:
- Count: 1
+ 127.0.0.1: (account = Iceyflames) (mobile = 0x30 'Druid')

Exception:
System.NullReferenceException: Object reference not set to an instance of an object.
   at Server.Gumps.ClassGump..ctor(Mobile from) in d:\RunUO10\Scripts\Customs\Race Class System\Gumps\RaceGump.cs:line 317
   at Server.LucidNagual.ControlCenter.OnLogin(LoginEventArgs e) in d:\RunUO10\Scripts\Spells\Base\AS Control Center\ASControlCenter.cs:line 306
   at Server.LoginEventHandler.Invoke(LoginEventArgs e)
   at Server.Network.PacketHandlers.DoLogin(NetState state, Mobile m)
   at Server.Network.PacketHandlers.CreateCharacter(NetState state, PacketReader pvSrc)
   at Server.Network.MessagePump.HandleReceive(NetState ns)
   at Server.Network.MessagePump.Slice()
   at Server.Core.Main(String[] args)
edit: heres the racegump file too...
Code:
/************************************************************************************************/
/**********Echo Dynamic Race Class System V2.0, ©2005********************************************/
/************************************************************************************************/

using System;
using Server;
using Server.Gumps;
using Server.Network;
using Server.Mobiles;
using Server.Race;
using Server.Items;
using System.Collections;
using System.Reflection;
using Server.Targeting;

namespace Server.Gumps
{

	
	public class RaceGump : Gump
	{
		private const int FieldsPerPage = 14;

		private Mobile m_From;
		private Mobile m_Mobile;

		public RaceGump ( Mobile from ) : base ( 20, 30 )
		{
			m_From = from;
			RaceOrb r_orb = null;
			RaceControl r_control = null;
			int h = 60;

			foreach (Item i in World.Items.Values) {
				if (i is RaceControl)
				r_control = i as RaceControl;
			}

			AddPage ( 0 );
			AddBackground( 0, 0, 340, (r_control.A_Races*25)+80, 5054 );

			AddImageTiled( 10, 10, 320, 23, 0x52 );
			AddImageTiled( 11, 11, 318, 23, 0xBBC );

			AddLabel( 100, 11, 0,  "Race/Class System" );

			AddLabel( 30, 34, 0,  "Choose your race." );
			
			foreach (Item i in World.Items.Values) {
				if (i is RaceOrb){
				r_orb = i as RaceOrb;
				if (r_orb.Activated){
				AddButton( 11, h, 0x15E3, 0x15E7, r_orb.RaceNumber, GumpButtonType.Reply, 1 );
				AddLabel( 30, h-1, 0, r_orb.RaceName );
				h += 25;}
				}
			}
			

		}
		public override void OnResponse( NetState sender, RelayInfo info )
		{
			Mobile from = sender.Mobile;
			RaceOrb r_orb = null;
			RCCONTROL rc =  from.Backpack.FindItemByType( typeof( RCCONTROL ) ) as RCCONTROL;
			
			foreach (Item i in World.Items.Values) {
				if (i is RaceOrb){
				r_orb = i as RaceOrb;
				if (info.ButtonID == r_orb.RaceNumber) {
				rc.Race = r_orb.RaceName;
				m_From.SendGump( new RaceDescGump( from, r_orb ) );
				}
				}
			}
			
			if (info.ButtonID == 0) {
				m_From.SendGump( new RaceGump( from ) );
			}
			
		}
	}
	
	public class RaceDescGump : Gump
	{
		private const int FieldsPerPage = 14;

		private Mobile m_From;
		private Mobile m_Mobile;

		public RaceDescGump ( Mobile from, RaceOrb orb ) : base ( 20, 30 )
		{
			m_From = from;

			AddPage ( 0 );
			AddBackground( 0, 0, 335, 230, 5054 );

			AddImageTiled( 10, 10, 315, 23, 0x52 );
			AddImageTiled( 11, 11, 313, 21, 0xBBC );

			AddLabel( 85, 11, 0, orb.RaceName+" Race Description" );
			AddHtml( 40, 50, 250, 150, @String.Format( orb.Description ), false, false );			
			AddLabel( 30, 174, 0, "To be a "+orb.RaceName+" Click here" );
			AddButton( 11, 175, 0x15E3, 0x15E7, 1, GumpButtonType.Reply, 1 );
			AddLabel( 15, 204, 0, "Right click to return to the Race Descriptions" );
			

		}

		public override void OnResponse( NetState sender, RelayInfo info )
		{
			Mobile from = sender.Mobile;
			RaceOrb r_orb = null;
			RCCONTROL rc =  from.Backpack.FindItemByType( typeof( RCCONTROL ) ) as RCCONTROL;
			
			if (info.ButtonID == 1){
			foreach (Item i in World.Items.Values) {
				if (i is RaceOrb){
				r_orb = i as RaceOrb;
				if (r_orb.RaceName == rc.Race) {
				m_From.SendGump( new BodyHueGump( from, r_orb, r_orb.BodyHues[0] ) );
				}
				}
			}
			}
			
			if (info.ButtonID == 0) {
				m_From.SendGump( new RaceGump( from ) );
			}
		}
	}	
	

	public class BodyHueGump : Gump
	{
		private const int FieldsPerPage = 14;

		private Mobile m_From;
		private Mobile m_Mobile;
			
		public BodyHueGump ( Mobile from, RaceOrb orb, int hue ) : base ( 20, 30 )
		{
			m_From = from;
			int h = 45;
			int b_v = 12;
			
			if (from.Female)
				b_v = 13;
				
			from.Hue = hue;

			AddPage ( 0 );
			AddBackground( 0, 0, 310, 360, 5054 );

			AddImageTiled( 10, 10, 290, 23, 0x52 );
			AddImageTiled( 11, 11, 288, 21, 0xBBC );

			AddLabel( 95, 11, 0, orb.RaceName+" Skin Colors" );
					
			for (int i=0; i<10; i++) {
				if (orb.BodyHues[i] != 0){
			AddLabel( 30, h, orb.BodyHues[i]-1, orb.RaceName );
			AddButton( 11, h+1, 0x15E3, 0x15E7, i+1, GumpButtonType.Reply, 1 );
			h += 25;}
			}
			
			AddImage( 110, 10, b_v, hue-1 ); //Body
			
			h += 10;
			AddLabel( 30, h, 0, "Select" );
			AddButton( 11, h+1, 0x15E3, 0x15E7, 15, GumpButtonType.Reply, 1 );
			
			AddLabel( 15, 330, 0, "Right click to return to the Race Descriptions" );
			

		}

		public override void OnResponse( NetState sender, RelayInfo info )
		{
			Mobile from = sender.Mobile;
			RaceOrb r_orb = null;
			RCCONTROL rc =  from.Backpack.FindItemByType( typeof( RCCONTROL ) ) as RCCONTROL;

			foreach (Item i in World.Items.Values) {
				if (i is RaceOrb){
				r_orb = i as RaceOrb;
				if (r_orb.RaceName == rc.Race)
				break;}
			}
		
			for (int i=0; i<10; i++) {
				if (info.ButtonID == i+1) {
					from.SendGump( new BodyHueGump( from, r_orb, r_orb.BodyHues[i] ) );
					
				}
			}
			
			if (info.ButtonID == 15)
				from.SendGump( new HairHueGump( from, r_orb, r_orb.HairHues[0] ) );	
			
			if (info.ButtonID == 0) {
				m_From.SendGump( new RaceGump( from ) );
			}
		
		}
	}
	
	public class HairHueGump : Gump
	{
		private const int FieldsPerPage = 14;

		private Mobile m_From;
		private Mobile m_Mobile;
			
		public HairHueGump ( Mobile from, RaceOrb orb, int hue ) : base ( 20, 30 )
		{
			m_From = from;
			int h = 45;
			int b_v = 12;
			Item beard = m_From.Beard;
			Item hair = m_From.Hair;
			
			if (from.Female)
				b_v = 13;
				
			if ( beard != null )
			beard.Hue = hue;

			if ( hair != null )
			hair.Hue = hue;

			AddPage ( 0 );
			AddBackground( 0, 0, 310, 360, 5054 );

			AddImageTiled( 10, 10, 290, 23, 0x52 );
			AddImageTiled( 11, 11, 288, 21, 0xBBC );

			AddLabel( 95, 11, 0, orb.RaceName+" Hair Colors" );
					
			for (int i=0; i<10; i++) {
				if (orb.HairHues[i] != 0){
			AddLabel( 30, h, orb.HairHues[i]-1, orb.RaceName );
			AddButton( 11, h+1, 0x15E3, 0x15E7, i+1, GumpButtonType.Reply, 1 );
			h += 25;}
			}
			
			AddImage( 110, 10, b_v, from.Hue-1 ); //Body
	      		AddImage( 110, 10, 50701, hue-1); //Hair
	      		if (!from.Female)
	      		AddImage( 110, 10, 50806, hue-1 ); //Beard
			
			h += 10;
			AddLabel( 30, h, 0, "Select" );
			AddButton( 11, h+1, 0x15E3, 0x15E7, 15, GumpButtonType.Reply, 1 );
			
			AddLabel( 15, 330, 0, "Right click to return to the Race Descriptions" );
			

		}

		public override void OnResponse( NetState sender, RelayInfo info )
		{
			Mobile from = sender.Mobile;
			RaceOrb r_orb = null;
			RCCONTROL rc =  from.Backpack.FindItemByType( typeof( RCCONTROL ) ) as RCCONTROL;

			foreach (Item i in World.Items.Values) {
				if (i is RaceOrb){
				r_orb = i as RaceOrb;
				if (r_orb.RaceName == rc.Race)
				break;}
			}
		
			for (int i=0; i<10; i++) {
				if (info.ButtonID == i+1) {
					from.SendGump( new HairHueGump( from, r_orb, r_orb.HairHues[i] ) );
					
				}
			}
			
			if (info.ButtonID == 15)
				from.SendGump( new ClassGump( from ) );	
			
			if (info.ButtonID == 0) {
				m_From.SendGump( new RaceGump( from ) );
			}
		
		}
	}
	
	public class ClassGump : Gump
	{
		private const int FieldsPerPage = 14;

		private Mobile m_From;
		private Mobile m_Mobile;

		public ClassGump ( Mobile from ) : base ( 20, 30 )
		{
			m_From = from;
			ClassOrb c_orb = null;
			ClassControl c_control = null;
			RaceOrb r_orb = null;
			int h = 60;
			bool isRestricted = false;
			int num = 0;
			RCCONTROL rc =  from.Backpack.FindItemByType( typeof( RCCONTROL ) ) as RCCONTROL;

			foreach (Item i in World.Items.Values) {
				if (i is ClassControl)
				c_control = i as ClassControl;
			}
			
			foreach (Item i in World.Items.Values) {
				if (i is RaceOrb){
				r_orb = i as RaceOrb;
				if (r_orb.RaceName == rc.Race)
				break;}
			}
			
			for (int i=0; i<5; i++) {
				if (r_orb.Restricted_C[i] != null)
					num += 1;
			}

			AddPage ( 0 );
			AddBackground( 0, 0, 340, ((c_control.A_Classes-num)*25)+80, 5054 );

			AddImageTiled( 10, 10, 320, 23, 0x52 );
			AddImageTiled( 11, 11, 318, 23, 0xBBC );

			AddLabel( 100, 11, 0,  "Race/Class System" );

			AddLabel( 30, 34, 0,  "Choose your class." );
			
			foreach (Item i in World.Items.Values) {
				if (i is ClassOrb){
				c_orb = i as ClassOrb;
				if (c_orb.Activated){
				
				isRestricted = false;
				
				for (int j=0; j<5; j++) {
				if (c_orb.ClassName == r_orb.Restricted_C[j])
				isRestricted = true;
				}
				
				if (!isRestricted) {
				AddButton( 11, h, 0x15E3, 0x15E7, c_orb.ClassNumber, GumpButtonType.Reply, 1 );
				AddLabel( 30, h-1, 0, c_orb.ClassName );
				h += 25;}}
				}
			}
			

		}
		public override void OnResponse( NetState sender, RelayInfo info )
		{
			Mobile from = sender.Mobile;
			ClassOrb c_orb = null;
			RCCONTROL rc =  from.Backpack.FindItemByType( typeof( RCCONTROL ) ) as RCCONTROL;
			
			foreach (Item i in World.Items.Values) {
				if (i is ClassOrb){
				c_orb = i as ClassOrb;
				if (info.ButtonID == c_orb.ClassNumber) {
				rc.P_Class = c_orb.ClassName;
				m_From.SendGump( new ClassDescGump( from, c_orb ) );
				}
				}
			}
			
			if (info.ButtonID == 0) {
				m_From.SendGump( new RaceGump( from ) );
			}
			
		}
	}
	
	
	public class ClassDescGump : Gump
	{
		private const int FieldsPerPage = 14;

		private Mobile m_From;
		private Mobile m_Mobile;

		public ClassDescGump ( Mobile from, ClassOrb orb ) : base ( 20, 30 )
		{
			m_From = from;
			int h = 135;

			AddPage ( 0 );
			AddBackground( 0, 0, 335, ((orb.Amount_Primary+orb.Amount_Restricted)*25)+350, 5054 );

			AddImageTiled( 10, 10, 315, 23, 0x52 );
			AddImageTiled( 11, 11, 313, 21, 0xBBC );

			AddLabel( 85, 11, 0, orb.ClassName+" Class Description" );
			AddHtml( 40, 50, 250, 180, @String.Format( orb.Description ), false, false );
			
			
			AddLabel( 35, h, 0, "Primary Skills:" );
			h += 25;
			for (int i=0; i < orb.Amount_Primary; i++) {
				AddLabel( 35, h, 0, orb.Primary_Skills[i]+" = "+orb.Primary_Values[i] );
				h += 25;
			}
			
			h += 10;
			AddLabel( 35, h, 0, "Restricted Skills:" );
			h += 25;
			
			for (int i=0; i < orb.Amount_Restricted; i++) {
				AddLabel(  35, h, 0, orb.Restricted_Skills[i] );
				h += 25;
			}
			
			h += 10;
			AddLabel( 35, h, 0, "Secondary Skills: "+orb.Amount_Secondary );
			h += 25;
			AddLabel( 35, h, 0, "Tertiary Skills: "+orb.Amount_Tertiary );
			h += 30;
			AddLabel( 35, h, 0, "Str Cap: "+orb.Str_Cap+"  "+"Dex Cap: "+orb.Dex_Cap+"  "+"Int Cap: "+orb.Int_Cap );
			h += 30;
			
			AddLabel( 30, h, 0, "To be a "+orb.ClassName+" Click here" );
			AddButton( 11, h+1, 0x15E3, 0x15E7, 1, GumpButtonType.Reply, 1 );
			AddLabel( 15, h+25, 0, "Right click to return to the Class List" );
			

		}

		public override void OnResponse( NetState sender, RelayInfo info )
		{
			Mobile from = sender.Mobile;
			ClassOrb c_orb = null;
			BonusPackControl b_control = null;
			RCCONTROL rc =  from.Backpack.FindItemByType( typeof( RCCONTROL ) ) as RCCONTROL;

			foreach (Item i in World.Items.Values) {
				if (i is BonusPackControl)
				b_control = i as BonusPackControl;
			}
			
			if (info.ButtonID == 1){
			foreach (Item i in World.Items.Values) {
				if (i is ClassOrb){
				c_orb = i as ClassOrb;
				if (c_orb.ClassName == rc.P_Class) {
				
				for (int j=0; j < c_orb.Amount_Primary; j++) {
					for (int k=0; k < 54; k++) {
						if (from.Skills[k].Name == c_orb.Primary_Skills[j]){
							from.Skills[k].Cap = c_orb.Primary_Values[j];
							m_From.SendMessage( 6, c_orb.Primary_Skills[j]+" Cap has been set to "+c_orb.Primary_Values[j] );}
					}
				}
				
				for (int l=0; l < c_orb.Amount_Restricted; l++) {
					for (int m=0; m < 54; m++) {
						if (from.Skills[m].Name == c_orb.Restricted_Skills[l]){
							from.Skills[m].Cap = 0.0;
							m_From.SendMessage( 6, c_orb.Restricted_Skills[l]+" Cap has been set to 0" );}
					}
				}
							
				if (b_control.A_BP == 0) {
				rc.Second = c_orb.Amount_Secondary;
				m_From.SendGump( new SecondaryGump( from, c_orb ) );
				}
				else {
				rc.Second = c_orb.Amount_Secondary;
				m_From.SendGump( new SetBonusPackGump( from ) );
				}
				}
			}
			}
			}
			
			if (info.ButtonID == 0) {
				m_From.SendGump( new ClassGump( from ) );
			}
	}
	}


	public class SetBonusPackGump : Gump
	{
		private const int FieldsPerPage = 14;

		private Mobile m_From;
		private Mobile m_Mobile;

		public SetBonusPackGump ( Mobile from ) : base ( 20, 30 )
		{
			m_From = from;
			BonusPackOrb b_orb = null;
			BonusPackControl b_control = null;
			int h = 115;
			int bp_add = 0;
			string desc = "A Bonus Pack is a group of lesser used skills that may be chosen at the cost of Secondary Skill Points.";
			RCCONTROL rc =  from.Backpack.FindItemByType( typeof( RCCONTROL ) ) as RCCONTROL;

			foreach (Item i in World.Items.Values) {
				if (i is BonusPackControl)
				b_control = i as BonusPackControl;
			}
			
			foreach (Item b in World.Items.Values) {
				if (b is BonusPackOrb) {
				b_orb = b as BonusPackOrb;
				if (rc.Second+1>b_orb.Sec_Skill_Cost)
				bp_add += 1;}
			}

			AddPage ( 0 );
			AddBackground( 0, 0, 340, (bp_add*25)+170, 5054 );

			AddImageTiled( 10, 10, 320, 23, 0x52 );
			AddImageTiled( 11, 11, 318, 23, 0xBBC );

			AddLabel( 100, 11, 0,  "Race/Class System" );

			AddHtml( 40, 50, 250, 120, @desc, false, false );
			
			foreach (Item i in World.Items.Values) {
				if (i is BonusPackOrb){
				b_orb = i as BonusPackOrb;
				if (b_orb.Activated){
				if (rc.Second+1>b_orb.Sec_Skill_Cost){
				AddButton( 11, h, 0x15E3, 0x15E7, b_orb.BPNumber, GumpButtonType.Reply, 1 );
				AddLabel( 30, h-1, 0, b_orb.BPName+" Bonus Pack" );
				h += 25;}}
				}
			}
			
			h += 10;
			AddButton( 11, h, 0x15E3, 0x15E7, 50, GumpButtonType.Reply, 1 );
			AddLabel( 30, h-1, 0, "Choose Secondary Skills Instead." );
			

		}
		public override void OnResponse( NetState sender, RelayInfo info )
		{
			Mobile from = sender.Mobile;
			BonusPackOrb b_orb = null;
			ClassOrb c_orb = null;
			RCCONTROL rc =  from.Backpack.FindItemByType( typeof( RCCONTROL ) ) as RCCONTROL;
			
			foreach (Item i in World.Items.Values) {
				if (i is BonusPackOrb){
				b_orb = i as BonusPackOrb;
				if (info.ButtonID == b_orb.BPNumber) {
				rc.BonusPack = b_orb.BPName;
				m_From.SendGump( new BPDescGump( from, b_orb ) );
				}
				}
			}
			
			foreach (Item i in World.Items.Values) {
				if (i is ClassOrb){
				c_orb = i as ClassOrb;
				if (rc.P_Class == c_orb.ClassName) 
				break;
				}
			}
			
			if (info.ButtonID == 50) {
			m_From.SendGump( new SecondaryGump( from, c_orb ) );
			}
				
			if (info.ButtonID == 0) {
				m_From.SendGump( new ClassGump( from ) );
			}
			
		}
	}
	
	public class BPDescGump : Gump
	{
		private const int FieldsPerPage = 14;

		private Mobile m_From;
		private Mobile m_Mobile;

		public BPDescGump ( Mobile from, BonusPackOrb orb ) : base ( 20, 30 )
		{
			m_From = from;
			int h = 45;

			AddPage ( 0 );
			AddBackground( 0, 0, 335, ((orb.AmountSkills)*25)+150, 5054 );

			AddImageTiled( 10, 10, 315, 23, 0x52 );
			AddImageTiled( 11, 11, 313, 21, 0xBBC );

			AddLabel( 85, 11, 0, orb.BPName+" Bonus Pack Skills" );
						
			for (int i=0; i < orb.AmountSkills; i++) {
				AddLabel( 35, h, 0, orb.BPSkills[i]+" = "+orb.BPValues[i] );
				h += 25;
			}
					
			h += 10;
			AddLabel( 35, h, 0, "Secondary Skill Cost: "+orb.Sec_Skill_Cost );
			h += 30;
			
			AddLabel( 30, h, 0, "To select the "+orb.BPName+" Bonus Pack, Click here" );
			AddButton( 11, h+1, 0x15E3, 0x15E7, 1, GumpButtonType.Reply, 1 );
			AddLabel( 15, h+25, 0, "Right click to return to the Bonus Pack List" );
			

		}

		public override void OnResponse( NetState sender, RelayInfo info )
		{
			Mobile from = sender.Mobile;
			ClassOrb c_orb = null;
			BonusPackOrb b_orb = null;
			RCCONTROL rc =  from.Backpack.FindItemByType( typeof( RCCONTROL ) ) as RCCONTROL;

			foreach (Item i in World.Items.Values) {
				if (i is ClassOrb){
				c_orb = i as ClassOrb;
				if (rc.P_Class == c_orb.ClassName) 
				break;
				}
			}
			
			if (info.ButtonID == 1){
			foreach (Item i in World.Items.Values) {
				if (i is BonusPackOrb){
				b_orb = i as BonusPackOrb;
				
				
				if (b_orb.BPName == rc.BonusPack) {
				
				for (int j=0; j < b_orb.AmountSkills; j++) {
					for (int k=0; k < 54; k++) {
						if (from.Skills[k].Name == b_orb.BPSkills[j]){
							from.Skills[k].Cap = b_orb.BPValues[j];
							m_From.SendMessage( 6, b_orb.BPSkills[j]+" Cap has been set to "+b_orb.BPValues[j] );}
					}
				}
											
				rc.Second = rc.Second - b_orb.Sec_Skill_Cost;
				if (rc.Second > 0)
				m_From.SendGump( new SecondaryGump( from, c_orb ) );
				else {
				rc.Third = c_orb.Amount_Tertiary;
				m_From.SendGump( new TertiaryGump( from, c_orb ) );}
				}
							
			}
			}
			}
			
			if (info.ButtonID == 0) {
				m_From.SendGump( new SetBonusPackGump( from ) );
			}
	}
}
	
	public class SecondaryGump : Gump
	{
		private const int FieldsPerPage = 14;

		private Mobile m_From;
		private Mobile m_Mobile;
			
		public SecondaryGump ( Mobile from, ClassOrb orb ) : base ( 20, 30 )
		{
			m_From = from;
			int h = 45;
			int w = 30;
			int m_move = 0;
			bool isUsed = false;
			ClassControl c_control = null;
			BonusPackOrb b_orb = null;
			RCCONTROL rc =  from.Backpack.FindItemByType( typeof( RCCONTROL ) ) as RCCONTROL;

			foreach (Item i in World.Items.Values) {
				if (i is ClassControl)
				c_control = i as ClassControl;
			}
			
			foreach (Item i in World.Items.Values) {
				if (i is BonusPackOrb){
				b_orb = i as BonusPackOrb;
				if (rc.BonusPack == b_orb.BPName) 
				break;
				}
			}

			AddPage ( 0 );
			AddBackground( 0, 0, 610, 420, 5054 );

			AddImageTiled( 180, 10, 290, 23, 0x52 );
			AddImageTiled( 181, 11, 288, 21, 0xBBC );

			AddLabel( 200, 11, 0, "Secondary Skills ("+c_control.Secondary_Cap+" Skill Cap) - "+rc.Second+" left" );


			for (int i=0; i < 54; i++) {
			
				isUsed = false;
				
				for (int j=0; j<10; j++) {
				if (orb.Primary_Skills[j] == from.Skills[i].Name)
				isUsed = true;
				}
				
				for (int k=0; k<10; k++) {
				if (orb.Restricted_Skills[k] == from.Skills[i].Name)
				isUsed = true;
				}
				
				if (b_orb != null){
				for (int l=0; l<5; l++) {
				if (b_orb.BPSkills[l] == from.Skills[i].Name)
				isUsed = true;
				}
				}
				
				for (int m=0; m<10; m++) {
				if (rc.Secondary[m] == from.Skills[i].Name)
				isUsed = true;
				}
				
				if (!isUsed){
				AddLabel( w, h, 0, from.Skills[i].Name );
				AddButton( w-19, h+1, 0x15E3, 0x15E7, i+1, GumpButtonType.Reply, 1 );
				
				h = h+20;
				m_move = m_move + 1;
				if (m_move == 15 || m_move == 30 || m_move == 45){
				w = w + 150;
				h = 45;}
				}
			
			}

			
			AddLabel( 20, 390, 0, "Right click to return to the Class List" );
			

		}
		public override void OnResponse( NetState sender, RelayInfo info )
		{
			Mobile from = sender.Mobile;
			ClassControl c_control = null;
			ClassOrb c_orb = null;
			RCCONTROL rc =  from.Backpack.FindItemByType( typeof( RCCONTROL ) ) as RCCONTROL;
			
			foreach (Item i in World.Items.Values) {
				if (i is ClassControl)
				c_control = i as ClassControl;
			}
			
			foreach (Item i in World.Items.Values) {
				if (i is ClassOrb){
				c_orb = i as ClassOrb;
				if (rc.P_Class == c_orb.ClassName)
				break;}
			}
			
			for (int i=0; i < 54; i++) {
				 if ((i+1) == info.ButtonID){
				 	
				 	from.Skills[i].Cap = c_control.Secondary_Cap;
				 	m_From.SendMessage( 6, from.Skills[i].Name+" Cap has been set to "+c_control.Secondary_Cap );
				 	rc.Secondary[c_orb.Amount_Secondary-rc.Second] = from.Skills[i].Name;
				 	rc.Second -= 1;
				 	if (rc.Second > 0)
				 	m_From.SendGump( new SecondaryGump( from, c_orb ) );
				 	else {
				 	rc.Third = c_orb.Amount_Tertiary;
				 	m_From.SendGump( new TertiaryGump( from, c_orb ) );}
				 	
				 }
			}
			
			if (info.ButtonID == 0) {
			for (int i=0; i<10; i++) {
				rc.Secondary[i] = null;
			}
			m_From.SendGump( new ClassGump( from ));}
			
		}
	}
	
	public class TertiaryGump : Gump
	{
		private const int FieldsPerPage = 14;

		private Mobile m_From;
		private Mobile m_Mobile;
			
		public TertiaryGump ( Mobile from, ClassOrb orb ) : base ( 20, 30 )
		{
			m_From = from;
			int h = 45;
			int w = 30;
			int m_move = 0;
			bool isUsed = false;
			ClassControl c_control = null;
			BonusPackOrb b_orb = null;
			RCCONTROL rc =  from.Backpack.FindItemByType( typeof( RCCONTROL ) ) as RCCONTROL;

			foreach (Item i in World.Items.Values) {
				if (i is ClassControl)
				c_control = i as ClassControl;
			}
			
			foreach (Item i in World.Items.Values) {
				if (i is BonusPackOrb){
				b_orb = i as BonusPackOrb;
				if (rc.BonusPack == b_orb.BPName) 
				break;
				}
			}

			AddPage ( 0 );
			AddBackground( 0, 0, 610, 420, 5054 );

			AddImageTiled( 180, 10, 290, 23, 0x52 );
			AddImageTiled( 181, 11, 288, 21, 0xBBC );

			AddLabel( 200, 11, 0, "Tertiary Skills ("+c_control.Tertiary_Cap+" Skill Cap) - "+rc.Third+" left" );


			for (int i=0; i < 54; i++) {
			
				isUsed = false;
				
				for (int j=0; j<10; j++) {
				if (orb.Primary_Skills[j] == from.Skills[i].Name)
				isUsed = true;
				}
				
				for (int k=0; k<10; k++) {
				if (orb.Restricted_Skills[k] == from.Skills[i].Name)
				isUsed = true;
				}
				
				if (b_orb != null){
				for (int l=0; l<5; l++) {
				if (b_orb.BPSkills[l] == from.Skills[i].Name)
				isUsed = true;
				}
				}
				
				for (int m=0; m<10; m++) {
				if (rc.Secondary[m] == from.Skills[i].Name)
				isUsed = true;
				}
				
				for (int n=0; n<10; n++) {
				if (rc.Tertiary[n] == from.Skills[i].Name)
				isUsed = true;
				}
				
				if (!isUsed){
				AddLabel( w, h, 0, from.Skills[i].Name );
				AddButton( w-19, h+1, 0x15E3, 0x15E7, i+1, GumpButtonType.Reply, 1 );
				
				h = h+20;
				m_move = m_move + 1;
				if (m_move == 15 || m_move == 30 || m_move == 45){
				w = w + 150;
				h = 45;}
				}
			
			}

			
			AddLabel( 20, 390, 0, "Right click to return to the Class List" );
			

		}
		public override void OnResponse( NetState sender, RelayInfo info )
		{
			Mobile from = sender.Mobile;
			ClassControl c_control = null;
			ClassOrb c_orb = null;
			bool isUsed = false;
			BonusPackOrb b_orb = null;
			RCCONTROL rc =  from.Backpack.FindItemByType( typeof( RCCONTROL ) ) as RCCONTROL;
			
			foreach (Item i in World.Items.Values) {
				if (i is ClassControl)
				c_control = i as ClassControl;
			}
			
			foreach (Item i in World.Items.Values) {
				if (i is ClassOrb){
				c_orb = i as ClassOrb;
				if (rc.P_Class == c_orb.ClassName)
				break;}
			}
			
			foreach (Item i in World.Items.Values) {
				if (i is BonusPackOrb){
				b_orb = i as BonusPackOrb;
				if (rc.BonusPack == b_orb.BPName) 
				break;
				}
			}
			
			for (int i=0; i < 54; i++) {
				 if ((i+1) == info.ButtonID){
				 	
				 	from.Skills[i].Cap = c_control.Tertiary_Cap;
				 	m_From.SendMessage( 6, from.Skills[i].Name+" Cap has been set to "+c_control.Tertiary_Cap );
				 	rc.Tertiary[c_orb.Amount_Tertiary-rc.Third] = from.Skills[i].Name;
				 	rc.Third -= 1;
				 	if (rc.Third > 0)
				 	m_From.SendGump( new TertiaryGump( from, c_orb ) );
				 	else {
					for (int o=0; o < 54; o++) {
			
						isUsed = false;
				
						for (int j=0; j<10; j++) {
						if (c_orb.Primary_Skills[j] == from.Skills[o].Name)
						isUsed = true;
						}
				
						for (int k=0; k<10; k++) {
						if (c_orb.Restricted_Skills[k] == from.Skills[o].Name)
						isUsed = true;
						}
				
						if (b_orb != null){
						for (int l=0; l<5; l++) {
						if (b_orb.BPSkills[l] == from.Skills[o].Name)
						isUsed = true;
						}
						}
				
						for (int m=0; m<10; m++) {
						if (rc.Secondary[m] == from.Skills[o].Name)
							isUsed = true;
						}
				
						for (int n=0; n<10; n++) {
						if (rc.Tertiary[n] == from.Skills[o].Name)
						isUsed = true;
						}
				
						if (!isUsed){
						from.Skills[o].Cap = c_control.Default_Cap;				
						}
			
					}
				 	m_From.SendGump( new FinalGump( from, c_orb ) );
				 	}
				 	
				 }
			}
			
			if (info.ButtonID == 0) {
			for (int i=0; i<10; i++) {
				rc.Tertiary[i] = null;
				rc.Secondary[i] = null;
			}
			m_From.SendGump( new ClassGump( from ));}
			
		}
	}
	
	public class FinalGump : Gump
	{
		private const int FieldsPerPage = 14;

		private Mobile m_From;
		private Mobile m_Mobile;

		public FinalGump ( Mobile from, ClassOrb orb ) : base ( 20, 30 )
		{
			m_From = from;
			int h = 194;
			RCCONTROL rc =  from.Backpack.FindItemByType( typeof( RCCONTROL ) ) as RCCONTROL;

			AddPage ( 0 );
			AddBackground( 0, 0, 335, ((orb.Amount_Secondary+orb.Amount_Tertiary)*25)+280, 5054 );

			AddImageTiled( 10, 10, 315, 23, 0x52 );
			AddImageTiled( 11, 11, 313, 21, 0xBBC );

			AddLabel( 85, 11, 0, "Summary of Character" );
			AddLabel( 30, 44, 0,  "You have chosen the following:" );
			AddLabel( 30, 74, 197,  "Race: "+ rc.Race);
			AddLabel( 30, 104, 197,  "Class: "+ rc.P_Class );
			if (rc.BonusPack != null)
			AddLabel( 30, 134, 197, "Bonus Pack: "+ rc.BonusPack );
			else
			h -= 65;
			
			AddLabel( 30, h, 0, "Secondary Skills:");
			h += 30;
			for (int i=0; i<10; i++) {
				if (rc.Secondary[i] != null){
				AddLabel( 30, h, 197, rc.Secondary[i]);
				h += 25;}
			}
			
			h += 10;
			
			AddLabel( 30, h, 0, "Tertiary Skills:" );
			h += 30;
			for (int j=0; j<10; j++) {
				if (rc.Tertiary[j] != null){
				AddLabel( 30, h, 197, rc.Tertiary[j]);
				h += 25;}
			}			

			h += 20;
			AddLabel( 30, h, 0, "Finish" );
			AddButton( 11, h+1, 0x15E3, 0x15E7, 1, GumpButtonType.Reply, 1 );;
			
		}

		public override void OnResponse( NetState sender, RelayInfo info )
		{
			Mobile from = sender.Mobile;
			ClassControl c_control = null;
			RaceControl r_control = null;
			RaceOrb r_orb = null;
			ClassOrb c_orb = null;
			RCCONTROL rc =  from.Backpack.FindItemByType( typeof( RCCONTROL ) ) as RCCONTROL;
			PlayerMobile pm = (PlayerMobile)from;
			RCChest chest = null;

			foreach (Item i in World.Items.Values) {
				if (i is ClassControl)
				c_control = i as ClassControl;
			}

			foreach (Item i in World.Items.Values) {
				if (i is RaceControl)
				r_control = i as RaceControl;
			}
			
			foreach (Item i in World.Items.Values) {
				if (i is RaceOrb){
				r_orb = i as RaceOrb;
				if (rc.Race == r_orb.RaceName) 
				break;
				}
			}
			
			foreach (Item i in World.Items.Values) {
				if (i is ClassOrb){
				c_orb = i as ClassOrb;
				if (rc.P_Class == c_orb.ClassName) 
				break;
				}
			}

			foreach (Item i in World.Items.Values) {
				if (i is RCChest)
				chest = i as RCChest;
			}
			
			if (info.ButtonID == 1 || info.ButtonID == 0) {
				if (pm.Young == false && chest.Young_F == true) {
				from.StatCap = c_control.Stat_Cap;
				from.Skills.Cap = 52000;
				
				if (from.Str > c_orb.Str_Cap)
					from.Str = c_orb.Str_Cap;
				if (from.Dex > c_orb.Dex_Cap)
					from.Dex = c_orb.Dex_Cap;
				if (from.Int > c_orb.Int_Cap)
					from.Int = c_orb.Int_Cap;
	
	   			 for (int i=0; i < 54; i++) {
				   if (from.Skills[i].Value > from.Skills[i].Cap) {
				       from.Skills[i].Base = from.Skills[i].Cap;
				   }
				 }
				
				foreach (Item i in World.Items.Values) {
					if (i is Bag && i.Name == rc.P_Class + " Restricted Armors") {
						rc.A_Bag = i as Bag;
						break;
					}
				}
				
				foreach (Item i in World.Items.Values) {
					if (i is Bag && i.Name == rc.P_Class + " Restricted Weapons") {
						rc.W_Bag = i as Bag;
						break;
					}
				}
				
				if (r_control.Race_Title) 
					from.Title = "the "+rc.Race;
				if (c_control.Class_Title)
					from.Title = "the "+rc.P_Class;
				if (r_control.Race_Title && c_control.Class_Title)
					from.Title = "the "+rc.Race + " " +rc.P_Class;
				rc.Active = true;
				if (r_control.Set_Location){
				from.Map = r_orb.Race_Map;
				from.Location = new Point3D(r_orb.Race_X,r_orb.Race_Y,r_orb.Race_Z);}
				}
				else {
				from.StatCap = c_control.Stat_Cap;
				from.Skills.Cap = 52000;
				from.Str = c_orb.Set_Str;
				from.Dex = c_orb.Set_Dex;
				from.Int = c_orb.Set_Int;
				
				if (from.Str > c_orb.Str_Cap)
					from.Str = c_orb.Str_Cap;
				if (from.Dex > c_orb.Dex_Cap)
					from.Dex = c_orb.Dex_Cap;
				if (from.Int > c_orb.Int_Cap)
					from.Int = c_orb.Int_Cap;
				
	   			 for (int i=0; i < 54; i++) {
					from.Skills[i].Base = 0;
				 }
				
				rc.Third = c_control.Amount_Start_Skills;
				
				foreach (Item i in World.Items.Values) {
					if (i is Bag && i.Name == rc.P_Class + " Restricted Armors") {
						rc.A_Bag = i as Bag;
						break;
					}
				}
				
				foreach (Item i in World.Items.Values) {
					if (i is Bag && i.Name == rc.P_Class + " Restricted Weapons") {
						rc.W_Bag = i as Bag;
						break;
					}
				}
				
				if (r_control.Race_Title) 
					from.Title = "the "+rc.Race;
				if (c_control.Class_Title)
					from.Title = "the "+rc.P_Class;
				if (r_control.Race_Title && c_control.Class_Title)
					from.Title = "the "+rc.Race + " " +rc.P_Class;
								
				m_From.SendGump( new SkillPickGump( from ) );
				}
			}

		}
	}

	public class SkillPickGump : Gump
	{
		private const int FieldsPerPage = 14;

		private Mobile m_From;
		private Mobile m_Mobile;
			
		public SkillPickGump ( Mobile from ) : base ( 20, 30 )
		{
			m_From = from;
			int h = 45;
			int w = 30;
			int m_move = 0;
			int bg = 0;
			ClassControl c_control = null;
			RCCONTROL rc =  from.Backpack.FindItemByType( typeof( RCCONTROL ) ) as RCCONTROL;

			foreach (Item i in World.Items.Values) {
				if (i is ClassControl)
				c_control = i as ClassControl;
			}

			for (int i=0; i < 54; i++) {

			if ((from.Skills[i].Cap > c_control.Start_Skills_Value+1) && (from.Skills[i].Value == 0)) 
				bg += 1;
			}

			AddPage ( 0 );
			AddBackground( 0, 0, 310, (bg*30)+25, 5054 );

			AddImageTiled( 10, 10, 290, 23, 0x52 );
			AddImageTiled( 11, 11, 288, 21, 0xBBC );

			AddLabel( 45, 11, 0, "Skill ("+c_control.Start_Skills_Value+" Skill per Choice) - "+rc.Third+" left" );

			for (int i=0; i < 54; i++) {

			if ((from.Skills[i].Cap > c_control.Start_Skills_Value+1) && (from.Skills[i].Value == 0)) {
			AddLabel( w, h, 0, from.Skills[i].Name );
			AddButton( w-19, h+1, 0x15E3, 0x15E7, i+1, GumpButtonType.Reply, 1 );
			
			h = h+20;
			m_move = m_move + 1;
			if (m_move == 15 || m_move == 30){
			w = w + 150;
			h = 45;}
			}
			
			}

			

		}

		public override void OnResponse( NetState sender, RelayInfo info )
		{
			Mobile from = sender.Mobile;
			ClassOrb c_orb = null;
			ClassControl c_control = null;
			RaceOrb r_orb = null;
			RaceControl r_control = null;
			BonusPackOrb b_orb = null;
			RCCONTROL rc =  from.Backpack.FindItemByType( typeof( RCCONTROL ) ) as RCCONTROL;

			foreach (Item i in World.Items.Values) {
				if (i is ClassControl)
				c_control = i as ClassControl;
			}
			
			foreach (Item i in World.Items.Values) {
				if (i is RaceControl)
				r_control = i as RaceControl;
			}
			
			foreach (Item i in World.Items.Values) {
				if (i is RaceOrb){
				r_orb = i as RaceOrb;
				if (rc.Race == r_orb.RaceName) 
				break;
				}
			}
			
			foreach (Item i in World.Items.Values) {
				if (i is ClassOrb){
				c_orb = i as ClassOrb;
				if (rc.P_Class == c_orb.ClassName) 
				break;
				}
			}
			
			foreach (Item i in World.Items.Values) {
				if (i is BonusPackOrb){
				b_orb = i as BonusPackOrb;
				if (rc.BonusPack == b_orb.BPName) 
				break;
				}
			}
			
			 for (int i=0; i < 54; i++) {
			 	 			 	 
				 if ((i+1) == info.ButtonID){

					from.Skills[i].Base = c_control.Start_Skills_Value;
				 	rc.Third = rc.Third - 1;
				 if (rc.Third > 0){
				 	from.SendGump( new SkillPickGump( from ) );
				 	break; 	}
				 else   {
					
					if (c_control.Equip_Players){
					
					
	      			  Container pouch = from.Backpack;
				  ArrayList finalitems = new ArrayList( pouch.Items );
				  ArrayList equipitems = new ArrayList( from.Items );
				  Container staff_bag = new Bag();

					if (from.AccessLevel == AccessLevel.Player){
						foreach (Item items in equipitems) { 
						if ((items.Layer != Layer.Bank) && (items.Layer != Layer.Backpack) && (items.Layer != Layer.Hair) && (items.Layer != Layer.Mount) && (items.Layer != Layer.FacialHair))
						{
							pouch.DropItem( items );
						}
	  			      }
	        
	   			     	finalitems = new ArrayList (pouch.Items);
					foreach (Item item in finalitems)
								
					{
							{
								if (item != rc)
								item.Delete();
							}
					}			
				}
				else	{
						foreach (Item items in equipitems) { 
						if ((items.Layer != Layer.Bank) && (items.Layer != Layer.Backpack) && (items.Layer != Layer.Hair) && (items.Layer != Layer.Mount) && (items.Layer != Layer.FacialHair))
						{
							pouch.DropItem( items );
						}
	     			   }
	     	   
	     			   finalitems = new ArrayList (pouch.Items);

					foreach (Item item in finalitems)
								
					{
							{
								if (item != rc)
								staff_bag.AddItem(item);
							}
					}
					from.AddToBackpack(staff_bag);
					}
					
					Bag c_bag = null;
					foreach (Item j in World.Items.Values) {
						if (j is Bag && j.Name == c_orb.ClassName+" Equip")
						c_bag = j as Bag;
					}
					
					ArrayList e_items = new ArrayList (c_bag.Items);
					
					foreach (Item k in e_items) {
						if (k.Layer != Layer.Invalid){
						
						
						
						Type t = k.GetType();

						ConstructorInfo[] cinfo = t.GetConstructors();

						foreach ( ConstructorInfo c in cinfo )
						{
							//if ( !c.IsDefined( typeof( ConstructableAttribute ), false ) ) continue;
		
							ParameterInfo[] paramInfo = c.GetParameters();
		
							if ( paramInfo.Length == 0 )
							{
								object[] objParams = new object[0];
		
								try 
								{
									for (int x=0;x<1;x++)
									{
										object o = c.Invoke( objParams );
		
										if ( o != null && o is Item )
										{
											Item newItem = (Item)o;
										
										
								PropertyInfo[] props = k.GetType().GetProperties(); 
		
								for ( int y = 0; y < props.Length; y++ ) 
								{ 
									try
									{
										if ( props[y].CanRead && props[y].CanWrite )
										{
											//Console.WriteLine( "Setting {0} = {1}", props[i].Name, props[i].GetValue( src, null ) );
											props[y].SetValue( newItem, props[y].GetValue( k, null ), null ); 
										}
									}
									catch
									{
										//Console.WriteLine( "Denied" );
									}
								}
											
											newItem.Parent = null;
											from.EquipItem (newItem);
											}
									}
								}
								catch
								{
									from.SendMessage( "Error!" );
									return;
								}
							}
						}	
						
						}
					}
					
					Bag c_bag2 = null;
					foreach (Item j in World.Items.Values) {
						if (j is Bag && j.Name == c_orb.ClassName+" Items")
						c_bag2 = j as Bag;
					}
					
					ArrayList e_items2 = new ArrayList (c_bag2.Items);
					
					foreach (Item k in e_items2) {
						
												
							Type t = k.GetType();
		
							ConstructorInfo[] cinfo = t.GetConstructors();
		
							foreach ( ConstructorInfo c in cinfo )
							{
								//if ( !c.IsDefined( typeof( ConstructableAttribute ), false ) ) continue;

								ParameterInfo[] paramInfo = c.GetParameters();
		
								if ( paramInfo.Length == 0 )
								{
									object[] objParams = new object[0];
			
									try 
									{
										for (int x=0;x<1;x++)
										{
											object o = c.Invoke( objParams );
			
											if ( o != null && o is Item )
											{
												Item newItem = (Item)o;
												
												
									PropertyInfo[] props = k.GetType().GetProperties(); 
			
									for ( int y = 0; y < props.Length; y++ ) 
									{ 
										try
										{
											if ( props[y].CanRead && props[y].CanWrite )
											{
												//Console.WriteLine( "Setting {0} = {1}", props[i].Name, props[i].GetValue( src, null ) );
												props[y].SetValue( newItem, props[y].GetValue( k, null ), null ); 
											}
										}
										catch
										{
										//Console.WriteLine( "Denied" );
										}
									}
												
												newItem.Parent = null;
												from.AddToBackpack (newItem);
											}
										}
									}
									catch
									{
										from.SendMessage( "Error!" );
										return;
									}
								}
							}	
								
					}
					
					if (rc.BonusPack != null) {
					Bag c_bag3 = null;
					foreach (Item j in World.Items.Values) {
						if (j is Bag && j.Name == b_orb.BPName+" Items")
						c_bag3 = j as Bag;
					}
					
					ArrayList e_items3 = new ArrayList (c_bag3.Items);
					
					foreach (Item k in e_items3) {
						
												
						Type t = k.GetType();

						ConstructorInfo[] cinfo = t.GetConstructors();

						foreach ( ConstructorInfo c in cinfo )
						{
							//if ( !c.IsDefined( typeof( ConstructableAttribute ), false ) ) continue;
		
							ParameterInfo[] paramInfo = c.GetParameters();
		
							if ( paramInfo.Length == 0 )
							{
								object[] objParams = new object[0];
		
								try 
								{
									for (int x=0;x<1;x++)
									{
										object o = c.Invoke( objParams );
		
										if ( o != null && o is Item )
										{
											Item newItem = (Item)o;
										
										
								PropertyInfo[] props = k.GetType().GetProperties(); 
		
								for ( int y = 0; y < props.Length; y++ ) 
								{ 
									try
									{
										if ( props[y].CanRead && props[y].CanWrite )
										{
											//Console.WriteLine( "Setting {0} = {1}", props[i].Name, props[i].GetValue( src, null ) );
											props[y].SetValue( newItem, props[y].GetValue( k, null ), null ); 
										}
									}
									catch
									{
										//Console.WriteLine( "Denied" );
									}
								}
											
											newItem.Parent = null;
											from.AddToBackpack (newItem);
											}
									}
								}
								catch
								{
									from.SendMessage( "Error!" );
									return;
								}
							}
						}	
						
			
					}	
					
					
					}
					
					
					
					Bag c_bag4 = null;
					foreach (Item j in World.Items.Values) {
						if (j is Bag && j.Name == r_orb.RaceName+" Items")
						c_bag4 = j as Bag;
					}
					
					ArrayList e_items4 = new ArrayList (c_bag4.Items);
					
					foreach (Item k in e_items4) {
						
												
						Type t = k.GetType();

						ConstructorInfo[] cinfo = t.GetConstructors();

						foreach ( ConstructorInfo c in cinfo )
						{
							//if ( !c.IsDefined( typeof( ConstructableAttribute ), false ) ) continue;
		
							ParameterInfo[] paramInfo = c.GetParameters();
		
							if ( paramInfo.Length == 0 )
							{
								object[] objParams = new object[0];
		
								try 
								{
									for (int x=0;x<1;x++)
									{
										object o = c.Invoke( objParams );
		
										if ( o != null && o is Item )
										{
											Item newItem = (Item)o;
										
										
								PropertyInfo[] props = k.GetType().GetProperties(); 
		
								for ( int y = 0; y < props.Length; y++ ) 
								{ 
									try
									{
										if ( props[y].CanRead && props[y].CanWrite )
										{
											//Console.WriteLine( "Setting {0} = {1}", props[i].Name, props[i].GetValue( src, null ) );
											props[y].SetValue( newItem, props[y].GetValue( k, null ), null ); 
										}
									}
									catch
									{
										//Console.WriteLine( "Denied" );
									}
								}
											
											newItem.Parent = null;
											from.AddToBackpack (newItem);
											}
									}
								}
								catch
								{
									from.SendMessage( "Error!" );
									return;
								}
							}
						}	
						
			
					}	
				
					
					
				}
				
					rc.Active = true;
					if (r_control.Set_Location){
					from.Map = r_orb.Race_Map;
					from.Location = new Point3D(r_orb.Race_X,r_orb.Race_Y,r_orb.Race_Z);}
				 	break;	}
			 	}
			  }
			  
			  if (info.ButtonID == 0) {
			  	m_From.SendGump( new SkillPickGump( from ) );}
		}
		
	}
	

}
 

Kin-Kran

Wanderer
I am having problems trying to recreate the crash. When items are placed in the tiem bag for the races the char that picks that race isnt recieving them,, i didnt see an option in the props for the races to set it from false to true.
 
Got another problem ;( it crashes on a new player logging in, i think it has something to do with your system lucid=/
No the crash is coming from this system. You just have it in my folder. Here are the fixes for the gumps. Try it out and let me know if it works. There is a chance it could have errors and can't test it cause I don't use this system I have my own race system in the works. Thanks.
 

Attachments

  • RaceGump.cs
    44.1 KB · Views: 20
Top