// Lootable Treasure Piles // a RunUO ver 1.0 Script // Written by David // last edited 4/28/06 /* Version 1.1; added MaxUses, fixed Serialize */ using System; using Server; using System.Collections; namespace Server.Items { #region TreasureLooter struct public struct TreasureLooter { public TreasureLooter( Mobile from ) { Looter = from; Time = DateTime.Now; } public Mobile Looter; public DateTime Time; } #endregion #region BaseTreasure class public class BaseTreasure : BaseAddon { private ArrayList Looters = new ArrayList(); private TreasureLooter m_Looter; private int m_usesCount; private TimeSpan m_LootWait = TimeSpan.FromHours( 18 ); private int m_MinAmount = 100; private int m_MaxAmount = 250; private int m_MaxUses = 0; // use zero for never decays private double m_GemChance = .15; public virtual TimeSpan LootWait { get { return m_LootWait; } set { m_LootWait = value; } } public virtual int MinAmount { get { return m_MinAmount; } set { m_MinAmount = value; } } public virtual int MaxAmount { get { return m_MaxAmount; } set { m_MaxAmount = value; } } public virtual int MaxUses { get { return m_MaxUses; } set { m_MaxUses = value; } } public virtual int UsesCount { get { return m_usesCount; } } public virtual double GemChance { get { return m_GemChance; } set { m_GemChance = value % 1; } } public BaseTreasure() : base() { } public virtual void OnLoot( Mobile from ) { DefragLooters(); if( !FindLooter( from ) ) { int g = Utility.RandomMinMax( m_MinAmount, m_MaxAmount ); from.AddToBackpack( new Gold( g ) ); if( Utility.RandomDouble() < GemChance ) { if( Utility.RandomBool() ) from.AddToBackpack( Loot.RandomGem() ); else from.AddToBackpack( Loot.RandomJewelry() ); from.SendMessage( "You retrieve {0} gold and a shiny bauble", g ); } else from.SendMessage( "You retrieve {0} gold", g ); Looters.Add( new TreasureLooter( from ) ); m_usesCount++; if( m_MaxUses > 0 && m_usesCount >= m_MaxUses ) { from.SendMessage( "You have recovered the last of the gold!" ); this.Delete(); } } else from.SendMessage( "You find nothing of value" ); } public bool FindLooter( Mobile from ) { bool rtn = false; if( Looters.Count == 0 ) return rtn; foreach( Object obj in Looters ) { if( obj is TreasureLooter ) { m_Looter = (TreasureLooter)obj; if( m_Looter.Looter == from ) { rtn = true; break; } } } return rtn; } public void DefragLooters() { if( Looters.Count == 0 ) return; for( int i = 0 ; i < Looters.Count ; i++ ) { try { if( Looters[i] is TreasureLooter ) { m_Looter = (TreasureLooter)Looters[i]; if( m_Looter.Time + m_LootWait < DateTime.Now || m_Looter.Looter == null ) { Looters.RemoveAt( i-- ); } } else { Looters.RemoveAt( i-- ); } } catch( Exception e ) { Console.Write( "BaseTreasure: " ); Console.WriteLine( e ); } } } public BaseTreasure( Serial serial ) : base( serial ) { } public override void Serialize( GenericWriter writer ) { base.Serialize( writer ); writer.Write( (int)1 ); writer.Write( m_LootWait ); writer.Write( m_GemChance ); writer.Write( m_MinAmount ); writer.Write( m_MaxAmount ); writer.Write( m_MaxUses ); writer.Write( m_usesCount ); } public override void Deserialize( GenericReader reader ) { base.Deserialize( reader ); int version = reader.ReadInt(); switch( version ) { case 1: { m_LootWait = reader.ReadTimeSpan(); m_GemChance = reader.ReadDouble(); m_MinAmount = reader.ReadInt(); m_MaxAmount = reader.ReadInt(); m_MaxUses = reader.ReadInt(); m_usesCount = reader.ReadInt(); break; } } } } #endregion #region TreasureComponent class public class TreasureComponent : AddonComponent { // Note: will crash if used in Addon other than BaseTreasure. [CommandProperty( AccessLevel.GameMaster )] public virtual TimeSpan LootWait { get { return ( (BaseTreasure)base.Addon ).LootWait; } set { ( (BaseTreasure)base.Addon ).LootWait = value; } } [CommandProperty( AccessLevel.GameMaster )] public virtual int MinAmount { get { return ( (BaseTreasure)base.Addon ).MinAmount; } set { ( (BaseTreasure)base.Addon ).MinAmount = value; } } [CommandProperty( AccessLevel.GameMaster )] public virtual int MaxAmount { get { return ( (BaseTreasure)base.Addon ).MaxAmount; } set { ( (BaseTreasure)base.Addon ).MaxAmount = value; } } [CommandProperty( AccessLevel.GameMaster )] public virtual int MaxUses { get { return ( (BaseTreasure)base.Addon ).MaxUses; } set { ( (BaseTreasure)base.Addon ).MaxUses = value; } } [CommandProperty( AccessLevel.GameMaster )] public virtual int UsesCount { get { return ( (BaseTreasure)base.Addon ).UsesCount; } } [CommandProperty( AccessLevel.GameMaster )] public virtual double GemChance { get { return ( (BaseTreasure)base.Addon ).GemChance; } set { ( (BaseTreasure)base.Addon ).GemChance = value; } } public TreasureComponent( int itemID ) : base( itemID ) { Name = "A Pile of Treasure"; } public override void OnDoubleClick( Mobile from ) { if( from.InRange( this, 1 ) ) { if( base.Addon is BaseTreasure ) ( (BaseTreasure)base.Addon ).OnLoot( from ); } } public TreasureComponent( Serial serial ) : base( serial ) { } public override void Serialize( GenericWriter writer ) { base.Serialize( writer ); writer.Write( (int)0 ); } public override void Deserialize( GenericReader reader ) { base.Deserialize( reader ); int version = reader.ReadInt(); } } #endregion #region TreasureEast class public class TreasureEast : BaseTreasure { [Constructable] public TreasureEast() { AddComponent( new TreasureComponent( 0x1b59 ), 0, 0, 0 ); AddComponent( new TreasureComponent( 0x1b5a ), 1, 0, 0 ); AddComponent( new TreasureComponent( 0x1b60 ), 0, 1, 0 ); } public TreasureEast( Serial serial ) : base( serial ) { } public override void Serialize( GenericWriter writer ) { base.Serialize( writer ); writer.Write( (int)0 ); } public override void Deserialize( GenericReader reader ) { base.Deserialize( reader ); int version = reader.ReadInt(); } } #endregion #region TreasureSouth class public class TreasureSouth : BaseTreasure { [Constructable] public TreasureSouth() { AddComponent( new TreasureComponent( 0x1b54 ), 0, 0, 0 ); AddComponent( new TreasureComponent( 0x1b42 ), 0, 0, 0 ); AddComponent( new TreasureComponent( 0x1b43 ), 1, 0, 0 ); AddComponent( new TreasureComponent( 0x1b44 ), 2, 0, 0 ); AddComponent( new TreasureComponent( 0x1b41 ), 0, 1, 0 ); AddComponent( new TreasureComponent( 0x1b40 ), 1, 1, 0 ); AddComponent( new TreasureComponent( 0x1b3f ), 2, 1, 0 ); } public TreasureSouth( Serial serial ) : base( serial ) { } public override void Serialize( GenericWriter writer ) { base.Serialize( writer ); writer.Write( (int)0 ); } public override void Deserialize( GenericReader reader ) { base.Deserialize( reader ); int version = reader.ReadInt(); } } #endregion #region TreasurePile class public class TreasurePile : BaseTreasure { [Constructable] public TreasurePile() { AddComponent( new TreasureComponent( 0x1b57 ), 0, 0, 0 ); AddComponent( new TreasureComponent( 0x1b58 ), 1, 0, 0 ); AddComponent( new TreasureComponent( 0x1b45 ), 2, 0, 0 ); AddComponent( new TreasureComponent( 0x1b5b ), 0, 1, 0 ); AddComponent( new TreasureComponent( 0x1b55 ), 1, 1, 0 ); } public TreasurePile( Serial serial ) : base( serial ) { } public override void Serialize( GenericWriter writer ) { base.Serialize( writer ); writer.Write( (int)0 ); } public override void Deserialize( GenericReader reader ) { base.Deserialize( reader ); int version = reader.ReadInt(); } } #endregion }