CODE | ||
Server Crash Report =================== RunUO Version 2.0, Build 2671.42452 Operating System: Microsoft Windows NT 6.0.6000.0 .NET Framework: 2.0.50727.312 Time: 4/28/2007 8:05:28 PM Mobiles: 4592 Items: 195749 Exception: System.MissingMethodException: Cannot create an abstract class. at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandle& ctor, Boolean& bNeedSecurityCheck) at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean fillCache) at System.RuntimeType.CreateInstanceImpl(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean fillCache) at System.Activator.CreateInstance(Type type, Boolean nonPublic) at System.Activator.CreateInstance(Type type) at Server.Mobiles.GenericBuyInfo.GetEntity() in c:\Program Files\RunUO 2.0 SVN 173\Scripts\Mobiles\Vendors\GenericBuy.cs:line 268 at Server.Mobiles.GenericBuyInfo.GetDisplayEntity() in c:\Program Files\RunUO 2.0 SVN 173\Scripts\Mobiles\Vendors\GenericBuy.cs:line 150 at Server.Mobiles.BaseVendor.VendorBuy(Mobile from) in c:\Program Files\RunUO 2.0 SVN 173\Scripts\Mobiles\Vendors\BaseVendor2.cs:line 689 at Server.ContextMenus.VendorBuyEntry.OnClick() in c:\Program Files\RunUO 2.0 SVN 173\Scripts\Mobiles\Vendors\BaseVendor2.cs:line 1548 at Server.Network.PacketHandlers.ContextMenuResponse(NetState state, PacketReader pvSrc) at Server.Network.PacketHandlers.ExtendedCommand(NetState state, PacketReader pvSrc) at Server.Network.MessagePump.HandleReceive(NetState ns) at Server.Network.MessagePump.Slice() at Server.Core.Main(String[] args) Clients: - Count: 1 + ::ffff:69.245.225.176: (account = fallonova) (mobile = 0xC0B 'Sylvie') heres script[CODE]using System; using System.Collections; using System.Collections.Generic; using Server.Items; using Server.Network; using Server.ContextMenus; using Server.Mobiles; using Server.Misc; using Server.Engines.BulkOrders; using Server.Regions; using Server.Factions; namespace Server.Mobiles { public enum VendorShoeType { None, Shoes, Boots, Sandals, ThighBoots } public abstract class BaseVendor : BaseCreature, IVendor { private const int MaxSell = 500; protected abstract ArrayList SBInfos{ get; } private ArrayList m_ArmorBuyInfo = new ArrayList(); private ArrayList m_ArmorSellInfo = new ArrayList(); private DateTime m_LastRestock; public override bool CanTeach{ get{ return true; } } public override bool PlayerRangeSensitive{ get{ return true; } } public virtual bool IsActiveVendor{ get{ return true; } } public virtual bool IsActiveBuyer{ get{ return IsActiveVendor; } } // response to vendor SELL public virtual bool IsActiveSeller{ get{ return IsActiveVendor; } } // repsonse to vendor BUY public virtual NpcGuild NpcGuild{ get{ return NpcGuild.None; } } public virtual bool IsInvulnerable{ get{ return true; } } public override bool ShowFameTitle{ get{ return false; } } public virtual bool IsValidBulkOrder( Item item ) { return false; } public virtual Item CreateBulkOrder( Mobile from, bool fromContextMenu ) { return null; } public virtual bool SupportsBulkOrders( Mobile from ) { return false; } public virtual TimeSpan GetNextBulkOrder( Mobile from ) { return TimeSpan.Zero; } public virtual void OnSuccessfulBulkOrderRecieve( Mobile from ) { } #region Faction public virtual int GetPriceScalar() { Town town = Town.FromRegion( this.Region ); if ( town != null ) return (100 + town.Tax); return 100; } public void UpdateBuyInfo() { int priceScalar = GetPriceScalar(); IBuyItemInfo[] buyinfo = (IBuyItemInfo[])m_ArmorBuyInfo.ToArray( typeof( IBuyItemInfo ) ); if ( buyinfo != null ) { foreach ( IBuyItemInfo info in buyinfo ) info.PriceScalar = priceScalar; } } #endregion private class BulkOrderInfoEntry : ContextMenuEntry { private Mobile m_From; private BaseVendor m_Vendor; public BulkOrderInfoEntry( Mobile from, BaseVendor vendor ) : base( 6152, 6 ) { m_From = from; m_Vendor = vendor; } public override void OnClick() { if ( m_Vendor.SupportsBulkOrders( m_From ) ) { TimeSpan ts = m_Vendor.GetNextBulkOrder( m_From ); int totalSeconds = (int)ts.TotalSeconds; int totalHours = (totalSeconds + 3599) / 3600; int totalMinutes = (totalSeconds + 59) / 60; if ( ((Core.SE ) ? totalMinutes == 0 : totalHours == 0) ) { m_From.SendLocalizedMessage( 1049038 ); // You can get an order now. if ( Core.AOS ) { Item bulkOrder = m_Vendor.CreateBulkOrder( m_From, true ); if ( bulkOrder is LargeBOD ) m_From.SendGump( new LargeBODAcceptGump( m_From, (LargeBOD)bulkOrder ) ); else if ( bulkOrder is SmallBOD ) m_From.SendGump( new SmallBODAcceptGump( m_From, (SmallBOD)bulkOrder ) ); } } else { int oldSpeechHue = m_Vendor.SpeechHue; m_Vendor.SpeechHue = 0x3B2; if( Core.SE ) m_Vendor.SayTo( m_From, 1072058, totalMinutes.ToString() ); // An offer may be available in about ~1_minutes~ minutes. else m_Vendor.SayTo( m_From, 1049039, totalHours.ToString() ); // An offer may be available in about ~1_hours~ hours. m_Vendor.SpeechHue = oldSpeechHue; } } } } public BaseVendor( string title ) : base( AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2 ) { LoadSBInfo(); this.Title = title; InitBody(); InitOutfit(); Container pack; //these packs MUST exist, or the client will crash when the packets are sent pack = new Backpack(); pack.Layer = Layer.ShopBuy; pack.Movable = false; pack.Visible = false; AddItem( pack ); pack = new Backpack(); pack.Layer = Layer.ShopResale; pack.Movable = false; pack.Visible = false; AddItem( pack ); m_LastRestock = DateTime.Now; } public BaseVendor( Serial serial ) : base( serial ) { } public DateTime LastRestock { get { return m_LastRestock; } set { m_LastRestock = value; } } public virtual TimeSpan RestockDelay { get { return TimeSpan.FromHours( 1 ); } } public Container BuyPack { get { Container pack = FindItemOnLayer( Layer.ShopBuy ) as Container; if ( pack == null ) { pack = new Backpack(); pack.Layer = Layer.ShopBuy; pack.Visible = false; AddItem( pack ); } return pack; } } public abstract void InitSBInfo(); public virtual bool IsTokunoVendor{ get{ return ( Map == Map.Tokuno ); } } protected void LoadSBInfo() { m_LastRestock = DateTime.Now; for ( int i = 0; i < m_ArmorBuyInfo.Count; ++i ) { GenericBuyInfo buy = m_ArmorBuyInfo[i] as GenericBuyInfo; if ( buy != null ) buy.DeleteDisplayEntity(); } SBInfos.Clear(); InitSBInfo(); m_ArmorBuyInfo.Clear(); m_ArmorSellInfo.Clear(); for ( int i = 0; i < SBInfos.Count; i++ ) { SBInfo sbInfo = (SBInfo)SBInfos[i]; m_ArmorBuyInfo.AddRange( sbInfo.BuyInfo ); m_ArmorSellInfo.Add( sbInfo.SellInfo ); } } public virtual bool GetGender() { return Utility.RandomBool(); } public virtual void InitBody() { InitStats( 100, 100, 25 ); SpeechHue = Utility.RandomDyedHue(); Hue = Utility.RandomSkinHue(); if ( IsInvulnerable && !Core.AOS ) NameHue = 0x35; if ( Female = GetGender() ) { Body = 0x191; Name = NameList.RandomName( "female" ); } else { Body = 0x190; Name = NameList.RandomName( "male" ); } } public virtual int GetRandomHue() { switch ( Utility.Random( 5 ) ) { default: case 0: return Utility.RandomBlueHue(); case 1: return Utility.RandomGreenHue(); case 2: return Utility.RandomRedHue(); case 3: return Utility.RandomYellowHue(); case 4: return Utility.RandomNeutralHue(); } } public virtual int GetShoeHue() { if ( 0.1 > Utility.RandomDouble() ) return 0; return Utility.RandomNeutralHue(); } public virtual VendorShoeType ShoeType { get{ return VendorShoeType.Shoes; } } public virtual int RandomBrightHue() { if ( 0.1 > Utility.RandomDouble() ) return Utility.RandomList( 0x62, 0x71 ); return Utility.RandomList( 0x03, 0x0D, 0x13, 0x1C, 0x21, 0x30, 0x37, 0x3A, 0x44, 0x59 ); } public virtual void CheckMorph() { if ( CheckGargoyle() ) return; if ( CheckNecromancer() ) return; //17APR2007 Added Elven Vendor for Heartwood *** START 1/2 *** if (CheckElvenVendor()) return; //17APR2007 Added Elven Vendor for Heartwood *** END 1/2 *** CheckTokuno(); } //17APR2007 Added Elven Vendor for Heartwood *** START 2/2*** public virtual bool CheckElvenVendor() { Map map = this.Map; if (!Region.IsPartOf("Heartwood")) return false; if ( Body != 605 && Body != 606 ) TurnToElvenVendor(); return true; } public virtual void TurnToElvenVendor() { List<Item> deleteList = new List<Item>(); for (int i = 0; i < Items.Count; ++i) { if (Items[i] is BaseClothing ) deleteList.Add( Items[i] ); } for (int i = 0; i < deleteList.Count; ++i) deleteList[i].Delete(); if ( Female = GetGender() ) { Body = 606; Name = NameList.RandomName("female"); Female = true; Race = Race.Elf; Hue = Utility.RandomList( 1154, 371, 798, 803, 283, 723, 993, 2119, 55, 471 ); } else { Body = 605; Name = NameList.RandomName("male"); Female = false; Race = Race.Elf; Hue = Utility.RandomList( 1154, 371, 798, 803, 283, 723, 993, 2119, 55, 471 ); } Item hair = new Item( Utility.RandomList( 0x2FD1, 0x2FCF, 0x2FC0, 0x2FC2, 0x2FBF, 0X2FCE ) ); hair.Hue = Utility.RandomList( 1153, 1175, 1260, 1266, 55, 471, 2119, 993, 723, 283, 803, 708 ); hair.Layer = Layer.Hair; hair.Movable = false; AddItem( hair ); switch (Utility.Random(6)) { case 0: //WoodLand Set { AddItem( new Server.Items.WoodlandArms() ); AddItem( new Server.Items.WoodlandChest() ); AddItem( new Server.Items.WoodlandGloves() ); AddItem( new Server.Items.WoodlandGorget() ); AddItem( new Server.Items.WoodlandLegs() ); AddItem( new Server.Items.VultureHelm() ); AddItem( new Server.Items.WoodlandBelt(GetRandomHue() ) ); AddItem( new Server.Items.ElvenBoots(GetRandomHue() ) ); break; } case 1: //DarkShirt & Pants & Boots { AddItem( new Server.Items.ElvenDarkShirt(GetRandomHue() ) ); AddItem( new Server.Items.ElvenPants(GetRandomHue() ) ); AddItem( new Server.Items.ElvenBoots(GetRandomHue() ) ); break; } case 2: //Shirt & Pants & Boots { AddItem( new Server.Items.ElvenShirt(GetRandomHue() ) ); AddItem( new Server.Items.ElvenPants(GetRandomHue() ) ); AddItem( new Server.Items.ElvenBoots(GetRandomHue() ) ); break; } case 3: //Leaf Set { AddItem( new Server.Items.LeafChest() ); AddItem( new Server.Items.LeafArms() ); AddItem( new Server.Items.ElvenBoots(GetRandomHue() ) ); AddItem( new Server.Items.LeafGloves() ); AddItem( new Server.Items.LeafGorget() ); AddItem( new Server.Items.LeafLegs() ); break; } case 4: //Hide Set { AddItem( new Server.Items.HideChest() ); AddItem( new Server.Items.HideGloves() ); AddItem( new Server.Items.HidePauldrons() ); AddItem( new Server.Items.HideGorget() ); AddItem( new Server.Items.HidePants() ); AddItem( new Server.Items.ElvenBoots(GetRandomHue() ) ); break; } case 5: //Robe & Boots { if (Female) { AddItem( new Server.Items.FemaleElvenRobe(GetRandomHue() ) ); AddItem( new Server.Items.ElvenBoots(GetRandomHue() ) ); break; } else { AddItem( new Server.Items.MaleElvenRobe(GetRandomHue() ) ); AddItem( new Server.Items.ElvenBoots(GetRandomHue() ) ); break; } } } } //17APR2007 Added Elven Vendor for Heartwood *** END 2/2 *** public virtual bool CheckTokuno() { if ( this.Map != Map.Tokuno ) return false; NameList n; if ( Female ) n = NameList.GetNameList( "tokuno female" ); else n = NameList.GetNameList( "tokuno male" ); if ( !n.ContainsName( this.Name ) ) TurnToTokuno(); return true; } public virtual void TurnToTokuno() { if ( Female ) this.Name = NameList.RandomName( "tokuno female" ); else this.Name = NameList.RandomName( "tokuno male" ); } public virtual bool CheckGargoyle() { Map map = this.Map; if ( map != Map.Ilshenar ) return false; if ( !Region.IsPartOf( "Gargoyle City" ) ) return false; if ( Body != 0x2F6 || (Hue & 0x8000) == 0 ) TurnToGargoyle(); return true; } public virtual bool CheckNecromancer() { Map map = this.Map; if ( map != Map.Malas ) return false; if ( !Region.IsPartOf( "Umbra" ) ) return false; if ( Hue != 0x83E8 ) TurnToNecromancer(); return true; } public override void OnAfterSpawn() { CheckMorph(); } protected override void OnMapChange( Map oldMap ) { base.OnMapChange( oldMap ); CheckMorph(); LoadSBInfo(); } public virtual int GetRandomNecromancerHue() { switch ( Utility.Random( 20 ) ) { case 0: return 0; case 1: return 0x4E9; default: return Utility.RandomList( 0x485, 0x497 ); } } public virtual void TurnToNecromancer() { for ( int i = 0; i < this.Items.Count; ++i ) { Item item = this.Items[i]; if ( item is Hair || item is Beard ) item.Hue = 0; else if ( item is BaseClothing || item is BaseWeapon || item is BaseArmor || item is BaseTool ) item.Hue = GetRandomNecromancerHue(); } HairHue = 0; FacialHairHue = 0; Hue = 0x83E8; } public virtual void TurnToGargoyle() { for ( int i = 0; i < this.Items.Count; ++i ) { Item item = this.Items[i]; if ( item is BaseClothing || item is Hair || item is Beard ) item.Delete(); } HairItemID = 0; FacialHairItemID = 0; Body = 0x2F6; Hue = RandomBrightHue() | 0x8000; Name = NameList.RandomName( "gargoyle vendor" ); CapitalizeTitle(); } public virtual void CapitalizeTitle() { string title = this.Title; if ( title == null ) return; string[] split = title.Split( ' ' ); for ( int i = 0; i < split.Length; ++i ) { if ( Insensitive.Equals( split[i], "the" ) ) continue; if ( split[i].Length > 1 ) split[i] = Char.ToUpper( split[i][0] ) + split[i].Substring( 1 ); else if ( split[i].Length > 0 ) split[i] = Char.ToUpper( split[i][0] ).ToString(); } this.Title = String.Join( " ", split ); } public virtual int GetHairHue() { return Utility.RandomHairHue(); } public virtual void InitOutfit() { switch ( Utility.Random( 3 ) ) { case 0: AddItem( new FancyShirt( GetRandomHue() ) ); break; case 1: AddItem( new Doublet( GetRandomHue() ) ); break; case 2: AddItem( new Shirt( GetRandomHue() ) ); break; } switch ( ShoeType ) { case VendorShoeType.Shoes: AddItem( new Shoes( GetShoeHue() ) ); break; case VendorShoeType.Boots: AddItem( new Boots( GetShoeHue() ) ); break; case VendorShoeType.Sandals: AddItem( new Sandals( GetShoeHue() ) ); break; case VendorShoeType.ThighBoots: AddItem( new ThighBoots( GetShoeHue() ) ); break; } int hairHue = GetHairHue(); Utility.AssignRandomHair( this, hairHue ); Utility.AssignRandomFacialHair( this, hairHue ); if ( Female ) { switch ( Utility.Random( 6 ) ) { case 0: AddItem( new ShortPants( GetRandomHue() ) ); break; case 1: case 2: AddItem( new Kilt( GetRandomHue() ) ); break; case 3: case 4: case 5: AddItem( new Skirt( GetRandomHue() ) ); break; } } else { switch ( Utility.Random( 2 ) ) { case 0: AddItem( new LongPants( GetRandomHue() ) ); break; case 1: AddItem( new ShortPants( GetRandomHue() ) ); break; } } PackGold( 100, 200 ); } public virtual void Restock() { m_LastRestock = DateTime.Now; IBuyItemInfo[] buyInfo = this.GetBuyInfo(); foreach ( IBuyItemInfo bii in buyInfo ) bii.OnRestock(); } private static TimeSpan InventoryDecayTime = TimeSpan.FromHours( 1.0 ); public virtual void VendorBuy( Mobile from ) { if ( !IsActiveSeller ) return; if ( !from.CheckAlive() ) return; if ( !CheckVendorAccess( from ) ) { Say( 501522 ); // I shall not treat with scum like thee! return; } if ( DateTime.Now - m_LastRestock > RestockDelay ) Restock(); UpdateBuyInfo(); int count = 0; ArrayList list; IBuyItemInfo[] buyInfo = this.GetBuyInfo(); IShopSellInfo[] sellInfo = this.GetSellInfo(); list = new ArrayList( buyInfo.Length ); Container cont = this.BuyPack; List<ObjectPropertyList> opls = null; for (int idx=0;idx<buyInfo.Length;idx++) { IBuyItemInfo buyItem = (IBuyItemInfo)buyInfo[idx]; if ( buyItem.Amount <= 0 || list.Count >= 250 ) continue; // NOTE: Only GBI supported; if you use another implementation of IBuyItemInfo, this will crash GenericBuyInfo gbi = (GenericBuyInfo) buyItem; IEntity disp = gbi.GetDisplayEntity(); list.Add( new BuyItemState( buyItem.Name, cont.Serial, disp == null ? (Serial) 0x7FC0FFEE : disp.Serial, buyItem.Price, buyItem.Amount, buyItem.ItemID, buyItem.Hue ) ); count++; if ( ObjectPropertyList.Enabled ) { if ( opls == null ) { opls = new List<ObjectPropertyList>(); } if ( disp is Item ) { opls.Add( ( ( Item ) disp ).PropertyList ); } else if ( disp is Mobile ) { opls.Add( ( ( Mobile ) disp ).PropertyList ); } } } List<Item> playerItems = cont.Items; for ( int i = playerItems.Count - 1; i >= 0; --i ) { if ( i >= playerItems.Count ) continue; Item item = playerItems[i]; if ( (item.LastMoved + InventoryDecayTime) <= DateTime.Now ) item.Delete(); } for ( int i = 0; i < playerItems.Count; ++i ) { Item item = playerItems[i]; int price = 0; string name = null; foreach( IShopSellInfo ssi in sellInfo ) { if ( ssi.IsSellable( item ) ) { price = ssi.GetBuyPriceFor( item ); name = ssi.GetNameFor( item ); break; } } if ( name != null && list.Count < 250 ) { list.Add( new BuyItemState( name, cont.Serial, item.Serial, price, item.Amount, item.ItemID, item.Hue ) ); count++; if ( ObjectPropertyList.Enabled ) { if ( opls == null ) { opls = new List<ObjectPropertyList>(); } opls.Add( item.PropertyList ); } } } //one (not all) of the packets uses a byte to describe number of items in the list. Osi = dumb. //if ( list.Count > 255 ) // Console.WriteLine( "Vendor Warning: Vendor {0} has more than 255 buy items, may cause client errors!", this ); if ( list.Count > 0 ) { list.Sort( new BuyItemStateComparer() ); SendPacksTo( from ); from.Send( new VendorBuyContent( list ) ); from.Send( new VendorBuyList( this, list ) ); from.Send( new DisplayBuyList( this ) ); from.Send( new MobileStatusExtended( from ) );//make sure their gold amount is sent if ( ObjectPropertyList.Enabled && opls != null ) { for ( int i = 0; i < opls.Count; ++i ) { from.Send( opls[i] ); } } SayTo( from, 500186 ); // Greetings. Have a look around. } } public virtual void SendPacksTo( Mobile from ) { Item pack = FindItemOnLayer( Layer.ShopBuy ); if ( pack == null ) { pack = new Backpack(); pack.Layer = Layer.ShopBuy; pack.Movable = false; pack.Visible = false; AddItem( pack ); } from.Send( new EquipUpdate( pack ) ); pack = FindItemOnLayer( Layer.ShopSell ); if ( pack != null ) from.Send( new EquipUpdate( pack ) ); pack = FindItemOnLayer( Layer.ShopResale ); if ( pack == null ) { pack = new Backpack(); pack.Layer = Layer.ShopResale; pack.Movable = false; pack.Visible = false; AddItem( pack ); } from.Send( new EquipUpdate( pack ) ); } public virtual void VendorSell( Mobile from ) { if ( !IsActiveBuyer ) return; if ( !from.CheckAlive() ) return; if ( !CheckVendorAccess( from ) ) { Say( 501522 ); // I shall not treat with scum like thee! return; } Container pack = from.Backpack; if ( pack != null ) { IShopSellInfo[] info = GetSellInfo(); Hashtable table = new Hashtable(); foreach ( IShopSellInfo ssi in info ) { Item[] items = pack.FindItemsByType( ssi.Types ); foreach ( Item item in items ) { if ( item is Container && ((Container)item).Items.Count != 0 ) continue; if ( item.IsStandardLoot() && item.Movable && ssi.IsSellable( item ) ) table[item] = new SellItemState( item, ssi.GetSellPriceFor( item ), ssi.GetNameFor( item ) ); } } if ( table.Count > 0 ) { SendPacksTo( from ); from.Send( new VendorSellList( this, table ) ); } else { Say( true, "You have nothing I would be interested in." ); } } } public override bool OnDragDrop( Mobile from, Item dropped ) { if ( dropped is SmallBOD || dropped is LargeBOD ) { if ( !IsValidBulkOrder( dropped ) || !SupportsBulkOrders( from ) ) { SayTo( from, 1045130 ); // That order is for some other shopkeeper. return false; } else if ( (dropped is SmallBOD && !((SmallBOD)dropped).Complete) || (dropped is LargeBOD && !((LargeBOD)dropped).Complete) ) { SayTo( from, 1045131 ); // You have not completed the order yet. return false; } Item reward; int gold, fame; if ( dropped is SmallBOD ) ((SmallBOD)dropped).GetRewards( out reward, out gold, out fame ); else ((LargeBOD)dropped).GetRewards( out reward, out gold, out fame ); from.SendSound( 0x3D ); SayTo( from, 1045132 ); // Thank you so much! Here is a reward for your effort. if ( reward != null ) from.AddToBackpack( reward ); if ( gold > 1000 ) from.AddToBackpack( new BankCheck( gold ) ); else if ( gold > 0 ) from.AddToBackpack( new Gold( gold ) ); Titles.AwardFame( from, fame, true ); OnSuccessfulBulkOrderRecieve( from ); dropped.Delete(); return true; } return base.OnDragDrop( from, dropped ); } private GenericBuyInfo LookupDisplayObject( object obj ) { IBuyItemInfo[] buyInfo = this.GetBuyInfo(); for ( int i = 0; i < buyInfo.Length; ++i ) { GenericBuyInfo gbi = (GenericBuyInfo)buyInfo[i]; if ( gbi.GetDisplayEntity() == obj ) return gbi; } return null; } private void ProcessSinglePurchase( BuyItemResponse buy, IBuyItemInfo bii, ArrayList validBuy, ref int controlSlots, ref bool fullPurchase, ref int totalCost ) { int amount = buy.Amount; if ( amount > bii.Amount ) amount = bii.Amount; if ( amount <= 0 ) return; int slots = bii.ControlSlots * amount; if ( controlSlots >= slots ) { controlSlots -= slots; } else { fullPurchase = false; return; } totalCost += bii.Price * amount; validBuy.Add( buy ); } private void ProcessValidPurchase( int amount, IBuyItemInfo bii, Mobile buyer, Container cont ) { if ( amount > bii.Amount ) amount = bii.Amount; if ( amount < 1 ) return; bii.Amount -= amount; IEntity o = bii.GetEntity(); if ( o is Item ) { Item item = (Item)o; if ( item.Stackable ) { item.Amount = amount; if ( cont == null || !cont.TryDropItem( buyer, item, false ) ) item.MoveToWorld( buyer.Location, buyer.Map ); } else { item.Amount = 1; if ( cont == null || !cont.TryDropItem( buyer, item, false ) ) item.MoveToWorld( buyer.Location, buyer.Map ); for (int i=1;i<amount;i++) { item = bii.GetEntity() as Item; if ( item != null ) { item.Amount = 1; if ( cont == null || !cont.TryDropItem( buyer, item, false ) ) item.MoveToWorld( buyer.Location, buyer.Map ); } } } } else if ( o is Mobile ) { Mobile m = (Mobile)o; m.Direction = (Direction)Utility.Random( 8 ); m.MoveToWorld( buyer.Location, buyer.Map ); m.PlaySound( m.GetIdleSound() ); if ( m is BaseCreature ) ((BaseCreature)m).SetControlMaster( buyer ); for ( int i = 1; i < amount; ++i ) { m = bii.GetEntity() as Mobile; if ( m != null ) { m.Direction = (Direction)Utility.Random( 8 ); m.MoveToWorld( buyer.Location, buyer.Map ); if ( m is BaseCreature ) ((BaseCreature)m).SetControlMaster( buyer ); } } } } public virtual bool OnBuyItems( Mobile buyer, ArrayList list ) { if ( !IsActiveSeller ) return false; if ( !buyer.CheckAlive() ) return false; if ( !CheckVendorAccess( buyer ) ) { Say( 501522 ); // I shall not treat with scum like thee! return false; } UpdateBuyInfo(); IBuyItemInfo[] buyInfo = this.GetBuyInfo(); IShopSellInfo[] info = GetSellInfo(); int totalCost = 0; ArrayList validBuy = new ArrayList( list.Count ); Container cont; bool bought = false; bool fromBank = false; bool fullPurchase = true; int controlSlots = buyer.FollowersMax - buyer.Followers; foreach ( BuyItemResponse buy in list ) { Serial ser = buy.Serial; int amount = buy.Amount; if ( ser.IsItem ) { Item item = World.FindItem( ser ); if ( item == null ) continue; GenericBuyInfo gbi = LookupDisplayObject( item ); if ( gbi != null ) { ProcessSinglePurchase( buy, gbi, validBuy, ref controlSlots, ref fullPurchase, ref totalCost ); } else if ( item.RootParent == this ) { if ( amount > item.Amount ) amount = item.Amount; if ( amount <= 0 ) continue; foreach ( IShopSellInfo ssi in info ) { if ( ssi.IsSellable( item ) ) { if ( ssi.IsResellable( item ) ) { totalCost += ssi.GetBuyPriceFor( item ) * amount; validBuy.Add( buy ); break; } } } } } else if ( ser.IsMobile ) { Mobile mob = World.FindMobile( ser ); if ( mob == null ) continue; GenericBuyInfo gbi = LookupDisplayObject( mob ); if ( gbi != null ) ProcessSinglePurchase( buy, gbi, validBuy, ref controlSlots, ref fullPurchase, ref totalCost ); } }//foreach if ( fullPurchase && validBuy.Count == 0 ) SayTo( buyer, 500190 ); // Thou hast bought nothing! else if ( validBuy.Count == 0 ) SayTo( buyer, 500187 ); // Your order cannot be fulfilled, please try again. if ( validBuy.Count == 0 ) return false; bought = ( buyer.AccessLevel >= AccessLevel.GameMaster ); cont = buyer.Backpack; if ( !bought && cont != null ) { if ( cont.ConsumeTotal( typeof( Gold ), totalCost ) ) bought = true; else if ( totalCost < 2000 ) SayTo( buyer, 500192 );//Begging thy pardon, but thou casnt afford that. } if ( !bought && totalCost >= 2000 ) { cont = buyer.FindBankNoCreate(); if ( cont != null && cont.ConsumeTotal( typeof( Gold ), totalCost ) ) { bought = true; fromBank = true; } else { SayTo( buyer, 500191 ); //Begging thy pardon, but thy bank account lacks these funds. } } if ( !bought ) return false; else buyer.PlaySound( 0x32 ); cont = buyer.Backpack; if ( cont == null ) cont = buyer.BankBox; foreach ( BuyItemResponse buy in validBuy ) { Serial ser = buy.Serial; int amount = buy.Amount; if ( amount < 1 ) continue; if ( ser.IsItem ) { Item item = World.FindItem( ser ); if ( item == null ) continue; GenericBuyInfo gbi = LookupDisplayObject( item ); if ( gbi != null ) { ProcessValidPurchase( amount, gbi, buyer, cont ); } else { if ( amount > item.Amount ) amount = item.Amount; foreach ( IShopSellInfo ssi in info ) { if ( ssi.IsSellable( item ) ) { if ( ssi.IsResellable( item ) ) { Item buyItem; if ( amount >= item.Amount ) { buyItem = item; } else { buyItem = Mobile.LiftItemDupe( item, item.Amount - amount ); if ( buyItem == null ) buyItem = item; } if ( cont == null || !cont.TryDropItem( buyer, buyItem, false ) ) buyItem.MoveToWorld( buyer.Location, buyer.Map ); break; } } } } } else if ( ser.IsMobile ) { Mobile mob = World.FindMobile( ser ); if ( mob == null ) continue; GenericBuyInfo gbi = LookupDisplayObject( mob ); if ( gbi != null ) ProcessValidPurchase( amount, gbi, buyer, cont ); } }//foreach if ( fullPurchase ) { if ( buyer.AccessLevel >= AccessLevel.GameMaster ) SayTo( buyer, true, "I would not presume to charge thee anything. Here are the goods you requested." ); else if ( fromBank ) SayTo( buyer, true, "The total of thy purchase is {0} gold, which has been withdrawn from your bank account. My thanks for the patronage.", totalCost ); else SayTo( buyer, true, "The total of thy purchase is {0} gold. My thanks for the patronage.", totalCost ); } else { if ( buyer.AccessLevel >= AccessLevel.GameMaster ) SayTo( buyer, true, "I would not presume to charge thee anything. Unfortunately, I could not sell you all the goods you requested." ); else if ( fromBank ) SayTo( buyer, true, "The total of thy purchase is {0} gold, which has been withdrawn from your bank account. My thanks for the patronage. Unfortunately, I could not sell you all the goods you requested.", totalCost ); else SayTo( buyer, true, "The total of thy purchase is {0} gold. My thanks for the patronage. Unfortunately, I could not sell you all the goods you requested.", totalCost ); } return true; } public virtual bool CheckVendorAccess( Mobile from ) { GuardedRegion reg = (GuardedRegion) this.Region.GetRegion( typeof( GuardedRegion ) ); if ( reg != null && !reg.CheckVendorAccess( this, from ) ) return false; if ( this.Region != from.Region ) { reg = (GuardedRegion) from.Region.GetRegion( typeof( GuardedRegion ) ); if ( reg != null && !reg.CheckVendorAccess( this, from ) ) return false; } return true; } public virtual bool OnSellItems( Mobile seller, ArrayList list ) { if ( !IsActiveBuyer ) return false; if ( !seller.CheckAlive() ) return false; if ( !CheckVendorAccess( seller ) ) { Say( 501522 ); // I shall not treat with scum like thee! return false; } seller.PlaySound( 0x32 ); IShopSellInfo[] info = GetSellInfo(); IBuyItemInfo[] buyInfo = this.GetBuyInfo(); int GiveGold = 0; int Sold = 0; Container cont; ArrayList delete = new ArrayList(); ArrayList drop = new ArrayList(); foreach ( SellItemResponse resp in list ) { if ( resp.Item.RootParent != seller || resp.Amount <= 0 || !resp.Item.IsStandardLoot() || !resp.Item.Movable || (resp.Item is Container && ((Container)resp.Item).Items.Count != 0) ) continue; foreach( IShopSellInfo ssi in info ) { if ( ssi.IsSellable( resp.Item ) ) { Sold++; break; } } } if ( Sold > MaxSell ) { SayTo( seller, true, "You may only sell {0} items at a time!", MaxSell ); return false; } else if ( Sold == 0 ) { return true; } foreach ( SellItemResponse resp in list ) { if ( resp.Item.RootParent != seller || resp.Amount <= 0 || !resp.Item.IsStandardLoot() || !resp.Item.Movable || (resp.Item is Container && ((Container)resp.Item).Items.Count != 0) ) continue; foreach( IShopSellInfo ssi in info ) { if ( ssi.IsSellable( resp.Item ) ) { int amount = resp.Amount; if ( amount > resp.Item.Amount ) amount = resp.Item.Amount; if ( ssi.IsResellable( resp.Item ) ) { bool found = false; foreach ( IBuyItemInfo bii in buyInfo ) { if ( bii.Restock( resp.Item, amount ) ) { resp.Item.Consume( amount ); found = true; break; } } if ( !found ) { cont = this.BuyPack; if ( amount < resp.Item.Amount ) { Item item = Mobile.LiftItemDupe( resp.Item, resp.Item.Amount - amount ); if ( item != null ) { item.SetLastMoved(); cont.DropItem( item ); } else { resp.Item.SetLastMoved(); cont.DropItem( resp.Item ); } } else { resp.Item.SetLastMoved(); cont.DropItem( resp.Item ); } } } else { if ( amount < resp.Item.Amount ) resp.Item.Amount -= amount; else resp.Item.Delete(); } GiveGold += ssi.GetSellPriceFor( resp.Item )*amount; break; } } } if ( GiveGold > 0 ) { while ( GiveGold > 60000 ) { seller.AddToBackpack( new Gold( 60000 ) ); GiveGold -= 60000; } seller.AddToBackpack( new Gold( GiveGold ) ); seller.PlaySound( 0x0037 );//Gold dropping sound if ( SupportsBulkOrders( seller ) ) { Item bulkOrder = CreateBulkOrder( seller, false ); if ( bulkOrder is LargeBOD ) seller.SendGump( new LargeBODAcceptGump( seller, (LargeBOD)bulkOrder ) ); else if ( bulkOrder is SmallBOD ) seller.SendGump( new SmallBODAcceptGump( seller, (SmallBOD)bulkOrder ) ); } } //no cliloc for this? //SayTo( seller, true, "Thank you! I bought {0} item{1}. Here is your {2}gp.", Sold, (Sold > 1 ? "s" : ""), GiveGold ); return true; } public override void Serialize( GenericWriter writer ) { base.Serialize( writer ); writer.Write( (int) 1 ); // version ArrayList sbInfos = this.SBInfos; for ( int i = 0; sbInfos != null && i < sbInfos.Count; ++i ) { SBInfo sbInfo = (SBInfo)sbInfos[i]; ArrayList buyInfo = sbInfo.BuyInfo; for ( int j = 0; buyInfo != null && j < buyInfo.Count; ++j ) { GenericBuyInfo gbi = (GenericBuyInfo)buyInfo[j]; int maxAmount = gbi.MaxAmount; int doubled = 0; switch ( maxAmount ) { case 40: doubled = 1; break; case 80: doubled = 2; break; case 160: doubled = 3; break; case 320: doubled = 4; break; case 640: doubled = 5; break; case 999: doubled = 6; break; } if ( doubled > 0 ) { writer.WriteEncodedInt( 1 + ((j * sbInfos.Count) + i) ); writer.WriteEncodedInt( doubled ); } } } writer.WriteEncodedInt( 0 ); } public override void Deserialize( GenericReader reader ) { base.Deserialize( reader ); int version = reader.ReadInt(); LoadSBInfo(); ArrayList sbInfos = this.SBInfos; switch ( version ) { case 1: { int index; while ( (index = reader.ReadEncodedInt()) > 0 ) { int doubled = reader.ReadEncodedInt(); if ( sbInfos != null ) { index -= 1; int sbInfoIndex = index % sbInfos.Count; int buyInfoIndex = index / sbInfos.Count; if ( sbInfoIndex >= 0 && sbInfoIndex < sbInfos.Count ) { SBInfo sbInfo = (SBInfo)sbInfos[sbInfoIndex]; ArrayList buyInfo = sbInfo.BuyInfo; if ( buyInfo != null && buyInfoIndex >= 0 && buyInfoIndex < buyInfo.Count ) { GenericBuyInfo gbi = (GenericBuyInfo)buyInfo[buyInfoIndex]; int amount = 20; switch ( doubled ) { case 1: amount = 40; break; case 2: amount = 80; break; case 3: amount = 160; break; case 4: amount = 320; break; case 5: amount = 640; break; case 6: amount = 999; break; } gbi.Amount = gbi.MaxAmount = amount; } } } } break; } } if ( IsParagon ) IsParagon = false; if ( Core.AOS && NameHue == 0x35 ) NameHue = -1; Timer.DelayCall( TimeSpan.Zero, new TimerCallback( CheckMorph ) ); } public override void AddCustomContextEntries( Mobile from, List<ContextMenuEntry> list ) { if ( from.Alive && IsActiveVendor ) { if ( IsActiveSeller ) list.Add( new VendorBuyEntry( from, this ) ); if ( IsActiveBuyer ) list.Add( new VendorSellEntry( from, this ) ); if ( SupportsBulkOrders( from ) ) list.Add( new BulkOrderInfoEntry( from, this ) ); } base.AddCustomContextEntries( from, list ); } public virtual IShopSellInfo[] GetSellInfo() { return (IShopSellInfo[])m_ArmorSellInfo.ToArray( typeof( IShopSellInfo ) ); } public virtual IBuyItemInfo[] GetBuyInfo() { return (IBuyItemInfo[])m_ArmorBuyInfo.ToArray( typeof( IBuyItemInfo ) ); } public override bool CanBeDamaged() { return !IsInvulnerable; } } } namespace Server.ContextMenus { public class VendorBuyEntry : ContextMenuEntry { private BaseVendor m_Vendor; public VendorBuyEntry( Mobile from, BaseVendor vendor ) : base( 6103, 8 ) { m_Vendor = vendor; Enabled = vendor.CheckVendorAccess( from ); } public override void OnClick() { m_Vendor.VendorBuy( this.Owner.From ); } } public class VendorSellEntry : ContextMenuEntry { private BaseVendor m_Vendor; public VendorSellEntry( Mobile from, BaseVendor vendor ) : base( 6104, 8 ) { m_Vendor = vendor; Enabled = vendor.CheckVendorAccess( from ); } public override void OnClick() { m_Vendor.VendorSell( this.Owner.From ); } } } namespace Server { public interface IShopSellInfo { //get display name for an item string GetNameFor( Item item ); //get price for an item which the player is selling int GetSellPriceFor( Item item ); //get price for an item which the player is buying int GetBuyPriceFor( Item item ); //can we sell this item | <
CODE |
Add( new GenericBuyInfo( "1041280", typeof( InteriorDecorator ), 10001, 20, 0xFC1, 0 ) ); |