Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
833
Scripts/Services/City Loyalty System/Trading/TradeSystem.cs
Normal file
833
Scripts/Services/City Loyalty System/Trading/TradeSystem.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user