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!

[RunUO 2.0 SVN] Universal Storage Keys

nevar2006

Sorceror
thats true

I really didnt think about it that way, with it taking a chance of drawing all the wood. Thanks for the clarification.
 

GhostRiderGrey

Sorceror
Hi Fenn, I'm updating my installation of the Universal Keys with the latest and have an issue in the Extras.cs file. I do have the FS ATS pet system and have uncommented the #define FS_ATS_PETS_PRESENT line at the top of the file but it is throwing the following error
Code:
Errors:
 + Customs/[045] Fenns Universal Storage Keys/Extras/Extras.cs:
    CS0246: Line 166: The type or namespace name 'List' could not be found (are
you missing a using directive or an assembly reference?)
Scripts: One or more scripts failed to compile or no script files were found.
 - Press return to exit, or R to try again.

I'm using RC1 if that makes a difference.

*EDIT* If I comment out the #define FS_ATS_PETS_PRESENT I can get everything to compile fine.

Thanks!
GhostRiderGrey
 

Fenn

Wanderer
GhostRiderGrey;798955 said:
Code:
Errors:
 + Customs/[045] Fenns Universal Storage Keys/Extras/Extras.cs:
    CS0246: Line 166: The type or namespace name 'List' could not be found (are
you missing a using directive or an assembly reference?)
Scripts: One or more scripts failed to compile or no script files were found.
 - Press return to exit, or R to try again.

Ah, my mistake. I just cut/pasted code without testing.

At the top of Extras.cs, in the using definitions, include the following:

Code:
using System.Collections.Generic;

Then uncomment the #define line and try to compile. Let me know if that works for you, and I'll update my file to reflect this change.
 

Red_Satiin

Sorceror
Gardeners Trowel + Potion Key

We've been having a problem we just can't seem to figure out...

When Feeding plants from keys We are getting odd items returned... Two of us have been testing this at various times of the day. We both get the exact same thing returned in the same quantity..

Example:

Feed plant Water (From Key) - We get 4 Stacked Nightshade
Feed plant Strength Potion (From Key) - We get 4 Stacked Nightshade and an empty bottle.

This does not occur all the time nor is it always Nightshade.. Sometimes it's Ginseng, Iron Ingots, Platinum Ingots, Crystals, Leather... Pretty much any resource you can think of on the server. What is the same is what we get together.

If I'm feeding plants and he is feeding plants at the same time We get the same resource. Today we got:

4 Stacked Nightshade then at the same time it switched to 3 ginseng again at the same time it switched to 25 Iron Ingots Then over to leather...

We are unsure why it's doing this... Our only guess is that the keys are not leaving the expected item that the main plant gump is expecting.. But we are at a total loss...

Feeding Process: (Note it does not ALWAYS occur but we have never gone more then 3 days without it happening)

Garden Tool in Main pack or on Master Key (In main pack Or in sub bag. Doesn't seem to matter)
Open plant. Feed Water (Occasionaly get something weird.. not always..)
Feed Strength
Feed other potions it may need.
Close Plant

I seem to get the most resources over my other tester. We are not sure why but he feeds Strength at the end of his feeding process and i feed strength at the beginning.

This was tested with a Staff character and it worked even less often. Seems to work most often with a player character. We have not determined if it works on any specific tile. But what it returns seems to be linked with time or some sort of cycle as we both get the same items during the same times. Even though we are across the shard from each other.

Any help with this would be greatly appreciated.

Red.
 

GhostRiderGrey

Sorceror
Fenn, I have begun playing around with the Armory key, and wonder if an adjustment can be made to prevent the overlap that is happening in the weapon area between the first column (Item) and the 2nd column (Resource), as we have a lot of items that end up running "under" the resource text due to their length.

Thanks!
GhostRiderGrey
 

GhostRiderGrey

Sorceror
Fenn, apologies, but we have run into another issue. the PSKey (which holds power scrolls and stat cap scrolls) takes both just fine, but it will not release the stat scrolls. I tried looking at the ItemListEntries.cs but I don't see anything out of place.

Thanks,
GhostRiderGrey
 

prplbeast

Sorceror
GhostRiderGrey;807928 said:
Fenn, I have begun playing around with the Armory key, and wonder if an adjustment can be made to prevent the overlap that is happening in the weapon area between the first column (Item) and the 2nd column (Resource), as we have a lot of items that end up running "under" the resource text due to their length.

Thanks!
GhostRiderGrey


ok in Universal Storage Keys\Main Data Management find this script StashSortData.cs look around line 57.
it will look something like this
Code:
this.Add( new StashSortEntry( "Item", "best name", 0, [COLOR="Red"]100[/COLOR] ) );
change in red to match this one
Code:
this.Add( new StashSortEntry( "Item", "best name", 0, [COLOR="Red"]310[/COLOR] ) );

this will help you see whats in there with out the overlap
hope it helps you
 

GhostRiderGrey

Sorceror
Thanks for the reply prplbeast! Testing it now.

EDIT: Change works great!! I settled on 200 as my number.

Have you run into the problem with the stat scrolls not releasing from the PSKey?

GhostRiderGrey
 

prplbeast

Sorceror
i have not messed with those keys. as i use a stand that works from inside the players house, i have not had any probs with the stand.

I have uploaded the one i use if you open it there is a few others inside it that are commented out, just uncomment them to make those one useable or change them to what ever type of scrolls you would like held in the stand
 

Attachments

  • SpecialtyScrollBookStand.cs
    4.8 KB · Views: 44

GhostRiderGrey

Sorceror
Thanks prplbeast for sharing your script. I have players who currently have stuck stat scrolls so would like to get Fenn's key working if I can. :eek:

-GhostRiderGrey
 

nevar2006

Sorceror
GhostRiderGrey;808236 said:
Thanks prplbeast for sharing your script. I have players who currently have stuck stat scrolls so would like to get Fenn's key working if I can. :eek:

-GhostRiderGrey

What key are they using i dont see a Stock stat scroll or Ps key? maybe if you posted your script we could help ya better, I use the storage keys for everything on my server, except for the once mentioned above.I have been using the specialy scroll stand for awhile now.
 

GhostRiderGrey

Sorceror
Nevar2006, there was a stock key in Fenn's latest release called PSKey.cs that holds both powerscrolls and statscrolls. I can post the PSKey.cs here, but it references other files in his key system so one kinda needs to look at the whole Fenn Key package.

prplbeast, I see that you used stashentries for your stat scrolls instead of the listentries that Fenn used. If I made a new key (our used your script) that would work great. Due to the existing keys, I need to try and get the listentries version working. I will post what I think are the 2 relavent scripts below

PSKey.cs
Code:
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Solaris.ItemStore;							//for connection to resource store data objects
using Server.Engines.BulkOrders;

namespace Server.Items
{
	//item inherited from BaseResourceKey
	public class PSKey : BaseStoreKey
	{
		public override int DisplayColumns{ get{ return 1; } }
		
		public override List<StoreEntry> EntryStructure
		{
			get
			{
				List<StoreEntry> entry = base.EntryStructure;
				
				string[] skillnames = Enum.GetNames( typeof( SkillName ) );
			
				entry.Add( new ListEntry( typeof( PowerScroll ), typeof( PowerScrollListEntry ), "Power Scrolls" ) );
				entry.Add( new ListEntry( typeof( StatCapScroll ), typeof( StatCapScrollListEntry ), "Stat Scrolls" ) );
				
				return entry;
			}
		}
		
		
		
		[Constructable]
		public PSKey() : base( 1153 )
		{
			ItemID = 8793;
			Name = "Ultimate Power Scroll Book";
			LootType = LootType.Blessed;
		}
		
		
		
		//this loads properties specific to the store, like the gump label, and whether it's a dynamic storage device
		protected override ItemStore GenerateItemStore()
		{
			//load the basic store info
			ItemStore store = base.GenerateItemStore();

			//properties of this storage device
			store.Label = "PS Storage";
			
			store.Dynamic = false;
			store.OfferDeeds = false;
			return store;
		}
		
		//serial constructor
		public PSKey( Serial serial ) : base( serial )
		{
		}
		
		//events
		
		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );
			
			writer.Write( 0 );
		}
		
		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );
			
			int version = reader.ReadInt();
		}
	}



}

ItemListEntries.cs starting at line 1297
Code:
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Engines.Plants;
using Solaris.CliLocHandler;

namespace Solaris.ItemStore
{
	//this is the base class for item entries stored in an item list
	public class ItemListEntry : IComparable
	{
		//reference back to the ListEntry objects which holds this particular entry
		protected ListEntry _ListEntry;
		
		public virtual int GumpWidth{ get{ return 400; } }
		
		//basic storage stuff needed to store items within this item list entry
		protected Type _Type;
		
		//insured/loot properties of item
		protected LootType _LootType;
		protected bool _Insured;
		
		protected string _Name;
		
		//used for display purposes, to help differentiate between special entries
		protected int _Hue;
		
		//gump specific positioning of data is stored in this fancy ItemListEntryColumn for easy access from above
		protected List<ItemListEntryColumn> _Columns;
		
		
		public Type Type{ get{ return _Type; } }
		public string Name{ get{ return _Name; } }
		public int Hue{ get{ return _Hue; } }
		public LootType LootType{ get{ return _LootType; } }
		public bool Insured{ get{ return _Insured; } }
		
		//this is the (overridable) public accessor and generator for the column formatting for the gump
		public virtual List<ItemListEntryColumn> Columns
		{
			get
			{
				if( _Columns == null )
				{
					_Columns = new List<ItemListEntryColumn>();
					
					//here's where the columns are defined
					_Columns.Add( new ItemListEntryColumn( 0, "Name", _Name ) );
				}
				
				return _Columns;
			}
		}
		
		
		//this is used for the sorting, determine which column in Columns to sort by
		public static int SortIndex;
		
		//set to either -1 or 1
		public static int SortOrder;
		
		public int CompareTo( object obj )
		{
			if( !(obj is ItemListEntry ) )
			{
				return 0;	//cannot sort
			}
			
			ItemListEntry entry = (ItemListEntry)obj;
			
			//if the sort index is invalid
			if( Columns.Count <= SortIndex || SortIndex == -1 )
			{
				return 0;
			}
			
			//TODO: special case:  sort by hue if SortIndex = -1
			
			//null text can't be sorted
			if( this.Columns[ SortIndex ].Text == null || entry.Columns[ SortIndex ].Text == null )
			{
				return 0;
			}
			
			return this.Columns[ SortIndex ].Text.CompareTo( entry.Columns[ SortIndex ].Text ) * SortOrder;
		}
		
		
		
		
		public ItemListEntry( Item item ) : this( item, ( item.Name == null ? item.GetType().Name : item.Name ) )
		{
		}
		
		
		//constructor with default listing hue
		public ItemListEntry( Item item, string name ) : this( item, name, 1153 )
		{
		}
		
		//master constructor
		public ItemListEntry( Item item, string name, int hue )
		{
			
			_Type = item.GetType();
			_Name = name;
			_Hue = hue;
			_LootType = item.LootType;
			_Insured = item.Insured;
			
		}
		
		//clone constructor
		public ItemListEntry( ItemListEntry entry )
		{
			_Type = entry.Type;
			_Name = entry.Name;
			_Hue = entry.Hue;
			_LootType = entry.LootType;
			_Insured = entry.Insured;
			
		}
		
		//world load constructor
		public ItemListEntry( GenericReader reader )
		{
			Deserialize( reader );
		}
		
		
		//this generates an item from what is stored in the entry.  Note no exception handling
		public virtual Item GenerateItem()
		{
			Item item = (Item)Activator.CreateInstance( _Type );
			
			item.Name = _Name;
			item.LootType = _LootType;
			item.Insured = _Insured;
			
			return item;
			
			
		}
		
		
		//this checks if the item you're attempting to create with is proper.  The child classes define specifics for this
		public virtual bool AllGood( Item item )
		{
			return ( item != null );
		}
		
		//this is used to drive the cloning process - derived classes fire their associated clone constructor
		public virtual ItemListEntry Clone()
		{
			return new ItemListEntry( this );
			
		}

		
		
		public virtual void Serialize( GenericWriter writer )
		{
			writer.Write( 2 );
			
			writer.Write( (int)_LootType );
			writer.Write( _Insured );
			
			writer.Write( _Hue );
			
			writer.Write( _Type.Name );
			writer.Write( _Name );
			
			
			
		}
		
		public virtual void Deserialize( GenericReader reader )
		{
			int version = reader.ReadInt();
			
			switch( version )
			{
				case 2:
				{
					_LootType = (LootType)reader.ReadInt();
					_Insured = reader.ReadBool();
					goto case 1;
				}
				case 1:
				{
					_Hue = reader.ReadInt();
					goto case 0;
				}
				case 0:
				default:
				{
					_Type = ScriptCompiler.FindTypeByName( reader.ReadString() );
					_Name = reader.ReadString();
					break;
				}
			}
				
			
			if( version == 0 )
			{
				//default hue from previous version;
				_Hue = 1153;
			}
			
			
		}
		
		
		//this is used to remove namespace text from a type name
		public static string TrimNamespace( string typename )
		{
			string trimname = typename;
			
			while( trimname.IndexOf( "." ) > -1 )
			{
				trimname = trimname.Substring( trimname.IndexOf( "." ), trimname.Length - trimname.IndexOf( "." ) );
			}
			return trimname;
			
		}
		

		
	}//class ItemListEntry
	
	public class TreasureMapListEntry : ItemListEntry 
	{
		public override int GumpWidth{ get{ return 400; } }
		
		//treasure map specific data
		protected Point2D _ChestLocation;
		protected Map _ChestMap;
		protected Mobile _Decoder;
		protected int _Level;
		protected Rectangle2D _Bounds;
		
		public override List<ItemListEntryColumn> Columns
		{
			get
			{
				if( _Columns == null )
				{
					List<ItemListEntryColumn> columns = base.Columns;
					
					//add in specifics for this list type here
					columns.Add( new ItemListEntryColumn( 150, "Map", _ChestMap.ToString() ) );
					columns.Add( new ItemListEntryColumn( 240, "Decoded?", ( _Decoder == null ? "no" : "yes" ) ) );
					
					return columns;
				}
				
				return _Columns;
			}
		}
		
		//public accessors
		public Point2D ChestLocation{ get{ return _ChestLocation; } }
		public Map ChestMap{ get{ return _ChestMap; } }
		public Mobile Decoder{ get{ return _Decoder; } }
		public int Level{ get{ return _Level; } }
		public Rectangle2D Bounds{ get{ return _Bounds; } }
		
		//master constructor
		public TreasureMapListEntry( Item item ) : base ( item )
		{
			TreasureMap map = (TreasureMap)item;
			
			//fill in the name based on the level
			//TODO: find a better way to do this
			switch( map.Level )
			{
				case 0:
				{
					_Name = "Youthful";
					break;
				}
				case 1:
				{
					_Name = "Plainly";
					break;
				}
				case 2:
				{
					_Name = "Expertly";
					break;
				}
				case 3:
				{
					_Name = "Adeptly";
					break;
				}
				case 4:
				{
					_Name = "Cleverly";
					break;
				}
				case 5:
				{
					_Name = "Deviously";
					break;
				}
				case 6:
				{
					_Name = "Ingeniously";
					break;
				}
				
				
			}
			
			_ChestLocation = map.ChestLocation;
			_ChestMap = map.ChestMap;
			_Decoder = map.Decoder;
			_Level = map.Level;
			_Bounds = map.Bounds;
			
			
		}
		
		//world load constructor
		public TreasureMapListEntry( GenericReader reader ) : base( reader )
		{
		}
		
		//clone constructor
		public TreasureMapListEntry( TreasureMapListEntry entry ) : base( entry )
		{
			_ChestLocation = entry.ChestLocation;
			_ChestMap = entry.ChestMap;
			_Decoder = entry.Decoder;
			_Level = entry.Level;
			_Bounds = entry.Bounds;
			
			
		}
		
