using System;
using System.Collections;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Gumps;
using Server.Prompts;
using Server.Targeting;
using Server.Misc;

namespace Server.Mobiles
{
	public class VendorItem
	{
		private int m_Price;
		private string m_Description;
		private Item m_Item;
		
		public VendorItem( Item item, int price, string description )
		{
			m_Item = item;
			m_Price = price;
			m_Description = description;
		}
		
		public Item Item{ get{ return m_Item; } }
		public int Price{ get{ return m_Price; } set{ m_Price = value; } }
		public string Description{ get{ return m_Description; } set{ m_Description = value; } }
		
		public bool IsForSale{ get{ return ( m_Item != null && !m_Item.Deleted && m_Price > 0 ); } }
	}
	
	public class VendorBackpack : Backpack
	{
		[Constructable]
		public VendorBackpack()
		{
			Layer = Layer.Backpack;
			Weight = 1.0;
		}

		public override int MaxWeight{ get{ return 0; } }

		public override bool CheckContentDisplay( Mobile from )
		{
			object root = this.RootParent;

			if ( root is PlayerVendor && ((PlayerVendor)root).IsOwner( from ) )
				return true;
			else
				return base.CheckContentDisplay( from );
		}

		public override bool CheckHold( Mobile m, Item item, bool message, bool checkItems )
		{
			if ( !base.CheckHold( m, item, message, checkItems ) )
				return false;

			Multis.BaseHouse house = Multis.BaseHouse.FindHouseAt( this );

			if ( house != null && house.IsAosRules && !house.CheckAosStorage( 1 + item.TotalItems ) )
			{
				if ( message )
					m.SendLocalizedMessage( 1061839 ); // This action would exceed the secure storage limit of the house.

				return false;
			}

			return true;
		}
		
		public override bool IsAccessibleTo( Mobile m )
		{
			return true;
		}

		public override bool CheckItemUse( Mobile from, Item item )
		{
			if ( !base.CheckItemUse( from, item ) )
				return false;

			object root = this.RootParent;

			if ( root is PlayerVendor && ((PlayerVendor)root).IsOwner( from ) )
				return true;

			if ( item is Container || item is Engines.BulkOrders.BulkOrderBook )
				return true;

			from.SendLocalizedMessage( 500447 ); // That is not accessible.
			return false;
		}

		public override bool CheckTarget( Mobile from, Target targ, object targeted )
		{
			if ( !base.CheckTarget( from, targ, targeted ) )
				return false;

			object root = this.RootParent;

			if ( root is PlayerVendor && ((PlayerVendor)root).IsOwner( from ) )
				return true;

			return ( targ is PlayerVendor.PVBuyTarget );
		}

		public override void OnSingleClickContained( Mobile from, Item item )
		{
			if ( RootParent is PlayerVendor )
			{
				PlayerVendor vend = (PlayerVendor)RootParent;
				
				VendorItem vi = (VendorItem)vend.SellItems[item];
				
				if ( vi != null )
				{
					if ( vi.IsForSale )
						item.LabelTo( from, 1043304, vi.Price.ToString() ); // Price: ~1_COST~
					else
						item.LabelTo( from, 1043307 ); // Price: Not for sale.
					
					if ( vi.Description != null && vi.Description != "" )
						item.LabelTo( from, 1043305, vi.Description ); // Description: ~1_DESC~
				}
			}
			
			base.OnSingleClickContained( from, item );
		}

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

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

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

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

