Omni

Member
got a problem with this script.. Although it complies perfectly fine without flagging any errors.

When i add the chest ingame it freezes my shard (not just client).

I can't seem to figure out why its doing it.

any help guys?

Code:
using Server;
using Server.Items;
using Server.Gumps;
using System;
using System.Collections;

namespace Server.Items
{
	
	[FlipableAttribute( 0xe41, 0xe40 )]
	public class PuzzleChest2 : Container
	{
		private bool m_Locked;
		private int m_Link, m_CColor, m_CPlace, m_Color1, m_Color2, m_Color3, m_Color4, m_Color5, m_NHint;
		private ArrayList m_Combo = new ArrayList();//For winning combo
		private ArrayList m_Hints = new ArrayList();//For Hints

		public ArrayList Combo // For correct puzzle combo
		{
			get { return m_Combo; }
		}

		public ArrayList Hints // For storing puzzle hints
		{
			get { return m_Hints; }
		}
		[CommandProperty( AccessLevel.GameMaster )]
		public bool Locked{ get{ return m_Locked; } set{ m_Locked = value; } }

		[CommandProperty( AccessLevel.GameMaster )]
		public int NHint{ get{ return m_NHint; } set{ m_NHint = value; } }

		[CommandProperty( AccessLevel.GameMaster )]
		public int CColor{ get{ return m_CColor; } set{ m_CColor = value; } }

		[CommandProperty( AccessLevel.GameMaster )]
		public int CPlace{ get{ return m_CPlace; } set{ m_CPlace = value; } }

		[CommandProperty( AccessLevel.GameMaster )]
		public int Color1{ get{ return m_Color1; } set{ m_Color1 = value; } }

		[CommandProperty( AccessLevel.GameMaster )]
		public int Color2{ get{ return m_Color2; } set{ m_Color2 = value; } }

		[CommandProperty( AccessLevel.GameMaster )]
		public int Color3{ get{ return m_Color3; } set{ m_Color3 = value; } }

		[CommandProperty( AccessLevel.GameMaster )]
		public int Color4{ get{ return m_Color4; } set{ m_Color4 = value; } }

		[CommandProperty( AccessLevel.GameMaster )]
		public int Color5{ get{ return m_Color5; } set{ m_Color5 = value; } }

		[CommandProperty( AccessLevel.GameMaster )]
		public int Link{ get{ return m_Link; } set{ m_Link = value; } }


		public override int DefaultGumpID{ get{ return 0x42; } }
		public override int DefaultDropSound{ get{ return 0x42; } }
		public override bool DisplaysContent{ get{ return false; } }

		public override Rectangle2D Bounds
		{
			get{ return new Rectangle2D( 20, 105, 150, 180 ); }
		}

		[Constructable]
		public PuzzleChest2() : base(0xe41)
		{
			Link = 0;
			Hue = 0x89E;
			Movable = false;
			Name = "metal chest";
			Locked = true;
			Color1 = 0;
			Color2 = 0;
			Color3 = 0;
			Color4 = 0;
			Color5 = 0;
			for (int i = 0; i < 5 ; i++)
				{
				switch (Utility.RandomMinMax(1, 8))
					{
					case 1: m_Combo.Add( 6249 ); break;
					case 2: m_Combo.Add( 6250 ); break;
					case 3: m_Combo.Add( 6251 ); break;
					case 4: m_Combo.Add( 6252 ); break;
					case 5: m_Combo.Add( 6253 ); break;
					case 6: m_Combo.Add( 6254 ); break;
					case 7: m_Combo.Add( 6255 ); break;
					case 8: m_Combo.Add( 6256 ); break;
					}
				}
			int hint1 = 0;
			int hint2 = 0;
			int hint3 = 0;
			while ( hint1 == hint2 || hint1 == hint3 || hint2 == hint3 )
				{
				hint1 = Utility.RandomMinMax( 1, 4 );
				hint2 = Utility.RandomMinMax( 1, 4 );
				hint3 = Utility.RandomMinMax( 1, 4 );
				}
			m_Hints.Add( m_Combo[hint1] );
			m_Hints.Add( m_Combo[hint2] );
			m_Hints.Add( m_Combo[hint3] );
			m_Hints.Add( m_Combo[0] );
			DropItem( new BagOfReagents( 50 ) );
			DropItem( new Gold( 650, 1000 ) );
        		switch ( Utility.Random( 7 ))
        		{
  		            case 0: DropItem( new DragonBall1() ); break;
      		      case 1: DropItem( new DragonBall2() ); break;
            		case 2: DropItem( new DragonBall3() ); break;
            		case 3: DropItem( new DragonBall4() ); break;
            		case 4: DropItem( new DragonBall5() ); break;
            		case 5: DropItem( new DragonBall6() ); break;
            		case 6: DropItem( new DragonBall7() ); break; 
        		}
			for (int i=0; i < Utility.RandomMinMax(5, 15); i++)
			{
  			Item gem = Loot.RandomGem();
  	 		Item gem2 = FindItemByType(gem.GetType());
  			if (gem2 != null )
  			{
      			  gem2.Amount++;
      			  gem.Delete();
  			}
  			else
      			  DropItem(gem);
			}
			PackMagicItems( 1, 5 );
			PackMagicItems( 1, 5, 0.50, 0.50);
			DropItem( new TreasureMap( Utility.RandomMinMax(1,3), Map ) );
			
		}