		//this generates an item from what is stored in the entry.  Note no exception handling
		public override Item GenerateItem()
		{
			TreasureMap map = (TreasureMap)Activator.CreateInstance( _Type, new object[]{ _Level, _ChestMap } );
			
			map.ChestLocation = _ChestLocation;
			
			//this is done to ensure the map gump displays properly
			map.Bounds = _Bounds;
			
			map.Decoder = _Decoder;
			
			
			//the map will have some bogus pin on it when it's first withdrawn.  First, remove the bogus pin
			map.ClearPins();
			
			//then add the proper pin
			map.AddWorldPin( _ChestLocation.X, _ChestLocation.Y );
			
			map.LootType = _LootType;
			map.Insured = _Insured;

			
			
			return map;
			
			
		}
		
		
		//this checks if the item you're attempting to create with is proper.  The child classes define specifics for this
		public override bool AllGood( Item item )
		{
			if( !base.AllGood( item ) )
			{
				return false;
			}
			
			if( !(item is TreasureMap ) )
			{
				return false;
			}
			
			TreasureMap map = (TreasureMap)item;
			
			//can't add completed maps
			return ( map.CompletedBy == null );
		}
		
		//this is used to drive the cloning process - derived classes fire their associated clone constructor
		public override ItemListEntry Clone()
		{
			return new TreasureMapListEntry( this );
			
		}
		
		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );
			
			writer.Write( 0 );

			writer.Write( _ChestLocation );
			writer.Write( _ChestMap );
			writer.Write( _Decoder );
			writer.Write( _Level );
			writer.Write( _Bounds );
		}
		
		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );
			
			int version = reader.ReadInt();
			
			_ChestLocation = reader.ReadPoint2D();
			_ChestMap = reader.ReadMap();
			_Decoder = reader.ReadMobile();
			_Level = reader.ReadInt();
			_Bounds = reader.ReadRect2D();
		}
		
		
	}
	
	public class SOSListEntry : ItemListEntry 
	{
		public override int GumpWidth{ get{ return 450; } }
		
		//SOS-specific data
		
		protected int _Level;
		protected int _MessageIndex;
		protected Map _TargetMap;
		protected Point3D _TargetLocation;
		
		public override List<ItemListEntryColumn> Columns
		{
			get
			{
				if( _Columns == null )
				{
					List<ItemListEntryColumn> columns = base.Columns;
					
					//add in specifics for this list type here
					columns.Add( new ItemListEntryColumn( 150, "Map", _TargetMap.ToString() ) );
					columns.Add( new ItemListEntryColumn( 240, "Location", GetCoordsText( _TargetLocation, _TargetMap ) ) );
					
					return columns;
				}
				
				return _Columns;
			}
		}
		
		//public accessors
		public int Level{ get{ return _Level; } }
		public int MessageIndex{ get{ return _MessageIndex; } }
		public Map TargetMap{ get{ return _TargetMap; } }
		public Point3D TargetLocation{ get{ return _TargetLocation; } }
		
		//this is copied right from the SOS gump code, used to display the location in sextant formatted coordinates
		public static string GetCoordsText( Point3D point, Map map )
		{
			int xLong = 0, yLat = 0;
			int xMins = 0, yMins = 0;
			bool xEast = false, ySouth = false;
			string fmt;

			if ( Sextant.Format( point, map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast, ref ySouth ) )
				fmt = String.Format( "{0}°{1}'{2},{3}°{4}'{5}", yLat, yMins, ySouth ? "S" : "N", xLong, xMins, xEast ? "E" : "W" );
			else
				fmt = "?????";
				
			return fmt;
		}
		
		//master constructor
		public SOSListEntry( Item item ) : base ( item )
		{
			SOS sos = (SOS)item;
			
			if( sos.IsAncient )
			{
				_Name = "Ancient SOS";
			}
			else
			{
				_Name = "SOS";
			}
				
			_Level = sos.Level;
			_MessageIndex = sos.MessageIndex;
			_TargetMap = sos.TargetMap;
			_TargetLocation = sos.TargetLocation;
		}
		
		//world load constructor
		public SOSListEntry( GenericReader reader ) : base( reader )
		{
		}
		
		//clone constructor
		public SOSListEntry( SOSListEntry entry ) : base( entry )
		{
			_Level = entry.Level;
			_MessageIndex = entry.MessageIndex;
			_TargetMap = entry.TargetMap;
			_TargetLocation = entry.TargetLocation;
		}
		
		//this generates an item from what is stored in the entry.  Note no exception handling
		public override Item GenerateItem()
		{
			SOS sos = new SOS( _TargetMap, _Level );
			
			sos.TargetLocation = _TargetLocation;
			sos.MessageIndex = _MessageIndex;
			
			sos.LootType = _LootType;
			sos.Insured = _Insured;

			
			return sos;
		}
		
		
		//this checks if the item you're attempting to create with is proper.  The child classes define specifics for this
		public override bool AllGood( Item item )
		{
			if( !base.AllGood( item ) )
			{
				return false;
			}
			
			if( !( item is SOS ) )
			{
				return false;
			}
			
			return ( true );
		}
		
		//this is used to drive the cloning process - derived classes fire their associated clone constructor
		public override ItemListEntry Clone()
		{
			return new SOSListEntry( this );
			
		}
		
		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );
			
			writer.Write( 0 );

			writer.Write( _Level );
			writer.Write( _MessageIndex );
			writer.Write( _TargetMap );
			writer.Write( _TargetLocation );
			
			
		}
		
		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );
			
			int version = reader.ReadInt();
			
			_Level = reader.ReadInt();
			_MessageIndex = reader.ReadInt();
			_TargetMap = reader.ReadMap();
			_TargetLocation = reader.ReadPoint3D();
		}
		
		
	}	

	public class SpecialFishingNetListEntry : ItemListEntry 
	{
		public override int GumpWidth{ get{ return 400; } }
		
		public override List<ItemListEntryColumn> Columns
		{
			get
			{
				if( _Columns == null )
				{
					List<ItemListEntryColumn> columns = base.Columns;
					
					//add in specifics for this list type here
					//no special listing for fishing nets
					
					return columns;
				}
				
				return _Columns;
			}
		}
		
		//master constructor, use the net hue to hue the entry
		public SpecialFishingNetListEntry( Item item ) : base ( item, item.GetType().Name, item.Hue - 1 )
		{
		}
		
		//world load constructor
		public SpecialFishingNetListEntry( GenericReader reader ) : base( reader )
		{
		}
		
		//clone constructor
		public SpecialFishingNetListEntry( SpecialFishingNetListEntry entry ) : base( entry )
		{
		}
		
		//this generates an item from what is stored in the entry.  Note no exception handling
		public override Item GenerateItem()
		{
			//this allows for derived classes of fishing net to fit into this entry.
			SpecialFishingNet net = (SpecialFishingNet)Activator.CreateInstance( _Type );
			
			//note: gump hue display is shifted by 1 for some crazy reason
			net.Hue = _Hue + 1;
			
			net.LootType = _LootType;
			net.Insured = _Insured;

			
			return net;
		}
		
		
		//this checks if the item you're attempting to create with is proper.  The child classes define specifics for this
		public override bool AllGood( Item item )
		{
			if( !base.AllGood( item ) )
			{
				return false;
			}
			
			//TODO: move this to base class, since the _Type is specified in ListEntry?
			if( !( item is SpecialFishingNet ) )
			{
				return false;
			}
			
			return true;
		}
		
		//this is used to drive the cloning process - derived classes fire their associated clone constructor
		public override ItemListEntry Clone()
		{
			return new SpecialFishingNetListEntry( this );
			
		}
		
		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );
			
			writer.Write( 0 );
		}
		
		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );
			
			int version = reader.ReadInt();
		}
		
		
	}	

	public class InstrumentListEntry : ItemListEntry 
	{
		public override int GumpWidth{ get{ return 750; } }
		
		protected InstrumentQuality _Quality;
		protected int _UsesRemaining;
		protected SlayerName _Slayer;
		protected SlayerName _Slayer2;
		protected Mobile _Crafter;
		
		public override List<ItemListEntryColumn> Columns
		{
			get
			{
				if( _Columns == null )
				{
					List<ItemListEntryColumn> columns = base.Columns;
					
					//add in specifics for this list type here
					_Columns.Add( new ItemListEntryColumn( 100, "Quality", _Quality.ToString() ) );
					_Columns.Add( new ItemListEntryColumn( 200, "Uses", _UsesRemaining.ToString() ) );
					_Columns.Add( new ItemListEntryColumn( 300, "Slayer 1", _Slayer.ToString() ) );
					_Columns.Add( new ItemListEntryColumn( 450, "Slayer 2", _Slayer2.ToString() ) );
					_Columns.Add( new ItemListEntryColumn( 600, "Crafter", _Crafter != null ? _Crafter.Name : "-none-" ) );
					
					return columns;
				}
				
				return _Columns;
			}
		}
		
		//public accessors
		public InstrumentQuality Quality{ get{ return _Quality;} }
		public int UsesRemaining{ get{ return _UsesRemaining;} }
		public SlayerName Slayer{ get{ return _Slayer;} }
		public SlayerName Slayer2{ get{ return _Slayer2;} }
		public Mobile Crafter{ get{ return _Crafter; } }
		
		//master constructor, use the net hue to hue the entry
		public InstrumentListEntry( Item item ) : base ( item )
		{
			_Name = TrimNamespace( item.GetType().Name );			
			
			BaseInstrument instrument = (BaseInstrument)item;
			
			_Quality = instrument.Quality;
			_UsesRemaining = instrument.UsesRemaining;
			_Slayer = instrument.Slayer;
			_Slayer2 = instrument.Slayer2;
			_Crafter = instrument.Crafter;
			
		}
		
		//world load constructor
		public InstrumentListEntry( GenericReader reader ) : base( reader )
		{
		}
		
		//clone constructor
		public InstrumentListEntry( InstrumentListEntry entry ) : base( entry )
		{
			_Quality = entry.Quality;
			_UsesRemaining = entry.UsesRemaining;
			_Slayer = entry.Slayer;
			_Slayer2 = entry.Slayer2;
			_Crafter = entry.Crafter;
		}
		
		//this generates an item from what is stored in the entry.  Note no exception handling
		public override Item GenerateItem()
		{
			BaseInstrument instrument = (BaseInstrument)Activator.CreateInstance( _Type );
			
			instrument.Quality = _Quality;
			instrument.UsesRemaining = _UsesRemaining;
			instrument.Slayer = _Slayer;
			instrument.Slayer2 = _Slayer2;
			instrument.Crafter = _Crafter;
			
			instrument.LootType = _LootType;
			instrument.Insured = _Insured;

			
			return instrument;
		}
		
		
		//this checks if the item you're attempting to create with is proper.  The child classes define specifics for this
		public override bool AllGood( Item item )
		{
			if( !base.AllGood( item ) )
			{
				return false;
			}
			
			//TODO: move this to base class, since the _Type is specified in ListEntry?
			if( !( item is BaseInstrument ) )
			{
				return false;
			}
			
			return true;
		}
		
		//this is used to drive the cloning process - derived classes fire their associated clone constructor
		public override ItemListEntry Clone()
		{
			return new InstrumentListEntry( this );
			
		}
		
		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );
			
			writer.Write( 0 );
			
			writer.Write( (int)_Quality );
			writer.Write( _UsesRemaining );
			writer.Write( (int)_Slayer );
			writer.Write( (int)_Slayer2 );
			writer.Write( _Crafter );
		}
		
		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );
			
			int version = reader.ReadInt();
			
			_Quality = (InstrumentQuality)reader.ReadInt();
			_UsesRemaining = reader.ReadInt();
			_Slayer = (SlayerName)reader.ReadInt();
			_Slayer2 = (SlayerName)reader.ReadInt();
			_Crafter = reader.ReadMobile();
		}
		
		
	}
	
	
	
	public class SeedListEntry : ItemListEntry 
	{
		public override int GumpWidth{ get{ return 500; } }
		
		
		protected PlantType _PlantType;
		protected PlantHue _PlantHue;
		protected bool _ShowType;
		
		public override List<ItemListEntryColumn> Columns
		{
			get
			{
				if( _Columns == null )
				{
					List<ItemListEntryColumn> columns = base.Columns;
					
					//add in specifics for this list type here
					
					//TODO: find some way of using the PlantHueInfo cliloc values
					_Columns.Add( new ItemListEntryColumn( 250, "Color", _PlantHue.ToString() ) );
					
					PlantHueInfo hueinfo = PlantHueInfo.GetInfo( _PlantHue );
					_Columns.Add( new ItemListEntryColumn( 350, "Bright?", hueinfo.IsBright() ? "yes" : "no" ) );
					
					return columns;
				}
				
				return _Columns;
			}
		}
		
		//public accessors
		public PlantType PlantType{ get{ return _PlantType; } }
		public PlantHue PlantHue{ get{ return _PlantHue; } }
		public bool ShowType{ get{ return _ShowType; } }
		
		//master constructor
		public SeedListEntry( Item item ) : base ( item )
		{
			
			
			Seed seed = (Seed)item;
			
			_PlantType = seed.PlantType;
			_PlantHue = seed.PlantHue;
			_ShowType = seed.ShowType;
			
			//TODO: find a way to using the PlantTypeInfo cliloc values
			PlantHueInfo hueInfo = PlantHueInfo.GetInfo( seed.PlantHue );
			PlantTypeInfo typeInfo = PlantTypeInfo.GetInfo( seed.PlantType );
			
				
			_Name = CliLoc.LocToString( hueInfo.IsBright() ? 1061918 : 1061917, String.Concat( "#", hueInfo.Name.ToString(), "\t#", typeInfo.Name.ToString() ) ); // [bright] ~1_COLOR~ ~2_TYPE~ seed
			//_PlantType.ToString();
		}
		
		//world load constructor
		public SeedListEntry( GenericReader reader ) : base( reader )
		{
		}
		
		//clone constructor
		public SeedListEntry( SeedListEntry entry ) : base( entry )
		{
			_PlantType = entry.PlantType;
			_PlantHue = entry.PlantHue;
			_ShowType = entry.ShowType;
		}
		
		//this generates an item from what is stored in the entry.  Note no exception handling
		public override Item GenerateItem()
		{
			//awesome constructor!
			Seed seed = new Seed( _PlantType, _PlantHue, _ShowType );
			
			seed.LootType = _LootType;
			seed.Insured = _Insured;

			
			return seed;
		}
		
		
		//this checks if the item you're attempting to create with is proper.  The child classes define specifics for this
		public override bool AllGood( Item item )
		{
			if( !base.AllGood( item ) )
			{
				return false;
			}
			
			//TODO: move this to base class, since the _Type is specified in ListEntry?
			if( !( item is Seed ) )
			{
				return false;
			}
			
			return true;
		}
		
		//this is used to drive the cloning process - derived classes fire their associated clone constructor
		public override ItemListEntry Clone()
		{
			return new SeedListEntry( this );
			
		}
		
		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );
			
			writer.Write( 0 );
			
			writer.Write( (int)_PlantType );
			writer.Write( (int)_PlantHue );
			writer.Write( _ShowType );
		}
		
		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );
			
			int version = reader.ReadInt();
			
			_PlantType = (PlantType)reader.ReadInt();
			_PlantHue = (PlantHue)reader.ReadInt();
			_ShowType = reader.ReadBool();
		}
		
		
	}
	
	public class RepairDeedListEntry : ItemListEntry 
	{
		protected RepairDeed.RepairSkillType _RepairSkillType;
		protected double _Level;
		protected Mobile _Crafter;
		
		public override List<ItemListEntryColumn> Columns
		{
			get
			{
				if( _Columns == null )
				{
					List<ItemListEntryColumn> columns = base.Columns;
					
					//add in specifics for this list type here
					
					_Columns.Add( new ItemListEntryColumn( 150, "Level", _Level.ToString() ) );
					
					_Columns.Add( new ItemListEntryColumn( 250, "Crafter", _Crafter == null ? "-null-" : _Crafter.Name ) );
					
					return columns;
				}
				
				return _Columns;
			}
		}
		
		//public accessors
		public RepairDeed.RepairSkillType RepairSkillType{ get{ return _RepairSkillType; } }
		public double Level{ get{ return _Level; } }
		public Mobile Crafter{ get{ return _Crafter; } }
		
		//master constructor
		public RepairDeedListEntry( Item item ) : base ( item )
		{
			
			
			RepairDeed deed = (RepairDeed)item;
			
			_Name = deed.RepairSkill.ToString();
			_RepairSkillType = deed.RepairSkill;
			_Level = deed.SkillLevel;
			_Crafter = deed.Crafter;
		}
		
		//world load constructor
		public RepairDeedListEntry( GenericReader reader ) : base( reader )
		{
		}
		
		//clone constructor
		public RepairDeedListEntry( RepairDeedListEntry entry ) : base( entry )
		{
			_RepairSkillType = entry.RepairSkillType;
			_Level = entry.Level;
			_Crafter = entry.Crafter;
		}
		
		//this generates an item from what is stored in the entry.  Note no exception handling
		public override Item GenerateItem()
		{
			//awesome constructor!
			RepairDeed deed = new RepairDeed( _RepairSkillType, _Level, _Crafter );
			
			deed.LootType = _LootType;
			deed.Insured = _Insured;

			
			return deed;
		}
		
		
		//this checks if the item you're attempting to create with is proper.  The child classes define specifics for this
		public override bool AllGood( Item item )
		{
			if( !base.AllGood( item ) )
			{
				return false;
			}
			
			//TODO: move this to base class, since the _Type is specified in ListEntry?
			if( !( item is RepairDeed ) )
			{
				return false;
			}
			
			return true;
		}
		
		//this is used to drive the cloning process - derived classes fire their associated clone constructor
		public override ItemListEntry Clone()
		{
			return new RepairDeedListEntry( this );
			
		}
		
		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );
			
			writer.Write( 0 );
			
			writer.Write( (int)_RepairSkillType );
			writer.Write( _Level );
			writer.Write( _Crafter );
		}
		
		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );
			
			int version = reader.ReadInt();
			
			_RepairSkillType = (RepairDeed.RepairSkillType)reader.ReadInt();
			_Level = reader.ReadDouble();
			_Crafter = reader.ReadMobile();
		}
		
		
	}		
	
	//stores addon deeds.   WARNING: what about addon deeds that need some constructor data?
	public class BaseAddonDeedListEntry : ItemListEntry 
	{
		public override int GumpWidth{ get{ return 400; } }
		
		public override List<ItemListEntryColumn> Columns
		{
			get
			{
				if( _Columns == null )
				{
					List<ItemListEntryColumn> columns = base.Columns;
					
					//add in specifics for this list type here
					
					
					return columns;
				}
				
				return _Columns;
			}
		}
		
		//master constructor, use the addon deed class name, and hue
		public BaseAddonDeedListEntry( Item item ) : base ( item, item.GetType().Name, item.Hue - 1 )
		{
		}
		
		//world load constructor
		public BaseAddonDeedListEntry( GenericReader reader ) : base( reader )
		{
		}
		
		//clone constructor
		public BaseAddonDeedListEntry( BaseAddonDeedListEntry entry ) : base( entry )
		{
		}
		
		//this generates an item from what is stored in the entry.  Note no exception handling
		public override Item GenerateItem()
		{
			//this allows for inherited classes of addon deeds to fit into this entry.
			//WARNING:  what if the addon deed carries more info, or has a constructor that requires parameters?
			BaseAddonDeed deed = (BaseAddonDeed)Activator.CreateInstance( _Type );
			
			//note: gump hue display is shifted by 1 for some crazy reason
			deed.Hue = _Hue + 1;
			
			deed.LootType = _LootType;
			deed.Insured = _Insured;
			
			return deed;
		}
		
		
		//this checks if the item you're attempting to create with is proper.  The child classes define specifics for this
		public override bool AllGood( Item item )
		{
			if( !base.AllGood( item ) )
			{
				return false;
			}
			
			//TODO: move this to base class, since the _Type is specified in ListEntry?
			if( !( item is BaseAddonDeed ) )
			{
				return false;
			}
			
			//test if the deed being added can be constructed with a zero parameter constructor
			try
			{
				BaseAddonDeed deed = (BaseAddonDeed)Activator.CreateInstance( item.GetType() );
				
				//if it constructs fine, then delete it
				deed.Delete();
			}
			catch
			{
				//this catch hits if the deed does not have a zero parameter constructor, and would have otherwise crashed the shard
				return false;
			}
			
			return true;
		}
		
		//this is used to drive the cloning process - derived classes fire their associated clone constructor
		public override ItemListEntry Clone()
		{
			return new BaseAddonDeedListEntry( this );
			
		}
		
		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );
			
			writer.Write( 0 );
		}
		
		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );
			
			int version = reader.ReadInt();
		}
		
		
	}
	
	
	//stores power scrolls
	public class PowerScrollListEntry : ItemListEntry 
	{
		public override int GumpWidth{ get{ return 400; } }
		
		protected SkillName _Skill;
		protected double _Value;
		
		public SkillName Skill{ get{ return _Skill; } }
		public double Value{ get{ return _Value; } }
		
		
		public override List<ItemListEntryColumn> Columns
		{
			get
			{
				if( _Columns == null )
				{
					List<ItemListEntryColumn> columns = base.Columns;
					
					_Columns.Add( new ItemListEntryColumn( 250, "Value", _Value.ToString() ) );

					return columns;
				}
				
				return _Columns;
			}
		}
		
		//master constructor, use the addon deed class name, and hue
		public PowerScrollListEntry( Item item ) : base ( item, ((PowerScroll)item).Skill.ToString(), item.Hue - 1 )
		{
			PowerScroll scroll = (PowerScroll)item;
			
			_Skill = scroll.Skill;
			_Value = scroll.Value;
		}
		
		//world load constructor
		public PowerScrollListEntry( GenericReader reader ) : base( reader )
		{
		}
		
		//clone constructor
		public PowerScrollListEntry( PowerScrollListEntry entry ) : base( entry )
		{
			_Skill = entry.Skill;
			_Value = entry.Value;
		}
		
		//this generates an item from what is stored in the entry.  Note no exception handling
		public override Item GenerateItem()
		{
			//this allows for inherited classes of addon deeds to fit into this entry.
			PowerScroll scroll = (PowerScroll)Activator.CreateInstance( _Type, new object[]{ _Skill, _Value } );
			
			return scroll;
		}
		
		
		//this checks if the item you're attempting to create with is proper.  The child classes define specifics for this
		public override bool AllGood( Item item )
		{
			if( !base.AllGood( item ) )
			{
				return false;
			}
			
			//TODO: move this to base class, since the _Type is specified in ListEntry?
			if( !( item is PowerScroll ) )
			{
				return false;
			}
			
			return true;
		}
		
		//this is used to drive the cloning process - derived classes fire their associated clone constructor
		public override ItemListEntry Clone()
		{
			return new PowerScrollListEntry( this );
			
		}
		
		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );
			
			writer.Write( 0 );
			writer.Write( (int)_Skill );
			writer.Write( _Value );
		}
		
		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );
			
			int version = reader.ReadInt();
			
			_Skill = (SkillName)reader.ReadInt();
			_Value = reader.ReadDouble();
		}
		
		
	}
	


	
	//stores stat scrolls
	public class StatCapScrollListEntry : ItemListEntry 
	{
		public override int GumpWidth{ get{ return 400; } }
		
		protected double _Value;
		public double Value{ get{ return _Value; } }
		
		
		public override List<ItemListEntryColumn> Columns
		{
			get
			{
				if( _Columns == null )
				{
					List<ItemListEntryColumn> columns = base.Columns;
					
					_Columns.Add( new ItemListEntryColumn( 250, "Value", _Value.ToString() ) );

					return columns;
				}
				
				return _Columns;
			}
		}
		
		//master constructor, use the addon deed class name, and hue
		public StatCapScrollListEntry( Item item ) : base ( item, "Scroll of Power", item.Hue - 1 )
		{
			_Value = ((StatCapScroll)item).Value;
		}
		
		//world load constructor
		public StatCapScrollListEntry( GenericReader reader ) : base( reader )
		{
		}
		
		//clone constructor
		public StatCapScrollListEntry( StatCapScrollListEntry entry ) : base( entry )
		{
			_Value = entry.Value;
		}
		
		//this generates an item from what is stored in the entry.  Note no exception handling
		public override Item GenerateItem()
		{
			//this allows for inherited classes of addon deeds to fit into this entry.
			StatCapScroll scroll = (StatCapScroll)Activator.CreateInstance( _Type, new object[]{ _Value } );
			
			return scroll;
		}
		
		
		//this checks if the item you're attempting to create with is proper.  The child classes define specifics for this
		public override bool AllGood( Item item )
		{
			if( !base.AllGood( item ) )
			{
				return false;
			}
			
			//TODO: move this to base class, since the _Type is specified in ListEntry?
			if( !( item is StatCapScroll ) )
			{
				return false;
			}
			
			return true;
		}
		
		//this is used to drive the cloning process - derived classes fire their associated clone constructor
		public override ItemListEntry Clone()
		{
			return new StatCapScrollListEntry( this );
			
		}
		
		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );
			
			writer.Write( 0 );
			writer.Write( _Value );
		}
		
		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );
			
			int version = reader.ReadInt();
			
			_Value = reader.ReadDouble();
		}
	}



	//this data structure is useful when arranging gump display columns
	public class ItemListEntryColumn
	{
		int _X;
		string _Header;		//header listed at the top of the column
		string _Text;		//the text for this particular entry
		
		
		public int X{ get{ return _X; } }
		public int Width;
		
		public string Header{ get{ return _Header; }}
		public string Text{ get{ return _Text; } }
		
		public ItemListEntryColumn( int x, string header, string text )
		{
			_X = x;
			_Header = header;
			_Text = text;
		}
	}
}