			int version = reader.ReadInt();
		}
	}
	
	public class PlayerVendor : Mobile
	{
		private Hashtable m_SellItems;
		private Mobile m_Owner;
		private int m_BankAccount;
		private int m_HoldGold;
		private Timer m_PayTimer;
		private bool m_Destroying;

		public bool Destroying
		{
			get{ return m_Destroying; }
			set{ m_Destroying = value; }
		}

		[CommandProperty( AccessLevel.GameMaster )]
		public Mobile Owner{ get{ return m_Owner; } set{ m_Owner = value; } }

		public override bool CanBeDamaged()
		{
			return m_Destroying;
		}
		
		public PlayerVendor( Mobile owner )
		{
			m_Owner = owner;

			m_BankAccount = 1000;
			m_HoldGold = 0;
			m_SellItems = new Hashtable();

			CantWalk = true;

			if ( !Core.AOS )
				NameHue = 0x35;

			InitStats( 75, 75, 75 );
			InitBody();
			InitOutfit();

			m_PayTimer = new PayTimer( this );
			m_PayTimer.Start();
		}

		public override DeathMoveResult GetInventoryMoveResultFor( Item item )
		{
			return DeathMoveResult.MoveToCorpse;
		}
		
		public PlayerVendor( Serial serial ) : base( serial )
		{
		}
		
		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );
			
			writer.Write( (int)0 );//version
			writer.Write( m_Owner );
			writer.Write( m_BankAccount );
			writer.Write( m_HoldGold );
			
			ArrayList list = new ArrayList( m_SellItems.Values );
			
			writer.Write( list.Count );
			for (int i=0;i<list.Count;i++)
			{
				VendorItem vi = (VendorItem)list[i];
				writer.Write( vi.Item );
				writer.Write( vi.Price );
				writer.Write( vi.Description );
			}
		}
		
		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );
			
			int version = reader.ReadInt();
			
			switch ( version )
			{
				case 0:
				{
					m_Owner = reader.ReadMobile();
					m_BankAccount = reader.ReadInt();
					m_HoldGold = reader.ReadInt();
					
					int count = reader.ReadInt();
					m_SellItems = new Hashtable();
					for (int i=0;i<count;i++)
					{
						Item item = reader.ReadItem();
						int p = reader.ReadInt();
						string d = reader.ReadString();
						
						if ( item != null && !item.Deleted )
							m_SellItems[item] = new VendorItem( item, p, d );
					}
					break;	
				}
			}
			
			m_PayTimer = new PayTimer( this );
			m_PayTimer.Start();

			Blessed = false;

			if ( Core.AOS && NameHue == 0x35 )
				NameHue = -1;
		}
		
		public void InitBody()
		{
			Hue = Utility.RandomSkinHue();
			SpeechHue = 0x3B2;

			if ( !Core.AOS )
				NameHue = 0x35;

			if ( this.Female = Utility.RandomBool() )
			{
				this.Body = 0x191;
				this.Name = NameList.RandomName( "female" );
			}
			else
			{
				this.Body = 0x190;
				this.Name = NameList.RandomName( "male" );
			}
		}
		
		public virtual void InitOutfit()
		{
			Item item = new FancyShirt( Utility.RandomNeutralHue() );
			item.Layer = Layer.InnerTorso;
			AddItem( item );
			AddItem( new LongPants( Utility.RandomNeutralHue() ) );
			AddItem( new BodySash( Utility.RandomNeutralHue() ) );
			AddItem( new Boots( Utility.RandomNeutralHue() ) );
			AddItem( new Cloak( Utility.RandomNeutralHue()) );

			Item hair = new Item( Utility.RandomList( 0x203B, 0x2049, 0x2048, 0x204A ) );
			hair.Hue = Utility.RandomNondyedHue();
			hair.Layer = Layer.Hair;
			hair.Movable = false;
			AddItem( hair );

			Container pack = new VendorBackpack();
			pack.Movable = false;
			AddItem( pack );
		}
		
		[CommandProperty( AccessLevel.GameMaster )]
		public int BankAccount
		{
			get { return m_BankAccount; }
			set { m_BankAccount = value; }
		}
		
		[CommandProperty( AccessLevel.GameMaster )]
		public int HoldGold
		{
			get { return m_HoldGold; }
			set { m_HoldGold = value; }
		}

		public int ChargePerDay
		{
			get
			{ 
				int total = 0;
				foreach (VendorItem v in m_SellItems.Values)
				{
					total += v.Price;
				}

				total -= 500;

				if ( total < 0 )
					total = 0;

				return 20 + (total / 500);
			}
		}

		public Hashtable SellItems { get{ return m_SellItems; } }
		
		public bool IsOwner( Mobile m )
		{
			return ( m == m_Owner || m.AccessLevel >= AccessLevel.GameMaster );
		}

		public override bool OnBeforeDeath()
		{
			if ( !base.OnBeforeDeath() )
				return false;

			Item shoes = this.FindItemOnLayer( Layer.Shoes );

			if ( shoes is Sandals )
				shoes.Hue = 0;

			return true;
		}
		
		public override void OnAfterDelete()
		{
			m_PayTimer.Stop();
		}
		
		public override bool IsSnoop( Mobile from )
		{
			return false;
		}
		
		public override bool OnDragDrop( Mobile from, Item item )
		{
			if ( IsOwner( from ) )
			{
				if ( item is Gold )
				{
					SayTo( from, 503210 ); // I'll take that to fund my services.
					m_BankAccount += item.Amount;
					item.Delete();
					return true;
				}
				else
				{
					Container pack = Backpack;

					if ( pack != null && pack.TryDropItem( from, item, false ) )
					{
						GiveItem( from, item, null );
						return true;
					}
					else
					{
						SayTo( from, 503211 ); // I can't carry any more.
						return false;
					}
				}
			}
			else
			{
				SayTo( from, 503209 );// I can only take item from the shop owner.
				return false;
			}
		}
		
		private void GiveItem( Mobile from, Item item, Item target )
		{
			if ( !(target is Container) )
				target = null;

			if ( target != null )
			{
				VendorItem targetVI = (VendorItem) m_SellItems[target];

				if ( targetVI != null && targetVI.IsForSale )
					return;
			}

			VendorItem vi;
			string name;

			vi = AddInfo( item, target );

			if ( item.Name != null && item.Name != "" )
				name = item.Name;
			else
				name = item.ItemData.Name;

			from.SendLocalizedMessage( 1043303, name  ); // Type in a price and description for ~1_ITEM~ (ESC=not for sale)
			from.Prompt = new VendorPricePrompt( this, item, target, vi );	
		}
		
		private VendorItem AddInfo( Item item, Item target )
		{
			int defPrice = 999;
			VendorItem vi;
			
			if ( item is BaseBook || ( item is Container && item.Items.Count == 0 ) )//|| item is KeyRing )
			{
				defPrice = 0;
			}
			else if ( target != null )
			{
				vi = (VendorItem)m_SellItems[target];
				
				if ( vi != null && vi.Price > 0 )
					defPrice = 0;
			}
			
			vi = new VendorItem( item, defPrice, "" );
			m_SellItems[item] = vi;

			if ( defPrice == 0 )
			{
				for (int i=0;i<item.Items.Count;i++)
					AddInfo( (Item)item.Items[i], null );
			}

			item.InvalidateProperties();
			
			return vi;
		}

		public override bool CheckNonlocalDrop( Mobile from, Item item, Item target )
		{
			if ( IsOwner( from ) )
			{
				GiveItem( from, item, target );
				return true;
			}
			else
			{
				SayTo( from, 503209 );// I can only take item from the shop owner.
				return false;
			}
		}
		
		public void RemoveInfo( Item item )
		{
			m_SellItems.Remove( item );
			for (int i=0;i<item.Items.Count;i++)
				RemoveInfo( (Item)item.Items[i] );

			item.InvalidateProperties();
		}

		public override bool CheckNonlocalLift( Mobile from, Item item )
		{
			if ( IsOwner( from ) )
			{
				RemoveInfo( item );
				return true;
			}
			else
			{
				SayTo( from, 503223 );// If you'd like to purchase an item, just ask.
				return false;
			}
		}

		public override void OnDoubleClick( Mobile from )
		{
			if ( IsOwner( from ) )
			{
				from.SendGump( new PlayerVendorOwnerGump( this, from ) );
			}
			else
			{
				Container pack = Backpack;

				if ( pack != null )
				{
					SayTo( from, 503208 );// Take a look at my goods.
					pack.DisplayTo( from );
				}
			}
		}

		public override void GetChildProperties( ObjectPropertyList list, Item item )
		{
			base.GetChildProperties( list, item );

			VendorItem vi = (VendorItem)m_SellItems[item];

			if ( vi != null )
			{
				if ( !vi.IsForSale )
					list.Add( 1043307 ); // Price: Not for sale.
				else if ( vi.Price <= 0 )
					list.Add( 1043306 ); // Price: FREE!
				else
					list.Add( 1043304, vi.Price.ToString() ); // Price: ~1_COST~

				if ( vi.Description != null && vi.Description.Length > 0 )
					list.Add( 1043305, vi.Description ); // Description: ~1_DESC~
			}
		}

		public void GiveGold( Mobile from )
		{
			if ( m_HoldGold > 0 )
			{
				Item item = null;

				if ( m_HoldGold < 1000000 )
				{
					if ( m_HoldGold < 5000 )
						item = new Gold( m_HoldGold );
					else
						item = new BankCheck( m_HoldGold );

					m_HoldGold = 0;
				}
				else
				{
					item = new BankCheck( 1000000 );
					m_HoldGold -= 1000000;
				}
				
				if ( item != null )
				{
					from.BankBox.DropItem( item );
					SayTo( from, 503234 ); // All the gold I have been carrying for you has been deposited into your bank account.
				}
			}
			else
			{
				SayTo( from, 503215 ); // I am holding no gold for you.
			}
		}
		
		private void Dismiss( Mobile from )
		{
			Container pack = this.Backpack;

			if ( pack != null && pack.Items.Count > 0 )
			{
				SayTo( from, 503229 ); // Thou canst replace me until thy removest all the item from my stock.
				return;
			}

			GiveGold( from );

			if ( m_HoldGold > 0 )
			{
				from.AddToBackpack( new BankCheck( m_HoldGold ) );
				m_HoldGold = 0;
			}

			Delete();
		}
		
		public override void DisplayPaperdollTo( Mobile m )
		{
			Container pack = Backpack;

			if ( pack != null )
			{
				SayTo( m, 503208 );// Take a look at my goods.
				pack.DisplayTo( m );
			}
		}

		public override bool HandlesOnSpeech( Mobile from )
		{
			return ( from.GetDistanceToSqrt( this ) <= 3 );
		}

		public bool WasNamed( string speech )
		{
			string name = this.Name;

			return ( name != null && Insensitive.StartsWith( speech, name ) );
		}

		public override void OnSpeech( SpeechEventArgs e )
		{
			Mobile from = e.Mobile;
			
			if ( e.Handled )
				return;
			
			if ( e.HasKeyword( 0x3C ) || (e.HasKeyword( 0x171 ) && WasNamed( e.Speech ))  ) // vendor buy, *buy*
			{
				if ( IsOwner( from ) )
				{
					SayTo( from, 503212 ); // You own this shop, just take what you want.
				}
				else
				{
					from.SendLocalizedMessage( 503213 );// Select the item you wish to buy.
					from.Target = new PVBuyTarget();
					e.Handled = true;
				}
			} 
			else if ( e.HasKeyword( 0x3D ) || (e.HasKeyword( 0x172 ) && WasNamed( e.Speech )) ) // vendor browse, *browse
			{
				Container pack = Backpack;

				if ( pack != null )
				{
					SayTo( from, IsOwner( from ) ? 1010642 : 503208 );// Take a look at my/your goods.
					pack.DisplayTo( from );
					e.Handled = true;
				}
			}
			else if ( e.HasKeyword( 0x3E ) || (e.HasKeyword( 0x173 ) && WasNamed( e.Speech )) ) // vendor collect, *collect
			{
				if ( IsOwner( from ) )
				{
					GiveGold( from );
					e.Handled = true;
				}
			}
			else if ( e.HasKeyword( 0x3F ) || (e.HasKeyword( 0x174 ) && WasNamed( e.Speech )) ) // vendor status, *status
			{
				if ( IsOwner( from  ) )
				{
					from.SendGump( new PlayerVendorOwnerGump( this, from ) );
					e.Handled = true;
				}
				else
				{
					SayTo( from, 503226 ); // What do you care? You don't run this shop.	
				}
			}
			else if ( e.HasKeyword( 0x40 ) || (e.HasKeyword( 0x175 ) && WasNamed( e.Speech )) ) // vendor dismiss, *dismiss
			{
				if ( IsOwner( from ) )
					Dismiss( from );
			}
			else if ( e.HasKeyword( 0x41 ) || (e.HasKeyword( 0x176 ) && WasNamed( e.Speech )) ) // vendor cycle, *cycle
			{
				if ( IsOwner( from ) )
					this.Direction = this.GetDirectionTo( from );
			}
		}
		
		private class PayTimer : Timer
		{
			private PlayerVendor m_Vendor;
			
			public PayTimer( PlayerVendor vend ) : base( TimeSpan.FromMinutes( Clock.MinutesPerUODay ), TimeSpan.FromMinutes( Clock.MinutesPerUODay ) )
			{
				m_Vendor = vend;
				Priority = TimerPriority.OneMinute;
			}
			
			protected override void OnTick()
			{
				int pay = m_Vendor.ChargePerDay;
				if ( m_Vendor.BankAccount < pay )
				{
					pay -= m_Vendor.BankAccount;
					m_Vendor.BankAccount = 0;
					
					if ( m_Vendor.HoldGold < pay )
					{
						m_Vendor.Say( 503235 ); // I regret nothing!postal
						m_Vendor.Destroying = true;
						m_Vendor.Blessed = false;
						m_Vendor.Kill();
					}
					else
					{
						m_Vendor.HoldGold -= pay;
					}
				}
				else
				{
					m_Vendor.BankAccount -= pay;
				}
			}
		}
		
		public class PVBuyTarget : Target
		{
			public PVBuyTarget() : base( 3, false, TargetFlags.None )
			{
				AllowNonlocal = true;
			}
			
			protected override void OnTarget( Mobile from, object targeted )
			{
				if ( targeted is Item )
				{
					Item item = (Item)targeted;

					PlayerVendor vendor = item.RootParent as PlayerVendor;

					if ( vendor == null )
						return;

					VendorItem vi = (VendorItem)vendor.SellItems[item];
					
					if ( vi != null )
					{
						if ( vi.IsForSale )
							from.SendGump( new PlayerVendorBuyGump( item, vendor, vi ) );
						else
							vendor.SayTo( from, 503202 ); // This item is not for sale.

						return;
					}

					vendor.SayTo( from, 503216 ); // You can't buy that.
				}
			}
		}
	}
}

