Overwrite

Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
Unstable Kitsune
2023-11-28 23:20:26 -05:00
parent 3cd54811de
commit b918192e4e
11608 changed files with 2644205 additions and 47 deletions

View File

@@ -0,0 +1,313 @@
using System;
using Server;
using Server.Mobiles;
using Server.Gumps;
using Server.Engines.Points;
using System.Collections.Generic;
using Server.Targeting;
using Server.Items;
namespace Server.Engines.CityLoyalty
{
public class CityDonationItem : Item
{
[CommandProperty(AccessLevel.GameMaster)]
public CityLoyaltySystem CitySystem { get { return CityLoyaltySystem.GetCityInstance(City); } set { } }
public City City { get; protected set; }
[CommandProperty(AccessLevel.GameMaster)]
public TradeMinister Minister { get; set; }
public Dictionary<Type, int> Table { get; protected set; }
public virtual bool Animals { get { return false; } }
public CityDonationItem(City city, TradeMinister minister, int itemid) : base(itemid)
{
City = city;
Minister = minister;
Movable = false;
}
public override void OnDoubleClick(Mobile from)
{
if (!CityLoyaltySystem.IsSetup())
return;
if(Animals && Table != null && Table.Count > 0)
{
from.Target = new InternalTarget(this);
from.SendLocalizedMessage(1152936); // Which animal do you wish to donate?
}
else if (!Animals)
{
SendMessageTo(from, 1152928); // If you wish to donate to the City simply drop the items into the crate.
}
}
public override bool OnDragDrop(Mobile from, Item dropped)
{
if (!CityLoyaltySystem.IsSetup())
return false;
if(!Animals && Table != null && Table.Count > 0)
{
int love = 0;
if (dropped is Container)
{
List<Item> items = new List<Item>(dropped.Items);
foreach (Item item in items)
{
love += CheckTurnin(item);
}
items.Clear();
items.TrimExcess();
}
else
{
love = CheckTurnin(dropped);
}
if (love > 0)
{
CityLoyaltySystem.GetCityInstance(City).AwardLove(from, love);
SendMessageTo(from, 1152926); // The City thanks you for your generosity!
return !(dropped is Container);
}
else
{
SendMessageTo(from, 1152927); // Your generosity is appreciated but the City does not require this item.
return false;
}
}
return false;
}
private int CheckTurnin(Item item)
{
Type dropType = item.GetType();
int love = 0;
foreach (KeyValuePair<Type, int> kvp in Table)
{
Type checkType = kvp.Key;
if (checkType == dropType || dropType.IsSubclassOf(checkType))
{
CityLoyaltySystem sys = CityLoyaltySystem.GetCityInstance(City);
if (sys != null)
{
// TODO: If anything adds to treasure, change this
if (item is MaritimeCargo)
{
AddToTreasury(sys, (MaritimeCargo)item);
}
item.Delete();
love = Table[checkType] * item.Amount;
break;
}
}
}
return love;
}
private void AddToTreasury(CityLoyaltySystem system, MaritimeCargo cargo)
{
if (system != null)
{
if (cargo.City == City)
{
system.AddToTreasury(null, cargo.GetAwardAmount() * 1000);
}
else
{
system.AddToTreasury(null, 100);
}
}
}
private class InternalTarget : Target
{
public CityDonationItem Item { get; private set; }
public InternalTarget(CityDonationItem item) : base(3, false, TargetFlags.None)
{
Item = item;
}
protected override void OnTarget(Mobile from, object targeted)
{
if(targeted is BaseCreature)
{
BaseCreature bc = targeted as BaseCreature;
Type t = bc.GetType();
if(bc.Controlled && !bc.Summoned && bc.GetMaster() == from)
{
if(Item.Table.ContainsKey(t))
{
CityLoyaltySystem sys = CityLoyaltySystem.GetCityInstance(Item.City);
if(sys != null)
{
bc.Delete();
sys.AwardLove(from, Item.Table[t]);
Item.SendMessageTo(from, 1152926); // The City thanks you for your generosity!
}
}
else
Item.SendMessageTo(from, 1152929); // That does not look like an animal the City is in need of.
}
else
Item.SendMessageTo(from, 1152930); // Erm. Uhh. I don't think that'd enjoy the stables much...
}
else
Item.SendMessageTo(from, 1152930); // Erm. Uhh. I don't think that'd enjoy the stables much...
}
}
private void SendMessageTo(Mobile m, int message)
{
if (Minister != null)
Minister.SayTo(m, message);
else
m.SendLocalizedMessage(message);
}
public CityDonationItem(Serial serial) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
writer.Write((int)City);
writer.Write(Minister);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int v = reader.ReadInt();
City = (City)reader.ReadInt();
Minister = reader.ReadMobile() as TradeMinister;
}
}
public class CityItemDonation : CityDonationItem
{
[Constructable]
public CityItemDonation(City city, TradeMinister minister) : base(city, minister, 0xE3C)
{
Table = ItemTable;
if (CitySystem != null && CitySystem.Minister != null)
CitySystem.Minister.DonationCrate = this;
}
public static Dictionary<Type, int> ItemTable { get; set; }
public static void Configure()
{
ItemTable = new Dictionary<Type, int>();
ItemTable.Add(typeof(BaseWoodBoard), 10);
ItemTable.Add(typeof(BaseIngot), 10);
ItemTable.Add(typeof(BaseHides), 10);
ItemTable.Add(typeof(BaseLeather), 10);
ItemTable.Add(typeof(RawRibs), 10);
ItemTable.Add(typeof(BreadLoaf), 10);
ItemTable.Add(typeof(RawFishSteak), 10);
ItemTable.Add(typeof(BaseCrabAndLobster), 15);
ItemTable.Add(typeof(BasePotion), 15);
ItemTable.Add(typeof(Bow), 20);
ItemTable.Add(typeof(Crossbow), 20);
ItemTable.Add(typeof(MaritimeCargo), 50);
}
public CityItemDonation(Serial serial) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int v = reader.ReadInt();
Table = ItemTable;
if (CitySystem != null && CitySystem.Minister != null)
CitySystem.Minister.DonationCrate = this;
}
}
public class CityPetDonation : CityDonationItem
{
public override bool Animals { get { return true; } }
[Constructable]
public CityPetDonation(City city, TradeMinister minister) : base(city, minister, 0x14E7)
{
Table = PetTable;
if (CitySystem != null && CitySystem.Minister != null)
CitySystem.Minister.DonationPost = this;
}
public static Dictionary<Type, int> PetTable { get; set; }
public static void Configure()
{
PetTable = new Dictionary<Type, int>();
PetTable.Add(typeof(Dog), 10);
PetTable.Add(typeof(Cat), 10);
PetTable.Add(typeof(Cow), 10);
PetTable.Add(typeof(Goat), 10);
PetTable.Add(typeof(Horse), 10);
PetTable.Add(typeof(Sheep), 10);
PetTable.Add(typeof(Pig), 10);
PetTable.Add(typeof(Chicken), 10);
}
public CityPetDonation(Serial serial) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int v = reader.ReadInt();
Table = PetTable;
if (CitySystem != null && CitySystem.Minister != null)
CitySystem.Minister.DonationPost = this;
}
}
}

View File

@@ -0,0 +1,326 @@
using System;
using Server;
using Server.Mobiles;
using Server.Engines.CityLoyalty;
using Server.Gumps;
namespace Server.Items
{
public abstract class CityBook : Item
{
public abstract int Title { get; }
public abstract int Content { get; }
public CityBook() : base(4030)
{
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
if(Title > 0)
list.Add(Title);
list.Add(1154760, "Adamu Edom"); // By: ~1_NAME~
}
public override void OnDoubleClick(Mobile m)
{
if (IsChildOf(m.Backpack))
{
Gump g = new Gump(150, 150);
g.AddImage(0, 0, 30236);
g.AddHtmlLocalized(110, 30, 350, 630, Content, false, false);
m.SendGump(g);
}
}
public static CityBook GetRandom()
{
switch (Utility.Random(9))
{
default:
case 0: return new LoyaltyBookBritain();
case 1: return new LoyaltyBookYew();
case 2: return new LoyaltyBookMoonglow();
case 3: return new LoyaltyBookNewMagincia();
case 4: return new LoyaltyBookVesper();
case 5: return new LoyaltyBookSkaraBrae();
case 6: return new LoyaltyBookJhelom();
case 7: return new LoyaltyBookMinoc();
case 8: return new LoyaltyBookTrinsic();
}
}
public CityBook(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class LoyaltyBookYew : CityBook
{
public override int Title { get { return 1153933; } }
public override int Content { get { return 1152698; } }
[Constructable]
public LoyaltyBookYew()
{
}
public LoyaltyBookYew(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class LoyaltyBookJhelom : CityBook
{
public override int Title { get { return 1153934; } }
public override int Content { get { return 1153436; } }
[Constructable]
public LoyaltyBookJhelom()
{
}
public LoyaltyBookJhelom(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class LoyaltyBookMoonglow : CityBook
{
public override int Title { get { return 1153935; } }
public override int Content { get { return 1153437; } }
[Constructable]
public LoyaltyBookMoonglow()
{
}
public LoyaltyBookMoonglow(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class LoyaltyBookTrinsic : CityBook
{
public override int Title { get { return 1153727; } }
public override int Content { get { return 1151755; } }
[Constructable]
public LoyaltyBookTrinsic()
{
}
public LoyaltyBookTrinsic(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class LoyaltyBookMinoc : CityBook
{
public override int Title { get { return 1153728; } }
public override int Content { get { return 1152317; } }
[Constructable]
public LoyaltyBookMinoc()
{
}
public LoyaltyBookMinoc(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class LoyaltyBookNewMagincia : CityBook
{
public override int Title { get { return 1153008; } }
public override int Content { get { return 1153723; } }
[Constructable]
public LoyaltyBookNewMagincia()
{
}
public LoyaltyBookNewMagincia(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class LoyaltyBookVesper : CityBook
{
public override int Title { get { return 1153012; } }
public override int Content { get { return 1153724; } }
[Constructable]
public LoyaltyBookVesper()
{
}
public LoyaltyBookVesper(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class LoyaltyBookSkaraBrae : CityBook
{
public override int Title { get { return 0; } }
public override int Content { get { return 1153725; } }
[Constructable]
public LoyaltyBookSkaraBrae()
{
}
public LoyaltyBookSkaraBrae(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class LoyaltyBookBritain : CityBook
{
public override int Title { get { return 1153726; } }
public override int Content { get { return 1151754; } }
[Constructable]
public LoyaltyBookBritain()
{
}
public LoyaltyBookBritain(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,35 @@
using System;
using Server;
using Server.Mobiles;
using Server.Engines.CityLoyalty;
namespace Server.Items
{
public class ExpiredVoucher : Item
{
public override int LabelNumber { get { return 1151749; } } // Expired Voucher for a Free Drink at the Fortune's Fire Casino
[Constructable]
public ExpiredVoucher()
: base(0x2831)
{
}
public ExpiredVoucher(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,35 @@
using System;
using Server;
using Server.Mobiles;
using Server.Engines.CityLoyalty;
namespace Server.Items
{
public class ForgedArtwork : Item
{
public override int LabelNumber { get { return 1151750; } } // Forged Artwork from King Blackthorn's Collection
[Constructable]
public ForgedArtwork() : base(Utility.Random(0x1224, 5))
{
Weight = 10;
}
public ForgedArtwork(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,36 @@
using System;
using Server;
using Server.Mobiles;
using Server.Engines.CityLoyalty;
namespace Server.Items
{
public class LittleBlackBook : Item
{
public override int LabelNumber { get { return 1151751; } } // Slim the Fence's little black book
[Constructable]
public LittleBlackBook()
: base(4030)
{
Hue = 1932;
}
public LittleBlackBook(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,51 @@
using System;
using Server;
using Server.Mobiles;
using Server.Engines.CityLoyalty;
using Server.Gumps;
namespace Server.Items
{
public class MysteriousNote : Item
{
public override int LabelNumber { get { return 1151753; } } // A Mysterious Note
[Constructable]
public MysteriousNote()
: base(0x14ED)
{
}
public override void OnDoubleClick(Mobile from)
{
Gump g = new Gump(100, 100);
g.AddBackground(0, 0, 404, 325, 9380);
/*You unfurl the parchment, it appears to be a handwritten note*<br><br>Taking up delivery of goods fer
* the crown are ya? Well...maybe yer interested in a bit of something fer yerself? Look fer me in Felucca...
* the taverns of Ocllo, Nujelm, & Serpent's Hold if ye want to fence yer goods.<br><br>-A Friend*/
g.AddHtmlLocalized(37, 50, 340, 225, 1151735, 0xC63, false, true);
from.SendGump(g);
}
public MysteriousNote(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,49 @@
using System;
using Server;
using Server.Mobiles;
using Server.Engines.CityLoyalty;
namespace Server.Items
{
public class RewardSign : Sign, IEngravable
{
public string EngravedText { get; set; }
[Constructable]
public RewardSign() : base((SignType)Utility.RandomMinMax(31, 58), Utility.RandomBool() ? SignFacing.North : SignFacing.West)
{
Movable = true;
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
if (!String.IsNullOrEmpty(EngravedText))
{
list.Add(1072305, EngravedText); // Engraved: ~1_INSCRIPTION~
}
}
public RewardSign(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
writer.Write(EngravedText);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
EngravedText = reader.ReadString();
}
}
}

View File

@@ -0,0 +1,36 @@
using System;
using Server;
using Server.Mobiles;
using Server.Engines.CityLoyalty;
namespace Server.Items
{
public class SlimsShadowVeil : LeatherMempo
{
public override int LabelNumber { get { return 1154906; } } // Slim's Shadow Veil
[Constructable]
public SlimsShadowVeil()
{
Hue = 1932;
Attributes.CastSpeed = 1;
}
public SlimsShadowVeil(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,162 @@
using System;
using Server;
using Server.Mobiles;
using Server.ContextMenus;
using Server.Engines.Points;
using Server.Targeting;
using Server.Gumps;
using System.Collections.Generic;
using Server.Items;
using Server.Misc;
namespace Server.Engines.CityLoyalty
{
public class SlimTheFence : BaseCreature
{
public override bool IsInvulnerable { get { return true; } }
[Constructable]
public SlimTheFence() : base(AIType.AI_Vendor, FightMode.None, 10, 1, .4, .2)
{
Body = 0x190;
SpeechHue = 0x3B2;
Blessed = true;
Name = "Slim";
Title = "the Fence";
HairItemID = 8264;
FacialHairItemID = 8269;
HairHue = 1932;
FacialHairHue = 1932;
Hue = Race.RandomSkinHue();
SetStr(150);
SetInt(50);
SetDex(150);
EquipItem(new JinBaori(1932));
EquipItem(new FancyShirt(1932));
EquipItem(new LongPants(1));
var boots = new Boots();
boots.Hue = 1;
EquipItem(boots);
CantWalk = true;
}
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
{
base.GetContextMenuEntries( from, list );
list.Add(new TurnInEntry(from, this));
}
private class TurnInEntry : ContextMenuEntry
{
public SlimTheFence Slim { get; private set; }
public Mobile Player { get; private set; }
public TurnInEntry(Mobile player, SlimTheFence slim) : base(1151729, 3) // Turn in a trade order
{
Player = player;
Slim = slim;
Enabled = CityTradeSystem.HasTrade(Player);
}
public override void OnClick()
{
if (CityTradeSystem.HasTrade(Player))
{
Player.Target = new InternalTarget(Slim);
Player.SendLocalizedMessage(1151730); // Target the trade order you wish to turn in.
}
}
private class InternalTarget : Target
{
public SlimTheFence Slim { get; private set; }
public InternalTarget(SlimTheFence slim) : base(-1, false, TargetFlags.None)
{
Slim = slim;
}
protected override void OnTarget(Mobile from, object targeted)
{
TradeOrderCrate order = targeted as TradeOrderCrate;
if(order != null)
{
if (CityLoyaltySystem.CityTrading.TryTurnInToSlim(from, order, Slim))
{
if (order.Entry != null && order.Entry.Distance > 0)
{
from.AddToBackpack(Slim.GiveAward());
from.SendLocalizedMessage(1073621); // Your reward has been placed in your backpack.
}
Titles.AwardKarma(from, -100, true);
}
}
else
{
from.SendLocalizedMessage(1151731); // That is not a valid trade order. Please try again.
from.Target = new InternalTarget(Slim);
}
}
}
}
private Item GiveAward()
{
if (0.05 > Utility.RandomDouble())
{
switch (Utility.Random(4))
{
case 0: return new ExpiredVoucher();
case 1: return new ForgedArtwork();
case 2: return new LittleBlackBook();
case 3: return new SlimsShadowVeil();
}
}
switch (Utility.Random(3))
{
default:
case 0:
return new Skeletonkey();
case 1:
Item item = Loot.RandomArmorOrShieldOrWeaponOrJewelry(false, false, true);
int min, max;
TreasureMapChest.GetRandomItemStat(out min, out max, 1.0);
RunicReforging.GenerateRandomItem(item, 0, min, max, this.Map);
return item;
case 2:
return ScrollOfTranscendence.CreateRandom(1, 10);
}
}
public SlimTheFence(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int v = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,343 @@
using System;
using Server;
using Server.Mobiles;
using Server.ContextMenus;
using Server.Engines.Points;
using Server.Targeting;
using Server.Gumps;
using Server.Network;
using System.Collections.Generic;
using Server.Items;
using Server.Misc;
namespace Server.Engines.CityLoyalty
{
public class TradeMinister : BaseCreature
{
[CommandProperty(AccessLevel.GameMaster)]
public City City { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public CityLoyaltySystem CitySystem { get { return CityLoyaltySystem.GetCityInstance(City); } set { } }
[CommandProperty(AccessLevel.GameMaster)]
public CityItemDonation DonationCrate { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public CityPetDonation DonationPost { get; set; }
public override bool IsInvulnerable { get { return true; } }
[Constructable]
public TradeMinister(City city) : base(AIType.AI_Vendor, FightMode.None, 10, 1, .4, .2)
{
City = city;
SpeechHue = 0x3B2;
Female = Utility.RandomDouble() > 0.75;
Blessed = true;
Name = Female ? NameList.RandomName("female") : NameList.RandomName("male");
Title = "the minister of trade";
Body = Female ? 0x191 : 0x190;
HairItemID = Race.RandomHair(Female);
FacialHairItemID = Race.RandomFacialHair(Female);
HairHue = Race.RandomHairHue();
Hue = Race.RandomSkinHue();
SetStr(150);
SetInt(50);
SetDex(150);
EquipItem(new Cloak(1157));
EquipItem(new BodySash(1326));
var chest = new ChainChest();
chest.Hue = 1908;
EquipItem(chest);
var boots = new ThighBoots();
boots.Hue = 1908;
EquipItem(boots);
EquipItem(new GoldRing());
Ministers.Add(this);
CantWalk = true;
}
public override void OnDoubleClick(Mobile from)
{
if(from.InRange(this.Location, 4))
{
from.SendGump(new InternalGump());
}
}
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
{
base.GetContextMenuEntries( from, list );
list.Add(new TradeOrderEntry(from, this));
list.Add(new TurnInEntry(from, this));
}
private class TradeOrderEntry : ContextMenuEntry
{
public TradeMinister Minister { get; private set; }
public Mobile Player { get; private set; }
public TradeOrderEntry(Mobile player, TradeMinister minister) : base(1114453, 5) // Get Trade Order
{
Player = player;
Minister = minister;
Enabled = !CityTradeSystem.HasTrade(Player);
}
public override void OnClick()
{
if (!CityTradeSystem.HasTrade(Player))
{
Player.SendGump(new InternalTradeOrderGump(Player as PlayerMobile, Minister));
}
}
}
private class TurnInEntry : ContextMenuEntry
{
public TradeMinister Minister { get; private set; }
public Mobile Player { get; private set; }
public TurnInEntry(Mobile player, TradeMinister minister) : base(1151729, 3) // Turn in a trade order
{
Player = player;
Minister = minister;
Enabled = CityTradeSystem.HasTrade(Player);
}
public override void OnClick()
{
if (CityTradeSystem.HasTrade(Player))
{
Player.Target = new InternalTarget(Minister);
Player.SendLocalizedMessage(1151730); // Target the trade order you wish to turn in.
}
}
private class InternalTarget : Target
{
public TradeMinister Minister { get; private set; }
public InternalTarget(TradeMinister minister) : base(-1, false, TargetFlags.None)
{
Minister = minister;
}
protected override void OnTarget(Mobile from, object targeted)
{
TradeOrderCrate order = targeted as TradeOrderCrate;
if(order != null)
{
if (CityLoyaltySystem.CityTrading.TryTurnIn(from, order, Minister))
{
if (order.Entry != null && order.Entry.Distance > 0)
{
from.AddToBackpack(Minister.GiveReward(order.Entry));
from.SendLocalizedMessage(1073621); // Your reward has been placed in your backpack.
}
Titles.AwardKarma(from, 100, true);
}
}
else
{
from.SendLocalizedMessage(1151731); // That is not a valid trade order. Please try again.
from.Target = new InternalTarget(Minister);
}
}
}
}
private Item GiveReward(TradeEntry entry)
{
if (0.01 > Utility.RandomDouble())
{
switch (Utility.Random(2))
{
default:
case 0: return CityBook.GetRandom();
case 1: return new RewardSign();
}
}
else
{
switch (Utility.Random(2))
{
default:
case 1: return RandomResource(entry);
case 2: return ScrollOfTranscendence.CreateRandom(1, 10);
}
}
}
private Item RandomResource(TradeEntry entry)
{
int amount = 40;
if (entry.Details.Count > 1)
amount = 40 + Utility.RandomMinMax(10, entry.Details.Count * 20);
switch (Utility.Random(4))
{
case 0:
switch (Utility.Random(9))
{
case 0: return new IronIngot(amount);
case 1: return new DullCopperIngot(amount);
case 2: return new ShadowIronIngot(amount);
case 3: return new CopperIngot(amount);
case 4: return new BronzeIngot(amount);
case 5: return new GoldIngot(amount);
case 6: return new AgapiteIngot(amount);
case 7: return new VeriteIngot(amount);
case 8: return new ValoriteIngot(amount);
}
break;
case 1:
switch (Utility.Random(4))
{
case 0: return new Leather(amount);
case 1: return new SpinedLeather(amount);
case 2: return new HornedLeather(amount);
case 3: return new BarbedLeather(amount);
}
break;
case 2:
switch (Utility.Random(7))
{
case 0: return new Board(amount);
case 1: return new OakBoard(amount);
case 2: return new AshBoard(amount);
case 3: return new YewBoard(amount);
case 4: return new BloodwoodBoard(amount);
case 5: return new HeartwoodBoard(amount);
case 6: return new FrostwoodBoard(amount);
}
break;
case 3:
Item item = Loot.Construct(SkillHandlers.Imbuing.IngredTypes[Utility.Random(SkillHandlers.Imbuing.IngredTypes.Length)]);
amount /= 10;
if (item != null && item.Stackable)
item.Amount = amount;
return item;
}
return null;
}
private class InternalGump : Gump
{
public InternalGump() : base(40, 40)
{
AddBackground(0, 0, 500, 400, 9380);
AddHtmlLocalized(30, 50, 400, 16, 1152962, 0x4800, false, false); // City Trade Minister
AddHtmlLocalized(30, 80, 440, 320, 1152963, 0x001F, false, false);
}
}
public class InternalTradeOrderGump : Gump
{
public TradeMinister Minister { get; private set; }
public PlayerMobile User { get; set; }
public InternalTradeOrderGump(PlayerMobile user, TradeMinister minister)
: base(100, 100)
{
Minister = minister;
User = user;
AddGumpLayout();
}
public void AddGumpLayout()
{
AddBackground(0, 0, 370, 420, 9300);
AddHtmlLocalized(10, 30, 350, 18, 1114513, "#1114454", 0x3442, false, false); // An Offer For a trade Order
/*
* Greetings! His majesty thanks you for furthering the economic interests of the City!
* The Trade Association hath decreed that all goods shall be transported without the use of magic,
* for fear that use of such magics will corrupt the quality of the goods held within.
* Be forewarned! The life of a trader is sure to be met with peril as highwayman and pirates
* alike seek to profit a bit of coin for the goods. Good luck!
*/
AddHtmlLocalized(10, 61, 350, 162, 1114455, 0x10, false, false);
/*
* <i>Should you accept this trade order your ability to magically teleport to another location will be disabled.
* You may cancel the trade order at any time by accessing the context menu on the trade crate by single left clicking</i>
*/
AddHtmlLocalized(10, 225, 350, 90, 1151721, 0x3442, false, false);
AddButton(10, 390, 4005, 4007, 1, GumpButtonType.Reply, 0);
AddHtmlLocalized(50, 390, 100, 20, 1049011, 0x10, false, false); // I Accept!
AddButton(330, 390, 4017, 4019, 0, GumpButtonType.Reply, 0);
AddHtmlLocalized(220, 390, 100, 20, 1114514, "#1006045", 0x4000, false, false); // Cancel
}
public override void OnResponse(NetState state, RelayInfo info)
{
if (info.ButtonID == 1)
{
if (!Minister.InRange(User, 5))
{
User.SendLocalizedMessage(500295); // You are too far away to do that.
}
else
{
CityLoyaltySystem.CityTrading.TryOfferTrade(User, Minister);
}
}
}
}
public TradeMinister(Serial serial) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
writer.Write((int)City);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int v = reader.ReadInt();
City = (City)reader.ReadInt();
if (CitySystem != null)
CitySystem.Minister = this;
Ministers.Add(this);
}
public static void Configure()
{
Ministers = new List<TradeMinister>();
}
public static List<TradeMinister> Ministers { get; private set; }
}
}

View File

@@ -0,0 +1,344 @@
using System;
using System.Collections.Generic;
using Server;
using Server.ContextMenus;
using Server.Items;
using Server.Gumps;
using System.Linq;
using Server.Network;
using Server.Engines.SeasonalEvents;
namespace Server.Engines.CityLoyalty
{
public class TradeOrderCrate : Container
{
public override int LabelNumber { get { return CityTradeSystem.KrampusEncounterActive ? 1123594 : base.LabelNumber; } }
[CommandProperty(AccessLevel.GameMaster)]
public TradeEntry Entry { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public Mobile Owner { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public bool Fulfilled
{
get
{
if(Entry == null)
return false;
foreach (var details in Entry.Details)
{
if (GetAmount(details.ItemType) < details.Amount)
return false;
}
return true;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public DateTime Expires { get; set; }
public bool Expired { get { return Expires < DateTime.UtcNow; } }
public override int DefaultMaxWeight { get { return 1000; } }
public TradeOrderCrate(Mobile from, TradeEntry entry)
: base(GetID())
{
Owner = from;
Entry = entry;
if (CityTradeSystem.KrampusEncounterActive)
{
Weight = 10.0;
Hue = Utility.Random(100);
}
Expires = DateTime.UtcNow + TimeSpan.FromHours(CityTradeSystem.CrateDuration);
}
private static int GetID()
{
if (CityTradeSystem.KrampusEncounterActive)
{
return Utility.Random(0x46A2, 6);
}
return Utility.Random(0xE3C, 4);
}
public override int DefaultGumpID
{
get
{
switch(ItemID)
{
default:
return base.DefaultGumpID;
case 0x46A2:
return 0x11B;
case 0x46A3:
return 0x11C;
case 0x46A4:
return 0x11D;
case 0x46A5:
case 0x46A6:
return 0x11E;
}
}
}
public override bool DisplaysContent { get { return false; } }
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
list.Add(1151737, String.Format("#{0}", CityLoyaltySystem.CityLocalization(Entry.Destination))); // Destination City: ~1_city~
list.Add(1076255); // NO-TRADE
int weight = Items.Sum(x => x.Amount);
list.Add(1072241, "{0}\t{1}\t{2}\t{3}", Items.Count, DefaultMaxItems, weight, DefaultMaxWeight); // Contents: ~1_COUNT~/~2_MAXCOUNT items, ~3_WEIGHT~/~4_MAXWEIGHT~ stones
list.Add(1072210, "75"); // Weight reduction: ~1_PERCENTAGE~%
if (Entry.Details != null)
{
for (int i = 0; i < Entry.Details.Count; i++)
{
if(Utility.ToInt32(Entry.Details[i].Name) > 0)
list.Add(1116453 + i, String.Format("#{0}\t{1}\t{2}", Entry.Details[i].Name, GetAmount(Entry.Details[i].ItemType), Entry.Details[i].Amount)); // ~1_val~: ~2_val~/~3_val~
else
list.Add(1116453 + i, String.Format("{0}\t{1}\t{2}", Entry.Details[i].Name, GetAmount(Entry.Details[i].ItemType), Entry.Details[i].Amount)); // ~1_val~: ~2_val~/~3_val~
}
}
if (!Expired)
{
int hours = (int)Math.Max(1, (Expires - DateTime.UtcNow).TotalHours);
list.Add(1153090, hours.ToString()); // Lifespan: ~1_val~ hours
}
}
public override void Delete()
{
CityLoyaltySystem.CityTrading.RemoveCrate(Owner, this);
base.Delete();
}
public override bool TryDropItem(Mobile from, Item item, bool message)
{
if(Entry == null)
return false;
if(TryAddItem(from, item, message))
return base.TryDropItem(from, item, message);
return false;
}
public bool TryAddItem(Mobile from, Item item, bool message = true)
{
bool canAdd = false;
foreach (var details in Entry.Details)
{
if (item.GetType() == details.ItemType)
{
int hasAmount = GetAmount(item.GetType());
if (hasAmount + item.Amount > details.Amount)
{
if (message)
from.SendLocalizedMessage(1151726); // You are trying to add too many of this item to the trade order. Only add the required quantity
break;
}
else
{
canAdd = true;
break;
}
}
}
if (!canAdd && message)
from.SendLocalizedMessage(1151725); // This trade order does not require this item.
return canAdd;
}
public override int GetTotal(TotalType type)
{
if (type == TotalType.Weight)
{
int weight = base.GetTotal(type);
if (weight > 0)
return (int)Math.Max(1, (base.GetTotal(type) * .25));
}
return base.GetTotal(type);
}
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
{
base.GetContextMenuEntries(from, list);
if(IsChildOf(from.Backpack))
{
list.Add(new FillFromPackEntry(this, from));
list.Add(new CancelOrderEntry(this, from));
}
}
private class FillFromPackEntry : ContextMenuEntry
{
public TradeOrderCrate Crate { get; private set; }
public Mobile Player { get; private set; }
public FillFromPackEntry(TradeOrderCrate crate, Mobile player) : base(1154908, 3) // Fill from pack
{
Crate = crate;
Player = player;
}
public override void OnClick()
{
if(Crate.IsChildOf(Player.Backpack) && !Crate.Deleted && Crate.Entry != null)
{
foreach (TradeEntry.TradeDetails detail in Crate.Entry.Details)
{
Item[] items = Player.Backpack.FindItemsByType(detail.ItemType);
foreach (Item item in items)
{
if (item.Amount == 1 && Crate.TryAddItem(Player, item, false))
Crate.DropItem(item);
}
}
}
}
}
private class CancelOrderEntry : ContextMenuEntry
{
public TradeOrderCrate Crate { get; private set; }
public Mobile Player { get; private set; }
public CancelOrderEntry(TradeOrderCrate crate, Mobile player) : base(1151727, 3) // cancel trade order
{
Crate = crate;
Player = player;
}
public override void OnClick()
{
Player.CloseGump(typeof(CancelTradeOrderGump));
Player.SendGump(new CancelTradeOrderGump(Crate, Player));
}
}
public override bool OnDroppedOnto(Mobile from, Item target)
{
from.SendLocalizedMessage(1076254); // That item cannot be dropped.
return false;
}
public override bool OnDroppedInto(Mobile from, Container target, Point3D p)
{
if (target == from.Backpack)
return base.OnDroppedInto(from, target, p);
from.SendLocalizedMessage(1076254); // That item cannot be dropped.
return false;
}
public override bool OnDragDropInto(Mobile from, Item item, Point3D p)
{
from.SendLocalizedMessage(1076254); // That item cannot be dropped.
return false;
}
public override bool OnDroppedToWorld(Mobile from, Point3D point)
{
from.SendLocalizedMessage(1076254); // That item cannot be dropped.
return false;
}
public override bool AllowSecureTrade(Mobile from, Mobile to, Mobile newOwner, bool accepted)
{
from.SendLocalizedMessage(1076256); // That item cannot be traded.
return false;
}
public TradeOrderCrate(Serial serial) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
writer.Write(Owner);
writer.Write(Expires);
Entry.Serialize(writer);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int v = reader.ReadInt();
Owner = reader.ReadMobile();
Expires = reader.ReadDateTime();
Entry = new TradeEntry(reader);
}
}
public class CancelTradeOrderGump : Gump
{
public TradeOrderCrate Crate { get; private set; }
public Mobile Player { get; private set; }
public CancelTradeOrderGump(TradeOrderCrate crate, Mobile player)
: base(100, 100)
{
Crate = crate;
Player = player;
AddPage(0);
AddBackground(0, 0, 291, 93, 0x13BE);
AddImageTiled(5, 5, 280, 60, 0xA40);
AddHtmlLocalized(9, 9, 272, 60, 1151728, 0x7FFF, false, false); // Are you sure you wish to cancel this trade order? All contents of the trade crate will be placed in your backpack.
AddButton(160, 67, 0xFB7, 0xFB8, 1, GumpButtonType.Reply, 0);
AddHtmlLocalized(195, 69, 120, 20, 1006044, 0x7FFF, false, false); // OKAY
AddButton(5, 67, 0xFB1, 0xFB2, 0, GumpButtonType.Reply, 0);
AddHtmlLocalized(40, 69, 100, 20, 1060051, 0x7FFF, false, false); // CANCEL
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (info.ButtonID == 1)
{
if (Crate != null && Crate.IsChildOf(Player.Backpack))
{
CityTradeSystem.CancelTradeOrder(Player, Crate);
}
}
}
}
}

View File

@@ -0,0 +1,146 @@
using System;
using Server;
using Server.Mobiles;
using Server.ContextMenus;
using System.Collections.Generic;
namespace Server.Engines.CityLoyalty
{
[PropertyObject]
public class TradeEntry
{
[CommandProperty(AccessLevel.GameMaster)]
public City Origin { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public City Destination { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public int Kills { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public int Distance { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public DateTime LastAmbush { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public string TurnIn
{
get
{
string str = "";
Details.ForEach(d =>
{
str += d.ItemType.Name + ", ";
});
return str;
}
}
public List<TradeDetails> Details { get; set; }
public TradeEntry(City destination, City origin, int distance)
{
Origin = origin;
Destination = destination;
Distance = distance;
Details = new List<TradeDetails>();
}
public override string ToString()
{
return "...";
}
public int CalculateGold()
{
if (Distance == 0)
return 0;
int gold = 0;
Details.ForEach(d =>
{
gold += d.Worth * 3;
});
return Math.Max(CityTradeSystem.TurnInGold, gold + (Distance * 10) + Math.Min(25000, (Kills * 500)));
}
public class TradeDetails
{
public Type ItemType { get; set; }
public int Amount { get; set; }
public int Worth { get; set; }
public string Name { get; set; }
public TradeDetails(Type type, int worth, int amount, string fallbackname)
{
ItemType = type;
Worth = worth;
Amount = amount;
Name = CityLoyaltySystem.CityTrading.GetNameFor(type, fallbackname);
}
public TradeDetails(GenericReader reader)
{
int version = reader.ReadInt();
ItemType = ScriptCompiler.FindTypeByName(reader.ReadString());
Worth = reader.ReadInt();
Amount = reader.ReadInt();
Name = reader.ReadString();
}
public void Serialize(GenericWriter writer)
{
writer.Write(0);
writer.Write(ItemType.Name);
writer.Write(Worth);
writer.Write(Amount);
writer.Write(Name);
}
}
public TradeEntry(GenericReader reader)
{
int version = reader.ReadInt();
Origin = (City)reader.ReadInt();
Destination = (City)reader.ReadInt();
LastAmbush = reader.ReadDateTime();
Kills = reader.ReadInt();
Distance = reader.ReadInt();
Details = new List<TradeDetails>();
int count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
Details.Add(new TradeDetails(reader));
}
}
public void Serialize(GenericWriter writer)
{
writer.Write(0);
writer.Write((int)Origin);
writer.Write((int)Destination);
writer.Write(LastAmbush);
writer.Write(Kills);
writer.Write(Distance);
writer.Write(Details.Count);
Details.ForEach(d => d.Serialize(writer));
}
}
}

View File

@@ -0,0 +1,833 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Server;
using Server.Mobiles;
using Server.ContextMenus;
using Server.Engines.Points;
using Server.Engines;
using Server.Items;
using Server.Multis;
using Server.Regions;
using Server.Engines.SeasonalEvents;
namespace Server.Engines.CityLoyalty
{
public enum TradeTitle
{
Trader = 1151739,
Exporter = 1151741,
Broker = 1151743,
Tycoon = 1151745,
Smuggler = 1151747,
Magnate = 1155481
}
public class CityTradeSystem : PointsSystem
{
public static readonly int TurnInGold = Config.Get("CityTrading.TurnInGold", 10000);
public static readonly int CrateDuration = Config.Get("CityTrading.CrateDuration", 24);
public static readonly int AmbushWaitDuration = Config.Get("CityTrading.AmbushWaitDuration", 5);
public static readonly int AmbusherDelete = Config.Get("CityTrading.AmbusherDelete", 10);
public override TextDefinition Name { get { return new TextDefinition("City Trading"); } }
public override PointsType Loyalty { get { return PointsType.CityTrading; } }
public override bool AutoAdd { get { return false; } }
public override double MaxPoints { get { return double.MaxValue; } }
public override bool ShowOnLoyaltyGump { get { return false; } }
public static bool KrampusEncounterActive { get { return KrampusEncounter.Enabled && KrampusEncounter.Encounter != null; } }
public static Dictionary<Mobile, TradeOrderCrate> ActiveTrades { get; private set; }
public static Dictionary<BaseCreature, DateTime> Ambushers { get; private set; }
public CityTradeSystem()
{
ActiveTrades = new Dictionary<Mobile, TradeOrderCrate>();
_NameBuffer = new Dictionary<Type, string>();
}
public override PointsEntry GetSystemEntry(PlayerMobile pm)
{
return new CityTradeEntry(pm);
}
public int GetMaxTrades(Mobile m)
{
CityTradeEntry entry = GetPlayerEntry<CityTradeEntry>(m as PlayerMobile);
if(entry == null)
return 1;
return Math.Min(8, Math.Max(1, (entry.Completed / 25) + 1));
}
public static bool HasTrade(Mobile from)
{
return ActiveTrades.ContainsKey(from);
}
public bool HasTurnIn(Mobile from, TradeMinister minister)
{
if(from == null || minister == null || !ActiveTrades.ContainsKey(from) || ActiveTrades[from] == null)
return false;
TradeOrderCrate crate = ActiveTrades[from];
return crate.Entry != null && crate.Entry.Origin != minister.City;
}
public bool TryOfferTrade(Mobile from, TradeMinister minister)
{
if(from == null || from.Backpack == null)
return true;
if (ActiveTrades.ContainsKey(from))
{
minister.SayTo(from, 1151722); // It appears you are already delivering a trade order. Deliver your current order before requesting another.
}
else if (KrampusEncounterActive && (KrampusEncounter.Encounter.Krampus != null || KrampusEncounter.Encounter.KrampusSpawning))
{
var p = KrampusEncounter.Encounter.SpawnLocation;
var map = KrampusEncounter.Encounter.SpawnMap;
minister.SayTo(
from,
1158790,
String.Format("{0}\t{1}",
WorldLocationInfo.GetLocationString(p, map),
Sextant.GetCoords(p, map)), 1150);
// Take notice! The vile Krampus has been spotted near ~2_where~ at ~1_coords~! New Trade Orders are suspended until Krampus has been defeated!
}
else
{
City origin = minister.City;
City destination;
do
{
destination = CityLoyaltySystem.GetRandomCity();
}
while (destination == origin);
int distance = GetDistance(minister, destination);
int trades = Utility.RandomMinMax(1, GetMaxTrades(from));
TradeEntry entry = new TradeEntry(destination, origin, distance);
TradeOrderCrate crate = new TradeOrderCrate(from, entry);
GetPlayerEntry<CityTradeEntry>(from as PlayerMobile, true);
for (int i = 0; i < trades; i++)
{
int worth = 1;
string name = null;
Type t = GetRandomTrade(origin, destination, ref worth, ref name);
if (t != null)
{
int amount = Utility.RandomList(5, 10, 15, 20);
entry.Details.Add(new TradeEntry.TradeDetails(t, worth, amount, name));
}
else
{
minister.SayTo(from, "There are no trades available at this time.");
return false;
}
}
if (from.Backpack == null || !from.Backpack.TryDropItem(from, crate, false))
{
crate.Delete();
from.SendLocalizedMessage(114456); // Your backpack cannot hold the Trade Order. Free up space and speak to the Trade Minister again.
}
ActiveTrades[from] = crate;
return true;
}
return false;
}
public bool TryTurnIn(Mobile from, TradeOrderCrate order, Mobile turninMobile)
{
if (order == null || from == null || turninMobile == null || order.Entry == null)
return false;
TradeEntry entry = order.Entry;
TradeMinister minister = turninMobile as TradeMinister;
if(from.AccessLevel == AccessLevel.Player && minister != null && minister.City != entry.Destination)
turninMobile.SayTo(from, 1151738, String.Format("#{0}", CityLoyaltySystem.GetCityLocalization(entry.Destination))); // Begging thy pardon, but those goods are destined for the City of ~1_city~
else if(!order.Fulfilled)
turninMobile.SayTo(from, 1151732); // This trade order has not been fulfilled. Fill the trade order with all necessary items and try again.
else
{
CityLoyaltySystem.OnTradeComplete(from, order.Entry);
CityTradeEntry pentry = GetPlayerEntry<CityTradeEntry>(from as PlayerMobile);
if (pentry != null)
{
pentry.Points++;
pentry.DistanceTraveled += entry.Distance;
pentry.Completed++;
CheckTitle(pentry);
}
order.Delete();
return true;
}
return false;
}
public bool TryTurnInToSlim(Mobile from, TradeOrderCrate order, SlimTheFence slim)
{
if (order == null || from == null || slim == null || order.Entry == null)
return false;
TradeEntry entry = order.Entry;
if (!order.Fulfilled)
slim.SayTo(from, 1151732); // This trade order has not been fulfilled. Fill the trade order with all necessary items and try again.
else
{
CityLoyaltySystem.OnSlimTradeComplete(from, order.Entry);
CityTradeEntry pentry = GetPlayerEntry<CityTradeEntry>(from as PlayerMobile, true);
if (pentry != null)
{
pentry.Points++;
pentry.DistanceTraveled += entry.Distance;
pentry.CompletedSlim++;
CheckTitle(pentry);
}
slim.SayTo(from, 1151736); // Haha! These goods will fetch me quite a bit o' coin! Thanks fer yer help! Here's a little something I was able to get me hands on...
order.Delete();
return true;
}
return false;
}
public void CheckTitle(CityTradeEntry entry)
{
switch (entry.Completed)
{
case 1: entry.Player.AddRewardTitle((int)TradeTitle.Trader); break;
case 25: entry.Player.AddRewardTitle((int)TradeTitle.Exporter); break;
case 50: entry.Player.AddRewardTitle((int)TradeTitle.Broker); break;
case 100: entry.Player.AddRewardTitle((int)TradeTitle.Tycoon); break;
case 150: entry.Player.AddRewardTitle((int)TradeTitle.Magnate); break;
}
if(entry.CompletedSlim == 50)
entry.Player.AddRewardTitle((int)TradeTitle.Smuggler);
}
public override void OnPlayerAdded(PlayerMobile m)
{
m.Backpack.DropItem(new MysteriousNote());
m.PrivateOverheadMessage(Server.Network.MessageType.Regular, 1150, 1151734, m.NetState); // *A passerby slips a rolled bit of parchment into your hand...*
}
public static void CancelTradeOrder(Mobile from, TradeOrderCrate crate)
{
if (from == null)
from = crate.Owner;
if (from != null)
{
crate.Items.ForEach(i =>
{
from.Backpack.DropItem(i);
});
CityTradeEntry entry = CityLoyaltySystem.CityTrading.GetPlayerEntry<CityTradeEntry>(from as PlayerMobile, true);
if (entry != null)
entry.Canceled++;
}
crate.Delete();
}
private Dictionary<Type, string> _NameBuffer;
public string GetNameFor(Type t, string fallbackname)
{
if (_NameBuffer.ContainsKey(t))
return _NameBuffer[t];
Item item = Loot.Construct(t);
if (item != null)
{
string name;
if (item.Name != null)
{
name = item.Name;
}
else
{
name = item.LabelNumber.ToString();
}
_NameBuffer[t] = name;
item.Delete();
return name;
}
Console.WriteLine("WARNING: Using Fallback name for: {0}", t.Name);
return fallbackname;
}
public void RemoveCrate(Mobile from, TradeOrderCrate crate)
{
if(ActiveTrades.ContainsKey(from))
{
ActiveTrades.Remove(from);
}
}
public static void OnPublicMoongateUsed(Mobile from)
{
if (ActiveTrades.ContainsKey(from))
{
ActiveTrades[from].Entry.Distance = 0;
}
}
public static int GetDistance(TradeMinister origin, City destination)
{
TradeMinister destMinister = TradeMinister.Ministers.FirstOrDefault(m => m.City == destination);
if(destMinister != null)
{
return (int)origin.GetDistanceToSqrt(destMinister.Location);
}
return 0;
}
public static Type GetRandomTrade(City originCity, City dest, ref int worth, ref string name)
{
Region region = CityLoyaltySystem.GetCityInstance(originCity).Definition.Region;
List<BaseVendor> list = new List<BaseVendor>(region.GetEnumeratedMobiles().OfType<BaseVendor>().Where(bv => bv.GetBuyInfo() != null && bv.GetBuyInfo().Length > 0));
if (list.Count == 0)
return null;
do
{
BaseVendor vendor = list[Utility.Random(list.Count)];
IBuyItemInfo[] buyInfo = vendor.GetBuyInfo();
GenericBuyInfo info = buyInfo[Utility.Random(buyInfo.Length)] as GenericBuyInfo;
if (!(info is BeverageBuyInfo) && !(info is AnimalBuyInfo) && info != null && info.Type != null && info.Args == null && info.Price < 5000)
{
list.Clear();
list.TrimExcess();
worth = info.Price;
name = info.Name;
return info.Type;
}
else
list.Remove(vendor);
}
while (list.Count > 0);
list.Clear();
list.TrimExcess();
return null;
}
public static void OnTick()
{
List<TradeOrderCrate> crates = new List<TradeOrderCrate>(ActiveTrades.Values);
List<BaseCreature> toDelete = new List<BaseCreature>();
foreach (var c in crates)
{
if (c.Expired)
{
CancelTradeOrder(c.Owner, c);
}
else if (c.Entry != null)
{
CheckAmbush(c);
}
}
if (Ambushers != null)
{
foreach (KeyValuePair<BaseCreature, DateTime> kvp in Ambushers)
{
if (kvp.Value < DateTime.UtcNow)
toDelete.Add(kvp.Key);
}
toDelete.ForEach(bc =>
{
if (!bc.Deleted)
bc.Delete();
Ambushers.Remove(bc);
});
}
toDelete.Clear();
toDelete.TrimExcess();
crates.Clear();
crates.TrimExcess();
}
public static void CheckAmbush(TradeOrderCrate crate)
{
if (crate == null || crate.Deleted || crate.Entry == null || crate.Expired || crate.Entry.LastAmbush + TimeSpan.FromMinutes(AmbushWaitDuration) > DateTime.UtcNow)
return;
if (crate.RootParentEntity is Mobile && !((Mobile)crate.RootParentEntity).Region.IsPartOf<GuardedRegion>())
{
Mobile m = crate.RootParentEntity as Mobile;
if (m.NetState != null && m.Map != null && m.Map != Map.Internal)
{
double chance = crate.Entry.LastAmbush == DateTime.MinValue ? 0.25 : .05;
if (chance > Utility.RandomDouble())
{
double dif = (double)(Math.Min(7200, m.SkillsTotal) + m.RawStr + m.RawInt + m.RawDex) / 10000;
m.RevealingAction();
SpawnCreatures(m, dif);
crate.Entry.LastAmbush = DateTime.UtcNow;
}
}
}
}
public static void SpawnCreatures(Mobile m, double difficulty)
{
BaseBoat boat = BaseBoat.FindBoatAt(m.Location, m.Map);
Type[] types = GetCreatureType(m, boat != null);
if (types == null)
{
return;
}
int amount = Utility.RandomMinMax(3, 5);
for (int i = 0; i < amount; i++)
{
BaseCreature bc = Activator.CreateInstance(types[Utility.Random(types.Length)]) as BaseCreature;
if (bc != null)
{
if (KrampusEncounterActive)
{
bc.Name = "An Icy Creature";
}
Rectangle2D zone;
if (boat != null)
{
if (boat.Facing == Direction.North || boat.Facing == Direction.South)
{
if (Utility.RandomBool())
{
zone = new Rectangle2D(boat.X - 7, m.Y - 4, 3, 3);
}
else
{
zone = new Rectangle2D(boat.X + 4, m.Y - 4, 3, 3);
}
}
else
{
if (Utility.RandomBool())
{
zone = new Rectangle2D(m.X + 4, boat.Y - 7, 3, 3);
}
else
{
zone = new Rectangle2D(m.X + 4, boat.Y + 4, 3, 3);
}
}
}
else
{
zone = new Rectangle2D(m.X - 3, m.Y - 3, 6, 6);
}
Point3D p = m.Location;
if (m.Map != null)
{
for (int j = 0; j < 25; j++)
{
Point3D check = m.Map.GetRandomSpawnPoint(zone);
if (CanFit(check.X, check.Y, check.Z, m.Map, bc))
{
p = check;
break;
}
}
}
foreach (Skill sk in bc.Skills.Where(s => s.Base > 0))
{
sk.Base += sk.Base * (difficulty);
}
bc.RawStr += (int)(bc.RawStr * difficulty);
bc.RawInt += (int)(bc.RawInt * difficulty);
bc.RawDex += (int)(bc.RawDex * difficulty);
if (bc.HitsMaxSeed == -1)
bc.HitsMaxSeed = bc.RawStr;
if (bc.StamMaxSeed == -1)
bc.StamMaxSeed = bc.RawDex;
if (bc.ManaMaxSeed == -1)
bc.ManaMaxSeed = bc.RawInt;
bc.HitsMaxSeed += (int)(bc.HitsMaxSeed * difficulty);
bc.StamMaxSeed += (int)(bc.StamMaxSeed * difficulty);
bc.ManaMaxSeed += (int)(bc.ManaMaxSeed * difficulty);
bc.Hits = bc.HitsMaxSeed;
bc.Stam = bc.RawDex;
bc.Mana = bc.RawInt;
bc.PhysicalResistanceSeed += (int)(bc.PhysicalResistanceSeed * (difficulty / 3));
bc.FireResistSeed += (int)(bc.FireResistSeed * (difficulty / 3));
bc.ColdResistSeed += (int)(bc.ColdResistSeed * (difficulty / 3));
bc.PoisonResistSeed += (int)(bc.PoisonResistSeed * (difficulty / 3));
bc.EnergyResistSeed += (int)(bc.EnergyResistSeed * (difficulty / 3));
bc.IsAmbusher = true;
if (Ambushers == null)
Ambushers = new Dictionary<BaseCreature, DateTime>();
Ambushers.Add(bc, DateTime.UtcNow + TimeSpan.FromMinutes(AmbusherDelete));
bc.MoveToWorld(p, m.Map);
Timer.DelayCall(() => bc.Combatant = m);
}
}
m.LocalOverheadMessage(Server.Network.MessageType.Regular, 1150, 1155479); // *Your keen senses alert you to an incoming ambush of attackers!*
m.SendLocalizedMessage(1049330, "", 0x22); // You have been ambushed! Fight for your honor!!!
}
public static Type[] GetCreatureType(Mobile m, bool wet)
{
if (KrampusEncounterActive)
{
return KrampusEncounter.Encounter.GetCreatureTypes(m, wet);
}
return wet ? _SeaTypes : _LandTypes;
}
public override void ProcessKill(Mobile victim, Mobile damager)
{
if (victim is BaseCreature && Ambushers != null && Ambushers.ContainsKey((BaseCreature)victim))
{
if (ActiveTrades.ContainsKey(damager))
{
TradeOrderCrate crate = ActiveTrades[damager];
if (crate.Entry != null)
crate.Entry.Kills++;
}
Ambushers.Remove((BaseCreature)victim);
}
}
private static Type[] _SeaTypes =
{
typeof(SeaSerpent), typeof(DeepSeaSerpent), typeof(Kraken), typeof(WaterElemental)
};
private static Type[] _LandTypes =
{
typeof(Troll), typeof(Ettin), typeof(GiantSpider), typeof(Brigand)
};
public static bool CanFit(int x, int y, int z, Map map, Mobile mob, int height = 16, bool checkMobiles = true, bool requireSurface = true)
{
if (map == null || map == Map.Internal)
return false;
if (x < 0 || y < 0 || x >= map.Width || y >= map.Height)
return false;
bool hasSurface = false;
bool canswim = mob.CanSwim;
bool cantwalk = mob.CantWalk;
LandTile lt = map.Tiles.GetLandTile(x, y);
int lowZ = 0, avgZ = 0, topZ = 0;
bool surface, impassable;
map.GetAverageZ(x, y, ref lowZ, ref avgZ, ref topZ);
TileFlag landFlags = TileData.LandTable[lt.ID & TileData.MaxLandValue].Flags;
impassable = (landFlags & TileFlag.Impassable) != 0;
bool wet = (landFlags & TileFlag.Wet) != 0;
if (cantwalk && !wet)
{
impassable = true;
}
if (canswim && wet)
{
impassable = false;
}
if (impassable && avgZ > z && (z + height) > lowZ)
return false;
else if (!impassable && z == avgZ && !lt.Ignored)
hasSurface = true;
StaticTile[] staticTiles = map.Tiles.GetStaticTiles(x, y, true);
for (int i = 0; i < staticTiles.Length; ++i)
{
ItemData id = TileData.ItemTable[staticTiles[i].ID & TileData.MaxItemValue];
surface = id.Surface;
impassable = id.Impassable;
wet = (id.Flags & TileFlag.Wet) != 0;
if (cantwalk && !wet)
{
impassable = true;
}
if (canswim && wet)
{
surface = true;
impassable = false;
}
if ((surface || impassable) && (staticTiles[i].Z + id.CalcHeight) > z && (z + height) > staticTiles[i].Z)
return false;
else if (surface && !impassable && z == (staticTiles[i].Z + id.CalcHeight))
hasSurface = true;
}
IPooledEnumerable eable = map.GetItemsInRange(new Point3D(x, y, z), 0);
foreach(Item item in eable)
{
if (item.ItemID < 0x4000)
{
ItemData id = item.ItemData;
surface = id.Surface;
impassable = id.Impassable;
wet = (id.Flags & TileFlag.Wet) != 0;
if (cantwalk && !wet)
{
impassable = true;
}
if (canswim && wet)
{
surface = true;
impassable = false;
}
if ((surface || impassable) && (item.Z + id.CalcHeight) > z && (z + height) > item.Z)
{
eable.Free();
return false;
}
else if (surface && !impassable && !item.Movable && z == (item.Z + id.CalcHeight))
{
hasSurface = true;
}
}
}
eable.Free();
if (checkMobiles)
{
eable = map.GetMobilesInRange(new Point3D(x, y, z), 0);
foreach(Mobile m in eable)
{
if (m.AccessLevel == AccessLevel.Player || !m.Hidden)
{
if ((m.Z + 16) > z && (z + height) > m.Z)
{
eable.Free();
return false;
}
}
}
eable.Free();
}
return !requireSurface || hasSurface;
}
[PropertyObject]
public class CityTradeEntry : PointsEntry
{
[CommandProperty(AccessLevel.GameMaster)]
public int Canceled { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public int DistanceTraveled { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public int Completed { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public int CompletedSlim { get; set; }
public CityTradeEntry(PlayerMobile pm) : base(pm)
{
}
public override string ToString()
{
return "...";
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(1);
writer.Write(Canceled);
writer.Write(DistanceTraveled);
writer.Write(Completed);
writer.Write(Ambushers == null ? 0 : Ambushers.Count);
if (Ambushers != null)
{
foreach (KeyValuePair<BaseCreature, DateTime> kvp in Ambushers)
{
writer.Write(kvp.Key);
writer.Write(kvp.Value);
}
}
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
Canceled = reader.ReadInt();
DistanceTraveled = reader.ReadInt();
Completed = reader.ReadInt();
int count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
BaseCreature bc = reader.ReadMobile() as BaseCreature;
DateTime dt = reader.ReadDateTime();
if (bc != null)
{
if (dt < DateTime.UtcNow)
bc.Delete();
else
{
if (Ambushers == null)
Ambushers = new Dictionary<BaseCreature, DateTime>();
bc.IsAmbusher = true;
Ambushers[bc] = dt;
}
}
}
if (version == 0)
{
Timer.DelayCall(() =>
{
if (Player.RemoveRewardTitle(2303807, true))
Player.AddRewardTitle(1151739);
});
}
}
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
writer.Write(ActiveTrades.Count);
foreach (KeyValuePair<Mobile, TradeOrderCrate> kvp in ActiveTrades)
{
writer.Write(kvp.Key);
writer.Write(kvp.Value);
}
writer.Write(_NameBuffer.Count);
foreach (KeyValuePair<Type, string> kvp in _NameBuffer)
{
writer.Write(kvp.Key.Name);
writer.Write(kvp.Value);
}
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
int count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
Mobile m = reader.ReadMobile();
TradeOrderCrate crate = reader.ReadItem() as TradeOrderCrate;
if (m != null && crate != null)
ActiveTrades[m] = crate;
}
_NameBuffer = new Dictionary<Type, string>();
count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
Type t = ScriptCompiler.FindTypeByName(reader.ReadString());
string name = reader.ReadString();
if (t != null)
_NameBuffer[t] = name;
}
}
}
}