		public void PackMagicItems( int minLevel, int maxLevel )
		{
			PackMagicItems( minLevel, maxLevel, 0.30, 0.15 );
		}

		public void PackMagicItems( int minLevel, int maxLevel, double armorChance, double weaponChance )
		{
			if ( !PackArmor( minLevel, maxLevel, armorChance ) )
				PackWeapon( minLevel, maxLevel, weaponChance );
		}

		public bool PackWeapon( int minLevel, int maxLevel )
		{
			return PackWeapon( minLevel, maxLevel, 1.0 );
		}

		public static void Cap( ref int val, int min, int max )
		{
			if ( val < min )
				val = min;
			else if ( val > max )
				val = max;
		}

		public bool PackWeapon( int minLevel, int maxLevel, double chance )
		{
			if ( chance <= Utility.RandomDouble() )
				return false;

			Cap( ref minLevel, 0, 5 );
			Cap( ref maxLevel, 0, 5 );

			if ( Core.AOS )
			{
				Item item = Loot.RandomWeaponOrJewelry();

				if ( item == null )
					return false;

				int attributeCount, min, max;
				GetRandomAOSStats( minLevel, maxLevel, out attributeCount, out min, out max );

				if ( item is BaseWeapon )
					BaseRunicTool.ApplyAttributesTo( (BaseWeapon)item, attributeCount, min, max );
				else if ( item is BaseJewel )
					BaseRunicTool.ApplyAttributesTo( (BaseJewel)item, attributeCount, min, max );

				DropItem( item );
			}
			else
			{
				BaseWeapon weapon = Loot.RandomWeapon();

				if ( weapon == null )
					return false;

				if ( 0.05 > Utility.RandomDouble() )
					weapon.Slayer = SlayerName.Silver;

				weapon.DamageLevel = (WeaponDamageLevel)RandomMinMaxScaled( minLevel, maxLevel );
				weapon.AccuracyLevel = (WeaponAccuracyLevel)RandomMinMaxScaled( minLevel, maxLevel );
				weapon.DurabilityLevel = (WeaponDurabilityLevel)RandomMinMaxScaled( minLevel, maxLevel );

				DropItem( weapon );
			}

			return true;
		}

		public bool PackArmor( int minLevel, int maxLevel )
		{
			return PackArmor( minLevel, maxLevel, 1.0 );
		}

		public bool PackArmor( int minLevel, int maxLevel, double chance )
		{
			if ( chance <= Utility.RandomDouble() )
				return false;

			Cap( ref minLevel, 0, 5 );
			Cap( ref maxLevel, 0, 5 );

			if ( Core.AOS )
			{
				Item item = Loot.RandomArmorOrShieldOrJewelry();

				if ( item == null )
					return false;

				int attributeCount, min, max;
				GetRandomAOSStats( minLevel, maxLevel, out attributeCount, out min, out max );

				if ( item is BaseArmor )
					BaseRunicTool.ApplyAttributesTo( (BaseArmor)item, attributeCount, min, max );
				else if ( item is BaseJewel )
					BaseRunicTool.ApplyAttributesTo( (BaseJewel)item, attributeCount, min, max );

				DropItem( item );
			}
			else
			{
				BaseArmor armor = Loot.RandomArmorOrShield();

				if ( armor == null )
					return false;

				armor.ProtectionLevel = (ArmorProtectionLevel)RandomMinMaxScaled( minLevel, maxLevel );
				armor.Durability = (ArmorDurabilityLevel)RandomMinMaxScaled( minLevel, maxLevel );

				DropItem( armor );
			}

			return true;
		}

		public static void GetRandomAOSStats( int minLevel, int maxLevel, out int attributeCount, out int min, out int max )
		{
			int v = RandomMinMaxScaled( minLevel, maxLevel );

			if ( v >= 5 )
			{
				attributeCount = Utility.RandomMinMax( 2, 6 );
				min = 20; max = 70;
			}
			else if ( v == 4 )
			{
				attributeCount = Utility.RandomMinMax( 2, 4 );
				min = 20; max = 50;
			}
			else if ( v == 3 )
			{
				attributeCount = Utility.RandomMinMax( 2, 3 );
				min = 20; max = 40;
			}
			else if ( v == 2 )
			{
				attributeCount = Utility.RandomMinMax( 1, 2 );
				min = 10; max = 30;
			}
			else
			{
				attributeCount = 1;
				min = 10; max = 20;
			}
		}

		public static int RandomMinMaxScaled( int min, int max )
		{
			if ( min == max )
				return min;

			if ( min > max )
			{
				int hold = min;
				min = max;
				max = hold;
			}

			/* Example:
			 *    min: 1
			 *    max: 5
			 *  count: 5
			 *
			 * total = (5*5) + (4*4) + (3*3) + (2*2) + (1*1) = 25 + 16 + 9 + 4 + 1 = 55
			 *
			 * chance for min+0 : 25/55 : 45.45%
			 * chance for min+1 : 16/55 : 29.09%
			 * chance for min+2 :  9/55 : 16.36%
			 * chance for min+3 :  4/55 :  7.27%
			 * chance for min+4 :  1/55 :  1.81%
			 */

			int count = max - min + 1;
			int total = 0, toAdd = count;

			for ( int i = 0; i < count; ++i, --toAdd )
				total += toAdd*toAdd;

			int rand = Utility.Random( total );
			toAdd = count;

			int val = min;

			for ( int i = 0; i < count; ++i, --toAdd, ++val )
			{
				rand -= toAdd*toAdd;

				if ( rand < 0 )
					break;
			}

			return val;
		}

		public override void OnDoubleClick( Mobile from )
		{
			if ( m_Locked )
				{
				if (m_Link==0)
					{
					this.Link = from.Serial;
					new PuzzleTimer( this ).Start();
					}
				if ( m_Link != from.Serial )
					from.SendMessage( "Someone else is currently trying to solve it.", from );
				else
					{
					double skillvalue = from.Skills[SkillName.Lockpicking].Value;
					if ( skillvalue > 99.9 )
						this.NHint = 5;
					else if ( skillvalue > 89.9 )
						this.NHint = 4;
					else if ( skillvalue > 79.9 )
						this.NHint = 3;
					else if ( skillvalue > 69.9 )
						this.NHint = 2;
					else if ( skillvalue > 59.9 )
						this.NHint = 1;
					else
						this.NHint = 0;
					from.SendGump( new PuzzleChestGump( from, this, Color1, Color2, Color3, Color4, Color5 ) );
					}
				}
			else
				base.OnDoubleClick( from );
		}

		public virtual void StartRespawn( PuzzleChest2 pc )
		{
		new ChestLockTimer( pc ).Start();
		}

		private class PuzzleTimer : Timer
		{
			private PuzzleChest2 m_pc;
			
			public PuzzleTimer( PuzzleChest2 PC ) : base( TimeSpan.FromMinutes( 5.0 ) ) // How long you give player eclusive access to try and solve it
			{
				m_pc = PC;
			}

			protected override void OnTick()
			{
				PuzzleChest2 pc = m_pc;
				new ChestLockTimer( pc, 0 ).Start();
			}
		}

		private class ChestLockTimer : Timer
		{
			private PuzzleChest2 m_pc;
			public ChestLockTimer( PuzzleChest2 PC ) : this ( PC, 10.0 )
			{
			}
			public ChestLockTimer( PuzzleChest2 PC, double time ) : base( TimeSpan.FromMinutes( time ) ) //Every how often you want chest to respawn
			{
				m_pc = PC;				
			}

			protected override void OnTick()
			{
				PuzzleChest2 pc = m_pc;
				PuzzleChest2 pc1 = new PuzzleChest2();
				pc1.Location = pc.Location;
				pc1.Map = pc.Map;
				pc.Delete();
				pc1.Delete();
			}
		}


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

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

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

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

			int version = reader.ReadInt();
			new ChestLockTimer( this, 0 ).Start();
			
		}
	}
}
 
No crashes here. I've commented out some parts that I don't have on my server

The crash may be happening on the PuzzleChest2() constructor (you said it crashes when you add it ingame)
Check your DragonBall1~8 constructors, the freeze source can be these items. Try adding each one ingame
 
Generally when something freezes but doesn't crash it's symptomatic of an infinite-loop. Check all for, for-each, and while statements.
 

Active Shards

Donations

Total amount
$0.00
Goal
$1,000.00
Back