namespace Server.Prompts
{
	public class VendorPricePrompt : Prompt
	{
		private PlayerVendor m_Vendor;
		private Item m_Item;
		private Item m_Cont;
		private VendorItem m_VI;

		public VendorPricePrompt( PlayerVendor vendor, Item item, Item target, VendorItem vi )
		{
			m_Vendor = vendor;
			m_Item = item;
			m_Cont = target;
			m_VI = vi;
		}

		private void RecurseClearSales( Container cont )
		{
			ArrayList items = cont.Items;

			for ( int i = 0; i < items.Count; ++i )
			{
				Item item = (Item)items[i];

				m_Vendor.SellItems.Remove( item );
				item.InvalidateProperties();

				if ( item is Container )
					RecurseClearSales( (Container) item );
			}
		}

		private void SetInfo( Mobile from, int price, string desc )
		{
			bool allowed = true;

			if ( price <= 0 )
			{
				VendorItem vi = null;

				if ( m_Cont != null )
					vi = (VendorItem)m_Vendor.SellItems[m_Cont];

				if ( vi == null || vi.Price == 0 )
				{
					if ( m_Item is Container )
					{
						if ( m_Item is LockableContainer && ((LockableContainer)m_Item).Locked )
						{
							price = 999;
							m_Vendor.SayTo( from, 1043298 ); // Locked items may not be made not-for-sale.
						}
						else if ( m_Item.Items.Count > 0 )
						{
							price = 999;
							m_Vendor.SayTo( from, 1043299 ); // To be not for sale, all items in a container must be for sale.
						}
					}
					else if ( !(m_Item is BaseBook) && !(m_Item is Engines.BulkOrders.BulkOrderBook) )
					{
						m_Vendor.SayTo( from, 1043301 );// Only the following may be made not-for-sale: books, containers, keyrings, and items in for-sale containers.
						allowed = false;
					}
				}
			}

			if ( price > 0 && m_Item is Container )
				RecurseClearSales( (Container) m_Item );
			
			if ( allowed )
			{
				m_VI.Price = price;
				m_VI.Description = desc;

				m_VI.Item.InvalidateProperties();
			}
		}
		
