fix: Fixes vendor OPL (#672)
This commit is contained in:
parent
3dc406624e
commit
b112be4e1f
6 changed files with 94 additions and 115 deletions
|
|
@ -62,8 +62,8 @@ namespace Server.Network
|
||||||
|
|
||||||
var desc = bis.Description ?? "";
|
var desc = bis.Description ?? "";
|
||||||
|
|
||||||
Stream.Write((byte)desc.Length);
|
Stream.Write((byte)(desc.Length + 1));
|
||||||
Stream.WriteAsciiFixed(desc, desc.Length);
|
Stream.WriteAsciiNull(desc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ namespace Server.Network
|
||||||
var length = 8;
|
var length = 8;
|
||||||
for (int i = 0; i < list.Count; i++)
|
for (int i = 0; i < list.Count; i++)
|
||||||
{
|
{
|
||||||
length += 5 + list[i].Description?.Length ?? 0;
|
length += 6 + list[i].Description?.Length ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
var writer = new SpanWriter(stackalloc byte[length]);
|
var writer = new SpanWriter(stackalloc byte[length]);
|
||||||
|
|
@ -101,8 +101,8 @@ namespace Server.Network
|
||||||
|
|
||||||
var desc = bis.Description ?? "";
|
var desc = bis.Description ?? "";
|
||||||
|
|
||||||
writer.Write((byte)desc.Length);
|
writer.Write((byte)(desc.Length + 1));
|
||||||
writer.WriteAscii(desc); // Doesn't look like it is used anymore
|
writer.WriteAsciiNull(desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
ns.Send(writer.Span);
|
ns.Send(writer.Span);
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ namespace Server.Commands.Generic
|
||||||
|
|
||||||
public void Acquire(TypeBuilder typeBuilder, ILGenerator il, string fieldName)
|
public void Acquire(TypeBuilder typeBuilder, ILGenerator il, string fieldName)
|
||||||
{
|
{
|
||||||
if (!(Value is string toParse))
|
if (Value is not string toParse)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ using Server.Misc;
|
||||||
using Server.Mobiles;
|
using Server.Mobiles;
|
||||||
using Server.Network;
|
using Server.Network;
|
||||||
using Server.Regions;
|
using Server.Regions;
|
||||||
|
using Server.Text;
|
||||||
|
|
||||||
namespace Server.Mobiles
|
namespace Server.Mobiles
|
||||||
{
|
{
|
||||||
|
|
@ -26,8 +27,8 @@ namespace Server.Mobiles
|
||||||
|
|
||||||
private static readonly TimeSpan InventoryDecayTime = TimeSpan.FromHours(1.0);
|
private static readonly TimeSpan InventoryDecayTime = TimeSpan.FromHours(1.0);
|
||||||
|
|
||||||
private readonly List<IBuyItemInfo> m_ArmorBuyInfo = new();
|
private readonly List<IBuyItemInfo> _buyInfo = new();
|
||||||
private readonly List<IShopSellInfo> m_ArmorSellInfo = new();
|
private readonly List<IShopSellInfo> _sellInfo = new();
|
||||||
|
|
||||||
public BaseVendor(string title = null)
|
public BaseVendor(string title = null)
|
||||||
: base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2)
|
: base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2)
|
||||||
|
|
@ -77,7 +78,7 @@ namespace Server.Mobiles
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (!(FindItemOnLayer(Layer.ShopBuy) is Container pack))
|
if (FindItemOnLayer(Layer.ShopBuy) is not Container pack)
|
||||||
{
|
{
|
||||||
pack = new Backpack { Layer = Layer.ShopBuy, Visible = false };
|
pack = new Backpack { Layer = Layer.ShopBuy, Visible = false };
|
||||||
AddItem(pack);
|
AddItem(pack);
|
||||||
|
|
@ -130,7 +131,6 @@ namespace Server.Mobiles
|
||||||
var info = GetSellInfo();
|
var info = GetSellInfo();
|
||||||
var totalCost = 0;
|
var totalCost = 0;
|
||||||
var validBuy = new List<BuyItemResponse>(list.Count);
|
var validBuy = new List<BuyItemResponse>(list.Count);
|
||||||
bool bought;
|
|
||||||
var fromBank = false;
|
var fromBank = false;
|
||||||
var fullPurchase = true;
|
var fullPurchase = true;
|
||||||
var controlSlots = buyer.FollowersMax - buyer.Followers;
|
var controlSlots = buyer.FollowersMax - buyer.Followers;
|
||||||
|
|
@ -213,7 +213,7 @@ namespace Server.Mobiles
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bought = buyer.AccessLevel >= AccessLevel.GameMaster;
|
var bought = buyer.AccessLevel >= AccessLevel.GameMaster;
|
||||||
|
|
||||||
var cont = buyer.Backpack;
|
var cont = buyer.Backpack;
|
||||||
if (!bought && cont != null)
|
if (!bought && cont != null)
|
||||||
|
|
@ -337,18 +337,17 @@ namespace Server.Mobiles
|
||||||
{
|
{
|
||||||
SayTo(
|
SayTo(
|
||||||
buyer,
|
buyer,
|
||||||
1151638,
|
1151638, // The total of your purchase is ~1_val~ gold, which has been drawn from your bank account. My thanks for the patronage.
|
||||||
totalCost
|
totalCost.ToString()
|
||||||
.ToString()
|
);
|
||||||
); // The total of your purchase is ~1_val~ gold, which has been drawn from your bank account. My thanks for the patronage.
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SayTo(
|
SayTo(
|
||||||
buyer,
|
buyer,
|
||||||
1151639,
|
1151639, // The total of your purchase is ~1_val~ gold. My thanks for the patronage.
|
||||||
totalCost.ToString()
|
totalCost.ToString()
|
||||||
); // The total of your purchase is ~1_val~ gold. My thanks for the patronage.
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -448,48 +447,45 @@ namespace Server.Mobiles
|
||||||
|
|
||||||
foreach (var ssi in info)
|
foreach (var ssi in info)
|
||||||
{
|
{
|
||||||
if (ssi.IsSellable(resp.Item))
|
if (!ssi.IsSellable(resp.Item))
|
||||||
{
|
{
|
||||||
var amount = resp.Amount;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (amount > resp.Item.Amount)
|
var amount = resp.Amount;
|
||||||
|
|
||||||
|
if (amount > resp.Item.Amount)
|
||||||
|
{
|
||||||
|
amount = resp.Item.Amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ssi.IsResellable(resp.Item))
|
||||||
|
{
|
||||||
|
var found = false;
|
||||||
|
|
||||||
|
foreach (var bii in buyInfo)
|
||||||
{
|
{
|
||||||
amount = resp.Item.Amount;
|
if (bii.Restock(resp.Item, amount))
|
||||||
|
{
|
||||||
|
resp.Item.Consume(amount);
|
||||||
|
found = true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ssi.IsResellable(resp.Item))
|
if (!found)
|
||||||
{
|
{
|
||||||
var found = false;
|
var cont = BuyPack;
|
||||||
|
|
||||||
foreach (var bii in buyInfo)
|
if (amount < resp.Item.Amount)
|
||||||
{
|
{
|
||||||
if (bii.Restock(resp.Item, amount))
|
var item = LiftItemDupe(resp.Item, resp.Item.Amount - amount);
|
||||||
|
|
||||||
|
if (item != null)
|
||||||
{
|
{
|
||||||
resp.Item.Consume(amount);
|
item.SetLastMoved();
|
||||||
found = true;
|
cont.DropItem(item);
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found)
|
|
||||||
{
|
|
||||||
var cont = BuyPack;
|
|
||||||
|
|
||||||
if (amount < resp.Item.Amount)
|
|
||||||
{
|
|
||||||
var item = LiftItemDupe(resp.Item, resp.Item.Amount - amount);
|
|
||||||
|
|
||||||
if (item != null)
|
|
||||||
{
|
|
||||||
item.SetLastMoved();
|
|
||||||
cont.DropItem(item);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
resp.Item.SetLastMoved();
|
|
||||||
cont.DropItem(resp.Item);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -497,22 +493,27 @@ namespace Server.Mobiles
|
||||||
cont.DropItem(resp.Item);
|
cont.DropItem(resp.Item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resp.Item.SetLastMoved();
|
||||||
|
cont.DropItem(resp.Item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (amount < resp.Item.Amount)
|
||||||
|
{
|
||||||
|
resp.Item.Amount -= amount;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (amount < resp.Item.Amount)
|
resp.Item.Delete();
|
||||||
{
|
|
||||||
resp.Item.Amount -= amount;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
resp.Item.Delete();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GiveGold += ssi.GetSellPriceFor(resp.Item) * amount;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GiveGold += ssi.GetSellPriceFor(resp.Item) * amount;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -566,9 +567,9 @@ namespace Server.Mobiles
|
||||||
{
|
{
|
||||||
LastRestock = Core.Now;
|
LastRestock = Core.Now;
|
||||||
|
|
||||||
for (var i = 0; i < m_ArmorBuyInfo.Count; ++i)
|
for (var i = 0; i < _buyInfo.Count; ++i)
|
||||||
{
|
{
|
||||||
if (m_ArmorBuyInfo[i] is GenericBuyInfo buy)
|
if (_buyInfo[i] is GenericBuyInfo buy)
|
||||||
{
|
{
|
||||||
buy.DeleteDisplayEntity();
|
buy.DeleteDisplayEntity();
|
||||||
}
|
}
|
||||||
|
|
@ -578,14 +579,14 @@ namespace Server.Mobiles
|
||||||
|
|
||||||
InitSBInfo();
|
InitSBInfo();
|
||||||
|
|
||||||
m_ArmorBuyInfo.Clear();
|
_buyInfo.Clear();
|
||||||
m_ArmorSellInfo.Clear();
|
_sellInfo.Clear();
|
||||||
|
|
||||||
for (var i = 0; i < SBInfos.Count; i++)
|
for (var i = 0; i < SBInfos.Count; i++)
|
||||||
{
|
{
|
||||||
var sbInfo = SBInfos[i];
|
var sbInfo = SBInfos[i];
|
||||||
m_ArmorBuyInfo.AddRange(sbInfo.BuyInfo);
|
_buyInfo.AddRange(sbInfo.BuyInfo);
|
||||||
m_ArmorSellInfo.Add(sbInfo.SellInfo);
|
_sellInfo.Add(sbInfo.SellInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -852,7 +853,7 @@ namespace Server.Mobiles
|
||||||
var list = new List<BuyItemState>(buyInfo.Length);
|
var list = new List<BuyItemState>(buyInfo.Length);
|
||||||
var cont = BuyPack;
|
var cont = BuyPack;
|
||||||
|
|
||||||
var opls = new List<ObjectPropertyList>();
|
var opls = ObjectPropertyList.Enabled ? new List<ObjectPropertyList>(buyInfo.Length) : null;
|
||||||
|
|
||||||
for (var idx = 0; idx < buyInfo.Length; idx++)
|
for (var idx = 0; idx < buyInfo.Length; idx++)
|
||||||
{
|
{
|
||||||
|
|
@ -863,7 +864,7 @@ namespace Server.Mobiles
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(buyItem is GenericBuyInfo gbi))
|
if (buyItem is not GenericBuyInfo gbi)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -884,7 +885,7 @@ namespace Server.Mobiles
|
||||||
|
|
||||||
if (disp is IPropertyListObject obj)
|
if (disp is IPropertyListObject obj)
|
||||||
{
|
{
|
||||||
opls.Add(obj.PropertyList);
|
opls?.Add(obj.PropertyList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -925,7 +926,7 @@ namespace Server.Mobiles
|
||||||
if (name != null && list.Count < 250)
|
if (name != null && list.Count < 250)
|
||||||
{
|
{
|
||||||
list.Add(new BuyItemState(name, cont.Serial, item.Serial, price, item.Amount, item.ItemID, item.Hue));
|
list.Add(new BuyItemState(name, cont.Serial, item.Serial, price, item.Amount, item.ItemID, item.Hue));
|
||||||
opls.Add(item.PropertyList);
|
opls?.Add(item.PropertyList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -954,9 +955,12 @@ namespace Server.Mobiles
|
||||||
from.NetState.SendDisplayBuyList(Serial);
|
from.NetState.SendDisplayBuyList(Serial);
|
||||||
from.NetState.SendMobileStatus(from); // make sure their gold amount is sent
|
from.NetState.SendMobileStatus(from); // make sure their gold amount is sent
|
||||||
|
|
||||||
for (var i = 0; i < opls.Count; ++i)
|
if (opls != null)
|
||||||
{
|
{
|
||||||
from.NetState?.Send(opls[i].Buffer);
|
for (var i = 0; i < opls.Count; ++i)
|
||||||
|
{
|
||||||
|
from.NetState?.Send(opls[i].Buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SayTo(from, 500186); // Greetings. Have a look around.
|
SayTo(from, 500186); // Greetings. Have a look around.
|
||||||
|
|
@ -1383,9 +1387,9 @@ namespace Server.Mobiles
|
||||||
base.AddCustomContextEntries(from, list);
|
base.AddCustomContextEntries(from, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual IShopSellInfo[] GetSellInfo() => m_ArmorSellInfo.ToArray();
|
public virtual IShopSellInfo[] GetSellInfo() => _sellInfo.ToArray();
|
||||||
|
|
||||||
public virtual IBuyItemInfo[] GetBuyInfo() => m_ArmorBuyInfo.ToArray();
|
public virtual IBuyItemInfo[] GetBuyInfo() => _buyInfo.ToArray();
|
||||||
|
|
||||||
public virtual int GetPriceScalar() => 100 + Town.FromRegion(Region)?.Tax ?? 0;
|
public virtual int GetPriceScalar() => 100 + Town.FromRegion(Region)?.Tax ?? 0;
|
||||||
|
|
||||||
|
|
@ -1393,7 +1397,7 @@ namespace Server.Mobiles
|
||||||
{
|
{
|
||||||
var priceScalar = GetPriceScalar();
|
var priceScalar = GetPriceScalar();
|
||||||
|
|
||||||
foreach (var info in m_ArmorBuyInfo.ToArray())
|
foreach (var info in _buyInfo.ToArray())
|
||||||
{
|
{
|
||||||
info.PriceScalar = priceScalar;
|
info.PriceScalar = priceScalar;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -106,23 +106,7 @@ namespace Server.Mobiles
|
||||||
{
|
{
|
||||||
if (m_Amount <= 0)
|
if (m_Amount <= 0)
|
||||||
{
|
{
|
||||||
/*
|
MaxAmount = Math.Min(999, MaxAmount * 2);
|
||||||
Core.ML using this vendor system is undefined behavior, so being
|
|
||||||
as it lends itself to an abusable exploit to cause ingame havok
|
|
||||||
and the stackable items are not found to be over 20 items, this is
|
|
||||||
changed until there is a better solution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
object Obj_Disp = GetDisplayEntity();
|
|
||||||
|
|
||||||
if (Core.ML && Obj_Disp is Item item && !item.Stackable)
|
|
||||||
{
|
|
||||||
MaxAmount = Math.Min(20, MaxAmount);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MaxAmount = Math.Min(999, MaxAmount * 2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -152,22 +136,15 @@ namespace Server.Mobiles
|
||||||
m_Amount = MaxAmount;
|
m_Amount = MaxAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsDeleted(IEntity obj) => obj.Deleted;
|
|
||||||
|
|
||||||
public void DeleteDisplayEntity()
|
public void DeleteDisplayEntity()
|
||||||
{
|
{
|
||||||
if (m_DisplayEntity == null)
|
m_DisplayEntity?.Delete();
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_DisplayEntity.Delete();
|
|
||||||
m_DisplayEntity = null;
|
m_DisplayEntity = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEntity GetDisplayEntity()
|
public IEntity GetDisplayEntity()
|
||||||
{
|
{
|
||||||
if (m_DisplayEntity != null && !IsDeleted(m_DisplayEntity))
|
if (m_DisplayEntity?.Deleted == false)
|
||||||
{
|
{
|
||||||
return m_DisplayEntity;
|
return m_DisplayEntity;
|
||||||
}
|
}
|
||||||
|
|
@ -179,13 +156,12 @@ namespace Server.Mobiles
|
||||||
m_DisplayEntity = DisplayCache.Cache.Lookup(Type);
|
m_DisplayEntity = DisplayCache.Cache.Lookup(Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_DisplayEntity == null || IsDeleted(m_DisplayEntity))
|
if (m_DisplayEntity?.Deleted != false)
|
||||||
{
|
{
|
||||||
m_DisplayEntity = GetEntity();
|
m_DisplayEntity = GetEntity();
|
||||||
|
DisplayCache.Cache.Store(Type, m_DisplayEntity, canCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplayCache.Cache.Store(Type, m_DisplayEntity, canCache);
|
|
||||||
|
|
||||||
return m_DisplayEntity;
|
return m_DisplayEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,7 +172,7 @@ namespace Server.Mobiles
|
||||||
|
|
||||||
private Dictionary<Type, IEntity> m_Table;
|
private Dictionary<Type, IEntity> m_Table;
|
||||||
|
|
||||||
public DisplayCache() : base(0)
|
private DisplayCache() : base(0)
|
||||||
{
|
{
|
||||||
m_Table = new Dictionary<Type, IEntity>();
|
m_Table = new Dictionary<Type, IEntity>();
|
||||||
m_Mobiles = new List<Mobile>();
|
m_Mobiles = new List<Mobile>();
|
||||||
|
|
@ -301,7 +277,7 @@ namespace Server.Mobiles
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeleteEntities(List<IEntity> entities)
|
private static void DeleteEntities(List<IEntity> entities)
|
||||||
{
|
{
|
||||||
foreach (var entity in entities)
|
foreach (var entity in entities)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -29,20 +29,19 @@ namespace Server.Mobiles
|
||||||
20,
|
20,
|
||||||
0x1ED0,
|
0x1ED0,
|
||||||
0,
|
0,
|
||||||
new object[] { 500 }
|
new object[] { 500 } // 500 charges
|
||||||
)
|
)
|
||||||
); // 500 charges
|
);
|
||||||
Add(
|
Add(new GenericBuyInfo(
|
||||||
new GenericBuyInfo(
|
|
||||||
"1060740",
|
"1060740",
|
||||||
typeof(BroadcastCrystal),
|
typeof(BroadcastCrystal),
|
||||||
131,
|
131,
|
||||||
20,
|
20,
|
||||||
0x1ED0,
|
0x1ED0,
|
||||||
0,
|
0,
|
||||||
new object[] { 1000 }
|
new object[] { 1000 } // 1000 charges
|
||||||
)
|
)
|
||||||
); // 1000 charges
|
);
|
||||||
Add(
|
Add(
|
||||||
new GenericBuyInfo(
|
new GenericBuyInfo(
|
||||||
"1060740",
|
"1060740",
|
||||||
|
|
@ -51,9 +50,9 @@ namespace Server.Mobiles
|
||||||
20,
|
20,
|
||||||
0x1ED0,
|
0x1ED0,
|
||||||
0,
|
0,
|
||||||
new object[] { 2000 }
|
new object[] { 2000 } // 2000 charges
|
||||||
)
|
)
|
||||||
); // 2000 charges
|
);
|
||||||
|
|
||||||
Add(new GenericBuyInfo("1060740", typeof(ReceiverCrystal), 6, 20, 0x1ED0, 0));
|
Add(new GenericBuyInfo("1060740", typeof(ReceiverCrystal), 6, 20, 0x1ED0, 0));
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue