Reorganizes Project (#41)

This commit is contained in:
Kamron Batman 2019-08-02 18:13:40 -07:00 • committed by GitHub
parent 08bf44af9a
commit 3614a66aee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3499 changed files with 79 additions and 55 deletions

View file

@ -0,0 +1,62 @@
namespace Server.Engines.BulkOrders
{
public class BOBFilter
{
public BOBFilter()
{
}
public BOBFilter(GenericReader reader)
{
int version = reader.ReadEncodedInt();
switch (version)
{
case 1:
{
Type = reader.ReadEncodedInt();
Quality = reader.ReadEncodedInt();
Material = reader.ReadEncodedInt();
Quantity = reader.ReadEncodedInt();
break;
}
}
}
public bool IsDefault => Type == 0 && Quality == 0 && Material == 0 && Quantity == 0;
public int Type{ get; set; }
public int Quality{ get; set; }
public int Material{ get; set; }
public int Quantity{ get; set; }
public void Clear()
{
Type = 0;
Quality = 0;
Material = 0;
Quantity = 0;
}
public void Serialize(GenericWriter writer)
{
if (IsDefault)
{
writer.WriteEncodedInt(0); // version
}
else
{
writer.WriteEncodedInt(1); // version
writer.WriteEncodedInt(Type);
writer.WriteEncodedInt(Quality);
writer.WriteEncodedInt(Material);
writer.WriteEncodedInt(Quantity);
}
}
}
}

View file

@ -0,0 +1,220 @@
using Server.Gumps;
using Server.Mobiles;
using Server.Network;
namespace Server.Engines.BulkOrders
{
public class BOBFilterGump : Gump
{
private const int LabelColor = 0x7FFF;
private static int[,] m_MaterialFilters =
{
{ 1044067, 1 }, // Blacksmithy
{ 1062226, 3 }, // Iron
{ 1018332, 4 }, // Dull Copper
{ 1018333, 5 }, // Shadow Iron
{ 1018334, 6 }, // Copper
{ 1018335, 7 }, // Bronze
{ 0, 0 }, // --Blank--
{ 1018336, 8 }, // Golden
{ 1018337, 9 }, // Agapite
{ 1018338, 10 }, // Verite
{ 1018339, 11 }, // Valorite
{ 0, 0 }, // --Blank--
{ 1044094, 2 }, // Tailoring
{ 1044286, 12 }, // Cloth
{ 1062235, 13 }, // Leather
{ 1062236, 14 }, // Spined
{ 1062237, 15 }, // Horned
{ 1062238, 16 } // Barbed
};
private static int[,] m_TypeFilters =
{
{ 1062229, 0 }, // All
{ 1062224, 1 }, // Small
{ 1062225, 2 } // Large
};
private static int[,] m_QualityFilters =
{
{ 1062229, 0 }, // All
{ 1011542, 1 }, // Normal
{ 1060636, 2 } // Exceptional
};
private static int[,] m_AmountFilters =
{
{ 1062229, 0 }, // All
{ 1049706, 1 }, // 10
{ 1016007, 2 }, // 15
{ 1062239, 3 } // 20
};
private static int[][,] m_Filters =
{
m_TypeFilters,
m_QualityFilters,
m_MaterialFilters,
m_AmountFilters
};
private static int[] m_XOffsets_Type = { 0, 75, 170 };
private static int[] m_XOffsets_Quality = { 0, 75, 170 };
private static int[] m_XOffsets_Amount = { 0, 75, 180, 275 };
private static int[] m_XOffsets_Material = { 0, 105, 210, 305, 390, 485 };
private static int[] m_XWidths_Small = { 50, 50, 70, 50 };
private static int[] m_XWidths_Large = { 80, 50, 50, 50, 50, 50 };
private BulkOrderBook m_Book;
private PlayerMobile m_From;
public BOBFilterGump(PlayerMobile from, BulkOrderBook book) : base(12, 24)
{
from.CloseGump<BOBGump>();
from.CloseGump<BOBFilterGump>();
m_From = from;
m_Book = book;
BOBFilter f = from.UseOwnFilter ? from.BOBFilter : book.Filter;
AddPage(0);
AddBackground(10, 10, 600, 439, 5054);
AddImageTiled(18, 20, 583, 420, 2624);
AddAlphaRegion(18, 20, 583, 420);
AddImage(5, 5, 10460);
AddImage(585, 5, 10460);
AddImage(5, 424, 10460);
AddImage(585, 424, 10460);
AddHtmlLocalized(270, 32, 200, 32, 1062223, LabelColor); // Filter Preference
AddHtmlLocalized(26, 64, 120, 32, 1062228, LabelColor); // Bulk Order Type
AddFilterList(25, 96, m_XOffsets_Type, 40, m_TypeFilters, m_XWidths_Small, f.Type, 0);
AddHtmlLocalized(320, 64, 50, 32, 1062215, LabelColor); // Quality
AddFilterList(320, 96, m_XOffsets_Quality, 40, m_QualityFilters, m_XWidths_Small, f.Quality, 1);
AddHtmlLocalized(26, 160, 120, 32, 1062232, LabelColor); // Material Type
AddFilterList(25, 192, m_XOffsets_Material, 40, m_MaterialFilters, m_XWidths_Large, f.Material, 2);
AddHtmlLocalized(26, 320, 120, 32, 1062217, LabelColor); // Amount
AddFilterList(25, 352, m_XOffsets_Amount, 40, m_AmountFilters, m_XWidths_Small, f.Quantity, 3);
AddHtmlLocalized(75, 416, 120, 32, 1062477, from.UseOwnFilter ? LabelColor : 16927); // Set Book Filter
AddButton(40, 416, 4005, 4007, 1);
AddHtmlLocalized(235, 416, 120, 32, 1062478, from.UseOwnFilter ? 16927 : LabelColor); // Set Your Filter
AddButton(200, 416, 4005, 4007, 2);
AddHtmlLocalized(405, 416, 120, 32, 1062231, LabelColor); // Clear Filter
AddButton(370, 416, 4005, 4007, 3);
AddHtmlLocalized(540, 416, 50, 32, 1011046, LabelColor); // APPLY
AddButton(505, 416, 4017, 4018, 0);
}
private void AddFilterList(int x, int y, int[] xOffsets, int yOffset, int[,] filters, int[] xWidths, int filterValue,
int filterIndex)
{
for (int i = 0; i < filters.GetLength(0); ++i)
{
int number = filters[i, 0];
if (number == 0)
continue;
bool isSelected = filters[i, 1] == filterValue ||
i % xOffsets.Length == 0 && filterValue == 0;
AddHtmlLocalized(x + 35 + xOffsets[i % xOffsets.Length], y + i / xOffsets.Length * yOffset,
xWidths[i % xOffsets.Length], 32, number, isSelected ? 16927 : LabelColor);
AddButton(x + xOffsets[i % xOffsets.Length], y + i / xOffsets.Length * yOffset, 4005, 4007,
4 + filterIndex + i * 4);
}
}
public override void OnResponse(NetState sender, RelayInfo info)
{
BOBFilter f = m_From.UseOwnFilter ? m_From.BOBFilter : m_Book.Filter;
int index = info.ButtonID;
switch (index)
{
case 0: // Apply
{
m_From.SendGump(new BOBGump(m_From, m_Book));
break;
}
case 1: // Set Book Filter
{
m_From.UseOwnFilter = false;
m_From.SendGump(new BOBFilterGump(m_From, m_Book));
break;
}
case 2: // Set Your Filter
{
m_From.UseOwnFilter = true;
m_From.SendGump(new BOBFilterGump(m_From, m_Book));
break;
}
case 3: // Clear Filter
{
f.Clear();
m_From.SendGump(new BOBFilterGump(m_From, m_Book));
break;
}
default:
{
index -= 4;
int type = index % 4;
index /= 4;
if (type >= 0 && type < m_Filters.Length)
{
int[,] filters = m_Filters[type];
if (index >= 0 && index < filters.GetLength(0))
{
if (filters[index, 0] == 0)
break;
switch (type)
{
case 0:
f.Type = filters[index, 1];
break;
case 1:
f.Quality = filters[index, 1];
break;
case 2:
f.Material = filters[index, 1];
break;
case 3:
f.Quantity = filters[index, 1];
break;
}
m_From.SendGump(new BOBFilterGump(m_From, m_Book));
}
}
break;
}
}
}
}
}

View file

@ -0,0 +1,647 @@
using System;
using System.Collections.Generic;
using Server.Gumps;
using Server.Items;
using Server.Mobiles;
using Server.Network;
using Server.Prompts;
namespace Server.Engines.BulkOrders
{
public class BOBGump : Gump
{
private const int LabelColor = 0x7FFF;
private BulkOrderBook m_Book;
private PlayerMobile m_From;
private List<IBOBEntry> m_List;
private int m_Page;
public BOBGump(PlayerMobile from, BulkOrderBook book, int page = 0, List<IBOBEntry> list = null) : base(12, 24)
{
from.CloseGump<BOBGump>();
from.CloseGump<BOBFilterGump>();
m_From = from;
m_Book = book;
m_Page = page;
if (list == null)
{
list = new List<IBOBEntry>(book.Entries.Count);
for (int i = 0; i < book.Entries.Count; ++i)
{
IBOBEntry entry = book.Entries[i];
if (CheckFilter(entry))
list.Add(entry);
}
}
m_List = list;
int index = GetIndexForPage(page);
int count = GetCountForIndex(index);
int tableIndex = 0;
PlayerVendor pv = book.RootParent as PlayerVendor;
bool canDrop = book.IsChildOf(from.Backpack);
bool canBuy = pv != null;
bool canPrice = canDrop || canBuy;
if (canBuy)
{
VendorItem vi = pv.GetVendorItem(book);
canBuy = vi?.IsForSale == false;
}
int width = 600;
if (!canPrice)
width = 516;
X = (624 - width) / 2;
AddPage(0);
AddBackground(10, 10, width, 439, 5054);
AddImageTiled(18, 20, width - 17, 420, 2624);
if (canPrice)
{
AddImageTiled(573, 64, 24, 352, 200);
AddImageTiled(493, 64, 78, 352, 1416);
}
if (canDrop)
AddImageTiled(24, 64, 32, 352, 1416);
AddImageTiled(58, 64, 36, 352, 200);
AddImageTiled(96, 64, 133, 352, 1416);
AddImageTiled(231, 64, 80, 352, 200);
AddImageTiled(313, 64, 100, 352, 1416);
AddImageTiled(415, 64, 76, 352, 200);
for (int i = index; i < index + count && i >= 0 && i < list.Count; ++i)
{
IBOBEntry entry = list[i];
if (!CheckFilter(entry))
continue;
AddImageTiled(24, 94 + tableIndex * 32, canPrice ? 573 : 489, 2, 2624);
tableIndex += entry is BOBLargeEntry largeEntry ? largeEntry.Entries.Length : 1;
}
AddAlphaRegion(18, 20, width - 17, 420);
AddImage(5, 5, 10460);
AddImage(width - 15, 5, 10460);
AddImage(5, 424, 10460);
AddImage(width - 15, 424, 10460);
AddHtmlLocalized(canPrice ? 266 : 224, 32, 200, 32, 1062220, LabelColor); // Bulk Order Book
AddHtmlLocalized(63, 64, 200, 32, 1062213, LabelColor); // Type
AddHtmlLocalized(147, 64, 200, 32, 1062214, LabelColor); // Item
AddHtmlLocalized(246, 64, 200, 32, 1062215, LabelColor); // Quality
AddHtmlLocalized(336, 64, 200, 32, 1062216, LabelColor); // Material
AddHtmlLocalized(429, 64, 200, 32, 1062217, LabelColor); // Amount
AddButton(35, 32, 4005, 4007, 1);
AddHtmlLocalized(70, 32, 200, 32, 1062476, LabelColor); // Set Filter
BOBFilter f = from.UseOwnFilter ? from.BOBFilter : book.Filter;
if (f.IsDefault)
AddHtmlLocalized(canPrice ? 470 : 386, 32, 120, 32, 1062475, 16927); // Using No Filter
else if (from.UseOwnFilter)
AddHtmlLocalized(canPrice ? 470 : 386, 32, 120, 32, 1062451, 16927); // Using Your Filter
else
AddHtmlLocalized(canPrice ? 470 : 386, 32, 120, 32, 1062230, 16927); // Using Book Filter
AddButton(375, 416, 4017, 4018, 0);
AddHtmlLocalized(410, 416, 120, 20, 1011441, LabelColor); // EXIT
if (canDrop)
AddHtmlLocalized(26, 64, 50, 32, 1062212, LabelColor); // Drop
if (canPrice)
{
AddHtmlLocalized(516, 64, 200, 32, 1062218, LabelColor); // Price
if (canBuy)
{
AddHtmlLocalized(576, 64, 200, 32, 1062219, LabelColor); // Buy
}
else
{
AddHtmlLocalized(576, 64, 200, 32, 1062227, LabelColor); // Set
AddButton(450, 416, 4005, 4007, 4);
AddHtml(485, 416, 120, 20, "<BASEFONT COLOR=#FFFFFF>Price all</FONT>");
}
}
tableIndex = 0;
if (page > 0)
{
AddButton(75, 416, 4014, 4016, 2);
AddHtmlLocalized(110, 416, 150, 20, 1011067, LabelColor); // Previous page
}
if (GetIndexForPage(page + 1) < list.Count)
{
AddButton(225, 416, 4005, 4007, 3);
AddHtmlLocalized(260, 416, 150, 20, 1011066, LabelColor); // Next page
}
for (int i = index; i < index + count && i >= 0 && i < list.Count; ++i)
{
IBOBEntry entry = list[i];
if (!CheckFilter(entry))
continue;
if (entry is BOBLargeEntry largeEntry)
{
int y = 96 + tableIndex * 32;
if (canDrop)
AddButton(35, y + 2, 5602, 5606, 5 + i * 2);
if (canDrop || canBuy && entry.Price > 0)
{
AddButton(579, y + 2, 2117, 2118, 6 + i * 2);
AddLabel(495, y, 1152, entry.Price.ToString());
}
AddHtmlLocalized(61, y, 50, 32, 1062225, LabelColor); // Large
for (int j = 0; j < largeEntry.Entries.Length; ++j)
{
BOBLargeSubEntry sub = largeEntry.Entries[j];
AddHtmlLocalized(103, y, 130, 32, sub.Number, LabelColor);
if (entry.RequireExceptional)
AddHtmlLocalized(235, y, 80, 20, 1060636, LabelColor); // exceptional
else
AddHtmlLocalized(235, y, 80, 20, 1011542, LabelColor); // normal
object name = GetMaterialName(entry.Material, entry.DeedType, sub.ItemType);
if (name is int intName)
AddHtmlLocalized(316, y, 100, 20, intName, LabelColor);
else
AddLabel(316, y, 1152, name.ToString());
AddLabel(421, y, 1152, $"{sub.AmountCur} / {entry.AmountMax}");
++tableIndex;
y += 32;
}
}
else
{
BOBSmallEntry smallEntry = (BOBSmallEntry)entry;
int y = 96 + tableIndex++ * 32;
if (canDrop)
AddButton(35, y + 2, 5602, 5606, 5 + i * 2);
if (canDrop || canBuy && smallEntry.Price > 0)
{
AddButton(579, y + 2, 2117, 2118, 6 + i * 2);
AddLabel(495, y, 1152, smallEntry.Price.ToString());
}
AddHtmlLocalized(61, y, 50, 32, 1062224, LabelColor); // Small
AddHtmlLocalized(103, y, 130, 32, smallEntry.Number, LabelColor);
if (smallEntry.RequireExceptional)
AddHtmlLocalized(235, y, 80, 20, 1060636, LabelColor); // exceptional
else
AddHtmlLocalized(235, y, 80, 20, 1011542, LabelColor); // normal
object name = GetMaterialName(smallEntry.Material, smallEntry.DeedType, smallEntry.ItemType);
if (name is int intName)
AddHtmlLocalized(316, y, 100, 20, intName, LabelColor);
else
AddLabel(316, y, 1152, name.ToString());
AddLabel(421, y, 1152, $"{smallEntry.AmountCur} / {smallEntry.AmountMax}");
}
}
}
public bool CheckFilter(IBOBEntry entry)
{
if (entry is BOBLargeEntry largeEntry)
return CheckFilter(entry.Material, entry.AmountMax, true, entry.RequireExceptional, entry.DeedType,
largeEntry.Entries.Length > 0 ? largeEntry.Entries[0].ItemType : null);
if (entry is BOBSmallEntry smallEntry)
return CheckFilter(entry.Material, entry.AmountMax, false, entry.RequireExceptional,
entry.DeedType, smallEntry.ItemType);
return false;
}
public bool CheckFilter(BulkMaterialType mat, int amountMax, bool isLarge, bool reqExc, BODType deedType,
Type itemType)
{
BOBFilter f = m_From.UseOwnFilter ? m_From.BOBFilter : m_Book.Filter;
if (f.IsDefault)
return true;
if (f.Quality == 1 && reqExc)
return false;
if (f.Quality == 2 && !reqExc)
return false;
if (f.Quantity == 1 && amountMax != 10)
return false;
if (f.Quantity == 2 && amountMax != 15)
return false;
if (f.Quantity == 3 && amountMax != 20)
return false;
if (f.Type == 1 && isLarge)
return false;
if (f.Type == 2 && !isLarge)
return false;
switch (f.Material)
{
default:
return true;
case 1: return deedType == BODType.Smith;
case 2: return deedType == BODType.Tailor;
case 3:
return mat == BulkMaterialType.None &&
BGTClassifier.Classify(deedType, itemType) == BulkGenericType.Iron;
case 4: return mat == BulkMaterialType.DullCopper;
case 5: return mat == BulkMaterialType.ShadowIron;
case 6: return mat == BulkMaterialType.Copper;
case 7: return mat == BulkMaterialType.Bronze;
case 8: return mat == BulkMaterialType.Gold;
case 9: return mat == BulkMaterialType.Agapite;
case 10: return mat == BulkMaterialType.Verite;
case 11: return mat == BulkMaterialType.Valorite;
case 12:
return mat == BulkMaterialType.None &&
BGTClassifier.Classify(deedType, itemType) == BulkGenericType.Cloth;
case 13:
return mat == BulkMaterialType.None &&
BGTClassifier.Classify(deedType, itemType) == BulkGenericType.Leather;
case 14: return mat == BulkMaterialType.Spined;
case 15: return mat == BulkMaterialType.Horned;
case 16: return mat == BulkMaterialType.Barbed;
}
}
public int GetIndexForPage(int page)
{
int index = 0;
while (page-- > 0)
index += GetCountForIndex(index);
return index;
}
public int GetCountForIndex(int index)
{
int slots = 0;
int count = 0;
List<IBOBEntry> list = m_List;
for (int i = index; i >= 0 && i < list.Count; ++i)
{
IBOBEntry entry = list[i];
if (CheckFilter(entry))
{
int add = entry is BOBLargeEntry largeEntry ? largeEntry.Entries.Length : 1;
if (slots + add > 10)
break;
slots += add;
}
++count;
}
return count;
}
public int GetPageForIndex(int index, int sizeDropped)
{
if (index <= 0)
return 0;
int count = 0;
int page = 0;
int i;
List<IBOBEntry> list = m_List;
for (i = 0; i < index && i < list.Count; i++)
{
IBOBEntry entry = list[i];
if (!CheckFilter(entry))
continue;
int add = entry is BOBLargeEntry largeEntry ? largeEntry.Entries.Length : 1;
count += add;
if (count > 10)
{
page++;
count = add;
}
}
/* now we are on the page of the bod preceding the dropped one.
* next step: checking whether we have to remain where we are.
* The counter i needs to be incremented as the bod to this very moment
* has not yet been removed from m_List */
i++;
/* if, for instance, a big bod of size 6 has been removed, smaller bods
* might fall back into this page. Depending on their sizes, the page needs
* to be adjusted accordingly. This is done now.
*/
if (count + sizeDropped > 10)
{
while (i < list.Count && count <= 10)
{
IBOBEntry entry = list[i];
if (CheckFilter(entry))
count += entry is BOBLargeEntry largeEntry ? largeEntry.Entries.Length : 1;
i++;
}
if (count > 10)
page++;
}
return page;
}
public object GetMaterialName(BulkMaterialType mat, BODType type, Type itemType)
{
switch (type)
{
case BODType.Smith:
{
switch (mat)
{
case BulkMaterialType.None: return 1062226;
case BulkMaterialType.DullCopper: return 1018332;
case BulkMaterialType.ShadowIron: return 1018333;
case BulkMaterialType.Copper: return 1018334;
case BulkMaterialType.Bronze: return 1018335;
case BulkMaterialType.Gold: return 1018336;
case BulkMaterialType.Agapite: return 1018337;
case BulkMaterialType.Verite: return 1018338;
case BulkMaterialType.Valorite: return 1018339;
}
break;
}
case BODType.Tailor:
{
switch (mat)
{
case BulkMaterialType.None:
{
if (itemType.IsSubclassOf(typeof(BaseArmor)) || itemType.IsSubclassOf(typeof(BaseShoes)))
return 1062235;
return 1044286;
}
case BulkMaterialType.Spined: return 1062236;
case BulkMaterialType.Horned: return 1062237;
case BulkMaterialType.Barbed: return 1062238;
}
break;
}
}
return "Invalid";
}
public override void OnResponse(NetState sender, RelayInfo info)
{
int index = info.ButtonID;
switch (index)
{
case 0: // EXIT
{
break;
}
case 1: // Set Filter
{
m_From.SendGump(new BOBFilterGump(m_From, m_Book));
break;
}
case 2: // Previous page
{
if (m_Page > 0)
m_From.SendGump(new BOBGump(m_From, m_Book, m_Page - 1, m_List));
return;
}
case 3: // Next page
{
if (GetIndexForPage(m_Page + 1) < m_List.Count)
m_From.SendGump(new BOBGump(m_From, m_Book, m_Page + 1, m_List));
break;
}
case 4: // Price all
{
if (m_Book.IsChildOf(m_From.Backpack))
{
m_From.Prompt = new SetPricePrompt(m_Book, null, m_Page, m_List);
m_From.SendMessage("Type in a price for all deeds in the book:");
}
break;
}
default:
{
index -= 5;
int type = index % 2;
index /= 2;
if (index < 0 || index >= m_List.Count)
break;
IBOBEntry bobEntry = m_List[index];
if (!m_Book.Entries.Contains(bobEntry))
{
m_From.SendLocalizedMessage(1062382); // The deed selected is not available.
break;
}
if (type == 0) // Drop
{
if (m_Book.IsChildOf(m_From.Backpack))
{
Item item = bobEntry.Reconstruct();
Container pack = m_From.Backpack;
if (pack?.CheckHold(m_From, item, true, true, 0,
item.PileWeight + item.TotalWeight) != true)
{
m_From.SendLocalizedMessage(503204); // You do not have room in your backpack for this
m_From.SendGump(new BOBGump(m_From, m_Book, m_Page));
}
else
{
if (m_Book.IsChildOf(m_From.Backpack))
{
int sizeOfDroppedBod = bobEntry is BOBLargeEntry entry ? entry.Entries.Length : 1;
m_From.AddToBackpack(item);
m_From.SendLocalizedMessage(
1045152); // The bulk order deed has been placed in your backpack.
m_Book.Entries.Remove(bobEntry);
m_Book.InvalidateProperties();
if (m_Book.Entries.Count / 5 < m_Book.ItemCount)
{
m_Book.ItemCount--;
m_Book.InvalidateItems();
}
if (m_Book.Entries.Count > 0)
{
m_Page = GetPageForIndex(index, sizeOfDroppedBod);
m_From.SendGump(new BOBGump(m_From, m_Book, m_Page));
}
else
{
m_From.SendLocalizedMessage(1062381); // The book is empty.
}
}
}
}
}
else // Set Price | Buy
{
if (m_Book.IsChildOf(m_From.Backpack))
{
m_From.Prompt = new SetPricePrompt(m_Book, bobEntry, m_Page, m_List);
m_From.SendLocalizedMessage(1062383); // Type in a price for the deed:
}
else if (m_Book.RootParent is PlayerVendor pv)
{
VendorItem vi = pv.GetVendorItem(m_Book);
if (vi?.IsForSale != false)
return;
int sizeOfDroppedBod = bobEntry is BOBLargeEntry largeEntry ? largeEntry.Entries.Length : 1;
int price = bobEntry.Price;
if (price == 0)
{
m_From.SendLocalizedMessage(1062382); // The deed selected is not available.
}
else
{
if (m_Book.Entries.Count > 0)
{
m_Page = GetPageForIndex(index, sizeOfDroppedBod);
m_From.SendGump(new BODBuyGump(m_From, m_Book, bobEntry, m_Page, price));
}
else
{
m_From.SendLocalizedMessage(1062381); // The book is emptz
}
}
}
}
break;
}
}
}
private class SetPricePrompt : Prompt
{
private BulkOrderBook m_Book;
private List<IBOBEntry> m_List;
private IBOBEntry m_Entry;
private int m_Page;
public SetPricePrompt(BulkOrderBook book, IBOBEntry entry, int page, List<IBOBEntry> list)
{
m_Book = book;
m_Entry = entry;
m_Page = page;
m_List = list;
}
public override void OnResponse(Mobile from, string text)
{
if (m_Entry != null && !m_Book.Entries.Contains(m_Entry))
{
from.SendLocalizedMessage(1062382); // The deed selected is not available.
return;
}
int price = Utility.ToInt32(text);
if (price < 0 || price > 250000000)
{
from.SendLocalizedMessage(1062390); // The price you requested is outrageous!
}
else if (m_Entry == null)
{
for (int i = 0; i < m_List.Count; ++i)
{
IBOBEntry entry = m_List[i];
if (!m_Book.Entries.Contains(entry))
continue;
entry.Price = price;
}
from.SendMessage("Deed prices set.");
if (from is PlayerMobile mobile)
mobile.SendGump(new BOBGump(mobile, m_Book, m_Page, m_List));
}
else
{
m_Entry.Price = price;
from.SendLocalizedMessage(1062384); // Deed price set.
if (from is PlayerMobile mobile)
mobile.SendGump(new BOBGump(mobile, m_Book, m_Page, m_List));
}
}
}
}
}

View file

@ -0,0 +1,106 @@
namespace Server.Engines.BulkOrders
{
public class BOBLargeEntry: IBOBEntry
{
public BOBLargeEntry(LargeBOD bod)
{
RequireExceptional = bod.RequireExceptional;
if (bod is LargeTailorBOD)
DeedType = BODType.Tailor;
else if (bod is LargeSmithBOD)
DeedType = BODType.Smith;
Material = bod.Material;
AmountMax = bod.AmountMax;
Entries = new BOBLargeSubEntry[bod.Entries.Length];
for (int i = 0; i < Entries.Length; ++i)
Entries[i] = new BOBLargeSubEntry(bod.Entries[i]);
}
public BOBLargeEntry(GenericReader reader)
{
int version = reader.ReadEncodedInt();
switch (version)
{
case 0:
{
RequireExceptional = reader.ReadBool();
DeedType = (BODType)reader.ReadEncodedInt();
Material = (BulkMaterialType)reader.ReadEncodedInt();
AmountMax = reader.ReadEncodedInt();
Price = reader.ReadEncodedInt();
Entries = new BOBLargeSubEntry[reader.ReadEncodedInt()];
for (int i = 0; i < Entries.Length; ++i)
Entries[i] = new BOBLargeSubEntry(reader);
break;
}
}
}
public bool RequireExceptional{ get; }
public BODType DeedType{ get; }
public BulkMaterialType Material{ get; }
public int AmountMax{ get; }
public int Price{ get; set; }
public BOBLargeSubEntry[] Entries{ get; }
public Item Reconstruct()
{
LargeBOD bod = null;
if (DeedType == BODType.Smith)
bod = new LargeSmithBOD(AmountMax, RequireExceptional, Material, ReconstructEntries());
else if (DeedType == BODType.Tailor)
bod = new LargeTailorBOD(AmountMax, RequireExceptional, Material, ReconstructEntries());
for (int i = 0; bod?.Entries.Length >= i; ++i)
bod.Entries[i].Owner = bod;
return bod;
}
private LargeBulkEntry[] ReconstructEntries()
{
LargeBulkEntry[] entries = new LargeBulkEntry[Entries.Length];
for (int i = 0; i < Entries.Length; ++i)
{
entries[i] = new LargeBulkEntry(null,
new SmallBulkEntry(Entries[i].ItemType, Entries[i].Number, Entries[i].Graphic)) { Amount = Entries[i].AmountCur };
}
return entries;
}
public void Serialize(GenericWriter writer)
{
writer.WriteEncodedInt(0); // version
writer.Write(RequireExceptional);
writer.WriteEncodedInt((int)DeedType);
writer.WriteEncodedInt((int)Material);
writer.WriteEncodedInt(AmountMax);
writer.WriteEncodedInt(Price);
writer.WriteEncodedInt(Entries.Length);
for (int i = 0; i < Entries.Length; ++i)
Entries[i].Serialize(writer);
}
}
}

View file

@ -0,0 +1,56 @@
using System;
namespace Server.Engines.BulkOrders
{
public class BOBLargeSubEntry
{
public BOBLargeSubEntry(LargeBulkEntry lbe)
{
ItemType = lbe.Details.Type;
AmountCur = lbe.Amount;
Number = lbe.Details.Number;
Graphic = lbe.Details.Graphic;
}
public BOBLargeSubEntry(GenericReader reader)
{
int version = reader.ReadEncodedInt();
switch (version)
{
case 0:
{
string type = reader.ReadString();
if (type != null)
ItemType = ScriptCompiler.FindTypeByFullName(type);
AmountCur = reader.ReadEncodedInt();
Number = reader.ReadEncodedInt();
Graphic = reader.ReadEncodedInt();
break;
}
}
}
public Type ItemType{ get; }
public int AmountCur{ get; }
public int Number{ get; }
public int Graphic{ get; }
public void Serialize(GenericWriter writer)
{
writer.WriteEncodedInt(0); // version
writer.Write(ItemType == null ? null : ItemType.FullName);
writer.WriteEncodedInt(AmountCur);
writer.WriteEncodedInt(Number);
writer.WriteEncodedInt(Graphic);
}
}
}

View file

@ -0,0 +1,100 @@
using System;
namespace Server.Engines.BulkOrders
{
public class BOBSmallEntry : IBOBEntry
{
public BOBSmallEntry(SmallBOD bod)
{
ItemType = bod.Type;
RequireExceptional = bod.RequireExceptional;
if (bod is SmallTailorBOD)
DeedType = BODType.Tailor;
else if (bod is SmallSmithBOD)
DeedType = BODType.Smith;
Material = bod.Material;
AmountCur = bod.AmountCur;
AmountMax = bod.AmountMax;
Number = bod.Number;
Graphic = bod.Graphic;
}
public BOBSmallEntry(GenericReader reader)
{
int version = reader.ReadEncodedInt();
switch (version)
{
case 0:
{
string type = reader.ReadString();
if (type != null)
ItemType = ScriptCompiler.FindTypeByFullName(type);
RequireExceptional = reader.ReadBool();
DeedType = (BODType)reader.ReadEncodedInt();
Material = (BulkMaterialType)reader.ReadEncodedInt();
AmountCur = reader.ReadEncodedInt();
AmountMax = reader.ReadEncodedInt();
Number = reader.ReadEncodedInt();
Graphic = reader.ReadEncodedInt();
Price = reader.ReadEncodedInt();
break;
}
}
}
public Type ItemType{ get; }
public bool RequireExceptional{ get; }
public BODType DeedType{ get; }
public BulkMaterialType Material{ get; }
public int AmountCur{ get; }
public int AmountMax{ get; }
public int Number{ get; }
public int Graphic{ get; }
public int Price{ get; set; }
public Item Reconstruct()
{
SmallBOD bod = null;
if (DeedType == BODType.Smith)
bod = new SmallSmithBOD(AmountCur, AmountMax, ItemType, Number, Graphic, RequireExceptional, Material);
else if (DeedType == BODType.Tailor)
bod = new SmallTailorBOD(AmountCur, AmountMax, ItemType, Number, Graphic, RequireExceptional, Material);
return bod;
}
public void Serialize(GenericWriter writer)
{
writer.WriteEncodedInt(0); // version
writer.Write(ItemType == null ? null : ItemType.FullName);
writer.Write(RequireExceptional);
writer.WriteEncodedInt((int)DeedType);
writer.WriteEncodedInt((int)Material);
writer.WriteEncodedInt(AmountCur);
writer.WriteEncodedInt(AmountMax);
writer.WriteEncodedInt(Number);
writer.WriteEncodedInt(Graphic);
writer.WriteEncodedInt(Price);
}
}
}

View file

@ -0,0 +1,122 @@
using Server.Gumps;
using Server.Items;
using Server.Mobiles;
using Server.Network;
namespace Server.Engines.BulkOrders
{
public class BODBuyGump : Gump
{
private BulkOrderBook m_Book;
private PlayerMobile m_From;
private IBOBEntry m_Entry;
private int m_Page;
private int m_Price;
public BODBuyGump(PlayerMobile from, BulkOrderBook book, IBOBEntry entry, int page, int price) : base(100, 200)
{
m_From = from;
m_Book = book;
m_Entry = entry;
m_Price = price;
m_Page = page;
AddPage(0);
AddBackground(100, 10, 300, 150, 5054);
AddHtmlLocalized(125, 20, 250, 24, 1019070); // You have agreed to purchase:
AddHtmlLocalized(125, 45, 250, 24, 1045151); // a bulk order deed
AddHtmlLocalized(125, 70, 250, 24, 1019071); // for the amount of:
AddLabel(125, 95, 0, price.ToString());
AddButton(250, 130, 4005, 4007, 1);
AddHtmlLocalized(282, 130, 100, 24, 1011012); // CANCEL
AddButton(120, 130, 4005, 4007, 2);
AddHtmlLocalized(152, 130, 100, 24, 1011036); // OKAY
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (info.ButtonID != 2)
{
m_From.SendLocalizedMessage(503207); // Cancelled purchase.
return;
}
if (!(m_Book.RootParent is PlayerVendor pv))
{
m_From.SendLocalizedMessage(1062382); // The deed selected is not available.
return;
}
if (!m_Book.Entries.Contains(m_Entry))
{
pv.SayTo(m_From, 1062382); // The deed selected is not available.
return;
}
int price = 0;
if (pv.GetVendorItem(m_Book)?.IsForSale == false)
price = m_Entry.Price;
if (price != m_Price)
{
pv.SayTo(m_From,
"The price has been been changed. If you like, you may offer to purchase the item again.");
return;
}
if (price == 0)
{
pv.SayTo(m_From, 1062382); // The deed selected is not available.
return;
}
Item item = m_Entry.Reconstruct();
pv.Say(m_From.Name);
Container pack = m_From.Backpack;
if (pack?.CheckHold(m_From, item, true, true, 0,
item.PileWeight + item.TotalWeight) != true)
{
pv.SayTo(m_From, 503204); // You do not have room in your backpack for this
m_From.SendGump(new BOBGump(m_From, m_Book, m_Page));
item.Delete();
}
else
{
if (pack.ConsumeTotal(typeof(Gold), price) || Banker.Withdraw(m_From, price))
{
m_Book.Entries.Remove(m_Entry);
m_Book.InvalidateProperties();
pv.HoldGold += price;
m_From.AddToBackpack(item);
m_From.SendLocalizedMessage(
1045152); // The bulk order deed has been placed in your backpack.
if (m_Book.Entries.Count / 5 < m_Book.ItemCount)
{
m_Book.ItemCount--;
m_Book.InvalidateItems();
}
if (m_Book.Entries.Count > 0)
m_From.SendGump(new BOBGump(m_From, m_Book, m_Page));
else
m_From.SendLocalizedMessage(1062381); // The book is empty.
}
else
{
pv.SayTo(m_From, 503205); // You cannot afford this item.
item.Delete();
}
}
}
}
}

View file

@ -0,0 +1,8 @@
namespace Server.Engines.BulkOrders
{
public enum BODType
{
Smith,
Tailor
}
}

View file

@ -0,0 +1,308 @@
using System.Collections.Generic;
using Server.Gumps;
using Server.Multis;
using Server.Prompts;
using Server.Mobiles;
using Server.ContextMenus;
using Server.Items;
namespace Server.Engines.BulkOrders
{
public class BulkOrderBook : Item, ISecurable
{
private string m_BookName;
[CommandProperty( AccessLevel.GameMaster )]
public string BookName
{
get => m_BookName;
set{ m_BookName = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public SecureLevel Level { get; set; }
public List<IBOBEntry> Entries { get; private set; }
public BOBFilter Filter { get; private set; }
public int ItemCount { get; set; }
[Constructible]
public BulkOrderBook() : base( 0x2259 )
{
Weight = 1.0;
LootType = LootType.Blessed;
Entries = new List<IBOBEntry>();
Filter = new BOBFilter();
Level = SecureLevel.CoOwners;
}
public override void OnDoubleClick( Mobile from )
{
if ( !from.InRange( GetWorldLocation(), 2 ) )
from.LocalOverheadMessage( Network.MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
else if ( Entries.Count == 0 )
from.SendLocalizedMessage( 1062381 ); // The book is empty.
else if ( from is PlayerMobile mobile )
mobile.SendGump( new BOBGump( mobile, this ) );
}
public override void OnDoubleClickSecureTrade( Mobile from )
{
if ( !from.InRange( GetWorldLocation(), 2 ) )
{
from.SendLocalizedMessage( 500446 ); // That is too far away.
}
else if ( Entries.Count == 0 )
{
from.SendLocalizedMessage( 1062381 ); // The book is empty.
}
else
{
from.SendGump( new BOBGump( (PlayerMobile)from, this ) );
SecureTrade trade = GetSecureTradeCont()?.Trade;
if (trade?.From.Mobile == from )
trade.To.Mobile.SendGump( new BOBGump( (PlayerMobile)trade.To.Mobile, this ) );
else if (trade?.To.Mobile == from )
trade.From.Mobile.SendGump( new BOBGump( (PlayerMobile)trade.From.Mobile, this ) );
}
}
public override bool OnDragDrop( Mobile from, Item dropped )
{
if ( dropped is BaseBOD )
{
if ( !IsChildOf( from.Backpack ) )
{
from.SendLocalizedMessage( 1062385 ); // You must have the book in your backpack to add deeds to it.
return false;
}
if ( !from.Backpack.CheckHold( from, dropped, true, true ) )
return false;
if ( Entries.Count < 500 )
{
if ( dropped is LargeBOD bod )
Entries.Add( new BOBLargeEntry( bod ) );
else
Entries.Add( new BOBSmallEntry( (SmallBOD)dropped ) );
InvalidateProperties();
if ( Entries.Count / 5 > ItemCount )
{
ItemCount++;
InvalidateItems();
}
from.SendSound(0x42, GetWorldLocation());
from.SendLocalizedMessage( 1062386 ); // Deed added to book.
if ( from is PlayerMobile pm )
pm.SendGump( new BOBGump( pm, this ) );
dropped.Delete();
return true;
}
from.SendLocalizedMessage( 1062387 ); // The book is full of deeds.
return false;
}
from.SendLocalizedMessage( 1062388 ); // That is not a bulk order deed.
return false;
}
public override int GetTotal( TotalType type )
{
int total = base.GetTotal( type );
if ( type == TotalType.Items )
total = ItemCount;
return total;
}
public void InvalidateItems()
{
if ( RootParent is Mobile m )
{
m.UpdateTotals();
InvalidateContainers( Parent );
}
}
public void InvalidateContainers(IEntity parent)
{
if ( parent is Container c )
{
c.InvalidateProperties();
InvalidateContainers( c.Parent );
}
}
public BulkOrderBook( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 2 ); // version
writer.Write( ItemCount );
writer.Write( (int) Level );
writer.Write( m_BookName );
Filter.Serialize( writer );
writer.WriteEncodedInt( Entries.Count );
for ( int i = 0; i < Entries.Count; ++i )
{
object obj = Entries[i];
if ( obj is BOBLargeEntry entry )
{
writer.WriteEncodedInt( 0 );
entry.Serialize( writer );
}
else
{
writer.WriteEncodedInt( 1 );
((BOBSmallEntry)obj).Serialize( writer );
}
}
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 2:
{
ItemCount = reader.ReadInt();
goto case 1;
}
case 1:
{
Level = (SecureLevel)reader.ReadInt();
goto case 0;
}
case 0:
{
m_BookName = reader.ReadString();
Filter = new BOBFilter( reader );
int count = reader.ReadEncodedInt();
Entries = new List<IBOBEntry>( count );
for ( int i = 0; i < count; ++i )
{
int v = reader.ReadEncodedInt();
switch ( v )
{
case 0: Entries.Add( new BOBLargeEntry( reader ) ); break;
case 1: Entries.Add( new BOBSmallEntry( reader ) ); break;
}
}
break;
}
}
}
public override void GetProperties( ObjectPropertyList list )
{
base.GetProperties( list );
list.Add( 1062344, Entries.Count.ToString() ); // Deeds in book: ~1_val~
if ( !string.IsNullOrEmpty(m_BookName) )
list.Add( 1062481, m_BookName ); // Book Name: ~1_val~
}
public override void OnSingleClick(Mobile from)
{
base.OnSingleClick(from);
LabelTo(from, 1062344, Entries.Count.ToString()); // Deeds in book: ~1_val~
if (!string.IsNullOrEmpty(m_BookName))
LabelTo(from, 1062481, m_BookName);
}
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
{
base.GetContextMenuEntries( from, list );
if ( from.CheckAlive() && IsChildOf( from.Backpack ) )
list.Add( new NameBookEntry( from, this ) );
SetSecureLevelEntry.AddTo( from, this, list );
}
private class NameBookEntry : ContextMenuEntry
{
private Mobile m_From;
private BulkOrderBook m_Book;
public NameBookEntry( Mobile from, BulkOrderBook book ) : base( 6216 )
{
m_From = from;
m_Book = book;
}
public override void OnClick()
{
if ( m_From.CheckAlive() && m_Book.IsChildOf( m_From.Backpack ) )
{
m_From.Prompt = new NameBookPrompt( m_Book );
m_From.SendLocalizedMessage( 1062479 ); // Type in the new name of the book:
}
}
}
private class NameBookPrompt : Prompt
{
private BulkOrderBook m_Book;
public NameBookPrompt( BulkOrderBook book )
{
m_Book = book;
}
public override void OnResponse( Mobile from, string text )
{
if ( text.Length > 40 )
text = text.Substring( 0, 40 );
if ( from.CheckAlive() && m_Book.IsChildOf( from.Backpack ) )
{
m_Book.BookName = Utility.FixHtml( text.Trim() );
from.SendLocalizedMessage( 1062480 ); // The bulk order book's name has been changed.
}
}
public override void OnCancel( Mobile from )
{
}
}
}
}

View file

@ -0,0 +1,12 @@
namespace Server.Engines.BulkOrders
{
public interface IBOBEntry
{
bool RequireExceptional{ get; }
BODType DeedType{ get; }
BulkMaterialType Material{ get; }
int AmountMax{ get; }
int Price{ get; set; }
Item Reconstruct();
}
}