Thanks!
GhostRiderGrey
 

coyan

Sorceror
I really love this entire system, and have been able to modify it for my own server... I just today got the scroll stand, as I have been looking for a way to store the enhancement deeds that I have on my server.. This works perfectly except one thing...

I wonder is there a way that the deeds can be stacked in the list if they are the same?? instead of them just listing 20 of the same scroll, can they stack in the list?

If possible, please let me know.. thanks..
coy...
 

prplbeast

Sorceror
was wonder if anyone has got the custom bods (tinker ,carp & Fletcher) i made all the mods needed to get them into the bod keys & the Fletcher & Carp ones will come out but the tinker ones wont.

Code:
  #region Custom CF Bods
    public class SmallCFBODListEntry : ItemListEntry
    {
        public override int GumpWidth { get { return 650; } }

        //generic bod-specific data
        protected int _AmountCur, _AmountMax;
        protected Type _BODFillType;				//the item to go into the BOD, different from the BOD type
        protected int _Number;
        protected int _Graphic;
        protected bool _RequireExceptional;
        protected BulkMaterialType _Material;

        public override List<ItemListEntryColumn> Columns
        {
            get
            {
                if (_Columns == null)
                {
                    //NOTE: the default name is overridden here completely
                    _Columns = new List<ItemListEntryColumn>();

                    //add in specifics for this list type here
                    _Columns.Add(new ItemListEntryColumn(0, "Item Type", CliLoc.GetName(_BODFillType)));
                    _Columns.Add(new ItemListEntryColumn(150, "Amount", _AmountCur.ToString() + "/" + _AmountMax.ToString()));
                    _Columns.Add(new ItemListEntryColumn(250, "Exceptional?", (_RequireExceptional ? "yes" : "no")));
                    _Columns.Add(new ItemListEntryColumn(350, "Resource", Enum.GetName(typeof(BulkMaterialType), (int)_Material)));
                }

                return _Columns;
            }
        }

        //public accessors
        public int AmountCur { get { return _AmountCur; } }
        public int AmountMax { get { return _AmountMax; } }
        public Type BODFillType { get { return _BODFillType; } }
        public int Number { get { return _Number; } }
        public int Graphic { get { return _Graphic; } }
        public bool RequireExceptional { get { return _RequireExceptional; } }
        public BulkMaterialType Material { get { return _Material; } }



        //master constructor
        public SmallCFBODListEntry(Item item)
            : base(item)
        {
            SmallCFBOD bod = (SmallCFBOD)item;
            _AmountCur = bod.AmountCur;
            _AmountMax = bod.AmountMax;
            _BODFillType = bod.Type;
            _Number = bod.Number;
            _Graphic = bod.Graphic;
            _RequireExceptional = bod.RequireExceptional;
            _Material = bod.Material;
        }

        //world load constructor
        public SmallCFBODListEntry(GenericReader reader)
            : base(reader)
        {
        }

        //clone constructor
        public SmallCFBODListEntry(SmallCFBODListEntry entry)
            : base(entry)
        {
            _AmountCur = entry.AmountCur;
            _AmountMax = entry.AmountMax;
            _BODFillType = entry.BODFillType;
            _Number = entry.Number;
            _Graphic = entry.Graphic;
            _RequireExceptional = entry.RequireExceptional;
            _Material = entry.Material;
        }

        //this generates an item from what is stored in the entry.  Note no exception handling
        public override Item GenerateItem()
        {
            SmallCFBOD bod = (SmallCFBOD)Activator.CreateInstance(_Type, new object[] { _AmountCur, _AmountMax, _BODFillType, _Number, _Graphic, _RequireExceptional, _Material });

            return bod;
        }


        //this checks if the item you're attempting to create with is proper.  The child classes define specifics for this
        public override bool AllGood(Item item)
        {
            if (!base.AllGood(item))
            {
                return false;
            }

            if (!(item is SmallCFBOD))
            {
                return false;
            }

            SmallCFBOD bod = (SmallCFBOD)item;

            //TODO: test for bod stuff here?

            return true;
        }

        //this is used to drive the cloning process - derived classes fire their associated clone constructor
        public override ItemListEntry Clone()
        {
            return new SmallCFBODListEntry(this);

        }

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

            writer.Write(0);

            writer.Write(_AmountCur);
            writer.Write(_AmountMax);
            writer.Write(_BODFillType.Name);
            writer.Write(_Number);
            writer.Write(_Graphic);
            writer.Write(_RequireExceptional);
            writer.Write((int)_Material);
        }

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

            int version = reader.ReadInt();

            _AmountCur = reader.ReadInt();
            _AmountMax = reader.ReadInt();
            _BODFillType = ScriptCompiler.FindTypeByName(reader.ReadString());
            _Number = reader.ReadInt();
            _Graphic = reader.ReadInt();
            _RequireExceptional = reader.ReadBool();
            _Material = (BulkMaterialType)reader.ReadInt();

        }
    }

    public class LargeCFBODListEntry : ItemListEntry
    {
        public override int GumpWidth { get { return 700; } }

        //large bod-specific data

        protected int _AmountMax;
        protected string _Contents;				//the name is a composite of the types within the bod
        protected bool _RequireExceptional;
        protected BulkMaterialType _Material;
        protected LargeCFBulkEntry[] _Entries;



        public override List<ItemListEntryColumn> Columns
        {
            get
            {
                if (_Columns == null)
                {
                    //NOTE: the default name is overridden here completely
                    _Columns = new List<ItemListEntryColumn>();

                    //add in specifics for this list type here
                    _Columns.Add(new ItemListEntryColumn(0, "Contents", _Contents));
                    _Columns.Add(new ItemListEntryColumn(350, "Amount", _AmountMax.ToString()));
                    _Columns.Add(new ItemListEntryColumn(450, "Exceptional?", (_RequireExceptional ? "yes" : "no")));
                    _Columns.Add(new ItemListEntryColumn(550, "Resource", Enum.GetName(typeof(BulkMaterialType), (int)_Material)));
                }

                return _Columns;
            }
        }

        //public accessors
        public int AmountMax { get { return _AmountMax; } }
        public string Contents { get { return _Contents; } }
        public bool RequireExceptional { get { return _RequireExceptional; } }
        public BulkMaterialType Material { get { return _Material; } }
        public LargeCFBulkEntry[] Entries { get { return _Entries; } }


        //master constructor
        public LargeCFBODListEntry(Item item)
            : base(item)
        {
            LargeCFBOD bod = (LargeCFBOD)item;
            _AmountMax = bod.AmountMax;
            _RequireExceptional = bod.RequireExceptional;
            _Material = bod.Material;

            //proper cloning is required

            _Entries = new LargeCFBulkEntry[bod.Entries.Length];
            for (int i = 0; i < bod.Entries.Length; i++)
            {
                _Entries[i] = new LargeCFBulkEntry(null, bod.Entries[i].Details);
                _Entries[i].Amount = bod.Entries[i].Amount;
            }



            //this produces the name for the bod based on the bod name definitions
            GenerateContentsName();
        }

        //world load constructor
        public LargeCFBODListEntry(GenericReader reader)
            : base(reader)
        {
        }

        //clone constructor
        public LargeCFBODListEntry(LargeCFBODListEntry entry)
            : base(entry)
        {
            _AmountMax = entry.AmountMax;
            _RequireExceptional = entry.RequireExceptional;
            _Material = entry.Material;

            _Entries = new LargeCFBulkEntry[entry.Entries.Length];

            //proper cloning is required
            for (int i = 0; i < entry.Entries.Length; i++)
            {
                _Entries[i] = new LargeCFBulkEntry(null, entry.Entries[i].Details);
                _Entries[i].Amount = entry.Entries[i].Amount;
            }

            GenerateContentsName();
        }

        public void GenerateContentsName()
        {
            _Contents = "";

            for (int i = 0; i < _Entries.Length; i++)
            {
                _Contents += CliLoc.GetName(_Entries[i].Details.Type);

                if (i < _Entries.Length - 1)
                {
                    _Contents += ", ";
                }
            }




        }


        //this generates an item from what is stored in the entry.  Note no exception handling
        public override Item GenerateItem()
        {
            LargeCFBOD bod = (LargeCFBOD)Activator.CreateInstance(_Type, new object[] { _AmountMax, _RequireExceptional, _Material, _Entries });

            //attach the large bod to the entries			
            for (int i = 0; i < bod.Entries.Length; i++)
            {
                bod.Entries[i].Owner = bod;
            }

            return bod;
        }


        //this checks if the item you're attempting to create with is proper.  The child classes define specifics for this
        public override bool AllGood(Item item)
        {
            if (!base.AllGood(item))
            {
                return false;
            }

            if (!(item is LargeCFBOD))
            {
                return false;
            }

            LargeCFBOD bod = (LargeCFBOD)item;

            //TODO: test for bod stuff here?

            return true;
        }

        //this is used to drive the cloning process - derived classes fire their associated clone constructor
        public override ItemListEntry Clone()
        {
            return new LargeCFBODListEntry(this);

        }

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

            writer.Write(0);

            writer.Write(_AmountMax);
            writer.Write(_RequireExceptional);
            writer.Write((int)_Material);

            writer.Write(_Entries.Length);

            for (int i = 0; i < _Entries.Length; i++)
            {
                _Entries[i].Serialize(writer);

            }
        }

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

            int version = reader.ReadInt();

            _AmountMax = reader.ReadInt();
            _RequireExceptional = reader.ReadBool();
            _Material = (BulkMaterialType)reader.ReadInt();

            int count = reader.ReadInt();

            _Entries = new LargeCFBulkEntry[count];
            for (int i = 0; i < count; i++)
            {
                _Entries[i] = new LargeCFBulkEntry(null, reader);
            }

            GenerateContentsName();

        }
    }
    #endregion

    #region Custom Tink Bods
    public class SmallTinkBODListEntry : ItemListEntry
    {
        public override int GumpWidth { get { return 650; } }

        //generic bod-specific data
        protected int _AmountCur, _AmountMax;
        protected Type _BODFillType;				//the item to go into the BOD, different from the BOD type
        protected int _Number;
        protected int _Graphic;
        protected bool _RequireExceptional;
        protected BulkMaterialType _Material;

        public override List<ItemListEntryColumn> Columns
        {
            get
            {
                if (_Columns == null)
                {
                    //NOTE: the default name is overridden here completely
                    _Columns = new List<ItemListEntryColumn>();

                    //add in specifics for this list type here
                    _Columns.Add(new ItemListEntryColumn(0, "Item Type", CliLoc.GetName(_BODFillType)));
                    _Columns.Add(new ItemListEntryColumn(150, "Amount", _AmountCur.ToString() + "/" + _AmountMax.ToString()));
                    _Columns.Add(new ItemListEntryColumn(250, "Exceptional?", (_RequireExceptional ? "yes" : "no")));
                    _Columns.Add(new ItemListEntryColumn(350, "Resource", Enum.GetName(typeof(BulkMaterialType), (int)_Material)));
                }

                return _Columns;
            }
        }

        //public accessors
        public int AmountCur { get { return _AmountCur; } }
        public int AmountMax { get { return _AmountMax; } }
        public Type BODFillType { get { return _BODFillType; } }
        public int Number { get { return _Number; } }
        public int Graphic { get { return _Graphic; } }
        public bool RequireExceptional { get { return _RequireExceptional; } }
        public BulkMaterialType Material { get { return _Material; } }



        //master constructor
        public SmallTinkBODListEntry(Item item)
            : base(item)
        {
            SmallTinkBOD bod = (SmallTinkBOD)item;
            _AmountCur = bod.AmountCur;
            _AmountMax = bod.AmountMax;
            _BODFillType = bod.Type;
            _Number = bod.Number;
            _Graphic = bod.Graphic;
            _RequireExceptional = bod.RequireExceptional;
            _Material = bod.Material;
        }

        //world load constructor
        public SmallTinkBODListEntry(GenericReader reader)
            : base(reader)
        {
        }

        //clone constructor
        public SmallTinkBODListEntry(SmallTinkBODListEntry entry)
            : base(entry)
        {
            _AmountCur = entry.AmountCur;
            _AmountMax = entry.AmountMax;
            _BODFillType = entry.BODFillType;
            _Number = entry.Number;
            _Graphic = entry.Graphic;
            _RequireExceptional = entry.RequireExceptional;
            _Material = entry.Material;
        }

        //this generates an item from what is stored in the entry.  Note no exception handling
        public override Item GenerateItem()
        {
            SmallTinkBOD bod = (SmallTinkBOD)Activator.CreateInstance(_Type, new object[] { _AmountCur, _AmountMax, _BODFillType, _Number, _Graphic, _RequireExceptional, _Material });

            return bod;
        }


        //this checks if the item you're attempting to create with is proper.  The child classes define specifics for this
        public override bool AllGood(Item item)
        {
            if (!base.AllGood(item))
            {
                return false;
            }

            if (!(item is SmallTinkBOD))
            {
                return false;
            }

            SmallTinkBOD bod = (SmallTinkBOD)item;

            //TODO: test for bod stuff here?

            return true;
        }

        //this is used to drive the cloning process - derived classes fire their associated clone constructor
        public override ItemListEntry Clone()
        {
            return new SmallTinkBODListEntry(this);

        }

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

            writer.Write(0);

            writer.Write(_AmountCur);
            writer.Write(_AmountMax);
            writer.Write(_BODFillType.Name);
            writer.Write(_Number);
            writer.Write(_Graphic);
            writer.Write(_RequireExceptional);
            writer.Write((int)_Material);
        }

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

            int version = reader.ReadInt();

            _AmountCur = reader.ReadInt();
            _AmountMax = reader.ReadInt();
            _BODFillType = ScriptCompiler.FindTypeByName(reader.ReadString());
            _Number = reader.ReadInt();
            _Graphic = reader.ReadInt();
            _RequireExceptional = reader.ReadBool();
            _Material = (BulkMaterialType)reader.ReadInt();

        }
    }
    
    public class LargeTinkBODListEntry : ItemListEntry
    {
        public override int GumpWidth { get { return 700; } }

        //large bod-specific data

        protected int _AmountMax;
        protected string _Contents;				//the name is a composite of the types within the bod
        protected bool _RequireExceptional;
        protected BulkMaterialType _Material;
        protected LargeTinkBulkEntry[] _Entries;



        public override List<ItemListEntryColumn> Columns
        {
            get
            {
                if (_Columns == null)
                {
                    //NOTE: the default name is overridden here completely
                    _Columns = new List<ItemListEntryColumn>();

                    //add in specifics for this list type here
                    _Columns.Add(new ItemListEntryColumn(0, "Contents", _Contents));
                    _Columns.Add(new ItemListEntryColumn(350, "Amount", _AmountMax.ToString()));
                    _Columns.Add(new ItemListEntryColumn(450, "Exceptional?", (_RequireExceptional ? "yes" : "no")));
                    _Columns.Add(new ItemListEntryColumn(550, "Resource", Enum.GetName(typeof(BulkMaterialType), (int)_Material)));
                }

                return _Columns;
            }
        }

        //public accessors
        public int AmountMax { get { return _AmountMax; } }
        public string Contents { get { return _Contents; } }
        public bool RequireExceptional { get { return _RequireExceptional; } }
        public BulkMaterialType Material { get { return _Material; } }
        public LargeTinkBulkEntry[] Entries { get { return _Entries; } }


        //master constructor
        public LargeTinkBODListEntry(Item item)
            : base(item)
        {
            LargeTinkBOD bod = (LargeTinkBOD)item;
            _AmountMax = bod.AmountMax;
            _RequireExceptional = bod.RequireExceptional;
            _Material = bod.Material;

            //proper cloning is required

            _Entries = new LargeTinkBulkEntry[bod.Entries.Length];
            for (int i = 0; i < bod.Entries.Length; i++)
            {
                _Entries[i] = new LargeTinkBulkEntry(null, bod.Entries[i].Details);
                _Entries[i].Amount = bod.Entries[i].Amount;
            }



            //this produces the name for the bod based on the bod name definitions
            GenerateContentsName();
        }

        //world load constructor
        public LargeTinkBODListEntry(GenericReader reader)
            : base(reader)
        {
        }

        //clone constructor
        public LargeTinkBODListEntry(LargeTinkBODListEntry entry)
            : base(entry)
        {
            _AmountMax = entry.AmountMax;
            _RequireExceptional = entry.RequireExceptional;
            _Material = entry.Material;

            _Entries = new LargeTinkBulkEntry[entry.Entries.Length];

            //proper cloning is required
            for (int i = 0; i < entry.Entries.Length; i++)
            {
                _Entries[i] = new LargeTinkBulkEntry(null, entry.Entries[i].Details);
                _Entries[i].Amount = entry.Entries[i].Amount;
            }

            GenerateContentsName();
        }

        public void GenerateContentsName()
        {
            _Contents = "";

            for (int i = 0; i < _Entries.Length; i++)
            {
                _Contents += CliLoc.GetName(_Entries[i].Details.Type);

                if (i < _Entries.Length - 1)
                {
                    _Contents += ", ";
                }
            }




        }


        //this generates an item from what is stored in the entry.  Note no exception handling
        public override Item GenerateItem()
        {
            LargeTinkBOD bod = (LargeTinkBOD)Activator.CreateInstance(_Type, new object[] { _AmountMax, _RequireExceptional, _Material, _Entries });

            //attach the large bod to the entries			
            for (int i = 0; i < bod.Entries.Length; i++)
            {
                bod.Entries[i].Owner = bod;
            }

            return bod;
        }


        //this checks if the item you're attempting to create with is proper.  The child classes define specifics for this
        public override bool AllGood(Item item)
        {
            if (!base.AllGood(item))
            {
                return false;
            }

            if (!(item is LargeTinkBOD))
            {
                return false;
            }

            LargeTinkBOD bod = (LargeTinkBOD)item;

            //TODO: test for bod stuff here?

            return true;
        }

        //this is used to drive the cloning process - derived classes fire their associated clone constructor
        public override ItemListEntry Clone()
        {
            return new LargeTinkBODListEntry(this);

        }

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

            writer.Write(0);

            writer.Write(_AmountMax);
            writer.Write(_RequireExceptional);
            writer.Write((int)_Material);

            writer.Write(_Entries.Length);

            for (int i = 0; i < _Entries.Length; i++)
            {
                _Entries[i].Serialize(writer);

            }
        }

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

            int version = reader.ReadInt();

            _AmountMax = reader.ReadInt();
            _RequireExceptional = reader.ReadBool();
            _Material = (BulkMaterialType)reader.ReadInt();

            int count = reader.ReadInt();

            _Entries = new LargeTinkBulkEntry[count];
            for (int i = 0; i < count; i++)
            {
                _Entries[i] = new LargeTinkBulkEntry(null, reader);
            }

            GenerateContentsName();

        }
    }

