1054 lines
47 KiB
C#
1054 lines
47 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
|
|
using Server.Commands;
|
|
using Server.Mobiles;
|
|
using Server.Items;
|
|
using Server.Engines.VendorSearching;
|
|
using Server.Gumps;
|
|
using Server.Network;
|
|
using Server.Engines.Points;
|
|
using Server.Multis;
|
|
|
|
namespace Server.Engines.UOStore
|
|
{
|
|
public enum StoreCategory
|
|
{
|
|
None,
|
|
Featured,
|
|
Character,
|
|
Equipment,
|
|
Decorations,
|
|
Mounts,
|
|
Misc,
|
|
Cart
|
|
}
|
|
|
|
public enum SortBy
|
|
{
|
|
Name,
|
|
PriceLower,
|
|
PriceHigher,
|
|
Newest,
|
|
Oldest
|
|
}
|
|
|
|
public static class UltimaStore
|
|
{
|
|
public static readonly string FilePath = Path.Combine("Saves/Misc", "UltimaStore.bin");
|
|
|
|
public static bool Enabled { get { return Configuration.Enabled; } set { Configuration.Enabled = value; } }
|
|
|
|
public static List<StoreEntry> Entries { get; private set; }
|
|
public static Dictionary<Mobile, List<Item>> PendingItems { get; private set; }
|
|
|
|
private static UltimaStoreContainer _UltimaStoreContainer;
|
|
|
|
public static UltimaStoreContainer UltimaStoreContainer
|
|
{
|
|
get
|
|
{
|
|
if (_UltimaStoreContainer != null && _UltimaStoreContainer.Deleted)
|
|
{
|
|
_UltimaStoreContainer = null;
|
|
}
|
|
|
|
return _UltimaStoreContainer ?? (_UltimaStoreContainer = new UltimaStoreContainer());
|
|
}
|
|
}
|
|
|
|
static UltimaStore()
|
|
{
|
|
Entries = new List<StoreEntry>();
|
|
PendingItems = new Dictionary<Mobile, List<Item>>();
|
|
PlayerProfiles = new Dictionary<Mobile, PlayerProfile>();
|
|
}
|
|
|
|
public static void Configure()
|
|
{
|
|
PacketHandlers.Register(0xFA, 1, true, UOStoreRequest);
|
|
|
|
CommandSystem.Register("Store", AccessLevel.Player, e => OpenStore(e.Mobile as PlayerMobile));
|
|
|
|
EventSink.WorldSave += OnSave;
|
|
EventSink.WorldLoad += OnLoad;
|
|
}
|
|
|
|
public static void Initialize()
|
|
{
|
|
// Featured
|
|
StoreCategory cat = StoreCategory.Featured;
|
|
Register<VirtueShield>(1109616, 1158384, 0x7818, 0, 0, 1500, cat);
|
|
Register<SoulstoneToken>(1158404, 1158405, 0x2A93, 0, 2598, 1000, cat, ConstructSoulstone);
|
|
//Register<DeluxeStarterPackToken>(1158368, 1158369, 0, 0x9CCB, 0, 2000, cat);
|
|
Register<GreenGoblinStatuette>(1125133, 1158015, 0xA095, 0, 0, 600, cat);
|
|
//Register<TotemOfChromaticFortune>(1157606, 1157604, 0, 0x9CC9, 0, 300, cat);
|
|
Register<MythicCharacterToken>(new TextDefinition[] { 1156614, 1156615 }, 1156679, 0x2AAA, 0, 0, 2500, cat);
|
|
|
|
// Character
|
|
cat = StoreCategory.Character;
|
|
|
|
Register<HABPromotionalToken>(new TextDefinition[] { 1158741, 1156615 }, 1158740, 0x2AAA, 0, 0, 600, cat);
|
|
Register<MysticalPolymorphTotem>(1158780, 1158781, 0xA276, 0, 0, 600, cat);
|
|
//Register<DeluxeStarterPackToken>(1158368, 1158369, 0, 0x9CCB, 0, 2000, cat);
|
|
Register<GreenGoblinStatuette>(1125133, 1158015, 0xA095, 0, 0, 600, cat);
|
|
Register<GreyGoblinStatuette>(1125135, 1158015, 0xA097, 0, 0, 600, cat);
|
|
Register<StableSlotIncreaseToken>(1157608, 1157609, 0x2AAA, 0, 0, 500, cat);
|
|
Register<MythicCharacterToken>(new TextDefinition[] { 1156614, 1156615 }, 1156679, 0x2AAA, 0, 0, 2500, cat);
|
|
Register<CharacterReincarnationToken>(new TextDefinition[] { 1156612, 1156615 }, 1156677, 0x2AAA, 0, 0, 2000, cat);
|
|
|
|
Register<AbyssalHairDye>(1149822, 1156676, 0, 0x9C7A, 0, 400, cat);
|
|
Register<SpecialHairDye>(new TextDefinition[] { 1071387, 1071439 }, 1156676, 0, 0x9C78, 0, 400, cat, ConstructHairDye); // Lemon Lime
|
|
Register<SpecialHairDye>(new TextDefinition[] { 1071387, 1071470 }, 1156676, 0, 0x9C6D, 0, 400, cat, ConstructHairDye); // Yew Brown
|
|
Register<SpecialHairDye>(new TextDefinition[] { 1071387, 1071471 }, 1156676, 0, 0x9C6E, 0, 400, cat, ConstructHairDye); // Bloodwood Red
|
|
Register<SpecialHairDye>(new TextDefinition[] { 1071387, 1071438 }, 1156676, 0, 0x9C6F, 0, 400, cat, ConstructHairDye); // Vivid Blue
|
|
Register<SpecialHairDye>(new TextDefinition[] { 1071387, 1071469 }, 1156676, 0, 0x9C71, 0, 400, cat, ConstructHairDye); // Ash Blonde
|
|
Register<SpecialHairDye>(new TextDefinition[] { 1071387, 1071472 }, 1156676, 0, 0x9C72, 0, 400, cat, ConstructHairDye); // Heartwood Green
|
|
Register<SpecialHairDye>(new TextDefinition[] { 1071387, 1071472 }, 1156676, 0, 0x9C85, 0, 400, cat, ConstructHairDye); // Oak Blonde
|
|
Register<SpecialHairDye>(new TextDefinition[] { 1071387, 1071474 }, 1156676, 0, 0x9C70, 0, 400, cat, ConstructHairDye); // Sacred White
|
|
Register<SpecialHairDye>(new TextDefinition[] { 1071387, 1071473 }, 1156676, 0, 0x9C73, 0, 400, cat, ConstructHairDye); // Frostwood Ice Green
|
|
Register<SpecialHairDye>(new TextDefinition[] { 1071387, 1071440 }, 1156676, 0, 0x9C76, 0, 400, cat, ConstructHairDye); // Fiery Blonde
|
|
Register<SpecialHairDye>(new TextDefinition[] { 1071387, 1071437 }, 1156676, 0, 0x9C77, 0, 400, cat, ConstructHairDye); // Bitter Brown
|
|
Register<SpecialHairDye>(new TextDefinition[] { 1071387, 1071442 }, 1156676, 0, 0x9C74, 0, 400, cat, ConstructHairDye); // Gnaw's Twisted Blue
|
|
Register<SpecialHairDye>(new TextDefinition[] { 1071387, 1071441 }, 1156676, 0, 0x9C75, 0, 400, cat, ConstructHairDye); // Dusk Black
|
|
|
|
Register<GenderChangeToken>(new TextDefinition[] { 1156609, 1156615 }, 1156642, 0x2AAA, 0, 0, 1000, cat);
|
|
Register<NameChangeToken>(new TextDefinition[] { 1156608, 1156615 }, 1156641, 0x2AAA, 0, 0, 1000, cat);
|
|
|
|
// Equipment
|
|
cat = StoreCategory.Equipment;
|
|
Register<VirtueShield>(1109616, 1158384, 0x7818, 0, 0, 1500, cat);
|
|
Register<HoodedBritanniaRobe>(1125155, 1158016, 0xA0AB, 0, 0, 1500, cat, ConstructRobe);
|
|
Register<HoodedBritanniaRobe>(1125155, 1158016, 0xA0AC, 0, 0, 1500, cat, ConstructRobe);
|
|
Register<HoodedBritanniaRobe>(1125155, 1158016, 0xA0AD, 0, 0, 1500, cat, ConstructRobe);
|
|
Register<HoodedBritanniaRobe>(1125155, 1158016, 0xA0AE, 0, 0, 1500, cat, ConstructRobe);
|
|
Register<HoodedBritanniaRobe>(1125155, 1158016, 0xA0AF, 0, 0, 1500, cat, ConstructRobe);
|
|
|
|
Register<HaochisPigment>(new TextDefinition[] { 1071249, 1157275 }, 1156671, 0, 0x9CBF, 0, 400, cat, ConstructHaochisPigment); // Heartwood Sienna
|
|
Register<HaochisPigment>(new TextDefinition[] { 1071249, 1157274 }, 1156671, 0, 0x9CBD, 0, 400, cat, ConstructHaochisPigment); // Campion White
|
|
Register<HaochisPigment>(new TextDefinition[] { 1071249, 1157273 }, 1156671, 0, 0x9CC2, 0, 400, cat, ConstructHaochisPigment); // Yewish Pine
|
|
Register<HaochisPigment>(new TextDefinition[] { 1071249, 1157272 }, 1156671, 0, 0x9CC0, 0, 400, cat, ConstructHaochisPigment); // Minocian Fire
|
|
Register<HaochisPigment>(new TextDefinition[] { 1071249, 1157269 }, 1156671, 0, 0x9CC1, 0, 400, cat, ConstructHaochisPigment); // Celtic Lime
|
|
|
|
Register<PigmentsOfTokuno>(new TextDefinition[] { 1070933, 1070994 }, 1156906, 0, 0x9CA8, 0, 400, cat, ConstructPigments); // Nox Green
|
|
Register<PigmentsOfTokuno>(new TextDefinition[] { 1070933, 1079584 }, 1156906, 0, 0x9CAF, 0, 400, cat, ConstructPigments); // Midnight Coal
|
|
Register<PigmentsOfTokuno>(new TextDefinition[] { 1070933, 1070995 }, 1156906, 0, 0x9CA5, 0, 400, cat, ConstructPigments); // Rum Red
|
|
Register<PigmentsOfTokuno>(new TextDefinition[] { 1070933, 1079580 }, 1156906, 0, 0x9CA4, 0, 400, cat, ConstructPigments); // Coal
|
|
Register<PigmentsOfTokuno>(new TextDefinition[] { 1070933, 1079582 }, 1156906, 0, 0x9CA3, 0, 400, cat, ConstructPigments); // Storm Bronze
|
|
Register<PigmentsOfTokuno>(new TextDefinition[] { 1070933, 1079581 }, 1156906, 0, 0x9CA2, 0, 400, cat, ConstructPigments); // Faded Gold
|
|
Register<PigmentsOfTokuno>(new TextDefinition[] { 1070933, 1070988 }, 1156906, 0, 0x9CA1, 0, 400, cat, ConstructPigments); // Violet Courage Purple
|
|
Register<PigmentsOfTokuno>(new TextDefinition[] { 1070933, 1079585 }, 1156906, 0, 0x9CA2, 0, 400, cat, ConstructPigments); // Faded Bronze
|
|
Register<PigmentsOfTokuno>(new TextDefinition[] { 1070933, 1070996 }, 1156906, 0, 0x9C9F, 0, 400, cat, ConstructPigments); // Fire Orange
|
|
Register<PigmentsOfTokuno>(new TextDefinition[] { 1070933, 1079586 }, 1156906, 0, 0x9C9E, 0, 400, cat, ConstructPigments); // Faded Rose
|
|
Register<PigmentsOfTokuno>(new TextDefinition[] { 1070933, 1079583 }, 1156906, 0, 0x9CA7, 0, 400, cat, ConstructPigments); // Rose
|
|
Register<PigmentsOfTokuno>(new TextDefinition[] { 1070933, 1079587 }, 1156906, 0, 0x9CA9, 0, 400, cat, ConstructPigments); // Deep Rose
|
|
Register<PigmentsOfTokuno>(new TextDefinition[] { 1070933, 1070990 }, 1156906, 0, 0x9CAA, 0, 400, cat, ConstructPigments); // Luna White
|
|
|
|
Register<CommemorativeRobe>(1157009, 1156908, 0x4B9D, 0, 0, 500, cat);
|
|
|
|
Register<PigmentsOfTokuno>(new TextDefinition[] { 1070933, 1070992 }, 1156906, 0, 0x9CAF, 0, 400, cat, ConstructPigments); // Shadow Dancer Black
|
|
Register<PigmentsOfTokuno>(new TextDefinition[] { 1070933, 1070989 }, 1156906, 0, 0x9CAE, 0, 400, cat, ConstructPigments); // Invulnerability Blue
|
|
Register<PigmentsOfTokuno>(new TextDefinition[] { 1070933, 1070991 }, 1156906, 0, 0x9CAD, 0, 400, cat, ConstructPigments); // Dryad Green
|
|
Register<PigmentsOfTokuno>(new TextDefinition[] { 1070933, 1070993 }, 1156906, 0, 0x9CAC, 0, 400, cat, ConstructPigments); // Berserker Red
|
|
Register<PigmentsOfTokuno>(new TextDefinition[] { 1070933, 1079579 }, 1156906, 0, 0x9CAB, 0, 400, cat, ConstructPigments); // Faded Coal
|
|
Register<PigmentsOfTokuno>(new TextDefinition[] { 1070933, 1070987 }, 1156906, 0, 0x9C9D, 0, 400, cat, ConstructPigments); // Paragon Gold
|
|
|
|
Register<HaochisPigment>(new TextDefinition[] { 1071249, 1071246 }, 1156671, 0, 0x9CAF, 0, 400, cat, ConstructHaochisPigment); // Ninja Black
|
|
Register<HaochisPigment>(new TextDefinition[] { 1071249, 1018352 }, 1156671, 0, 0x9C83, 0, 400, cat, ConstructHaochisPigment); // Olive
|
|
Register<HaochisPigment>(new TextDefinition[] { 1071249, 1071247 }, 1156671, 0, 0x9C7D, 0, 400, cat, ConstructHaochisPigment); // Dark Reddish Brown
|
|
Register<HaochisPigment>(new TextDefinition[] { 1071249, 1071245 }, 1156671, 0, 0x9C85, 0, 400, cat, ConstructHaochisPigment); // Yellow
|
|
Register<HaochisPigment>(new TextDefinition[] { 1071249, 1071244 }, 1156671, 0, 0x9C80, 0, 400, cat, ConstructHaochisPigment); // Pretty Pink
|
|
Register<HaochisPigment>(new TextDefinition[] { 1071249, 1071248 }, 1156671, 0, 0x9C81, 0, 400, cat, ConstructHaochisPigment); // Midnight Blue
|
|
Register<HaochisPigment>(new TextDefinition[] { 1071249, 1023856 }, 1156671, 0, 0x9C7F, 0, 400, cat, ConstructHaochisPigment); // Emerald
|
|
Register<HaochisPigment>(new TextDefinition[] { 1071249, 1115467 }, 1156671, 0, 0x9C82, 0, 400, cat, ConstructHaochisPigment); // Smoky Gold
|
|
Register<HaochisPigment>(new TextDefinition[] { 1071249, 1115468 }, 1156671, 0, 0x9C7E, 0, 400, cat, ConstructHaochisPigment); // Ghost's Grey
|
|
Register<HaochisPigment>(new TextDefinition[] { 1071249, 1115471 }, 1156671, 0, 0x9C84, 0, 400, cat, ConstructHaochisPigment); // Ocean Blue
|
|
|
|
Register<SmugglersEdge>(1071499, 1156664, 0, 0x9C63, 0, 400, cat);
|
|
Register<UndertakersStaff>(1071498, 1156663, 0x13F8, 0, 0, 500, cat);
|
|
Register<ReptalonFormTalisman>(new TextDefinition[] { 1157010, 1075202 }, 1156967, 0x2F59, 0, 0, 100, cat);
|
|
Register<QuiverOfInfinity>(1075201, 1156971, 0x2B02, 0, 0, 100, cat);
|
|
Register<CuSidheFormTalisman>(new TextDefinition[] { 1157010, 1031670 }, 1156970, 0x2F59, 0, 0, 100, cat);
|
|
Register<FerretFormTalisman>(new TextDefinition[] { 1157010, 1031672 }, 1156969, 0x2F59, 0, 0, 100, cat);
|
|
Register<LeggingsOfEmbers>(1062911, 1156956, 0x1411, 0, 0x2C, 100, cat);
|
|
Register<ShaminoCrossbow>(1062915, 1156957, 0x26C3, 0, 0x504, 100, cat);
|
|
Register<SamuraiHelm>(1062923, 1156959, 0x236C, 0, 0, 100, cat);
|
|
Register<HolySword>(1062921, 1156962, 0xF61, 0, 0x482, 100, cat);
|
|
Register<DupresShield>(1075196, 1156963, 0x2B01, 0, 0, 100, cat);
|
|
Register<OssianGrimoire>(1078148, 1156965, 0x2253, 0, 0, 100, cat);
|
|
Register<SquirrelFormTalisman>(new TextDefinition[] { 1157010, 1031671 }, 1156966, 0x2F59, 0, 0, 100, cat);
|
|
Register<EarringsOfProtection>(new TextDefinition[] { 1156821, 1156822 }, 1156659, 0, 0x9C66, 0, 200, cat, ConstructEarrings); // Physcial
|
|
Register<EarringsOfProtection>(1071092, 1156659, 0, 0x9C66, 0, 200, cat, ConstructEarrings); // Fire
|
|
Register<EarringsOfProtection>(1071093, 1156659, 0, 0x9C66, 0, 200, cat, ConstructEarrings); // Cold
|
|
Register<EarringsOfProtection>(1071094, 1156659, 0, 0x9C66, 0, 200, cat, ConstructEarrings); // Poison
|
|
Register<EarringsOfProtection>(1071095, 1156659, 0, 0x9C66, 0, 200, cat, ConstructEarrings); // Energy
|
|
Register<HoodedShroudOfShadows>(1079727, 1156643, 0x2684, 0, 0x455, 1000, cat);
|
|
|
|
// decorations
|
|
cat = StoreCategory.Decorations;
|
|
Register<DecorativeKitchenSet>(1158970, 1158971, 0, 0x9CE8, 0, 1200, cat);
|
|
Register<SquirrelMailbox>(1158859, 1158857, 0xA207, 0, 0, 400, cat);
|
|
Register<BarrelMailbox>(1158859, 1158857, 0xA1F7, 0, 0, 400, cat);
|
|
Register<DecorativeBlackwidowDeed>(1157897, 1157898, 0, 0x9CD7, 0, 600, cat);
|
|
Register<HildebrandtDragonRugDeed>(1157889, 1157890, 0, 0x9CD8, 0, 700, cat);
|
|
Register<SmallWorldTreeRugAddonDeed>(1157206, 1157898, 0, 0x9CBA, 0, 300, cat);
|
|
Register<LargeWorldTreeRugAddonDeed>(1157207, 1157898, 0, 0x9CBA, 0, 500, cat);
|
|
Register<MountedPixieWhiteDeed>(new TextDefinition[] { 1074482, 1156915 }, 1156974, 0x2A79, 0, 0, 100, cat);
|
|
Register<MountedPixieLimeDeed>(new TextDefinition[] { 1074482, 1156914 }, 1156974, 0x2A77, 0, 0, 100, cat);
|
|
Register<MountedPixieBlueDeed>(new TextDefinition[] { 1074482, 1156913 }, 1156974, 0x2A75, 0, 0, 100, cat);
|
|
Register<MountedPixieOrangeDeed>(new TextDefinition[] { 1074482, 1156912 }, 1156974, 0x2A73, 0, 0, 100, cat);
|
|
Register<MountedPixieGreenDeed>(new TextDefinition[] { 1074482, 1156911 }, 1156974, 0x2A71, 0, 0, 100, cat);
|
|
Register<UnsettlingPortraitDeed>(1074480, 1156973, 0x2A65, 0, 0, 100, cat);
|
|
Register<CreepyPortraitDeed>(1074481, 1156972, 0x2A69, 0, 0, 100, cat);
|
|
Register<DisturbingPortraitDeed>(1074479, 1156955, 0x2A5D, 0, 0, 100, cat);
|
|
Register<DawnsMusicBox>(1075198, 1156968, 0x2AF9, 0, 0, 100, cat);
|
|
Register<BedOfNailsDeed>(1074801, 1156975, 0, 0x9C8D, 0, 100, cat);
|
|
Register<BrokenCoveredChairDeed>(1076257, 1156950, 0xC17, 0, 0, 100, cat);
|
|
Register<BoilingCauldronDeed>(1076267, 1156949, 0, 0x9CB9, 0, 100, cat);
|
|
Register<SuitOfGoldArmorDeed>(1076265, 1156943, 0x3DAA, 0, 0, 100, cat);
|
|
Register<BrokenBedDeed>(1076263, 1156945, 0, 0x9C8F, 0, 100, cat);
|
|
Register<BrokenArmoireDeed>(1076262, 1156946, 0xC12, 0, 0, 100, cat);
|
|
Register<BrokenVanityDeed>(1076260, 1156947, 0, 0x9C90, 0, 100, cat);
|
|
Register<BrokenBookcaseDeed>(1076258, 1156948, 0xC14, 0, 0, 100, cat);
|
|
Register<SacrificialAltarDeed>(1074818, 1156954, 0, 0x9C8E, 0, 100, cat);
|
|
Register<HauntedMirrorDeed>(1074800, 1156953, 0x2A7B, 0, 0, 100, cat);
|
|
Register<BrokenChestOfDrawersDeed>(1076261, 1156951, 0xC24, 0, 0, 100, cat);
|
|
Register<StandingBrokenChairDeed>(1076259, 1156952, 0xC1B, 0, 0, 100, cat);
|
|
Register<FountainOfLifeDeed>(1075197, 1156964, 0x2AC0, 0, 0, 100, cat);
|
|
Register<TapestryOfSosaria>(1062917, 1156961, 0x234E, 0, 0, 100, cat);
|
|
Register<RoseOfTrinsic>(1062913, 1156960, 0x234D, 0, 0, 100, cat);
|
|
Register<HearthOfHomeFireDeed>(1062919, 1156958, 0, 0x9C97, 0, 100, cat);
|
|
|
|
Register<StoreSingingBall>(1041245, 1156907, 0, 0x9CB8, 0, 200, cat);
|
|
Register<SecretChest>(1151583, 1156909, 0x9706, 0, 0, 500, cat);
|
|
|
|
Register<MiniHouseDeed>(new TextDefinition[] { 1062096, 1157015 }, 1156916, 0, 0x9CB5, 0, 200, cat, ConstructMiniHouseDeed); // two story wood & plaster
|
|
Register<MiniHouseDeed>(new TextDefinition[] { 1062096, 1011317 }, 1156916, 0x22F5, 0, 0, 200, cat, ConstructMiniHouseDeed); // small stone tower
|
|
Register<MiniHouseDeed>(new TextDefinition[] { 1062096, 1011307 }, 1156916, 0x22E0, 0, 0, 200, cat, ConstructMiniHouseDeed); // wood and plaster house
|
|
Register<MiniHouseDeed>(new TextDefinition[] { 1062096, 1011308 }, 1156916, 0x22E1, 0, 0, 200, cat, ConstructMiniHouseDeed); // thathed-roof cottage
|
|
Register<MiniHouseDeed>(new TextDefinition[] { 1062096, 1011312 }, 1156916, 0, 0x9CB2, 0, 200, cat, ConstructMiniHouseDeed); // Tower
|
|
Register<MiniHouseDeed>(new TextDefinition[] { 1062096, 1011313 }, 1156916, 0, 0x9CB1, 0, 200, cat, ConstructMiniHouseDeed); // Small stone keep
|
|
Register<MiniHouseDeed>(new TextDefinition[] { 1062096, 1011314 }, 1156916, 0, 0x9CB0, 0, 200, cat, ConstructMiniHouseDeed); // Castle
|
|
|
|
Register<HangingSwordsDeed>(1076272, 1156936, 0, 0x9C96, 0, 100, cat);
|
|
Register<UnmadeBedDeed>(1076279, 1156935, 0, 0x9C9B, 0, 100, cat);
|
|
Register<CurtainsDeed>(1076280, 1156934, 0, 0x9C93, 0, 100, cat);
|
|
Register<TableWithOrangeClothDeed>(new TextDefinition[] { 1157012, 1157013 }, 1156933, 0x118E, 0, 0, 100, cat);
|
|
|
|
Register<MiniHouseDeed>(new TextDefinition[] { 1062096, 1011320 }, 1156916, 0x22F3, 0, 0, 200, cat, ConstructMiniHouseDeed); // sanstone house with patio
|
|
Register<MiniHouseDeed>(new TextDefinition[] { 1062096, 1011316 }, 1156916, 0, 0x9CB3, 0, 200, cat, ConstructMiniHouseDeed); // marble house with patio
|
|
Register<MiniHouseDeed>(new TextDefinition[] { 1062096, 1011319 }, 1156916, 0x2300, 0, 0, 200, cat, ConstructMiniHouseDeed); // two story villa
|
|
Register<MiniHouseDeed>(new TextDefinition[] { 1062096, 1157014 }, 1156916, 0, 0x9CB6, 0, 200, cat, ConstructMiniHouseDeed); // two story stone & plaster
|
|
Register<MiniHouseDeed>(new TextDefinition[] { 1062096, 1011315 }, 1156916, 0, 0x9CB4, 0, 200, cat, ConstructMiniHouseDeed); // Large house with patio
|
|
Register<MiniHouseDeed>(new TextDefinition[] { 1062096, 1011309 }, 1156916, 0, 0x9CB7, 0, 200, cat, ConstructMiniHouseDeed); // brick house
|
|
Register<MiniHouseDeed>(new TextDefinition[] { 1062096, 1011304 }, 1156916, 0x22C9, 0, 0, 200, cat, ConstructMiniHouseDeed); // field stone house
|
|
Register<MiniHouseDeed>(new TextDefinition[] { 1062096, 1011306 }, 1156916, 0x22DF, 0, 0, 200, cat, ConstructMiniHouseDeed); // wooden house
|
|
Register<MiniHouseDeed>(new TextDefinition[] { 1062096, 1011305 }, 1156916, 0x22DE, 0, 0, 200, cat, ConstructMiniHouseDeed); // small brick house
|
|
Register<MiniHouseDeed>(new TextDefinition[] { 1062096, 1011303 }, 1156916, 0x22E1, 0, 0, 200, cat, ConstructMiniHouseDeed); // stone and plaster house
|
|
Register<MiniHouseDeed>(new TextDefinition[] { 1062096, 1011318 }, 1156916, 0x22FB, 0, 0, 200, cat, ConstructMiniHouseDeed); // two-story log cabin
|
|
Register<MiniHouseDeed>(new TextDefinition[] { 1062096, 1011321 }, 1156916, 0x22F6, 0, 0, 200, cat, ConstructMiniHouseDeed); // small stone workshop
|
|
Register<MiniHouseDeed>(new TextDefinition[] { 1062096, 1011322 }, 1156916, 0x22F4, 0, 0, 200, cat, ConstructMiniHouseDeed); // small marble workshop
|
|
|
|
Register<TableWithBlueClothDeed>(1076276, 1156932, 0x118C, 0, 0, 100, cat);
|
|
Register<CherryBlossomTreeDeed>(1076268, 1156940, 0, 0x9C91, 0, 100, cat);
|
|
Register<IronMaidenDeed>(1076288, 1156924, 0x1249, 0, 0, 100, cat);
|
|
Register<SmallFishingNetDeed>(1076286, 1156923, 0x1EA3, 0, 0, 100, cat);
|
|
Register<StoneStatueDeed>(1076284, 1156922, 0, 0x9C9A, 0, 100, cat);
|
|
Register<WallTorchDeed>(1076282, 1156921, 0x3D98, 0, 0, 100, cat);
|
|
Register<HouseLadderDeed>(1076287, 1156920, 0x2FDE, 0, 0, 100, cat);
|
|
Register<LargeFishingNetDeed>(1076285, 1156919, 0x3D8E, 0, 0, 100, cat);
|
|
Register<FountainDeed>(1076283, 1156918, 0, 0x9C94, 0, 100, cat);
|
|
Register<ScarecrowDeed>(1076608, 1156917, 0x1E34, 0, 0, 100, cat);
|
|
Register<HangingAxesDeed>(1076271, 1156937, 0, 0x9C95, 0, 100, cat);
|
|
Register<AppleTreeDeed>(1076269, 1156938, 0, 0x9C8C, 0, 100, cat);
|
|
Register<GuillotineDeed>(1024656, 1156941, 0x125E, 0, 0, 100, cat);
|
|
Register<SuitOfSilverArmorDeed>(1076266, 1156942, 0x3D86, 0, 0, 100, cat);
|
|
Register<PeachTreeDeed>(1076270, 1156939, 0, 0x9C98, 0, 100, cat);
|
|
Register<CherryBlossomTrunkDeed>(1076784, 1156925, 0x26EE, 0, 0, 100, cat);
|
|
Register<PeachTrunkDeed>(1076786, 1156926, 0xD9C, 0, 0, 100, cat);
|
|
Register<BrokenFallenChairDeed>(1076264, 1156944, 0xC19, 0, 0, 100, cat);
|
|
Register<TableWithRedClothDeed>(1076277, 1156930, 0x118E, 0, 0, 100, cat);
|
|
Register<VanityDeed>(1074027, 1156931, 0, 0x9C9C, 0, 100, cat);
|
|
Register<AppleTrunkDeed>(1076785, 1156927, 0xD98, 0, 0, 100, cat);
|
|
Register<TableWithPurpleClothDeed>(new TextDefinition[] { 1157011, 1157013 }, 1156929, 0x118B, 0, 0, 100, cat);
|
|
Register<WoodenCoffinDeed>(1076274, 1156928 , 0, 0x9C92, 0, 100, cat);
|
|
Register<RaisedGardenDeed>(new TextDefinition[] { 1150359, 1156688 }, 1156680, 0, 0x9C8B, 0, 2000, cat, ConstructRaisedGarden);
|
|
Register<HouseTeleporterTileBag>(new TextDefinition[] { 1156683, 1156826 }, 1156668, 0x40B9, 0, 1201, 1000, cat);
|
|
Register<WoodworkersBenchDeed>(1026641, 1156670, 0x14F0, 0, 0, 600, cat);
|
|
Register<LargeGlowingLadyBug>(1071400, 1156660, 0x2CFD, 0, 0, 200, cat);
|
|
Register<FreshGreenLadyBug>(1071401, 1156661, 0x2D01, 0, 0, 200, cat);
|
|
Register<WillowTreeDeed>(1071105, 1156658, 0x224A, 0, 0, 200, cat);
|
|
|
|
Register<FallenLogDeed>(1071088, 1156649, 0, 0x9C88, 0, 200, cat);
|
|
Register<LampPost2>(1071089, 1156650, 0xB22, 0, 0, 200, cat, ConstructLampPost);
|
|
Register<HitchingPost>(1071090, 1156651, 0x14E7, 0, 0, 200, cat, ConstructHitchingPost);
|
|
Register<AncestralGravestone>(1071096, 1156653, 0x1174, 0, 0, 200, cat);
|
|
Register<WoodenBookcase>(1071102, 1156655, 0x0A9D, 0, 0, 200, cat);
|
|
Register<SnowTreeDeed>(1071103, 1156656, 0, 0x9C8A, 0, 200, cat);
|
|
Register<MapleTreeDeed>(1071104, 1156657, 0, 0x9C87, 0, 200, cat);
|
|
|
|
// mounts
|
|
cat = StoreCategory.Mounts;
|
|
Register<CoconutCrabStatue>(1159165, 1159166, 0xA335, 0, 0, 1000, cat);
|
|
Register<SkeletalCatStatue>(1158462, 1158738, 0xA138, 0, 0, 1000, cat);
|
|
Register<EowmuStatue>(1158082, 1158433, 0xA0C0, 0, 0, 1000, cat);
|
|
Register<WindrunnerStatue>(1124685, 1157373, 0x9ED5, 0, 0, 1000, cat);
|
|
Register<LasherStatue>(1157214, 1157305, 0x9E35, 0, 0, 1000, cat);
|
|
Register<ChargerOfTheFallen>(1075187, 1156646, 0x2D9C, 0, 0, 1000, cat);
|
|
|
|
// misc
|
|
cat = StoreCategory.Misc;
|
|
Register<SoulstoneToken>(1158404, 1158405, 0x2A93, 0, 2598, 1000, cat, ConstructSoulstone);
|
|
Register<BagOfBulkOrderCovers>(1071116, 1157603, 0, 0x9CC6, 0, 200, cat, ConstructBOBCoverOne);
|
|
|
|
//TODO: UndeadWeddingBundle, TotemOfChromaticFortune,
|
|
|
|
Register<PetBrandingIron>(1157314, 1157372, 0, 0x9CC3, 0, 600, cat);
|
|
Register<ImprovedRockHammer>(1157177, 1157306, 0, 0x9CBB, 0, 1000, cat);
|
|
Register<PetBondingPotion>(1152921, 1156678, 0, 0x9CBC, 0, 500, cat);
|
|
|
|
Register<ForgedMetalOfArtifacts>(new TextDefinition[] { 1149868, 1156686 }, 1156674, 0, 0x9C65, 0, 1000, cat, ConstructForgedMetal);
|
|
Register<ForgedMetalOfArtifacts>(new TextDefinition[] { 1149868, 1156687 }, 1156675, 0, 0x9C65, 0, 600, cat, ConstructForgedMetal);
|
|
Register<PenOfWisdom>(1115358, 1156669, 0, 0x9C62, 0, 600, cat);
|
|
|
|
Register<BritannianShipDeed>(1150100, 1156673, 0, 0x9C6A, 0, 1200, cat);
|
|
|
|
Register<SoulstoneToken>(1078835, 1158405, 0x2ADC, 0, 0, 1000, cat, ConstructSoulstone);
|
|
Register<SoulstoneToken>(1078834, 1158405, 0x2A93, 0, 0, 1000, cat, ConstructSoulstone);
|
|
|
|
Register<MerchantsTrinket>(new TextDefinition[] { 1156827, 1156681 }, 1156666, 0, 0x9C67, 0, 300, cat, ConstructMerchantsTrinket);
|
|
Register<MerchantsTrinket>(new TextDefinition[] { 1156828, 1156682 }, 1156667, 0, 0x9C67, 0, 500, cat, ConstructMerchantsTrinket);
|
|
|
|
Register<ArmorEngravingToolToken>(1080547, 1156652, 0, 0x9C65, 0, 200, cat);
|
|
Register<BagOfBulkOrderCovers>(1071116, 1156654, 0, 0x9CC6, 0, 200, cat, ConstructBOBCoverTwo);
|
|
}
|
|
|
|
public static void Register<T>(TextDefinition name, int tooltip, int itemID, int gumpID, int hue, int cost, StoreCategory cat, Func<Mobile, StoreEntry, Item> constructor = null) where T : Item
|
|
{
|
|
Register(typeof(T), name, tooltip, itemID, gumpID, hue, cost, cat, constructor);
|
|
}
|
|
|
|
public static void Register(Type itemType, TextDefinition name, int tooltip, int itemID, int gumpID, int hue, int cost, StoreCategory cat, Func<Mobile, StoreEntry, Item> constructor = null)
|
|
{
|
|
Register(new StoreEntry(itemType, name, tooltip, itemID, gumpID, hue, cost, cat, constructor));
|
|
}
|
|
|
|
public static void Register<T>(TextDefinition[] name, int tooltip, int itemID, int gumpID, int hue, int cost, StoreCategory cat, Func<Mobile, StoreEntry, Item> constructor = null) where T : Item
|
|
{
|
|
Register(typeof(T), name, tooltip, itemID, gumpID, hue, cost, cat, constructor);
|
|
}
|
|
|
|
public static void Register(Type itemType, TextDefinition[] name, int tooltip, int itemID, int gumpID, int hue, int cost, StoreCategory cat, Func<Mobile, StoreEntry, Item> constructor = null)
|
|
{
|
|
Register(new StoreEntry(itemType, name, tooltip, itemID, gumpID, hue, cost, cat, constructor));
|
|
}
|
|
|
|
public static void Register(StoreEntry entry)
|
|
{
|
|
Entries.Add(entry);
|
|
}
|
|
|
|
public static bool CanSearch(Mobile m)
|
|
{
|
|
return m != null && m.Region.GetLogoutDelay(m) <= TimeSpan.Zero;
|
|
}
|
|
|
|
public static void UOStoreRequest(NetState state, PacketReader pvSrc)
|
|
{
|
|
OpenStore(state.Mobile as PlayerMobile);
|
|
}
|
|
|
|
public static void OpenStore(PlayerMobile user)
|
|
{
|
|
if (user == null || user.NetState == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!Enabled || (Configuration.Expansion != Expansion.None && Core.Expansion < Configuration.Expansion))
|
|
{
|
|
// The promo code redemption system is currently unavailable. Please try again later.
|
|
user.SendLocalizedMessage(1062904);
|
|
return;
|
|
}
|
|
|
|
if (Configuration.CurrencyImpl == CurrencyType.None)
|
|
{
|
|
// The promo code redemption system is currently unavailable. Please try again later.
|
|
user.SendLocalizedMessage(1062904);
|
|
return;
|
|
}
|
|
|
|
if (!user.NetState.UltimaStore)
|
|
{
|
|
user.SendMessage("You must update Ultima Online in order to use the in game store.");
|
|
return;
|
|
}
|
|
|
|
if (user.AccessLevel < AccessLevel.Counselor && !CanSearch(user))
|
|
{
|
|
// Before using the in game store, you must be in a safe log-out location
|
|
// such as an inn or a house which has you on its Owner, Co-owner, or Friends list.
|
|
user.SendLocalizedMessage(1156586);
|
|
return;
|
|
}
|
|
|
|
if (!user.HasGump(typeof(UltimaStoreGump)))
|
|
{
|
|
BaseGump.SendGump(new UltimaStoreGump(user));
|
|
}
|
|
}
|
|
|
|
#region Constructors
|
|
public static Item ConstructHairDye(Mobile m, StoreEntry entry)
|
|
{
|
|
var info = NaturalHairDye.Table.FirstOrDefault(x => x.Localization == entry.Name[1].Number);
|
|
|
|
if(info != null)
|
|
{
|
|
return new NaturalHairDye(info.Type);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public static Item ConstructHaochisPigment(Mobile m, StoreEntry entry)
|
|
{
|
|
var info = HaochisPigment.Table.FirstOrDefault(x => x.Localization == entry.Name[1].Number);
|
|
|
|
if (info != null)
|
|
{
|
|
return new HaochisPigment(info.Type, 50);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public static Item ConstructPigments(Mobile m, StoreEntry entry)
|
|
{
|
|
PigmentType type = PigmentType.None;
|
|
|
|
for (int i = 0; i < PigmentsOfTokuno.Table.Length; i++)
|
|
{
|
|
if (PigmentsOfTokuno.Table[i][1] == entry.Name[1].Number)
|
|
{
|
|
type = (PigmentType)i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (type != PigmentType.None)
|
|
{
|
|
return new PigmentsOfTokuno(type, 50);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public static Item ConstructEarrings(Mobile m, StoreEntry entry)
|
|
{
|
|
AosElementAttribute ele = AosElementAttribute.Physical;
|
|
|
|
switch (entry.Name[0].Number)
|
|
{
|
|
case 1071092: ele = AosElementAttribute.Fire; break;
|
|
case 1071093: ele = AosElementAttribute.Cold; break;
|
|
case 1071094: ele = AosElementAttribute.Poison; break;
|
|
case 1071095: ele = AosElementAttribute.Energy; break;
|
|
}
|
|
|
|
return new EarringsOfProtection(ele);
|
|
}
|
|
|
|
public static Item ConstructRobe(Mobile m, StoreEntry entry)
|
|
{
|
|
return new HoodedBritanniaRobe(entry.ItemID);
|
|
}
|
|
|
|
public static Item ConstructMiniHouseDeed(Mobile m, StoreEntry entry)
|
|
{
|
|
int label = entry.Name[1].Number;
|
|
|
|
switch (label)
|
|
{
|
|
default:
|
|
for (int i = 0; i < MiniHouseInfo.Info.Length; i++)
|
|
{
|
|
if (MiniHouseInfo.Info[i].LabelNumber == entry.Name[1].Number)
|
|
{
|
|
var type = (MiniHouseType)i;
|
|
|
|
return new MiniHouseDeed(type);
|
|
}
|
|
}
|
|
return null;
|
|
case 1157015: return new MiniHouseDeed(MiniHouseType.TwoStoryWoodAndPlaster);
|
|
case 1157014: return new MiniHouseDeed(MiniHouseType.TwoStoryStoneAndPlaster);
|
|
}
|
|
}
|
|
|
|
public static Item ConstructRaisedGarden(Mobile m, StoreEntry entry)
|
|
{
|
|
var bag = new Bag();
|
|
|
|
bag.DropItem(new RaisedGardenDeed());
|
|
bag.DropItem(new RaisedGardenDeed());
|
|
bag.DropItem(new RaisedGardenDeed());
|
|
|
|
return bag;
|
|
}
|
|
|
|
public static Item ConstructLampPost(Mobile m, StoreEntry entry)
|
|
{
|
|
var item = new LampPost2
|
|
{
|
|
Movable = true,
|
|
LootType = LootType.Blessed
|
|
};
|
|
|
|
return item;
|
|
}
|
|
|
|
public static Item ConstructForgedMetal(Mobile m, StoreEntry entry)
|
|
{
|
|
switch (entry.Name[1].Number)
|
|
{
|
|
case 1156686: return new ForgedMetalOfArtifacts(10);
|
|
case 1156687: return new ForgedMetalOfArtifacts(5);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public static Item ConstructSoulstone(Mobile m, StoreEntry entry)
|
|
{
|
|
switch (entry.Name[0].Number)
|
|
{
|
|
case 1078835: return new SoulstoneToken(SoulstoneType.Blue);
|
|
case 1078834: return new SoulstoneToken(SoulstoneType.Green);
|
|
case 1158404: return new SoulstoneToken(SoulstoneType.Violet);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public static Item ConstructMerchantsTrinket(Mobile m, StoreEntry entry)
|
|
{
|
|
switch(entry.Name[0].Number)
|
|
{
|
|
case 1156827: return new MerchantsTrinket(false);
|
|
case 1156828: return new MerchantsTrinket(true);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public static Item ConstructBOBCoverOne(Mobile m, StoreEntry entry)
|
|
{
|
|
return new BagOfBulkOrderCovers(12, 25);
|
|
}
|
|
|
|
public static Item ConstructBOBCoverTwo(Mobile m, StoreEntry entry)
|
|
{
|
|
return new BagOfBulkOrderCovers(1, 11);
|
|
}
|
|
|
|
public static Item ConstructHitchingPost(Mobile m, StoreEntry entry)
|
|
{
|
|
return new HitchingPost(false);
|
|
}
|
|
#endregion
|
|
|
|
public static void AddPendingItem(Mobile m, Item item)
|
|
{
|
|
if (!PendingItems.TryGetValue(m, out List<Item> list))
|
|
{
|
|
PendingItems[m] = list = new List<Item>();
|
|
}
|
|
|
|
if (!list.Contains(item))
|
|
{
|
|
list.Add(item);
|
|
}
|
|
|
|
UltimaStoreContainer.DropItem(item);
|
|
}
|
|
|
|
public static bool HasPendingItem(PlayerMobile pm)
|
|
{
|
|
return PendingItems.ContainsKey(pm);
|
|
}
|
|
|
|
public static void CheckPendingItem(Mobile m)
|
|
{
|
|
if (PendingItems.TryGetValue(m, out List<Item> list))
|
|
{
|
|
var index = list.Count;
|
|
|
|
while (--index >= 0)
|
|
{
|
|
if (index >= list.Count)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var item = list[index];
|
|
|
|
if (item != null)
|
|
{
|
|
if (m.Backpack != null && m.Alive && m.Backpack.TryDropItem(m, item, false))
|
|
{
|
|
if (item is IPromotionalToken && ((IPromotionalToken)item).ItemName != null)
|
|
{
|
|
// A token has been placed in your backpack. Double-click it to redeem your ~1_PROMO~.
|
|
m.SendLocalizedMessage(1075248, ((IPromotionalToken)item).ItemName.ToString());
|
|
}
|
|
else if (item.LabelNumber > 0 || item.Name != null)
|
|
{
|
|
var name = item.LabelNumber > 0 ? ("#" + item.LabelNumber) : item.Name;
|
|
|
|
// Your purchase of ~1_ITEM~ has been placed in your backpack.
|
|
m.SendLocalizedMessage(1156844, name);
|
|
}
|
|
else
|
|
{
|
|
// Your purchased item has been placed in your backpack.
|
|
m.SendLocalizedMessage(1156843);
|
|
}
|
|
|
|
list.RemoveAt(index);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
list.RemoveAt(index);
|
|
}
|
|
}
|
|
|
|
if (list.Count == 0 && PendingItems.Remove(m))
|
|
{
|
|
list.TrimExcess();
|
|
}
|
|
}
|
|
}
|
|
|
|
public static List<StoreEntry> GetSortedList(string searchString)
|
|
{
|
|
var list = new List<StoreEntry>();
|
|
|
|
list.AddRange(Entries.Where(e => Insensitive.Contains(GetStringName(e.Name), searchString)));
|
|
|
|
return list;
|
|
}
|
|
|
|
public static string GetStringName(TextDefinition[] text)
|
|
{
|
|
var str = string.Empty;
|
|
|
|
foreach (var td in text)
|
|
{
|
|
if (td.Number > 0 && VendorSearch.StringList != null)
|
|
{
|
|
str += String.Format("{0} ", VendorSearch.StringList.GetString(td.Number));
|
|
}
|
|
else if (!String.IsNullOrWhiteSpace(td.String))
|
|
{
|
|
str += String.Format("{0} ", td.String);
|
|
}
|
|
}
|
|
|
|
return str;
|
|
}
|
|
|
|
public static string GetStringName(TextDefinition text)
|
|
{
|
|
var str = text.String;
|
|
|
|
if (text.Number > 0 && VendorSearch.StringList != null)
|
|
{
|
|
str = VendorSearch.StringList.GetString(text.Number);
|
|
}
|
|
|
|
return str ?? String.Empty;
|
|
}
|
|
|
|
public static List<StoreEntry> GetList(StoreCategory cat)
|
|
{
|
|
return Entries.Where(e => e.Category == cat).ToList();
|
|
}
|
|
|
|
public static void SortList(List<StoreEntry> list, SortBy sort)
|
|
{
|
|
switch (sort)
|
|
{
|
|
case SortBy.Name:
|
|
list.Sort((a, b) => String.CompareOrdinal(GetStringName(a.Name), GetStringName(b.Name)));
|
|
break;
|
|
case SortBy.PriceLower:
|
|
list.Sort((a, b) => a.Price.CompareTo(b.Price));
|
|
break;
|
|
case SortBy.PriceHigher:
|
|
list.Sort((a, b) => b.Price.CompareTo(a.Price));
|
|
break;
|
|
case SortBy.Newest:
|
|
break;
|
|
case SortBy.Oldest:
|
|
list.Reverse();
|
|
break;
|
|
}
|
|
}
|
|
|
|
public static int CartCount(Mobile m)
|
|
{
|
|
var profile = GetProfile(m, false);
|
|
|
|
if (profile != null)
|
|
{
|
|
return profile.Cart.Count;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
public static int GetSubTotal(Dictionary<StoreEntry, int> cart)
|
|
{
|
|
if (cart == null || cart.Count == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
var sub = 0.0;
|
|
|
|
foreach (var kvp in cart)
|
|
{
|
|
sub += kvp.Key.Cost * kvp.Value;
|
|
}
|
|
|
|
return (int)sub;
|
|
}
|
|
|
|
public static int GetCurrency(Mobile m, bool sendMessage = false)
|
|
{
|
|
switch (Configuration.CurrencyImpl)
|
|
{
|
|
case CurrencyType.Sovereigns:
|
|
{
|
|
if (m is PlayerMobile)
|
|
{
|
|
return ((PlayerMobile)m).AccountSovereigns;
|
|
}
|
|
}
|
|
break;
|
|
case CurrencyType.Gold:
|
|
return Banker.GetBalance(m);
|
|
case CurrencyType.PointsSystem:
|
|
{
|
|
var sys = PointsSystem.GetSystemInstance(Configuration.PointsImpl);
|
|
|
|
if (sys != null)
|
|
{
|
|
return (int)Math.Min(Int32.MaxValue, sys.GetPoints(m));
|
|
}
|
|
}
|
|
break;
|
|
case CurrencyType.Custom:
|
|
return Configuration.GetCustomCurrency(m);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
public static void TryPurchase(Mobile m)
|
|
{
|
|
var cart = GetCart(m);
|
|
var total = GetSubTotal(cart);
|
|
|
|
if (cart == null || cart.Count == 0 || total == 0)
|
|
{
|
|
// Purchase failed due to your cart being empty.
|
|
m.SendLocalizedMessage(1156842);
|
|
}
|
|
else if (total > GetCurrency(m, true))
|
|
{
|
|
if (m is PlayerMobile)
|
|
{
|
|
BaseGump.SendGump(new NoFundsGump((PlayerMobile)m));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var subtotal = 0;
|
|
var fail = false;
|
|
|
|
var remove = new List<StoreEntry>();
|
|
|
|
foreach (var entry in cart)
|
|
{
|
|
for (var i = 0; i < entry.Value; i++)
|
|
{
|
|
if (!entry.Key.Construct(m))
|
|
{
|
|
fail = true;
|
|
|
|
try
|
|
{
|
|
using (var op = File.AppendText("UltimaStoreError.log"))
|
|
{
|
|
op.WriteLine("Bad Constructor: {0}", entry.Key.ItemType.Name);
|
|
|
|
Utility.WriteConsoleColor(ConsoleColor.Red, "[Ultima Store]: Bad Constructor: {0}", entry.Key.ItemType.Name);
|
|
}
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
else
|
|
{
|
|
remove.Add(entry.Key);
|
|
|
|
subtotal += entry.Key.Cost;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (subtotal > 0)
|
|
{
|
|
DeductCurrency(m, subtotal);
|
|
}
|
|
|
|
var profile = GetProfile(m);
|
|
|
|
foreach (var entry in remove)
|
|
{
|
|
profile.RemoveFromCart(entry);
|
|
}
|
|
|
|
if (fail)
|
|
{
|
|
// Failed to process one of your items. Please check your cart and try again.
|
|
m.SendLocalizedMessage(1156853);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Should have already passed GetCurrency
|
|
/// </summary>
|
|
/// <param name="m"></param>
|
|
/// <param name="amount"></param>
|
|
public static int DeductCurrency(Mobile m, int amount)
|
|
{
|
|
switch (Configuration.CurrencyImpl)
|
|
{
|
|
case CurrencyType.Sovereigns:
|
|
{
|
|
if (m is PlayerMobile && ((PlayerMobile)m).WithdrawSovereigns(amount))
|
|
{
|
|
return amount;
|
|
}
|
|
}
|
|
break;
|
|
case CurrencyType.Gold:
|
|
{
|
|
if (Banker.Withdraw(m, amount, true))
|
|
{
|
|
return amount;
|
|
}
|
|
}
|
|
break;
|
|
case CurrencyType.PointsSystem:
|
|
{
|
|
var sys = PointsSystem.GetSystemInstance(Configuration.PointsImpl);
|
|
|
|
if (sys != null && sys.DeductPoints(m, amount, true))
|
|
{
|
|
return amount;
|
|
}
|
|
}
|
|
break;
|
|
case CurrencyType.Custom:
|
|
return Configuration.DeductCustomCurrecy(m, amount);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#region Player Persistence
|
|
public static Dictionary<Mobile, PlayerProfile> PlayerProfiles { get; private set; }
|
|
|
|
public static PlayerProfile GetProfile(Mobile m, bool create = true)
|
|
{
|
|
PlayerProfile profile;
|
|
|
|
if ((!PlayerProfiles.TryGetValue(m, out profile) || profile == null) && create)
|
|
{
|
|
PlayerProfiles[m] = profile = new PlayerProfile(m);
|
|
}
|
|
|
|
return profile;
|
|
}
|
|
|
|
public static Dictionary<StoreEntry, int> GetCart(Mobile m)
|
|
{
|
|
var profile = GetProfile(m, false);
|
|
|
|
if (profile != null)
|
|
{
|
|
return profile.Cart;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public static void OnSave(WorldSaveEventArgs e)
|
|
{
|
|
Persistence.Serialize(FilePath, Serialize);
|
|
}
|
|
|
|
public static void OnLoad()
|
|
{
|
|
Persistence.Deserialize(FilePath, Deserialize);
|
|
}
|
|
|
|
private static void Serialize(GenericWriter writer)
|
|
{
|
|
writer.Write(0);
|
|
|
|
writer.Write(_UltimaStoreContainer);
|
|
|
|
writer.Write(PendingItems.Count);
|
|
|
|
foreach (var kvp in PendingItems)
|
|
{
|
|
writer.Write(kvp.Key);
|
|
writer.WriteItemList(kvp.Value, true);
|
|
}
|
|
|
|
writer.Write(PlayerProfiles.Count);
|
|
|
|
foreach (var pe in PlayerProfiles)
|
|
{
|
|
pe.Value.Serialize(writer);
|
|
}
|
|
}
|
|
|
|
private static void Deserialize(GenericReader reader)
|
|
{
|
|
reader.ReadInt();
|
|
|
|
_UltimaStoreContainer = reader.ReadItem<UltimaStoreContainer>();
|
|
|
|
var count = reader.ReadInt();
|
|
|
|
for (var i = 0; i < count; i++)
|
|
{
|
|
var m = reader.ReadMobile();
|
|
var list = reader.ReadStrongItemList<Item>();
|
|
|
|
if (m != null && list.Count > 0)
|
|
{
|
|
PendingItems[m] = list;
|
|
}
|
|
}
|
|
|
|
count = reader.ReadInt();
|
|
|
|
for (var i = 0; i < count; i++)
|
|
{
|
|
var pe = new PlayerProfile(reader);
|
|
|
|
if (pe.Player != null)
|
|
{
|
|
PlayerProfiles[pe.Player] = pe;
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
|
|
[DeleteConfirm("This is the Ultima Store item display container. You should not delete this.")]
|
|
public sealed class UltimaStoreContainer : Container
|
|
{
|
|
private static readonly List<Item> _DisplayItems = new List<Item>();
|
|
|
|
public override bool Decays { get { return false; } }
|
|
|
|
public override string DefaultName { get { return "Ultima Store Display Container"; } }
|
|
|
|
public UltimaStoreContainer()
|
|
: base(0) // No Draw
|
|
{
|
|
Movable = false;
|
|
Visible = false;
|
|
|
|
Internalize();
|
|
}
|
|
|
|
public UltimaStoreContainer(Serial serial)
|
|
: base(serial)
|
|
{ }
|
|
|
|
public void AddDisplayItem(Item item)
|
|
{
|
|
if (item == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!_DisplayItems.Contains(item))
|
|
{
|
|
_DisplayItems.Add(item);
|
|
}
|
|
|
|
DropItem(item);
|
|
}
|
|
|
|
public Item FindDisplayItem(Type t)
|
|
{
|
|
var item = GetDisplayItem(t);
|
|
|
|
if (item == null)
|
|
{
|
|
item = Loot.Construct(t);
|
|
|
|
if (item != null)
|
|
{
|
|
AddDisplayItem(item);
|
|
}
|
|
}
|
|
|
|
return item;
|
|
}
|
|
|
|
public Item GetDisplayItem(Type t)
|
|
{
|
|
return _DisplayItems.FirstOrDefault(x => x.GetType() == t);
|
|
}
|
|
|
|
public override void Serialize(GenericWriter writer)
|
|
{
|
|
base.Serialize(writer);
|
|
|
|
writer.Write(0);
|
|
|
|
writer.WriteItemList(_DisplayItems, true);
|
|
}
|
|
|
|
public override void Deserialize(GenericReader reader)
|
|
{
|
|
base.Deserialize(reader);
|
|
|
|
reader.ReadInt();
|
|
|
|
var list = reader.ReadStrongItemList();
|
|
|
|
if (list.Count > 0)
|
|
{
|
|
Timer.DelayCall(o => o.ForEach(AddDisplayItem), list);
|
|
}
|
|
}
|
|
}
|
|
}
|