Files
Unstable Kitsune b918192e4e Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
2023-11-28 23:20:26 -05:00

1274 lines
43 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.ContextMenus;
using Server.Commands;
using Server.Targeting;
using Server.Regions;
using Server.Gumps;
using Server.Engines.Auction;
namespace Server.Engines.VendorSearching
{
public class VendorSearch
{
public static string FilePath = Path.Combine("Saves/Misc", "VendorSearch.bin");
public static Ultima.StringList StringList { get; private set; }
public static List<SearchItem> DoSearchAuction(Mobile m, SearchCriteria criteria)
{
if (criteria == null || Auction.Auction.Auctions == null || Auction.Auction.Auctions.Count == 0)
{
return null;
}
List<SearchItem> list = new List<SearchItem>();
bool excludefel = criteria.Details.FirstOrDefault(d => d.Attribute is Misc && (Misc)d.Attribute == Misc.ExcludeFel) != null;
foreach (Auction.Auction pv in Auction.Auction.Auctions.Where(pv => pv.AuctionItem != null &&
pv.AuctionItem.Map != Map.Internal &&
pv.AuctionItem.Map != null &&
pv.OnGoing &&
(!excludefel || pv.AuctionItem.Map != Map.Felucca)))
{
list.Add(new SearchItem(pv.Safe, pv.AuctionItem, (int)pv.Buyout, false));
}
switch (criteria.SortBy)
{
case SortBy.LowToHigh: list = list.OrderBy(vi => vi.Price).ToList(); break;
case SortBy.HighToLow: list = list.OrderBy(vi => -vi.Price).ToList(); break;
}
return list;
}
public static List<SearchItem> DoSearch(Mobile m, SearchCriteria criteria)
{
if (criteria == null || PlayerVendor.PlayerVendors == null || PlayerVendor.PlayerVendors.Count == 0)
return null;
List<SearchItem> list = new List<SearchItem>();
bool excludefel = criteria.Details.FirstOrDefault(d => d.Attribute is Misc && (Misc)d.Attribute == Misc.ExcludeFel) != null;
foreach (PlayerVendor pv in PlayerVendor.PlayerVendors.Where(pv => pv.Map != Map.Internal &&
pv.Map != null &&
pv.Backpack != null &&
pv.VendorSearch &&
pv.Backpack.Items.Count > 0 &&
(!excludefel || pv.Map != Map.Felucca)))
{
List<Item> items = GetItems(pv);
foreach (Item item in items)
{
VendorItem vendorItem = pv.GetVendorItem(item);
int price = 0;
bool isChild = false;
if (vendorItem != null)
{
price = vendorItem.Price;
}
else if (item.Parent is Container)
{
vendorItem = GetParentVendorItem(pv, (Container)item.Parent);
if (vendorItem != null)
{
isChild = true;
price = vendorItem.Price;
}
}
if (price > 0 && CheckMatch(item, price, criteria))
{
list.Add(new SearchItem(pv, item, price, isChild));
}
}
ColUtility.Free(items);
}
switch (criteria.SortBy)
{
case SortBy.LowToHigh: list = list.OrderBy(vi => vi.Price).ToList(); break;
case SortBy.HighToLow: list = list.OrderBy(vi => -vi.Price).ToList(); break;
}
return list;
}
private static VendorItem GetParentVendorItem(PlayerVendor pv, Container parent)
{
VendorItem vendorItem = pv.GetVendorItem(parent);
if (vendorItem == null)
{
if (parent.Parent is Container)
{
return GetParentVendorItem(pv, (Container)parent.Parent);
}
}
return vendorItem;
}
public static bool CheckMatch(Item item, int price, SearchCriteria searchCriteria)
{
if (item is CommodityDeed && ((CommodityDeed)item).Commodity != null)
{
item = ((CommodityDeed)item).Commodity;
}
if (searchCriteria.MinPrice > -1 && price < searchCriteria.MinPrice)
return false;
if (searchCriteria.MaxPrice > -1 && price > searchCriteria.MaxPrice)
return false;
if (!string.IsNullOrEmpty(searchCriteria.SearchName))
{
string name;
if (item is CommodityDeed && ((CommodityDeed)item).Commodity is ICommodity)
{
var commodity = (ICommodity)((CommodityDeed)item).Commodity;
if (!string.IsNullOrEmpty(commodity.Description.String))
{
name = commodity.Description.String;
}
else
{
name = StringList.GetString(commodity.Description.Number);
}
}
else
{
name = GetItemName(item);
}
if(name == null)
{
return false; // TODO? REturn null names?
}
if (!CheckKeyword(searchCriteria.SearchName, item) && name.ToLower().IndexOf(searchCriteria.SearchName.ToLower()) < 0)
{
return false;
}
}
if (searchCriteria.SearchType != Layer.Invalid && searchCriteria.SearchType != item.Layer)
{
return false;
}
if(searchCriteria.Details.Count == 0)
return true;
foreach(SearchDetail detail in searchCriteria.Details)
{
object o = detail.Attribute;
int value = detail.Value;
if (value == 0)
value = 1;
if (o is AosAttribute)
{
AosAttributes attrs = RunicReforging.GetAosAttributes(item);
if (attrs == null || attrs[(AosAttribute)o] < value)
return false;
}
else if (o is AosWeaponAttribute)
{
AosWeaponAttributes attrs = RunicReforging.GetAosWeaponAttributes(item);
if ((AosWeaponAttribute)o == AosWeaponAttribute.MageWeapon)
{
if (attrs == null || attrs[(AosWeaponAttribute)o] == 0 || attrs[(AosWeaponAttribute)o] > Math.Max(0, 30 - value))
return false;
}
else if (attrs == null || attrs[(AosWeaponAttribute)o] < value)
return false;
}
else if (o is SAAbsorptionAttribute)
{
SAAbsorptionAttributes attrs = RunicReforging.GetSAAbsorptionAttributes(item);
if (attrs == null || attrs[(SAAbsorptionAttribute)o] < value)
return false;
}
else if (o is AosArmorAttribute)
{
AosArmorAttributes attrs = RunicReforging.GetAosArmorAttributes(item);
if (attrs == null || attrs[(AosArmorAttribute)o] < value)
return false;
}
else if (o is SkillName)
{
if (detail.Category != Category.RequiredSkill)
{
AosSkillBonuses skillbonuses = RunicReforging.GetAosSkillBonuses(item);
if (skillbonuses != null)
{
bool hasSkill = false;
for (int i = 0; i < 5; i++)
{
SkillName check;
double bonus;
if (skillbonuses.GetValues(i, out check, out bonus) && check == (SkillName)o && bonus >= value)
{
hasSkill = true;
break;
}
}
if (!hasSkill)
return false;
}
else if (item is SpecialScroll && value >= 105)
{
if (((SpecialScroll)item).Skill != (SkillName)o || ((SpecialScroll)item).Value < value)
return false;
}
else
{
return false;
}
}
else if (!(item is BaseWeapon) || ((BaseWeapon)item).DefSkill != (SkillName)o)
{
return false;
}
}
else if (!CheckSlayer(item, o))
{
return false;
}
else if (o is AosElementAttribute)
{
if (item is BaseWeapon)
{
BaseWeapon wep = item as BaseWeapon;
if (detail.Category == Category.DamageType)
{
int phys, fire, cold, pois, nrgy, chaos, direct;
wep.GetDamageTypes(null, out phys, out fire, out cold, out pois, out nrgy, out chaos, out direct);
switch ((AosElementAttribute)o)
{
case AosElementAttribute.Physical: if (phys < value) return false; break;
case AosElementAttribute.Fire: if (fire < value) return false; break;
case AosElementAttribute.Cold: if (cold < value) return false; break;
case AosElementAttribute.Poison: if (pois < value) return false; break;
case AosElementAttribute.Energy: if (nrgy < value) return false; break;
case AosElementAttribute.Chaos: if (chaos < value) return false; break;
case AosElementAttribute.Direct: if (direct < value) return false; break;
}
}
else
{
switch ((AosElementAttribute)o)
{
case AosElementAttribute.Physical:
if (wep.WeaponAttributes.ResistPhysicalBonus < value) return false;
break;
case AosElementAttribute.Fire:
if (wep.WeaponAttributes.ResistFireBonus < value) return false;
break;
case AosElementAttribute.Cold:
if (wep.WeaponAttributes.ResistColdBonus < value) return false;
break;
case AosElementAttribute.Poison:
if (wep.WeaponAttributes.ResistPoisonBonus < value) return false;
break;
case AosElementAttribute.Energy:
if (wep.WeaponAttributes.ResistEnergyBonus < value) return false;
break;
}
}
}
else if (item is BaseArmor && detail.Category == Category.Resists)
{
BaseArmor armor = item as BaseArmor;
switch ((AosElementAttribute)o)
{
case AosElementAttribute.Physical:
if (armor.PhysicalResistance < value) return false;
break;
case AosElementAttribute.Fire:
if (armor.FireResistance < value) return false;
break;
case AosElementAttribute.Cold:
if (armor.ColdResistance < value) return false;
break;
case AosElementAttribute.Poison:
if (armor.PoisonResistance < value) return false;
break;
case AosElementAttribute.Energy:
if (armor.EnergyResistance < value) return false;
break;
}
}
else if (detail.Category != Category.DamageType)
{
AosElementAttributes attrs = RunicReforging.GetElementalAttributes(item);
if (attrs == null || attrs[(AosElementAttribute)o] < value)
{
return false;
}
}
else
{
return false;
}
}
else if (o is Misc)
{
switch ((Misc)o)
{
case Misc.ExcludeFel: break;
case Misc.GargoyleOnly:
if (!IsGargoyle(item))
return false;
break;
case Misc.NotGargoyleOnly:
if (IsGargoyle(item))
return false;
break;
case Misc.ElvesOnly:
if (!IsElf(item))
return false;
break;
case Misc.NotElvesOnly:
if (IsElf(item))
return false;
break;
case Misc.FactionItem:
if (!(item is Factions.IFactionItem))
return false;
break;
case Misc.PromotionalToken:
if (!(item is PromotionalToken))
return false;
break;
case Misc.Cursed:
if (item.LootType != LootType.Cursed)
return false;
break;
case Misc.NotCursed:
if (item.LootType == LootType.Cursed)
return false;
break;
case Misc.CannotRepair:
if (CheckCanRepair(item))
return false;
break;
case Misc.NotCannotBeRepaired:
if (!CheckCanRepair(item))
return false;
break;
case Misc.Brittle:
NegativeAttributes neg2 = RunicReforging.GetNegativeAttributes(item);
if (neg2 == null || neg2.Brittle == 0)
return false;
break;
case Misc.NotBrittle:
NegativeAttributes neg3 = RunicReforging.GetNegativeAttributes(item);
if (neg3 != null && neg3.Brittle > 0)
return false;
break;
case Misc.Antique:
NegativeAttributes neg4 = RunicReforging.GetNegativeAttributes(item);
if (neg4 == null || neg4.Antique == 0)
return false;
break;
case Misc.NotAntique:
NegativeAttributes neg5 = RunicReforging.GetNegativeAttributes(item);
if (neg5 != null && neg5.Antique > 0)
return false;
break;
}
}
else if (o is string)
{
string str = o as string;
if (str == "WeaponVelocity" && (!(item is BaseRanged) || ((BaseRanged)item).Velocity < value))
return false;
if (str == "SearingWeapon" && (!(item is BaseWeapon) || !((BaseWeapon)item).SearingWeapon))
return false;
if (str == "ArtifactRarity" && (!(item is IArtifact) || ((IArtifact)item).ArtifactRarity < value))
{
return false;
}
}
}
return true;
}
private static bool CheckSlayer(Item item, object o)
{
if (o is TalismanSlayerName && (TalismanSlayerName)o == TalismanSlayerName.Undead)
{
if (!(item is ISlayer) || ((((ISlayer)item).Slayer != SlayerName.Silver && ((ISlayer)item).Slayer2 != SlayerName.Silver)))
{
if (!(item is BaseTalisman) || ((BaseTalisman)item).Slayer != TalismanSlayerName.Undead)
{
return false;
}
}
}
else
{
if (o is SlayerName && (!(item is ISlayer) || (((ISlayer)item).Slayer != (SlayerName)o && ((ISlayer)item).Slayer2 != (SlayerName)o)))
{
return false;
}
else if (o is TalismanSlayerName && (!(item is BaseTalisman) || ((BaseTalisman)item).Slayer != (TalismanSlayerName)o))
{
return false;
}
}
return true;
}
private static bool CheckCanRepair(Item item)
{
NegativeAttributes neg = RunicReforging.GetNegativeAttributes(item);
return neg != null && neg.NoRepair != 0;
}
private static bool CheckKeyword(string searchstring, Item item)
{
if (item is CommodityDeed && ((CommodityDeed)item).Commodity != null)
{
item = ((CommodityDeed)item).Commodity;
}
if (item is IResource)
{
var resName = CraftResources.GetName(((IResource)item).Resource);
if (resName.ToLower().IndexOf(searchstring.ToLower()) >= 0)
{
return true;
}
}
if (item is ICommodity)
{
var commodity = (ICommodity)item;
string name = commodity.Description.String;
if (string.IsNullOrEmpty(name) && commodity.Description.Number > 0)
{
name = StringList.GetString(commodity.Description.Number);
}
if (!string.IsNullOrEmpty(name) && name.ToLower().IndexOf(searchstring.ToLower()) >= 0)
{
return true;
}
}
return Keywords.ContainsKey(searchstring.ToLower()) && Keywords[searchstring.ToLower()] == item.GetType();
}
public static bool IsGargoyle(Item item)
{
if (item is BaseArmor)
{
return ((BaseArmor)item).RequiredRace == Race.Gargoyle;
}
else if (item is BaseWeapon)
{
return ((BaseWeapon)item).RequiredRace == Race.Gargoyle;
}
else if (item is BaseClothing)
{
return ((BaseClothing)item).RequiredRace == Race.Gargoyle;
}
else if (item is BaseJewel)
{
return ((BaseJewel)item).RequiredRace == Race.Gargoyle;
}
return false;
}
public static bool IsElf(Item item)
{
if (item is BaseArmor)
{
return ((BaseArmor)item).RequiredRace == Race.Elf;
}
else if (item is BaseWeapon)
{
return ((BaseWeapon)item).RequiredRace == Race.Elf;
}
else if (item is BaseClothing)
{
return ((BaseClothing)item).RequiredRace == Race.Elf;
}
else if (item is BaseJewel)
{
return ((BaseJewel)item).RequiredRace == Race.Elf;
}
return false;
}
public static SearchCriteria AddNewContext(PlayerMobile pm)
{
SearchCriteria criteria = new SearchCriteria();
Contexts[pm] = criteria;
return criteria;
}
public static SearchCriteria GetContext(PlayerMobile pm)
{
if (Contexts.ContainsKey(pm))
return Contexts[pm];
return null;
}
public static Dictionary<PlayerMobile, SearchCriteria> Contexts { get; set; }
public static List<SearchCategory> Categories { get; set; }
public static Dictionary<string, Type> Keywords { get; set; }
public static void Configure()
{
EventSink.WorldSave += OnSave;
EventSink.WorldLoad += OnLoad;
}
public static void OnSave(WorldSaveEventArgs e)
{
Persistence.Serialize(
FilePath,
writer =>
{
writer.Write(0);
writer.Write(Contexts == null ? 0 : Contexts.Where(kvp => !kvp.Value.IsEmpty).Count());
if (Contexts != null)
{
foreach (var kvp in Contexts.Where(kvp => !kvp.Value.IsEmpty))
{
writer.Write(kvp.Key);
kvp.Value.Serialize(writer);
}
}
});
}
public static void OnLoad()
{
Persistence.Deserialize(
FilePath,
reader =>
{
int version = reader.ReadInt();
int count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
PlayerMobile pm = reader.ReadMobile() as PlayerMobile;
var criteria = new SearchCriteria(reader);
if (pm != null)
{
if (Contexts == null)
Contexts = new Dictionary<PlayerMobile, SearchCriteria>();
Contexts[pm] = criteria;
}
}
});
}
public static void Initialize()
{
try
{
StringList = new Ultima.StringList("enu");
}
catch { }
CommandSystem.Register("GetOPLString", AccessLevel.Administrator, e =>
{
e.Mobile.BeginTarget(-1, false, TargetFlags.None, (m, targeted) =>
{
if (targeted is Item)
{
Console.WriteLine(GetItemName((Item)targeted));
e.Mobile.SendMessage(GetItemName((Item)targeted));
}
});
});
Categories = new List<SearchCategory>();
if (Contexts == null)
{
Contexts = new Dictionary<PlayerMobile, SearchCriteria>();
}
Timer.DelayCall(TimeSpan.FromSeconds(1), () =>
{
SearchCategory price = new SearchCategory(Category.PriceRange);
Categories.Add(price);
SearchCriteriaCategory.AllCategories.ToList().ForEach(x =>
{
SearchCategory cat = new SearchCategory(x.Category);
x.Criteria.ToList().ForEach(y =>
{
if (y.PropCliloc != 0)
{
cat.Register(y.Object, y.Cliloc, y.PropCliloc);
}
else
{
cat.Register(y.Object, y.Cliloc);
}
});
Categories.Add(cat);
});
SearchCategory sort = new SearchCategory(Category.Sort);
Categories.Add(sort);
});
Keywords = new Dictionary<string, Type>();
Keywords["power scroll"] = typeof(PowerScroll);
Keywords["stat scroll"] = typeof(StatCapScroll);
}
public static string GetItemName(Item item)
{
if (StringList == null || item.Name != null)
return item.Name;
ObjectPropertyList opl = new ObjectPropertyList(item);
item.GetProperties(opl);
if (opl == null)
{
//if there was a problem with this process, just return null
return null;
}
//since the object property list is based on a packet object, the property info is packed away in a packet format
byte[] data = opl.UnderlyingStream.UnderlyingStream.ToArray();
int index = 15; // First localization number index
string basestring = null;
//reset the number property
uint number = 0;
//if there's not enough room for another record, quit
if (index + 4 >= data.Length)
{
return null;
}
//read number property from the packet data
number = (uint)(data[index++] << 24 | data[index++] << 16 | data[index++] << 8 | data[index++]);
//reset the length property
ushort length = 0;
//if there's not enough room for another record, quit
if (index + 2 > data.Length)
{
return null;
}
//read length property from the packet data
length = (ushort)(data[index++] << 8 | data[index++]);
//determine the location of the end of the string
int end = index + length;
//truncate if necessary
if (end >= data.Length)
{
end = data.Length - 1;
}
//read the string into a StringBuilder object
StringBuilder s = new StringBuilder();
while (index + 2 <= end + 1)
{
short next = (short)(data[index++] | data[index++] << 8);
if (next == 0)
break;
s.Append(Encoding.Unicode.GetString(BitConverter.GetBytes(next)));
}
basestring = StringList.GetString((int)number);
string args = s.ToString();
if (args == null || args == string.Empty)
{
return basestring;
}
string[] parms = args.Split('\t');
try
{
if (parms.Length > 1)
{
for (int i = 0; i < parms.Length; i++)
{
parms[i] = parms[i].Trim(' ');
if (parms[i].IndexOf("#") == 0)
{
parms[i] = StringList.GetString(Convert.ToInt32(parms[i].Substring(1, parms[i].Length - 1)));
}
}
}
else if (parms.Length == 1 && parms[0].IndexOf("#") == 0)
{
parms[0] = StringList.GetString(Convert.ToInt32(args.Substring(1, parms[0].Length - 1)));
}
}
catch
{
return null;
}
Ultima.StringEntry entry = StringList.GetEntry((int)number);
if (entry != null)
{
return entry.Format(parms);
}
return basestring;
}
private static List<Item> GetItems(PlayerVendor pv)
{
List<Item> list = new List<Item>();
foreach (Item item in pv.Items)
if (item.Movable && item != pv.Backpack && item.Layer != Layer.Hair && item.Layer != Layer.FacialHair)
list.Add(item);
if (pv.Backpack != null)
{
GetItems(pv.Backpack, list);
}
return list;
}
public static void GetItems(Container c, List<Item> list)
{
if (c == null || c.Items.Count == 0)
return;
foreach (Item item in c.Items)
{
if (item is Container && !IsSearchableContainer(item.GetType()))
GetItems((Container)item, list);
else
list.Add(item);
}
}
public static bool CanSearch(Mobile m)
{
Region r = m.Region;
if (r.GetLogoutDelay(m) == TimeSpan.Zero)
return true;
return r is GuardedRegion && !((GuardedRegion)r).Disabled || r is HouseRegion && ((HouseRegion)r).House.IsFriend(m);
}
private static bool IsSearchableContainer(Type type)
{
return _SearchableContainers.Any(t => t == type || type.IsSubclassOf(t));
}
private static Type[] _SearchableContainers =
{
typeof(BaseQuiver), typeof(BaseResourceSatchel),
typeof(FishBowl), typeof(FirstAidBelt),
typeof(Plants.SeedBox), typeof(BaseSpecialScrollBook),
typeof(GardenShedBarrel), typeof(JewelryBox),
};
}
public enum SortBy
{
LowToHigh,
HighToLow
}
public enum Category
{
PriceRange,
Misc,
Equipment,
Combat,
Casting,
DamageType,
HitSpell,
HitArea,
Resists,
Stats,
Slayer1,
Slayer2,
Slayer3,
RequiredSkill,
Skill1,
Skill2,
Skill3,
Skill4,
Skill5,
Skill6,
Sort,
Auction
}
public enum Misc
{
ExcludeFel,
GargoyleOnly,
NotGargoyleOnly,
ElvesOnly,
NotElvesOnly,
FactionItem,
PromotionalToken,
Cursed,
NotCursed,
CannotRepair,
NotCannotBeRepaired,
Brittle,
NotBrittle,
Antique,
NotAntique
}
public enum SpecialSearch
{
PowerScroll,
StatScroll,
Transcendence,
Alacrity,
UsesRemaining
}
public class SearchCategory
{
public Category Category { get; private set; }
public int Label { get { return (int)Category; } }
public List<Tuple<object, int, int>> Objects { get; private set; }
public SearchCategory(Category category)
{
Category = category;
Objects = new List<Tuple<object, int, int>>();
}
public void Register(object o, int label)
{
if (Objects.FirstOrDefault(t => t.Item1 == o) == null)
{
Objects.Add(new Tuple<object, int, int>(o, label, 0));
}
}
public void Register(object o, int label, int pcliloc)
{
if (Objects.FirstOrDefault(t => t.Item1 == o) == null)
{
Objects.Add(new Tuple<object, int, int>(o, label, pcliloc));
}
}
}
public class SearchCriteria
{
public Layer SearchType { get; set; }
public string SearchName { get; set; }
public SortBy SortBy { get; set; }
public bool Auction { get; set; }
public long MinPrice { get; set; }
public long MaxPrice { get; set; }
public bool EntryPrice { get; set; }
public List<SearchDetail> Details { get; set; }
public SearchCriteria()
{
Details = new List<SearchDetail>();
MinPrice = 0;
MaxPrice = 175000000;
SearchType = Layer.Invalid;
}
public void Reset()
{
Details.Clear();
Details.TrimExcess();
Details = new List<SearchDetail>();
MinPrice = 0;
MaxPrice = 175000000;
SortBy = SortBy.LowToHigh;
Auction = false;
SearchName = null;
SearchType = Layer.Invalid;
EntryPrice = false;
}
public int GetValueForDetails(object o)
{
SearchDetail detail = Details.FirstOrDefault(d => d.Attribute == o);
return detail != null ? detail.Value : 0;
}
public void TryAddDetails(object o, int name, int propname, int value, Category cat)
{
SearchDetail d = Details.FirstOrDefault(det => det.Attribute == o);
if (o is Layer)
{
SearchDetail layer = Details.FirstOrDefault(det => det.Attribute is Layer && (Layer)det.Attribute != (Layer)o);
if (layer != null)
{
Details.Remove(layer);
}
Details.Add(new SearchDetail(o, name, propname, value, cat));
SearchType = (Layer)o;
}
else if (d == null)
{
d = new SearchDetail(o, name, propname, value, cat);
Details.Add(d);
}
else if (d.Value != value)
{
d.Value = value;
}
/*if (d.Attribute is TalismanSlayerName && (TalismanSlayerName)d.Attribute == TalismanSlayerName.Undead)
{
TryAddDetails(SlayerName.Silver, name, value, cat);
}*/
}
public bool IsEmpty
{
get { return Details.Count == 0 && !EntryPrice && string.IsNullOrEmpty(SearchName) && SearchType == Layer.Invalid; }
}
public SearchCriteria(GenericReader reader)
{
int version = reader.ReadInt();
Details = new List<SearchDetail>();
if (version > 1)
Auction = reader.ReadBool();
if (version != 0)
EntryPrice = reader.ReadBool();
SearchType = (Layer)reader.ReadInt();
SearchName = reader.ReadString();
SortBy = (SortBy)reader.ReadInt();
MinPrice = reader.ReadLong();
MaxPrice = reader.ReadLong();
int count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
Details.Add(new SearchDetail(reader));
}
}
public void Serialize(GenericWriter writer)
{
writer.Write(2);
writer.Write((bool)Auction);
writer.Write((bool)EntryPrice);
writer.Write((int)SearchType);
writer.Write(SearchName);
writer.Write((int)SortBy);
writer.Write(MinPrice);
writer.Write(MaxPrice);
writer.Write(Details.Count);
for (int i = 0; i < Details.Count; i++)
{
Details[i].Serialize(writer);
}
}
}
public class SearchDetail
{
public enum AttributeID
{
None = 0,
AosAttribute,
AosArmorAttribute,
AosWeaponAttribute,
AosElementAttribute,
SkillName,
SAAbosorptionAttribute,
ExtendedWeaponAttribute,
NegativeAttribute,
SlayerName,
String,
TalismanSlayerName,
TalismanSkill,
TalismanRemoval,
Int,
}
public object Attribute { get; set; }
public int Label { get; set; }
public int PropLabel { get; set; }
public int Value { get; set; }
public Category Category { get; set; }
public SearchDetail(object o, int label, int proplabel, int value, Category category)
{
Attribute = o;
Label = label;
PropLabel = proplabel;
Value = value;
Category = category;
}
public SearchDetail(GenericReader reader)
{
int version = reader.ReadInt(); // version
if (version > 0)
{
PropLabel = reader.ReadInt();
}
ReadAttribute(reader);
Label = reader.ReadInt();
Value = reader.ReadInt();
Category = (Category)reader.ReadInt();
}
public void Serialize(GenericWriter writer)
{
writer.Write(1);
writer.Write(PropLabel);
WriteAttribute(writer);
writer.Write(Label);
writer.Write(Value);
writer.Write((int)Category);
}
private void WriteAttribute(GenericWriter writer)
{
int attrID = GetAttributeID(Attribute);
writer.Write(attrID);
switch (attrID)
{
case 0: break;
case 1: writer.Write((int)(AosAttribute)Attribute); break;
case 2: writer.Write((int)(AosArmorAttribute)Attribute); break;
case 3: writer.Write((int)(AosWeaponAttribute)Attribute); break;
case 4: writer.Write((int)(AosElementAttribute)Attribute); break;
case 5: writer.Write((int)(SkillName)Attribute); break;
case 6: writer.Write((int)(SAAbsorptionAttribute)Attribute); break;
case 7: writer.Write((int)(ExtendedWeaponAttribute)Attribute); break;
case 8: writer.Write((int)(NegativeAttribute)Attribute); break;
case 9: writer.Write((int)(SlayerName)Attribute); break;
case 10: writer.Write((string)Attribute); break;
case 11: writer.Write((int)(TalismanSlayerName)Attribute); break;
case 12: writer.Write((int)(TalismanSkill)Attribute); break;
case 13: writer.Write((int)(TalismanRemoval)Attribute); break;
case 14: writer.Write((int)Attribute); break;
}
}
private void ReadAttribute(GenericReader reader)
{
switch (reader.ReadInt())
{
case 0: break;
case 1: Attribute = (AosAttribute)reader.ReadInt(); break;
case 2: Attribute = (AosArmorAttribute)reader.ReadInt(); break;
case 3: Attribute = (AosWeaponAttribute)reader.ReadInt(); break;
case 4: Attribute = (AosElementAttribute)reader.ReadInt(); break;
case 5: Attribute = (SkillName)reader.ReadInt(); break;
case 6: Attribute = (SAAbsorptionAttribute)reader.ReadInt(); break;
case 7: Attribute = (ExtendedWeaponAttribute)reader.ReadInt(); break;
case 8: Attribute = (NegativeAttribute)reader.ReadInt(); break;
case 9: Attribute = (SlayerName)reader.ReadInt(); break;
case 10: Attribute = reader.ReadString(); break;
case 11: Attribute = (TalismanSlayerName)reader.ReadInt(); break;
case 12: Attribute = (TalismanSkill)reader.ReadInt(); break;
case 13: Attribute = (TalismanRemoval)reader.ReadInt(); break;
case 14: Attribute = reader.ReadInt(); break;
}
}
public static int GetAttributeID(object o)
{
if (o is AosAttribute)
return (int)AttributeID.AosAttribute;
if (o is AosArmorAttribute)
return (int)AttributeID.AosArmorAttribute;
if (o is AosWeaponAttribute)
return (int)AttributeID.AosWeaponAttribute;
if (o is AosElementAttribute)
return (int)AttributeID.AosElementAttribute;
if (o is SkillName)
return (int)AttributeID.SkillName;
if (o is SAAbsorptionAttribute)
return (int)AttributeID.SAAbosorptionAttribute;
if (o is ExtendedWeaponAttribute)
return (int)AttributeID.ExtendedWeaponAttribute;
if (o is NegativeAttribute)
return (int)AttributeID.NegativeAttribute;
if (o is SlayerName)
return (int)AttributeID.SlayerName;
if (o is TalismanSlayerName)
return (int)AttributeID.TalismanSlayerName;
if (o is string)
return (int)AttributeID.String;
if (o is TalismanSkill)
return (int)AttributeID.TalismanSkill;
if (o is TalismanRemoval)
return (int)AttributeID.TalismanRemoval;
if (o is int)
return (int)AttributeID.Int;
return (int)AttributeID.None;
}
}
public class SearchVendors : ContextMenuEntry
{
public PlayerMobile Player { get; set; }
public SearchVendors(PlayerMobile pm)
: base(1154679, -1)
{
Player = pm;
Enabled = VendorSearch.CanSearch(pm);
}
public override void OnClick()
{
if (VendorSearch.CanSearch(Player))
{
BaseGump.SendGump(new VendorSearchGump(Player));
}
}
}
public class SearchItem
{
public PlayerVendor Vendor { get; set; }
public AuctionSafe AuctionSafe { get; set; }
public Item Item { get; set; }
public int Price { get; set; }
public bool IsChild { get; set; }
public bool IsAuction { get; set; }
public SearchItem(PlayerVendor vendor, Item item, int price, bool isChild)
{
Vendor = vendor;
Item = item;
Price = price;
IsChild = isChild;
IsAuction = false;
}
public SearchItem(AuctionSafe auctionsafe, Item item, int price, bool isChild)
{
AuctionSafe = auctionsafe;
Item = item;
Price = price;
IsChild = isChild;
IsAuction = true;
}
}
}