AvatarsConquest/Scripts/Mobiles/Base/GenericBuy.cs

347 lines
No EOL
7.6 KiB
C#

using System;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Network;
namespace Server.Mobiles
{
public class GenericBuyInfo : IBuyItemInfo
{
private class DisplayCache : Container
{
private static DisplayCache m_Cache;
public static DisplayCache Cache {
get {
if ( m_Cache == null || m_Cache.Deleted )
m_Cache = new DisplayCache();
return m_Cache;
}
}
private Dictionary<Type, IEntity> m_Table;
private List<Mobile> m_Mobiles;
public DisplayCache() : base( 0 )
{
m_Table = new Dictionary<Type, IEntity>();
m_Mobiles = new List<Mobile>();
}
public IEntity Lookup( Type key )
{
IEntity e = null;
m_Table.TryGetValue( key, out e );
return e;
}
public void Store( Type key, IEntity obj, bool cache )
{
if ( cache )
m_Table[key] = obj;
if ( obj is Item )
{
Item sell = (Item)obj;
if ( sell is BaseJewel )
((BaseJewel)sell).GemType = GemType.None;
AddItem( (Item)obj );
}
else if ( obj is Mobile )
m_Mobiles.Add( (Mobile)obj );
}
public DisplayCache( Serial serial ) : base( serial )
{
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
for ( int i = 0; i < m_Mobiles.Count; ++i )
m_Mobiles[i].Delete();
m_Mobiles.Clear();
for ( int i = Items.Count - 1; i >= 0; --i )
if ( i < Items.Count )
Items[i].Delete();
if ( m_Cache == this )
m_Cache = null;
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( m_Mobiles );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
m_Mobiles = reader.ReadStrongMobileList();
for ( int i = 0; i < m_Mobiles.Count; ++i )
m_Mobiles[i].Delete();
m_Mobiles.Clear();
for ( int i = Items.Count - 1; i >= 0; --i )
if ( i < Items.Count )
Items[i].Delete();
if ( m_Cache == null )
m_Cache = this;
else
Delete();
m_Table = new Dictionary<Type, IEntity>();
}
}
private Type m_Type;
private string m_Name;
private int m_Price;
private int m_MaxAmount, m_Amount;
private int m_ItemID;
private int m_Hue;
private object[] m_Args;
private IEntity m_DisplayEntity;
public virtual int ControlSlots{ get{ return 0; } }
public virtual bool CanCacheDisplay{ get{ return false; } } //return ( m_Args == null || m_Args.Length == 0 ); }
private bool IsDeleted( IEntity obj )
{
if ( obj is Item )
return ((Item)obj).Deleted;
else if ( obj is Mobile )
return ((Mobile)obj).Deleted;
return false;
}
public void DeleteDisplayEntity()
{
if ( m_DisplayEntity == null )
return;
m_DisplayEntity.Delete();
m_DisplayEntity = null;
}
public IEntity GetDisplayEntity()
{
if ( m_DisplayEntity != null && !IsDeleted( m_DisplayEntity ) )
return m_DisplayEntity;
bool canCache = this.CanCacheDisplay;
if ( canCache )
m_DisplayEntity = DisplayCache.Cache.Lookup( m_Type );
if ( m_DisplayEntity == null || IsDeleted( m_DisplayEntity ) )
m_DisplayEntity = GetEntity();
DisplayCache.Cache.Store( m_Type, m_DisplayEntity, canCache );
return m_DisplayEntity;
}
public Type Type
{
get{ return m_Type; }
set{ m_Type = value; }
}
public string Name
{
get{ return m_Name; }
set{ m_Name = value; }
}
public int DefaultPrice{ get{ return m_PriceScalar; } }
private int m_PriceScalar;
public int PriceScalar
{
get{ return m_PriceScalar; }
set{ m_PriceScalar = value; }
}
public int Price
{
get
{
if ( m_PriceScalar != 0 )
{
if ( m_Price > 5000000 )
{
long price = m_Price;
price *= m_PriceScalar;
price += 50;
price /= 100;
if ( price > int.MaxValue )
price = int.MaxValue;
return (int)price;
}
return ( ((m_Price * m_PriceScalar) + 50) / 100 );
}
return m_Price;
}
set{ m_Price = value; }
}
public int ItemID
{
get{ return m_ItemID; }
set{ m_ItemID = value; }
}
public int Hue
{
get{ return m_Hue; }
set{ m_Hue = value; }
}
public int Amount
{
get{ return m_Amount; }
set{ if ( value < 0 ) value = 0; m_Amount = value; }
}
public int MaxAmount
{
get{ return m_MaxAmount; }
set{ m_MaxAmount = value; }
}
public object[] Args
{
get{ return m_Args; }
set{ m_Args = value; }
}
public GenericBuyInfo( Type type, int price, int amount, int itemID, int hue ) : this( null, type, price, amount, itemID, hue, null )
{
}
public GenericBuyInfo( string name, Type type, int price, int amount, int itemID, int hue ) : this( name, type, price, amount, itemID, hue, null )
{
}
public GenericBuyInfo( Type type, int price, int amount, int itemID, int hue, object[] args ) : this( null, type, price, amount, itemID, hue, args )
{
}
public GenericBuyInfo( string name, Type type, int price, int amount, int itemID, int hue, object[] args )
{
if ( amount > 10 )
amount = Utility.RandomMinMax( (amount-5), (amount+10) );
m_Type = type;
m_Price = price;
m_MaxAmount = m_Amount = amount;
m_ItemID = itemID;
m_Hue = hue;
m_Args = args;
if ( name == null )
m_Name = itemID < 0x4000 ? (1020000 + itemID).ToString() : (1078872 + itemID).ToString();
else
m_Name = name;
}
//get a new instance of an object (we just bought it)
public virtual IEntity GetEntity()
{
if ( m_Args == null || m_Args.Length == 0 )
return (IEntity)Activator.CreateInstance( m_Type );
return (IEntity)Activator.CreateInstance( m_Type, m_Args );
//return (Item)Activator.CreateInstance( m_Type );
}
//Attempt to restock with item, (return true if restock sucessful)
public bool Restock( Item item, int amount )
{
return false;
/*if ( item.GetType() == m_Type )
{
if ( item is BaseWeapon )
{
BaseWeapon weapon = (BaseWeapon)item;
if ( weapon.Quality == WeaponQuality.Low || weapon.Quality == WeaponQuality.Exceptional || (int)weapon.DurabilityLevel > 0 || (int)weapon.DamageLevel > 0 || (int)weapon.AccuracyLevel > 0 )
return false;
}
if ( item is BaseArmor )
{
BaseArmor armor = (BaseArmor)item;
if ( armor.Quality == ArmorQuality.Low || armor.Quality == ArmorQuality.Exceptional || (int)armor.Durability > 0 || (int)armor.ProtectionLevel > 0 )
return false;
}
m_Amount += amount;
return true;
}
else
{
return false;
}*/
}
public void OnRestock()
{
if ( m_Amount <= 0 )
{
m_MaxAmount *= 2;
if ( m_MaxAmount >= 999 )
m_MaxAmount = 999;
}
else
{
/* NOTE: According to UO.com, the quantity is halved if the item does not reach 0
* Here we implement differently: the quantity is halved only if less than half
* of the maximum quantity was bought. That is, if more than half is sold, then
* there's clearly a demand and we should not cut down on the stock.
*/
int halfQuantity = m_MaxAmount;
if ( halfQuantity >= 999 )
halfQuantity = 640;
else if ( halfQuantity > 20 )
halfQuantity /= 2;
if ( m_Amount >= halfQuantity )
m_MaxAmount = halfQuantity;
}
m_Amount = m_MaxAmount;
}
}
}