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,123 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Engines.Points;
namespace Server.Engines.RisingTide
{
public class BlackMarketMerchant : BaseTurnInMobile
{
public static BlackMarketMerchant InstanceTram { get; set; }
public static BlackMarketMerchant InstanceFel { get; set; }
public static Point3D SpawnLocation { get { return new Point3D(2719, 2187, 0); } }
public override int TitleLocalization { get { return 1158918; } } // Maritime Black Market
public override int CancelLocalization { get { return 1158911; } } // Bring me maritime trade cargo and I will pay you in doubloons!
public override int TurnInLocalization { get { return 1158912; } } // Sell Maritime Trade Cargo
public override int ClaimLocalization { get { return 1158913; } } // Buy Pirate Loot
public override bool IsShrineHealer { get { return false; } }
[Constructable]
public BlackMarketMerchant() : base("the Pirate")
{
}
public override void InitBody()
{
base.InitBody();
Name = NameList.RandomName("male");
SpeechHue = 0x3B2;
Hue = Utility.RandomSkinHue();
Body = 0x190;
PackItem(new QuartermasterRewardDeed());
PackItem(new SailingMasterRewardDeed());
PackItem(new BotswainRewardDeed());
PackItem(new PowderMonkeyRewardDeed());
PackItem(new SpikedWhipOfPlundering());
PackItem(new BladedWhipOfPlundering());
PackItem(new BarbedWhipOfPlundering());
PackItem(new TritonStatue());
}
public override void InitOutfit()
{
SetWearable(new ElvenPants(), 1307);
SetWearable(new Shirt(), 1209);
SetWearable(new JinBaori(), 2017);
SetWearable(new Sandals(), 0);
SetWearable(new Bandana(), 2051);
SetWearable(new BarbedWhip(), 2721);
SetWearable(new ShoulderParrot(), 18);
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
list.Add(1158914); // Maritime Black Market Merchant
}
public override void AwardPoints(PlayerMobile pm, Item item, int amount)
{
if (item is MaritimeCargo)
{
PointsSystem.RisingTide.AwardPoints(pm, ((MaritimeCargo)item).GetAwardAmount());
}
}
public override bool IsRedeemableItem(Item item)
{
return item is MaritimeCargo;
}
public override void SendRewardGump(Mobile m)
{
if (m.Player && m.CheckAlive())
m.SendGump(new RisingTideRewardGump(this, m as PlayerMobile));
}
public override void Delete()
{
base.Delete();
if (InstanceTram == this)
{
InstanceTram = null;
}
else if (InstanceFel == this)
{
InstanceFel = null;
}
}
public BlackMarketMerchant(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();
if (Map == Map.Trammel)
{
InstanceTram = this;
}
else if (Map == Map.Felucca)
{
InstanceFel = this;
}
}
}
}

View File

@@ -0,0 +1,118 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Network;
using Server.Engines.Points;
namespace Server.Engines.RisingTide
{
public static class RisingTideGeneration
{
public static void Initialize()
{
EventSink.WorldSave += OnWorldSave;
if (BlackMarketMerchant.InstanceTram != null)
{
BlackMarketMerchant.InstanceTram.MoveToWorld(BlackMarketMerchant.SpawnLocation, Map.Trammel);
}
if (BlackMarketMerchant.InstanceFel != null)
{
BlackMarketMerchant.InstanceFel.MoveToWorld(BlackMarketMerchant.SpawnLocation, Map.Felucca);
}
if (PointsSystem.RisingTide.Enabled && PlunderBeaconSpawner.Spawner == null)
{
new PlunderBeaconSpawner();
}
}
private static void OnWorldSave(WorldSaveEventArgs e)
{
CheckEnabled(true);
}
public static void CheckEnabled(bool timed = false)
{
var risingTide = PointsSystem.RisingTide;
if (risingTide.Enabled && !risingTide.InSeason)
{
if (timed)
{
Timer.DelayCall(TimeSpan.FromSeconds(30), () =>
{
Utility.WriteConsoleColor(ConsoleColor.Green, "Auto Disabling Rising Tide");
Remove();
risingTide.Enabled = false;
});
}
else
{
Utility.WriteConsoleColor(ConsoleColor.Green, "Auto Disabling Rising Tide");
Remove();
risingTide.Enabled = false;
}
}
else if (!risingTide.Enabled && risingTide.InSeason)
{
if (timed)
{
Timer.DelayCall(TimeSpan.FromSeconds(30), () =>
{
Utility.WriteConsoleColor(ConsoleColor.Green, "Enabling Rising Tide");
Generate();
risingTide.Enabled = true;
});
}
else
{
Utility.WriteConsoleColor(ConsoleColor.Green, "Enabling Rising Tide");
Generate();
risingTide.Enabled = true;
}
}
}
public static void Generate()
{
if (BlackMarketMerchant.InstanceTram == null)
{
BlackMarketMerchant.InstanceTram = new BlackMarketMerchant();
BlackMarketMerchant.InstanceTram.MoveToWorld(BlackMarketMerchant.SpawnLocation, Map.Trammel);
BlackMarketMerchant.InstanceTram.Home = BlackMarketMerchant.SpawnLocation;
BlackMarketMerchant.InstanceTram.RangeHome = 2;
}
if (BlackMarketMerchant.InstanceFel == null)
{
BlackMarketMerchant.InstanceFel = new BlackMarketMerchant();
BlackMarketMerchant.InstanceFel.MoveToWorld(BlackMarketMerchant.SpawnLocation, Map.Felucca);
BlackMarketMerchant.InstanceFel.Home = BlackMarketMerchant.SpawnLocation;
BlackMarketMerchant.InstanceFel.RangeHome = 2;
}
if (PlunderBeaconSpawner.Spawner == null)
{
new PlunderBeaconSpawner();
}
}
public static void Remove()
{
if (PlunderBeaconSpawner.Spawner != null)
{
PlunderBeaconSpawner.Spawner.SystemDeactivate();
}
}
}
}

View File