#endregion
thats the edits to BODListEntries.cs

Code:
	public override List<StoreEntry> EntryStructure
		{
			get
			{
				List<StoreEntry> entry = base.EntryStructure;
				
				entry.Add( new ListEntry( typeof( SmallSmithBOD ), typeof( SmallBODListEntry ), "Sm. Blacksmith", 0x2258, 0x44E  ) );
				entry.Add( new ListEntry( typeof( SmallTailorBOD ), typeof( SmallBODListEntry ), "Sm. Tailor", 0x2258, 0x483 ) );
                entry.Add(new ListEntry(typeof(SmallTamingBOD), typeof(SmallBODMobileListEntry), "Sm. Taming", 0x14EF, 0x1CA));
                entry.Add(new ListEntry(typeof(SmallTinkerBOD), typeof(SmallTinkBODListEntry), "Sm. Tinker", 0x2258, 0x14));
                entry.Add(new ListEntry(typeof(SmallFletcherBOD), typeof(SmallCFBODListEntry), "Sm. Fletcher", 0x2258, 0x58));
                entry.Add(new ListEntry(typeof(SmallCarpenterBOD), typeof(SmallCFBODListEntry), "Sm. Carpenter", 0x14EF, 0x30));
				
				entry.Add( new ColumnSeparationEntry() );
				
				entry.Add( new ListEntry( typeof( LargeSmithBOD ), typeof( LargeBODListEntry ), "Lg. Blacksmith", 0x2258, 0x44E ) );
				entry.Add( new ListEntry( typeof( LargeTailorBOD ), typeof( LargeBODListEntry ), "Lg. Tailor", 0x2258, 0x483 ) );
                entry.Add(new ListEntry(typeof(LargeTamingBOD), typeof(LargeBODMobileListEntry), "Lg. Taming", 0x2258, 0x1CA));
                entry.Add(new ListEntry(typeof(LargeTinkerBOD), typeof(LargeTinkBODListEntry), "Lg. Tinker", 0x2258, 0x14));
                entry.Add(new ListEntry(typeof(LargeFletcherBOD), typeof(LargeCFBODListEntry), "Lg. Fletcher", 0x2258, 0x58));
                entry.Add(new ListEntry(typeof(LargeCarpenterBOD), typeof(LargeCFBODListEntry), "Lg. Carpenter", 0x2258, 0x30));

				return entry;
			}
		}

heres the mod to the keys. like i said the tinkering will not remove but it will add.
 
Top