		public override void OnResponse( Mobile from, string text )
		{
			int space = text.IndexOf( ' ' );
			if ( space == -1 )
				space = text.Length;
			int price = 0;
			string desc = "";
			
			try
			{
				price = Convert.ToInt32( text.Substring( 0, space ) );
			}
			catch
			{
				price = 0;
			}
			
			if ( space < text.Length )
				desc = text.Substring( space+1 );
			
			SetInfo( from, price, desc );
		}
		
		public override void OnCancel( Mobile from )
		{
			SetInfo( from, 0, "" );
		}
	}
}


PlayerVendor.cs Dosyasına geldiğim zaman hepinizin bildiği korkutucu vendor para buguyla karsı karsıya kalıyoruz ancak benim sanırım bir hatam var.

Değiştirdiğim bölüm



		public int ChargePerDay
		{
			get
			{ 
				int total = 0;
				foreach (VendorItem v in m_SellItems.Values)
				{
					total += v.Price;
				}

				total -= 500;

				if ( total < 0 )
					total = 0;

				return 20 + (total / 500);
			}
		}



Ve Buda Eklediğim Bölüm

public int ChargePerRealWorldDay
		{
			get
			{
				if ( BaseHouse.NewVendorSystem )
				{
					long total = 0;
					foreach ( VendorItem vi in m_SellItems.Values )
					{
						total += vi.Price;
					}

					return (int)(60 + (total / 500) * 3);
				}
				else
				{
					return ChargePerDay * 12;
				}
			}
		}


Ancak bug yine oluyor 24 saat sonra vendora yine para geliyor :S Hatam nerede anlamış değilim Yardım ederseniz sevinirim.
Kanfelaketi üyesi avatar
ummmm
Bu para bugunun ne olduğunu bilmediğim için birşey söyleyemiycem bide onun ne olduğunu anlatsan ona göre yardım etsek ?
oguz12 üyesi avatar
birde benmde sorucam bişe war bankanın üstüne doğru merdiveni nasıl yapabilirim

Üye Ol veya Giriş Yap

Bu forum başlığına mesaj atmak istiyorsanız hemen üye olun veya giriş yapın.

Benzer Konular