@@ -0,0 +1,534 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Server;
using Server.Mobiles;
using Server.Multis;
using Server.Spells;
namespace Server.Items
{
public abstract class MannedCannon : Item
{
public virtual TimeSpan ScanDelay { get { return TimeSpan.FromSeconds(Utility.RandomMinMax(5, 10)); } }
[CommandProperty(AccessLevel.GameMaster)]
public Mobile Operator { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public Direction Facing { get { return GetFacing(); } }
public DateTime NextScan { get; set; }
public bool CanFireUnmanned { get; set; }
public abstract CannonPower Power { get; }
public abstract int Range { get; }
public virtual AmmunitionType AmmoType { get { return AmmunitionType.Cannonball; } }
public virtual int LateralOffset { get { return 1; } }
public MannedCannon(Mobile opera, Direction facing)
: base(0)
{
ItemID = GetID(facing, Power);
Operator = opera;
Movable = false;
}
private static int GetID(Direction facing, CannonPower power)
{
switch (facing)
{
default:
case Direction.South:
return BaseGalleon.CannonIDs[0][(int)power];
case Direction.West:
return BaseGalleon.CannonIDs[1][(int)power];
case Direction.North:
return BaseGalleon.CannonIDs[2][(int)power];
case Direction.East:
return BaseGalleon.CannonIDs[3][(int)power];
}
}
public Direction GetFacing()
{
if (BaseGalleon.CannonIDs[0].Any(id => id == ItemID))
{
return Direction.South;
}
if (BaseGalleon.CannonIDs[1].Any(id => id == ItemID))
{
return Direction.West;
}
if (BaseGalleon.CannonIDs[2].Any(id => id == ItemID))
{
return Direction.North;
}
return Direction.East;
}
public bool Scan(bool shoot)
{
var targets = AcquireTarget();
bool acquiredTarget = false;
if (targets != null && targets.Length > 0)
{
foreach (var t in targets)
{
if (t.Entity is BaseGalleon && AmmoType != AmmunitionType.Grapeshot)
{
if (shoot)
{
DoShootEffects();
TimeSpan delay = TimeSpan.FromSeconds((double)t.Range / 10.0);
Timer.DelayCall(delay, new TimerStateCallback(OnShipHit), new object[] { (BaseGalleon)t.Entity, t.Location, AmmoType });
}
acquiredTarget = true;
}
else if (t.Entity is Mobile && AmmoType == AmmunitionType.Grapeshot)
{
var m = t.Entity as Mobile;
if (shoot)
{
DoShootEffects();
TimeSpan delay = TimeSpan.FromSeconds((double)t.Range / 10.0);
Timer.DelayCall(delay, new TimerStateCallback(OnMobileHit), new object[] { m, t.Location, AmmoType });
}
acquiredTarget = true;
}
}
}
return acquiredTarget;
}
public Target[] AcquireTarget()
{
AmmoInfo ammo = AmmoInfo.GetAmmoInfo(AmmoType);
int xOffset = 0; int yOffset = 0;
int currentRange = 0;
Point3D pnt = Location;
Map map = Map;
switch (GetFacing())
{
case Direction.North:
xOffset = 0; yOffset = -1; break;
case Direction.South:
xOffset = 0; yOffset = 1; break;
case Direction.West:
xOffset = -1; yOffset = 0; break;
case Direction.East:
xOffset = 1; yOffset = 0; break;
}
int xo = xOffset;
int yo = yOffset;
int lateralOffset = 1;
while (currentRange++ <= Range)
{
xOffset = xo;
yOffset = yo;
if (LateralOffset > 1 && currentRange % LateralOffset == 0)
lateralOffset++;
TimeSpan delay = TimeSpan.FromSeconds((double)currentRange / 10.0);
switch (AmmoType)
{
case AmmunitionType.Empty: break;
case AmmunitionType.Cannonball:
case AmmunitionType.FrostCannonball:
case AmmunitionType.FlameCannonball:
{
Point3D newPoint = pnt;
//List<IEntity> list = new List<IEntity>();
for (int i = -lateralOffset; i <= lateralOffset; i++)
{
if (xOffset == 0)
newPoint = new Point3D(pnt.X + (xOffset + i), pnt.Y + (yOffset * currentRange), pnt.Z);
else
newPoint = new Point3D(pnt.X + (xOffset * currentRange), pnt.Y + (yOffset + i), pnt.Z);
BaseGalleon g = FindValidBoatTarget(newPoint, map, ammo);
if (g != null && g.DamageTaken < DamageLevel.Severely && g.Owner is PlayerMobile)
{
var target = new Target();
target.Entity = g;
target.Location = newPoint;
target.Range = currentRange;
return new Target[] { target };
}
}
}
break;
case AmmunitionType.Grapeshot:
{
Point3D newPoint = pnt;
List<Target> mobiles = new List<Target>();
for (int i = -lateralOffset; i <= lateralOffset; i++)
{
if (xOffset == 0)
newPoint = new Point3D(pnt.X + (xOffset + i), pnt.Y + (yOffset * currentRange), pnt.Z);
else
newPoint = new Point3D(pnt.X + (xOffset * currentRange), pnt.Y + (yOffset + i), pnt.Z);
foreach (Mobile m in GetTargets(newPoint, map))
{
var target = new Target();
target.Entity = m;
target.Location = newPoint;
target.Range = currentRange;
mobiles.Add(target);
}
if (mobiles.Count > 0 && ammo.SingleTarget)
{
var toHit = mobiles[Utility.Random(mobiles.Count)];
ColUtility.Free(mobiles);
return new Target[] { toHit };
}
}
if (mobiles.Count > 0)
{
return mobiles.ToArray();
}
}
break;
}
}
return null;
}
private IEnumerable<Mobile> GetTargets(Point3D newPoint, Map map)
{
if (Operator != null)
{
foreach (Mobile m in SpellHelper.AcquireIndirectTargets(Operator, newPoint, map, 0).OfType<Mobile>())
{
yield return m;
}
yield break;
}
IPooledEnumerable eable = map.GetMobilesInRange(newPoint, 0);
foreach (Mobile m in eable)
{
if (m is PlayerMobile || (m is BaseCreature && ((BaseCreature)m).GetMaster() is PlayerMobile))
{
yield return m;
}
}
}
public struct Target
{
public IEntity Entity { get; set; }
public Point3D Location { get; set; }
public int Range { get; set; }
}
private BaseGalleon FindValidBoatTarget(Point3D newPoint, Map map, AmmoInfo info)
{
BaseGalleon galleon = BaseGalleon.FindGalleonAt(newPoint, map);
if (galleon != null && info.RequiresSurface)
{
int d = galleon is BritannianShip ? 3 : 2;
switch (galleon.Facing)
{
case Direction.North:
case Direction.South:
if (newPoint.X <= galleon.X - d || newPoint.X >= galleon.X + d)
return null;
break;
case Direction.East:
case Direction.West:
if (newPoint.Y <= galleon.Y - d || newPoint.Y >= galleon.Y + d)
return null;
break;
}
StaticTile[] tiles = map.Tiles.GetStaticTiles(newPoint.X, newPoint.Y, true);
foreach (StaticTile tile in tiles)
{
ItemData id = TileData.ItemTable[tile.ID & TileData.MaxItemValue];
bool isWater = (tile.ID >= 0x1796 && tile.ID <= 0x17B2);
if (!isWater && id.Surface && !id.Impassable)
{
return galleon;
}
}
return null;
}
return galleon;
}
public virtual void OnShipHit(object obj)
{
object[] list = (object[])obj;
BaseBoat target = list[0] as BaseBoat;
Point3D pnt = (Point3D)list[1];
var ammoInfo = AmmoInfo.GetAmmoInfo((AmmunitionType)list[2]);
if (ammoInfo != null && target != null)
{
int damage = (Utility.RandomMinMax(ammoInfo.MinDamage, ammoInfo.MaxDamage));
damage /= 7;
target.OnTakenDamage(Operator, damage);
int z = target.ZSurface;
if (target.TillerMan != null && target.TillerMan is IEntity)
{
z = ((IEntity)target.TillerMan).Z;
}
Direction d = Utility.GetDirection(this, pnt);
int xOffset = 0;
int yOffset = 0;
Point3D hit = pnt;
if (!ammoInfo.RequiresSurface)
{
switch (d)
{
default:
case Direction.North:
xOffset = Utility.RandomMinMax(-1, 1);
yOffset = Utility.RandomMinMax(-2, 0);
hit = new Point3D(pnt.X + xOffset, pnt.Y + yOffset, z);
break;
case Direction.South:
xOffset = Utility.RandomMinMax(-1, 1);
yOffset = Utility.RandomMinMax(0, 2);
hit = new Point3D(pnt.X + xOffset, pnt.Y + yOffset, z);
break;
case Direction.East:
xOffset = Utility.RandomMinMax(0, 2);
yOffset = Utility.RandomMinMax(-1, 1);
hit = new Point3D(pnt.X + xOffset, pnt.Y + yOffset, z);
break;
case Direction.West:
xOffset = Utility.RandomMinMax(-2, 0);
yOffset = Utility.RandomMinMax(-1, 1);
hit = new Point3D(pnt.X + xOffset, pnt.Y + yOffset, z);
break;
}
}
Effects.SendLocationEffect(hit, target.Map, Utility.RandomBool() ? 14000 : 14013, 15, 10);
Effects.PlaySound(hit, target.Map, 0x207);
if (Operator != null && (!Operator.Deleted || CanFireUnmanned))
{
Mobile victim = target.Owner;
if (victim != null && target.Contains(victim) && Operator.CanBeHarmful(victim, false))
{
Operator.DoHarmful(victim);
}
else
{
List<Mobile> candidates = new List<Mobile>();
SecurityLevel highest = SecurityLevel.Passenger;
foreach (var mob in target.GetMobilesOnBoard().OfType<PlayerMobile>().Where(pm => Operator.CanBeHarmful(pm, false)))
{
if (target is BaseGalleon && ((BaseGalleon)target).GetSecurityLevel(mob) > highest)
{
candidates.Insert(0, mob);
}
else
{
candidates.Add(mob);
}
}
if (candidates.Count > 0)
{
Operator.DoHarmful(candidates[0]);
}
else if (victim != null && Operator.IsHarmfulCriminal(victim))
{
Operator.CriminalAction(false);
}
ColUtility.Free(candidates);
}
}
}
}
public virtual void OnMobileHit(object obj)
{
object[] objects = (object[])obj;
Mobile toHit = objects[0] as Mobile;
Point3D pnt = (Point3D)objects[1];
AmmoInfo ammoInfo = AmmoInfo.GetAmmoInfo((AmmunitionType)objects[2]);
if (ammoInfo != null)
{
int damage = (int)(Utility.RandomMinMax(ammoInfo.MinDamage, ammoInfo.MaxDamage));
if (Operator != null)
{
Operator.DoHarmful(toHit);
}
AOS.Damage(toHit, Operator, damage, ammoInfo.PhysicalDamage, ammoInfo.FireDamage, ammoInfo.ColdDamage, ammoInfo.PoisonDamage, ammoInfo.EnergyDamage);
Effects.SendLocationEffect(toHit.Location, toHit.Map, Utility.RandomBool() ? 14000 : 14013, 15, 10);
Effects.PlaySound(toHit.Location, toHit.Map, 0x207);
}
}
public void DoShootEffects()
{
Point3D p = Location;
Map map = Map;
p.Z -= 3;
switch (Facing)
{
case Direction.North: p.Y--; break;
case Direction.East: p.X++; break;
case Direction.South: p.Y++; break;
case Direction.West: p.X--; break;
}
Effects.SendLocationEffect(p, map, 14120, 15, 10);
Effects.PlaySound(p, map, 0x664);
}
public MannedCannon(Serial serial) : base(serial) { }
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)1);
writer.Write(Operator);
writer.Write(CanFireUnmanned);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch (version)
{
case 1:
Operator = reader.ReadMobile();
CanFireUnmanned = reader.ReadBool();
break;
}
}
}
public class MannedCulverin : MannedCannon
{
public override int Range { get { return 10; } }
public override CannonPower Power { get { return CannonPower.Light; } }
public MannedCulverin(Mobile oper, Direction facing)
: base(oper, facing)
{
}
public MannedCulverin(Serial serial) : base(serial) { }
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class MannedCarronade : MannedCannon
{
public override int Range { get { return 10; } }
public override CannonPower Power { get { return CannonPower.Heavy; } }
public MannedCarronade(Mobile oper, Direction facing)
: base(oper, facing)
{
}
public MannedCarronade(Serial serial) : base(serial) { }
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class MannedBlundercannon : MannedCannon
{
public override int LabelNumber { get { return 1158942; } } // Blundercannon
public override int Range { get { return 12; } }
public override CannonPower Power { get { return CannonPower.Massive; } }
public MannedBlundercannon(Mobile oper, Direction facing)
: base(oper, facing)
{
}
public MannedBlundercannon(Serial serial) : base(serial) { }
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,204 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Engines.CityLoyalty;
using Server.Engines.RisingTide;
namespace Server.Items
{
public enum CargoQuality
{
Grandmaster,
Exalted,
Legendary,
Mythical
}
public enum CargoType
{
Cloth = 1257,
Jewelry = 353,
Wood = 1155,
Metal = 1175,
Munitions = 1157,
Granite = 2498,
Reagents = 1156,
Glassware = 1158,
}
// 1158907 You recover maritime trade cargo!
[Flipable(0xA2C4, 0xA2C5)]
public class MaritimeCargo : Item
{
private CargoQuality _CargoQuality;
private CargoType _CargoType;
private City _City;
[CommandProperty(AccessLevel.GameMaster)]
public CargoQuality CargoQuality
{
get { return _CargoQuality; }
set
{
_CargoQuality = value;
if (_CargoQuality == CargoQuality.Mythical)
{
Hue = 1177;
}
InvalidateProperties();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public CargoType CargoType
{
get { return _CargoType; }
set
{
_CargoType = value;
if (_CargoQuality != CargoQuality.Mythical && Hue != (int)_CargoType)
{
Hue = (int)_CargoType;
}
InvalidateProperties();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public City City { get { return _City; } set { _City = value; InvalidateProperties(); } }
[Constructable]
public MaritimeCargo()
: this(RandomQuality(), RandomCity(), RandomType())
{
}
[Constructable]
public MaritimeCargo(CargoQuality quality)
: this(quality, RandomCity(), RandomType())
{
}
[Constructable]
public MaritimeCargo(CargoQuality quality, City city, CargoType type)
: base(0xA2C4)
{
CargoQuality = quality;
City = city;
CargoType = type;
}
private static CargoQuality RandomQuality()
{
var random = Utility.RandomDouble();
if (random < 0.05)
{
return CargoQuality.Legendary;
}
if (random < 0.33)
{
return CargoQuality.Exalted;
}
return CargoQuality.Grandmaster;
}
private static City RandomCity()
{
return (City)Utility.Random(9);
}
private static CargoType RandomType()
{
switch (Utility.Random(8))
{
default:
case 0: return CargoType.Cloth;
case 1: return CargoType.Jewelry;
case 2: return CargoType.Wood;
case 3: return CargoType.Metal;
case 4: return CargoType.Munitions;
case 5: return CargoType.Granite;
case 6: return CargoType.Reagents;
case 7: return CargoType.Glassware;
}
}
public int GetAwardAmount()
{
int amount;
switch (_CargoQuality)
{
default:
case CargoQuality.Grandmaster: amount = Utility.RandomMinMax(100, 200); break;
case CargoQuality.Exalted: amount = Utility.RandomMinMax(500, 600); break;
case CargoQuality.Legendary: amount = Utility.RandomMinMax(1000, 1100); break;
case CargoQuality.Mythical: amount = Utility.RandomMinMax(10000, 15000); break;
}
return amount;
}
public override void AddNameProperty(ObjectPropertyList list)
{
list.Add(1158906, String.Format("#{0}", CityLoyaltySystem.GetCityLocalization(_City).ToString())); // Maritime Trade Cargo Destined for ~1_CITY~
}
public override void AddWeightProperty(ObjectPropertyList list)
{
base.AddWeightProperty(list);
list.Add(_CargoQuality < CargoQuality.Mythical ? 1158903 + (int)_CargoQuality : 1158969, String.Format("#{0}", TypeLabel(_CargoType)));
}
public static int TypeLabel(CargoType type)
{
switch (type)
{
default:
case CargoType.Cloth: return 1044286;
case CargoType.Jewelry: return 1011172;
case CargoType.Wood: return 1079435;
case CargoType.Metal: return 1049567;
case CargoType.Munitions: return 1158902;
case CargoType.Granite: return 1158900;
case CargoType.Reagents: return 1002127;
case CargoType.Glassware: return 1158901;
}
}
public MaritimeCargo(Serial serial) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
writer.Write((int)_CargoQuality);
writer.Write((int)_CargoType);
writer.Write((int)_City);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
_CargoQuality = (CargoQuality)reader.ReadInt();
_CargoType = (CargoType)reader.ReadInt();
_City = (City)reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,124 @@
using System;
using System.Linq;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Mobiles;
namespace Server.Items
{
public class PlunderBeacon : Beacon
{
[CommandProperty(AccessLevel.GameMaster)]
public PlunderBeaconAddon Controller { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public Mobile LastDamager { get; set; }
public override bool CanDamage { get { return Controller == null || Controller.BeaconVulnerable; } }
public PlunderBeacon(PlunderBeaconAddon controller)
{
Controller = controller;
Name = "a plunderbeacon";
ResistBasePhys = 0;
ResistBaseFire = 0;
ResistBaseCold = 0;
ResistBasePoison = 0;
ResistBaseEnergy = 0;
HitsMax = 70000;
Hits = HitsMax;
}
public override void OnHalfDamage()
{
/*IPooledEnumerable eable = this.Map.GetMobilesInRange(this.Location, 20);
foreach (Mobile m in eable)
{
if (m.NetState != null)
m.PrivateOverheadMessage(Server.Network.MessageType.Regular, 1154, 1154551, m.NetState); // *Minax's Beacon surges with energy into an invulnerable state! Defeat her Captains to weaken the Beacon's defenses!*
}
eable.Free();
if (Controller != null)
Timer.DelayCall(TimeSpan.FromSeconds(1), () => Controller.SpawnWave());*/
}
public override bool CheckAreaDamage(Mobile from, int amount)
{
if (amount >= 5000)
{
return false;
}
return base.CheckAreaDamage(from, amount);
}
public override void OnDamage(int amount, Mobile from, bool willkill)
{
base.OnDamage(amount, from, willkill);
LastDamager = from;
}
public override bool OnBeforeDestroyed()
{
if (DamageStore != null)
{
var eligables = DamageStore.Keys.Where(m => m.InRange(Location, 20)).ToList();
if (eligables.Count > 0 && 0.5 > Utility.RandomDouble())
{
var winner = eligables[Utility.Random(eligables.Count)];
if (winner != null)
{
winner.AddToBackpack(new MaritimeCargo(CargoQuality.Mythical));
winner.SendLocalizedMessage(1158907); // You recover maritime trade cargo!
}
}
}
if (Controller != null)
Controller.OnBeaconDestroyed();
return base.OnBeforeDestroyed();
}
public override void Delete()
{
base.Delete();
if (Controller != null && !Controller.Deleted)
{
Controller.Delete();
}
}
public PlunderBeacon(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
writer.WriteItem<PlunderBeaconAddon>(Controller);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
reader.ReadInt();
Controller = reader.ReadItem<PlunderBeaconAddon>();
}
}
}

View File

@@ -0,0 +1,500 @@
using System;
using System.Linq;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Mobiles;
namespace Server.Items
{
public class PlunderBeaconAddon : BaseAddon
{
public static readonly int MaxSpawn = 5;
[CommandProperty(AccessLevel.GameMaster)]
public PlunderBeacon Beacon { get; set; }
public List<BaseCreature> Crew { get; set; }
public Dictionary<BaseCreature, bool> Spawn { get; set; }
public List<MannedCannon> Cannons { get; set; }
public bool CannonsOperational { get { return Crew.Any(c => c.Alive && !c.Deleted); } }
public bool BeaconVulnerable { get { return !CannonsOperational; } }
public override BaseAddonDeed Deed { get { return null; } }
public Timer Timer { get; set; }
public DateTime NextShoot { get; set; }
public DateTime NextSpawn { get; set; }
public bool InitialSpawn { get; set; }
[Constructable]
public PlunderBeaconAddon()
{
for (int i = 0; i < m_AddOnSimpleComponents.Length / 4; i++)
AddComponent(new AddonComponent(m_AddOnSimpleComponents[i, 0]), m_AddOnSimpleComponents[i, 1], m_AddOnSimpleComponents[i, 2], m_AddOnSimpleComponents[i, 3]);
AddComplexComponent((BaseAddon)this, 2572, 0, 2, 37, 0, 5, "", 1);
AddComplexComponent((BaseAddon)this, 2567, 2, 0, 37, 0, 5, "", 1);
Crew = new List<BaseCreature>();
Spawn = new Dictionary<BaseCreature, bool>();
Cannons = new List<MannedCannon>();
Beacon = new PlunderBeacon(this);
Beacon.MoveToWorld(new Point3D(X + 1, Y + 1, Z + 14), Map);
AddCannon(Direction.South, CannonPower.Massive, -3, 5, 7);
AddCannon(Direction.South, CannonPower.Massive, -1, 5, 7);
AddCannon(Direction.South, CannonPower.Massive, 1, 5, 7);
AddCannon(Direction.South, CannonPower.Massive, 3, 5, 7);
AddCannon(Direction.North, CannonPower.Massive, -3, -4, 7);
AddCannon(Direction.North, CannonPower.Massive, -1, -4, 7);
AddCannon(Direction.North, CannonPower.Massive, 1, -4, 7);
AddCannon(Direction.North, CannonPower.Massive, 3, -4, 7);
AddCannon(Direction.West, CannonPower.Light, -2, -2, 12, false);
AddCannon(Direction.West, CannonPower.Light, -2, 0, 12, false);
AddCannon(Direction.West, CannonPower.Light, -2, 2, 12, false);
AddCannon(Direction.East, CannonPower.Light, 2, -2, 12, false);
AddCannon(Direction.East, CannonPower.Light, 2, 0, 12, false);
AddCannon(Direction.East, CannonPower.Light, 2, 2, 12, false);
Timer = Timer.DelayCall(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), OnTick);
}
private void AddCannon(Direction d, CannonPower type, int xOffset, int yOffset, int zOffset, bool oper = true)
{
MannedCannon cannon;
BaseCreature mob = null;
if (oper)
{
mob = new PirateCrew();
mob.CantWalk = true;
Crew.Add(mob);
}
switch (type)
{
default:
case CannonPower.Light:
cannon = new MannedCulverin(mob, d); break;
case CannonPower.Heavy:
cannon = new MannedCarronade(mob, d); break;
case CannonPower.Massive:
cannon = new MannedBlundercannon(mob, d); break;
}
if (mob == null)
{
cannon.CanFireUnmanned = true;
}
cannon.MoveToWorld(new Point3D(X + xOffset, Y + yOffset, Z + zOffset), Map);
Cannons.Add(cannon);
if (mob != null)
{
Point3D offset;
switch (d)
{
default:
case Direction.South:
offset = new Point3D(0, -1, 0); break;
case Direction.North:
offset = new Point3D(0, 1, 0); break;
case Direction.West:
offset = new Point3D(1, 0, 0); break;
case Direction.East:
offset = new Point3D(-1, 0, 0); break;
}
mob.MoveToWorld(new Point3D(cannon.X + offset.X, cannon.Y + offset.Y, cannon.Z + offset.Z), Map);
}
}
public override void OnLocationChange(Point3D old)
{
base.OnLocationChange(old);
foreach (var c in Cannons)
{
c.Location = new Point3D(X + (c.X - old.X), Y + (c.Y - old.Y), Z + (c.Z - old.Z));
}
foreach (var c in Crew)
{
c.Location = new Point3D(X + (c.X - old.X), Y + (c.Y - old.Y), Z + (c.Z - old.Z));
}
foreach (var c in Spawn.Keys.Where(c => c != null && !c.Deleted))
{
c.Location = new Point3D(X + (c.X - old.X), Y + (c.Y - old.Y), Z + (c.Z - old.Z));
}
if (Beacon != null)
{
Beacon.Location = new Point3D(X + (Beacon.X - old.X), Y + (Beacon.Y - old.Y), Z + (Beacon.Z - old.Z));
}
}
public override void OnMapChange()
{
base.OnMapChange();
foreach (var c in Cannons)
{
c.Map = Map;
}
foreach (var c in Crew.Where(c => c != null && !c.Deleted))
{
c.Map = Map;
}
foreach (var c in Spawn.Keys.Where(c => c != null && !c.Deleted))
{
c.Map = Map;
}
if (Beacon != null)
{
Beacon.Map = Map;
}
}
public void OnBeaconDestroyed()
{
if (Deleted)
return;
for (int i = 0; i < 4; i++)
{
Timer.DelayCall(TimeSpan.FromSeconds(3 + (i * 3)), stage =>
{
Z -= 1;
if (stage == 3)
{
Delete();
}
}, i);
}
}
public override void OnSectorActivate()
{
if (Timer == null)
{
Timer = Timer.DelayCall(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), OnTick);
}
}
public override void OnSectorDeactivate()
{
if (Timer != null && SpawnCount() >= MaxSpawn)
{
Timer.Stop();
Timer = null;
}
}
public void OnTick()
{
var map = Map;
if (map == null)
{
return;
}
else if (!InitialSpawn)
{
for (int i = 0; i < MaxSpawn; i++)
{
SpawnHelper(true);
InitialSpawn = true;
}
}
else if (CannonsOperational && NextShoot < DateTime.UtcNow)
{
foreach (var cannon in Cannons.Where(c => c != null && !c.Deleted && (c.CanFireUnmanned || (c.Operator != null && !c.Operator.Deleted && c.Operator.Alive))))
{
cannon.Scan(true);
}
NextShoot = DateTime.UtcNow + TimeSpan.FromSeconds(2);
}
if (NextSpawn < DateTime.UtcNow)
{
Timer.DelayCall(TimeSpan.FromSeconds(1), () =>
{
if (SpawnCount() < MaxSpawn)
{
SpawnHelper(false);
}
});
}
}
private void SpawnHelper(bool initial)
{
if (Map == null || Beacon == null)
return;
Point3D p = Location;
var map = Map;
var range = 15;
if (Beacon.LastDamager != null && Beacon.LastDamager.InRange(Location, 20))
{
p = Beacon.LastDamager.Location;
range = 8;
}
BaseCreature creature = Activator.CreateInstance(_SpawnTypes[Utility.Random(_SpawnTypes.Length)]) as BaseCreature;
for (int i = 0; i < 50; i++)
{
var spawnLoc = new Point3D(Utility.RandomMinMax(p.X - range, p.X + range), Utility.RandomMinMax(p.Y - range, p.Y + range), -5);
if (map.CanFit(spawnLoc.X, spawnLoc.Y, spawnLoc.Z, 16, true, true, false, creature))
{
if (creature != null)
{
creature.MoveToWorld(spawnLoc, map);
creature.Home = spawnLoc;
creature.RangeHome = 10;
if (creature.IsSoulboundEnemies)
creature.IsSoulbound = true;
Spawn.Add(creature, initial);
NextSpawn = DateTime.UtcNow + TimeSpan.FromSeconds(Utility.RandomMinMax(30, 60));
return;
}
}
}
creature.Delete();
}
private int SpawnCount()
{
return Spawn.Keys.Where(s => s != null && !s.Deleted).Count();
}
private Type[] _SpawnTypes =
{
typeof(WaterElemental),
typeof(SeaSerpent),
typeof(DeepSeaSerpent)
};
public override void Delete()
{
base.Delete();
if (Beacon != null && !Beacon.Deleted)
{
Beacon.Delete();
}
if (Timer != null)
{
Timer.Stop();
Timer = null;
}
foreach (var bc in Crew.Where(c => c != null && !c.Deleted))
{
bc.Kill();
}
foreach (var bc in Spawn.Keys.Where(sp => sp != null && !sp.Deleted))
{
bc.Kill();
}
foreach (var cannon in Cannons)
{
cannon.Delete();
}
if (PlunderBeaconSpawner.Spawner != null)
{
PlunderBeaconSpawner.Spawner.RemovePlunderBeacon(this);
}
}
public bool Contains(IPoint3D p)
{
return p.X >= X - 8 && p.X <= X + 8 && p.Y >= Y - 8 && p.Y <= Y + 8;
}
public PlunderBeaconAddon( Serial serial ) : base( serial )
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // Version
writer.Write(InitialSpawn);
writer.WriteItem<PlunderBeacon>(Beacon);
writer.WriteItemList(Cannons, true);
writer.WriteMobileList(Crew, true);
//writer.WriteMobileList(Spawn, true);
writer.Write(Spawn.Count);
foreach (var kvp in Spawn)
{
writer.WriteMobile(kvp.Key);
writer.Write(kvp.Value);
}
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch (version)
{
case 1:
InitialSpawn = reader.ReadBool();
goto case 0;
case 0:
Beacon = reader.ReadItem<PlunderBeacon>();
Cannons = reader.ReadStrongItemList<MannedCannon>();
Crew = reader.ReadStrongMobileList<BaseCreature>();
Spawn = new Dictionary<BaseCreature, bool>();
if (version == 0)
{
//Spawn = reader.ReadStrongMobileList<BaseCreature>();
List<BaseCreature> list = reader.ReadStrongMobileList<BaseCreature>();
foreach (var bc in list)
{
Spawn[bc] = true;
}
}
else
{
int count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
var bc = reader.ReadMobile<BaseCreature>();
var initial = reader.ReadBool();
if (bc != null)
{
Spawn[bc] = initial;
}
}
}
break;
}
Timer = Timer.DelayCall(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), OnTick);
}
#region Components
private static void AddComplexComponent(BaseAddon addon, int item, int xoffset, int yoffset, int zoffset, int hue, int lightsource)
{
AddComplexComponent(addon, item, xoffset, yoffset, zoffset, hue, lightsource, null, 1);
}
private static void AddComplexComponent(BaseAddon addon, int item, int xoffset, int yoffset, int zoffset, int hue, int lightsource, string name, int amount)
{
AddonComponent ac;
ac = new AddonComponent(item);
if (name != null && name.Length > 0)
ac.Name = name;
if (hue != 0)
ac.Hue = hue;
if (amount > 1)
{
ac.Stackable = true;
ac.Amount = amount;
}
if (lightsource != -1)
ac.Light = (LightType)lightsource;
addon.AddComponent(ac, xoffset, yoffset, zoffset);
}
private static int[,] m_AddOnSimpleComponents = new int[,] {
{16017, -5, -3, 4}, {16011, -2, 4, 4}// 1 2 3
, {16011, -2, -4, 4}, {16020, -5, -5, 4}, {16008, -2, -5, 4}// 4 5 6
, {16014, -4, -3, 4}, {16011, 3, -4, 4}, {16008, -2, 3, 4}// 7 8 9
, {16021, -6, 4, 4}, {15998, 3, -3, 4}, {16016, -4, -5, 4}// 10 11 12
, {16008, 1, 3, 4}, {16011, -1, -3, 4}, {16014, -4, 5, 4}// 13 14 15
, {16011, 4, -4, 4}, {16011, 1, 5, 4}, {16011, 1, -4, 4}// 16 17 18
, {16011, 2, 5, 4}, {16010, 0, -6, 4}, {16012, -3, -3, 4}// 19 20 21
, {15996, 4, -3, 4}, {16011, 3, 4, 4}, {16010, 1, 2, 4}// 22 23 24
, {15997, 4, -5, 4}, {16010, 0, 2, 4}// 25 26 27
, {15993, 5, -3, 4}, {16010, 2, -6, 4}, {15996, 4, 5, 4}// 28 29 30
, {16011, -3, -4, 4}, {16005, 1, -2, 4}, {16011, 0, -4, 4}// 31 32 33
, {15998, 3, 5, 4}, {16011, 1, -3, 4}, {16005, 2, 6, 4}// 34 35 36
, {16017, -5, 5, 4}, {16008, 2, 3, 4}, {16011, -3, 4, 4}// 37 38 39
, {16008, 0, 3, 4}, {16010, 2, 2, 4}, {16010, -1, 2, 4}// 40 41 42
, {16011, 2, -3, 4}, {16015, -4, -4, 4}, {16005, 2, -2, 4}// 43 44 45
, {16010, -2, -6, 4}, {16008, 0, -5, 4}// 46 47 48
, {16010, -2, 2, 4}, {16011, 4, 4, 4}// 49 50 51
, {16013, -3, -5, 4}, {15997, 4, 3, 4}, {16008, -1, 3, 4}// 52 53 54
, {16005, 0, -2, 4}, {15999, 3, -5, 4}, {16011, 0, 5, 4}// 55 56 57
, {16011, 0, -3, 4}, {16005, 1, 6, 4}, {15993, 5, 5, 4}// 58 59 60
, {15999, 3, 3, 4}, {16011, 0, 4, 4}// 61 62 63
, {16011, 2, -4, 4}, {16005, 0, 6, 4}, {16010, 1, -6, 4}// 64 65 66
, {16008, 2, -5, 4}, {16011, -2, -3, 4}// 67 68 69
, {15995, 5, -5, 4}, {16015, -4, 4, 4}, {16011, 1, 4, 4}// 70 71 72
, {16021, -6, -4, 4}, {16005, -2, 6, 4 } // 73 74 75
, {16012, -3, 5, 4}, {16008, 1, -5, 4}, {16013, -3, 3, 4}// 76 77 78
, {16011, 2, 4, 4}, {16016, -4, 3, 4}// 79 80 81
, {15990, 6, 4, 4}, {16020, -5, 3, 4}, {15995, 5, 3, 4}// 82 83 84
, {16011, -1, 5, 4}, {16011, -2, 5, 4}, {16008, -1, -5, 4}// 85 86 87
, {15990, 6, -4, 4}, {5367, 3, 0, 4}, {2462, -1, 2, 17}// 88 89 90
, {4014, 1, 1, 17}, {4014, 1, 2, 12} // 91 92 93
, {4014, 1, 1, 10}, {16933, 1, 2, 17}, {15991, 5, 5, 4}// 94 95 96
, {19341, 0, 2, 12}, {16035, -2, -1, 9} // 97 98 99
, {16011, -1, 4, 4}, {4014, -1, 1, 12}, {4334, 4, 4, 7}// 100 101 102
, {4014, -1, 2, 12}, {16019, -5, 4, 4}, {16036, 2, 1, 9}// 104 105 106
, {16011, 1, -1, 9}, {16011, 1, 0, 9}, {16035, -2, 0, 9}// 107 108 109
, {30715, -1, 3, 5}, {30715, 0, 3, 5}, {16036, 2, -1, 9}// 110 111 112
, {16036, 2, 0, 9}, {16011, -1, -1, 9}// 113 114 115
, {16011, -1, 0, 9}, {16036, 2, 2, 9}, {16011, -1, 1, 9}// 116 117 118
, {4335, 2, 4, 7}, {16011, -1, 2, 9}, {16011, 0, -1, 9}// 119 120 121
, {16011, 0, 0, 9}, {16011, 0, 1, 9}, {7846, 3, -1, 0}// 122 123 124
, {6941, 3, 2, 35}, {16011, 0, 2, 9}, {16011, 1, 2, 9}// 125 126 127
, {6942, 1, 2, 24}, {30715, -2, 3, 5} // 128 129 130
, {7846, 3, 2, 0}, {16035, -2, 1, 9}, {16011, 1, 1, 9}// 131 132 133
, {30715, 2, 3, 5}, {4335, -3, 5, 7}, {30715, 1, 3, 5}// 134 135 136
, {16010, -1, 2, 7}, {16035, -2, 2, 9}, {16005, -1, 6, 4}// 137 138 139
, {16011, 5, 4, 8}, {16933, 0, -2, 17}, {4335, 4, -4, 7}// 140 141 142
, {30717, -2, -3, 5}, {15991, 5, -3, 4}, {30717, -1, -3, 5}// 143 144 145
, {30717, 0, -3, 5}, {16035, -2, -2, 9}, {30717, 2, -3, 5}// 146 147 148
, {4334, -2, -4, 7}, {16019, -5, -4, 4}, {4335, 3, -4, 7}// 149 150 151
, {30717, 1, -3, 5}, {16011, 1, -2, 9}, {16036, 2, -2, 9}// 152 153 154
, {4014, 0, -2, 12}, {16011, -1, -2, 9}// 155 156 157
, {16011, 0, -2, 9}, {16011, -1, -4, 4}, {16010, -1, -6, 4}// 158 159 160
, {16005, -1, -2, 7}, {16011, 5, -4, 8}// 161 162
};
#endregion
}
}

View File

@@ -0,0 +1,230 @@
using System;
using System.Linq;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Multis;
namespace Server.Items
{
public class PlunderBeaconSpawner
{
public enum PlunderZone
{
None = -1,
Tram,
Fel,
Tokuno1,
Tokuno2,
Tokuno3,
Tokuno4
}
public static PlunderBeaconSpawner Spawner { get; set; }
public Dictionary<PlunderZone, List<PlunderBeaconAddon>> PlunderBeacons { get; set; }
public static void AddPlunderBeacon(PlunderZone zone, PlunderBeaconAddon beacon)
{
if (Spawner == null)
return;
if (!Spawner.PlunderBeacons[zone].Contains(beacon))
{
Spawner.PlunderBeacons[zone].Add(beacon);
}
}
public void RemovePlunderBeacon(PlunderBeaconAddon beacon)
{
if (Spawner == null || Spawner.PlunderBeacons == null)
return;
foreach (var kvp in Spawner.PlunderBeacons)
{
if (kvp.Value.Contains(beacon))
{
kvp.Value.Remove(beacon);
}
}
}
public void SystemDeactivate()
{
if (Timer != null)
{
Timer.Stop();
Timer = null;
}
var list = new List<PlunderBeaconAddon>();
foreach (var kvp in PlunderBeacons)
{
list.AddRange(kvp.Value);
}
foreach (var beacon in list)
{
beacon.Delete();
}
PlunderBeacons.Clear();
Spawner = null;
}
private Rectangle2D[] _Zones =
{
new Rectangle2D(1574, 3620, 766, 465),
new Rectangle2D(1574, 3620, 766, 465),
new Rectangle2D(403, 843, 80, 335),
new Rectangle2D(631, 20, 189, 110),
new Rectangle2D(1037, 20, 190, 150),
new Rectangle2D(1274, 977, 141, 221)
};
private int[] _SpawnCount =
{
5, 5, 3, 3, 3, 3
};
public Timer Timer { get; set; }
public PlunderBeaconSpawner()
{
if (Spawner == null)
{
Spawner = this;
Timer = Timer.DelayCall(TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1), TickTock);
PlunderBeacons = new Dictionary<PlunderZone, List<PlunderBeaconAddon>>();
PlunderBeacons[PlunderZone.Tram] = new List<PlunderBeaconAddon>();
PlunderBeacons[PlunderZone.Fel] = new List<PlunderBeaconAddon>();
PlunderBeacons[PlunderZone.Tokuno1] = new List<PlunderBeaconAddon>();
PlunderBeacons[PlunderZone.Tokuno2] = new List<PlunderBeaconAddon>();
PlunderBeacons[PlunderZone.Tokuno3] = new List<PlunderBeaconAddon>();
PlunderBeacons[PlunderZone.Tokuno4] = new List<PlunderBeaconAddon>();
}
else
{
Console.WriteLine("ALREADY HAS A SPAWNER!");
}
}
public void TickTock()
{
CheckSpawn();
}
public void CheckSpawn()
{
foreach (int i in Enum.GetValues(typeof(PlunderZone)))
{
if (i == -1)
continue;
var zone = (PlunderZone)i;
int low = _SpawnCount[i] - PlunderBeacons[zone].Count;
if (low > 0)
{
Spawn(zone, low);
}
}
}
public void Spawn(PlunderZone zone, int amount)
{
Map map = Map.Trammel;
if (zone == PlunderZone.Fel)
map = Map.Felucca;
else if (zone > PlunderZone.Fel)
map = Map.Tokuno;
for (int i = 0; i < amount; i++)
{
var rec = _Zones[(int)zone];
Point3D p;
while(true)
{
p = map.GetRandomSpawnPoint(rec); //new Point3D(rec.X + Utility.Random(rec.Width), rec.Y + Utility.RandomMinMax(rec.Start.X, rec.Height), -5);
if (p.Z != -5)
p.Z = -5;
var bounds = new Rectangle2D(p.X - 7, p.Y - 7, 15, 15);
bool badSpot = false;
for (int x = bounds.Start.X; x <= bounds.Start.X + bounds.Width; x++)
{
for (int y = bounds.Start.Y; y <= bounds.Start.Y + bounds.Height; y++)
{
if (BaseBoat.FindBoatAt(new Point3D(x, y, -5), map) != null || !SpecialFishingNet.ValidateDeepWater(map, x, y))
{
badSpot = true;
break;
}
}
if (badSpot)
break;
}
if (!badSpot)
{
IPooledEnumerable eable = map.GetMobilesInBounds(bounds);
foreach (Mobile m in eable)
{
if (m.AccessLevel == AccessLevel.Player)
{
badSpot = true;
break;
}
}
eable.Free();
if (!badSpot)
{
var beacon = new PlunderBeaconAddon();
beacon.MoveToWorld(p, map);
PlunderBeacons[zone].Add(beacon);
break;
}
}
}
}
}
public void Serialize(GenericWriter writer)
{
writer.Write(0);
writer.Write(PlunderBeacons.Count);
foreach (var kvp in PlunderBeacons)
{
writer.Write((int)kvp.Key);
writer.WriteItemList(kvp.Value);
}
}
public void Deserialize(GenericReader reader)
{
reader.ReadInt();
int count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
PlunderBeacons[(PlunderZone)reader.ReadInt()] = reader.ReadStrongItemList<PlunderBeaconAddon>();
}
}
}
}

View File

@@ -0,0 +1,636 @@
using System;
using System.Linq;
using Server;
using Server.Gumps;
using Server.Multis;
namespace Server.Items
{
public class DragonCannon : BaseAddon
{
public override BaseAddonDeed Deed { get { return new DragonCannonDeed(); } }
[Constructable]
public DragonCannon()
: this(DirectionType.South)
{
}
[Constructable]
public DragonCannon(DirectionType direction)
{
switch (direction)
{
case DirectionType.North:
AddComponent(new AddonComponent(0x44F4), 0, 0, 0);
AddComponent(new AddonComponent(0x44F3), 0, 1, 0);
AddComponent(new AddonComponent(0x44F5), 0, -1, 0);
break;
case DirectionType.West:
AddComponent(new AddonComponent(0x424A), 0, 0, 0);
AddComponent(new AddonComponent(0x4223), 1, 0, 0);
AddComponent(new AddonComponent(0x418F), -1, 0, 0);
break;
case DirectionType.South:
AddComponent(new AddonComponent(0x4221), 0, 0, 0);
AddComponent(new AddonComponent(0x4222), 0, 1, 0);
AddComponent(new AddonComponent(0x4220), 0, -1, 0);
break;
case DirectionType.East:
AddComponent(new AddonComponent(0x44F7), 0, 0, 0);
AddComponent(new AddonComponent(0x44F6), 1, 0, 0);
AddComponent(new AddonComponent(0x44F8), -1, 0, 0);
break;
}
}
public DragonCannon(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);
reader.ReadInt();
}
}
public class DragonCannonDeed : BaseAddonDeed, IRewardOption
{
public override int LabelNumber { get { return 1158926; } } // Decorative Dragon Cannon
public override BaseAddon Addon { get { return new DragonCannon(_Direction); } }
private DirectionType _Direction;
[Constructable]
public DragonCannonDeed()
{
}
public void GetOptions(RewardOptionList list)
{
list.Add((int)DirectionType.North, 1075389); // North
list.Add((int)DirectionType.West, 1075390); // West
list.Add((int)DirectionType.South, 1075386); // South
list.Add((int)DirectionType.East, 1075387); // East
}
public void OnOptionSelected(Mobile from, int choice)
{
_Direction = (DirectionType)choice;
if (!Deleted)
base.OnDoubleClick(from);
}
public override void OnDoubleClick(Mobile from)
{
if (IsChildOf(from.Backpack))
{
from.CloseGump(typeof(RewardOptionGump));
from.SendGump(new RewardOptionGump(this, 1076783)); // Please select your shadow altar position
}
else
{
from.SendLocalizedMessage(1062334); // This item must be in your backpack to be used.
}
}
public DragonCannonDeed(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);
reader.ReadInt();
}
}
[Flipable(0xA2CA, 0xA2CB)]
public class ShoulderParrot : BaseOuterTorso
{
private DateTime _NextFly;
private DateTime _FlyEnd;
private Timer _Timer;
private Mobile _LastShoulder;
private string _MasterName;
[CommandProperty(AccessLevel.GameMaster)]
public string MasterName { get { return _MasterName; } set { _MasterName = value; InvalidateProperties(); } }
[Constructable]
public ShoulderParrot()
: base(0xA2CA)
{
LootType = LootType.Blessed;
}
public override void AddNameProperty(ObjectPropertyList list)
{
if (_MasterName != null)
{
list.Add(1158958, String.Format("{0}{1}", _MasterName, _MasterName.ToLower().EndsWith("s") || _MasterName.ToLower().EndsWith("z") ? "'" : "'s"));
}
else
{
list.Add(1158928); // Shoulder Parrot
}
}
public override void OnDoubleClick(Mobile m)
{
if (m.FindItemOnLayer(Layer.OuterTorso) == this)
{
if (_NextFly > DateTime.UtcNow)
{
m.SendLocalizedMessage(1158956); // Your parrot is too tired to fly right now.
}
else
{
_Timer = Timer.DelayCall(TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(500), FlyOnTick);
_Timer.Start();
Movable = false;
_LastShoulder = m;
MoveToWorld(new Point3D(m.X, m.Y, m.Z + 15), m.Map);
ItemID = 0xA2CC;
_FlyEnd = DateTime.UtcNow + TimeSpan.FromSeconds(Utility.RandomMinMax(3, 5));
}
}
else
{
m.SendLocalizedMessage(1158957); // Your parrot can't fly here.
}
}
private void FlyOnTick()
{
if (_FlyEnd < DateTime.UtcNow)
{
Movable = true;
ItemID = 0xA2CA;
if (_LastShoulder.FindItemOnLayer(Layer.OuterTorso) != null)
{
_LastShoulder.Backpack.DropItem(this);
}
else
{
_LastShoulder.AddItem(this);
}
_LastShoulder = null;
_Timer.Stop();
_NextFly = DateTime.UtcNow + TimeSpan.FromMinutes(2);
}
}
public ShoulderParrot(Serial serial) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
writer.Write(_MasterName);
writer.Write(_LastShoulder);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
reader.ReadInt();
_MasterName = reader.ReadString();
Mobile m = reader.ReadMobile();
if (m != null)
{
ItemID = 0xA2CA;
Timer.DelayCall(() =>
{
if (m.FindItemOnLayer(Layer.OuterTorso) != null)
{
m.Backpack.DropItem(this);
}
else
{
m.AddItem(this);
}
});
}
}
}
[Flipable(0xA2C8, 0xA2C9)]
public class PirateWallMap : Item
{
public override int LabelNumber { get { return 1158938; } } // Pirate Wall Map
[Constructable]
public PirateWallMap()
: base(0xA2C8)
{
}
public override void OnDoubleClick(Mobile m)
{
if (m.InRange(GetWorldLocation(), 2))
{
var gump = new Gump(50, 50);
gump.AddImage(0, 0, 0x9CE9);
m.SendGump(gump);
}
}
public PirateWallMap(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);
reader.ReadInt();
}
}
[Flipable(0xA2C6, 0xA2C7)]
public class MysteriousStatue : Item
{
public override int LabelNumber { get { return 1158935; } } // Mysterious Statue
[Constructable]
public MysteriousStatue()
: base(0xA2C6)
{
}
public override void OnDoubleClick(Mobile m)
{
if (m.InRange(GetWorldLocation(), 2))
{
m.SendGump(new BasicInfoGump(1158937));
/*This mysterious statue towers above you. Even as skilled a mason as you are, the craftsmanship is uncanny, and unlike anything you have encountered before.
* The stone appears to be smooth and special attention was taken to sculpt the statue as a perfect likeness. According to the pirate you purchased the statue
* from, it was recovered somewhere at sea. The amount of marine growth seems to reinforce this claim, yet you cannot discern how long it may have been
* submerged and are thus unsure of its age. Whatever its origins, one thing is clear - the figure is one you hope you do not encounter anytime soon...*/
}
}
/*public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
list.Add(1158936); // Purchased from a Pirate Merchant
}*/
public MysteriousStatue(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);
reader.ReadInt();
}
}
[Flipable(0x4C26, 0x4C27)]
public class DecorativeWoodCarving : Item
{
public string _ShipName;
[CommandProperty(AccessLevel.GameMaster)]
public string ShipName { get { return _ShipName; } set { _ShipName = value; InvalidateProperties(); } }
[Constructable]
public DecorativeWoodCarving()
: base(0x4C26)
{
Hue = 2968;
}
public void AssignRandomName()
{
var list = BaseBoat.Boats.Where(b => !String.IsNullOrEmpty(b.ShipName)).Select(x => x.ShipName).ToList();
if (list.Count > 0)
{
_ShipName = list[Utility.Random(list.Count)];
}
else
{
_ShipName = _ShipNames[Utility.Random(_ShipNames.Length)];
}
InvalidateProperties();
ColUtility.Free(list);
}
private static string[] _ShipNames =
{
"Adventure Galley",
"Queen Anne's Revenge",
"Fancy",
"Whydah",
"Royal Fortune",
"The Black Pearl",
"Satisfaction",
"The Golden Fleece",
"Bachelor's Delight",
"The Revenge",
"The Flying Dragon",
"The Gabriel",
"Privateer's Death",
"Kiss of Death",
"Devil's Doom",
"Monkeebutt",
"Mourning Star",
"Cursed Sea-Dog",
"The Howling Lusty Wench",
"Scourage of the Seven Seas",
"Neptune's Plague",
"Sea's Hellish Plague",
"The Salty Bastard"
};
public override void AddNameProperty(ObjectPropertyList list)
{
if (String.IsNullOrEmpty(_ShipName))
{
list.Add(1158943); // Wood Carving of [Ship's Name]
}
else
{
list.Add(1158921, _ShipName); // Wood Carving of ~1_name~
}
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
if (String.IsNullOrEmpty(_ShipName))
{
list.Add(1158953); // Named with a random famous ship, or if yer lucky - named after you!
}
}
public DecorativeWoodCarving(Serial serial) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
writer.Write(_ShipName);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
reader.ReadInt();
_ShipName = reader.ReadString();
}
}
public class QuartermasterRewardDeed : BaseRewardTitleDeed
{
public override TextDefinition Title { get { return 1158951; } } // Quartermaster
[Constructable]
public QuartermasterRewardDeed()
{
}
public QuartermasterRewardDeed(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 SailingMasterRewardDeed : BaseRewardTitleDeed
{
public override TextDefinition Title { get { return 1158950; } } // Sailing Master
[Constructable]
public SailingMasterRewardDeed()
{
}
public SailingMasterRewardDeed(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 BotswainRewardDeed : BaseRewardTitleDeed
{
public override TextDefinition Title { get { return 1158949; } } // Botswain
[Constructable]
public BotswainRewardDeed()
{
}
public BotswainRewardDeed(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 PowderMonkeyRewardDeed : BaseRewardTitleDeed
{
public override TextDefinition Title { get { return 1158948; } } // Powder Monkey
[Constructable]
public PowderMonkeyRewardDeed()
{
}
public PowderMonkeyRewardDeed(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 SpikedWhipOfPlundering : SpikedWhip
{
public override int LabelNumber { get { return 1158925; } } // Spiked Whip of Plundering
[Constructable]
public SpikedWhipOfPlundering()
{
ExtendedWeaponAttributes.HitExplosion = 15;
WeaponAttributes.HitLeechMana = 81;
Attributes.SpellChanneling = 1;
Attributes.Luck = 100;
Attributes.WeaponDamage = 70;
}
public SpikedWhipOfPlundering(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 BladedWhipOfPlundering : BladedWhip
{
public override int LabelNumber { get { return 1158924; } } // Bladed Whip of Plundering
[Constructable]
public BladedWhipOfPlundering()
{
ExtendedWeaponAttributes.HitExplosion = 15;
WeaponAttributes.HitLeechMana = 81;
Attributes.SpellChanneling = 1;
Attributes.Luck = 100;
Attributes.WeaponDamage = 70;
}
public BladedWhipOfPlundering(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 BarbedWhipOfPlundering : BarbedWhip
{
public override int LabelNumber { get { return 1158923; } } // Barbed Whip of Plundering
[Constructable]
public BarbedWhipOfPlundering()
{
ExtendedWeaponAttributes.HitExplosion = 15;
WeaponAttributes.HitLeechMana = 81;
Attributes.SpellChanneling = 1;
Attributes.Luck = 100;
Attributes.WeaponDamage = 70;
}
public BarbedWhipOfPlundering(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,86 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Gumps;
using Server.Mobiles;
using Server.Engines.Points;
namespace Server.Engines.RisingTide
{
public class RisingTideRewardGump : BaseRewardGump
{
public override int PointsName { get { return 1158916; } } // Your Doubloons
public override int RewardLabel { get { return 1158917; } } // What ye buyin' Matey?
public RisingTideRewardGump(Mobile owner, PlayerMobile user)
: base(owner, user, Rewards, 1158918)
{
}
public override int GetYOffset(int id)
{
if (id == 0xA2C6)
{
return 70;
}
if (id == 0xA2C8)
{
return 50;
}
if (id == 0xA28B)
{
return 15;
}
return 20;
}
public override double GetPoints(Mobile m)
{
return PointsSystem.RisingTide.GetPoints(m);
}
public override void RemovePoints(double points)
{
PointsSystem.RisingTide.DeductPoints(User, points);
}
public override void OnItemCreated(Item item)
{
if (item is DecorativeWoodCarving)
{
((DecorativeWoodCarving)item).AssignRandomName();
}
else if (item is ShoulderParrot)
{
((ShoulderParrot)item).MasterName = User.Name;
}
}
public static List<CollectionItem> Rewards { get; set; }
public static void Initialize()
{
Rewards = new List<CollectionItem>();
Rewards.Add(new CollectionItem(typeof(DragonCannonDeed), 0x14EF, 1158926, 0, 120000));
Rewards.Add(new CollectionItem(typeof(BlundercannonDeed), 0x14F2, 1158942, 1126, 25000));
Rewards.Add(new CollectionItem(typeof(PirateWallMap), 0xA2C8, 1158938, 0, 45000));
Rewards.Add(new CollectionItem(typeof(MysteriousStatue), 0xA2C6, 1158935, 0, 35000));
Rewards.Add(new CollectionItem(typeof(ShoulderParrot), 0xA2CA, 1158928, 0, 100000));
Rewards.Add(new CollectionItem(typeof(DecorativeWoodCarving), 0x4C26, 1158943, 2968, 15000));
Rewards.Add(new CollectionItem(typeof(QuartermasterRewardDeed), 0x14EF, 0, 0, 25000));
Rewards.Add(new CollectionItem(typeof(SailingMasterRewardDeed), 0x14EF, 0, 0, 20000));
Rewards.Add(new CollectionItem(typeof(BotswainRewardDeed), 0x14EF, 0, 0, 15000));
Rewards.Add(new CollectionItem(typeof(PowderMonkeyRewardDeed), 0x14EF, 0, 0, 10000));
Rewards.Add(new CollectionItem(typeof(SpikedWhipOfPlundering), 0xA28B, 0, 0, 180000));
Rewards.Add(new CollectionItem(typeof(BladedWhipOfPlundering), 0xA28B, 0, 0, 180000));
Rewards.Add(new CollectionItem(typeof(BarbedWhipOfPlundering), 0xA28B, 0, 0, 180000));
Rewards.Add(new CollectionItem(typeof(TritonStatue), 0xA2D8, 0, 2713, 140000));
}
}
}

View File

@@ -0,0 +1,129 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Engines.SeasonalEvents;
namespace Server.Engines.Points
{
public class RisingTide : PointsSystem
{
public override PointsType Loyalty { get { return PointsType.RisingTide; } }
public override TextDefinition Name { get { return m_Name; } }
public override bool AutoAdd { get { return true; } }
public override double MaxPoints { get { return double.MaxValue; } }
public override bool ShowOnLoyaltyGump { get { return false; } }
public bool InSeason { get { return SeasonalEventSystem.IsActive(EventType.RisingTide); } }
private TextDefinition m_Name = null;
public static readonly double CargoChance = 0.1;
public RisingTide()
{
}
public override void SendMessage(PlayerMobile from, double old, double points, bool quest)
{
from.SendLocalizedMessage(1158910, ((int)points).ToString()); // You have ~1_COUNT~ doubloons!
}
public override void ProcessKill(Mobile victim, Mobile damager)
{
if (Enabled && victim is BaseCreature && damager is PlayerMobile)
{
var bc = victim as BaseCreature;
var beacon = GetPlunderBeacon(bc);
if (beacon != null)
{
if (CargoChance > Utility.RandomDouble())
{
damager.AddToBackpack(new MaritimeCargo());
damager.SendLocalizedMessage(1158907); // You recover maritime trade cargo!
}
}
else if (CargoDropsTypes.Any(type => type == bc.GetType()))
{
double chance = CargoChance;
if (bc is BaseShipCaptain)
{
chance = 0.33;
}
if (chance > Utility.RandomDouble())
{
var corpse = victim.Corpse;
if (corpse != null)
{
corpse.DropItem(new MaritimeCargo());
}
}
}
}
}
private Type[] CargoDropsTypes =
{
typeof(PirateCaptain), typeof(MerchantCaptain), typeof(PirateCrew), typeof(MerchantCrew)
};
public static PlunderBeaconAddon GetPlunderBeacon(BaseCreature bc)
{
if (PlunderBeaconSpawner.Spawner != null)
{
foreach (var list in PlunderBeaconSpawner.Spawner.PlunderBeacons.Values)
{
var addon = list.FirstOrDefault(beacon => beacon.Crew.Contains(bc) || (beacon.Spawn.ContainsKey(bc) && beacon.Spawn[bc]));
if (addon != null)
{
return addon;
}
}
}
return null;
}
public bool Enabled { get; set; }
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
writer.Write(Enabled);
if (PlunderBeaconSpawner.Spawner != null)
{
writer.Write(0);
PlunderBeaconSpawner.Spawner.Serialize(writer);
}
else
{
writer.Write(1);
}
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
Enabled = reader.ReadBool();
if (reader.ReadInt() == 0)
{
var spawner = new PlunderBeaconSpawner();
spawner.Deserialize(reader);
}
}
}
}