Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
274
Scripts/Services/Expansions/High Seas/Mobiles/BaseSeaChampion.cs
Normal file
274
Scripts/Services/Expansions/High Seas/Mobiles/BaseSeaChampion.cs
Normal file
@@ -0,0 +1,274 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Multis;
|
||||
using Server.Items;
|
||||
using Server.Engines.CannedEvil;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class BaseSeaChampion : BaseChampion
|
||||
{
|
||||
public override Type[] UniqueList { get { return new Type[] { }; } }
|
||||
public override Type[] SharedList { get { return new Type[] { }; } }
|
||||
public override Type[] DecorativeList { get { return new Type[] { }; } }
|
||||
public override MonsterStatuetteType[] StatueTypes { get { return new MonsterStatuetteType[] { }; } }
|
||||
|
||||
public override ChampionSkullType SkullType
|
||||
{
|
||||
get
|
||||
{
|
||||
return ChampionSkullType.None;
|
||||
}
|
||||
}
|
||||
|
||||
private DateTime m_NextBoatDamage;
|
||||
private bool m_InDamageMode;
|
||||
private Mobile m_Fisher;
|
||||
|
||||
public virtual bool CanDamageBoats { get { return false; } }
|
||||
public virtual TimeSpan BoatDamageCooldown { get { return TimeSpan.MaxValue; } }
|
||||
public virtual DateTime NextBoatDamage { get { return m_NextBoatDamage; } }
|
||||
public virtual int MinBoatDamage { get { return 0; } }
|
||||
public virtual int MaxBoatDamage { get { return 0; } }
|
||||
public virtual int DamageRange { get { return 15; } }
|
||||
|
||||
public override double BonusPetDamageScalar { get { return 1.75; } }
|
||||
|
||||
public BaseSeaChampion(Mobile fisher, AIType ai, FightMode fm)
|
||||
: base(ai, fm)
|
||||
{
|
||||
m_NextBoatDamage = DateTime.UtcNow;
|
||||
m_InDamageMode = false;
|
||||
m_Fisher = fisher;
|
||||
|
||||
m_DamageEntries = new Dictionary<Mobile, int>();
|
||||
}
|
||||
|
||||
public override void OnThink()
|
||||
{
|
||||
base.OnThink();
|
||||
|
||||
if (m_InDamageMode)
|
||||
TryDamageBoat();
|
||||
|
||||
else if (CanDamageBoats && DateTime.UtcNow >= NextBoatDamage)
|
||||
m_InDamageMode = true;
|
||||
}
|
||||
|
||||
public override bool OnBeforeDeath()
|
||||
{
|
||||
RegisterDamageTo(this);
|
||||
AwardArtifact(GetArtifact());
|
||||
|
||||
return base.OnBeforeDeath();
|
||||
}
|
||||
|
||||
Dictionary<Mobile, int> m_DamageEntries;
|
||||
|
||||
public virtual void RegisterDamageTo(Mobile m)
|
||||
{
|
||||
if (m == null)
|
||||
return;
|
||||
|
||||
foreach (DamageEntry de in m.DamageEntries)
|
||||
{
|
||||
Mobile damager = de.Damager;
|
||||
|
||||
Mobile master = damager.GetDamageMaster(m);
|
||||
|
||||
if (master != null)
|
||||
damager = master;
|
||||
|
||||
RegisterDamage(damager, de.DamageGiven);
|
||||
}
|
||||
}
|
||||
|
||||
public void RegisterDamage(Mobile from, int amount)
|
||||
{
|
||||
if (from == null || !from.Player)
|
||||
return;
|
||||
|
||||
if (m_DamageEntries.ContainsKey(from))
|
||||
m_DamageEntries[from] += amount;
|
||||
else
|
||||
m_DamageEntries.Add(from, amount);
|
||||
}
|
||||
|
||||
public void AwardArtifact(Item artifact)
|
||||
{
|
||||
if (artifact == null)
|
||||
return;
|
||||
|
||||
int totalDamage = 0;
|
||||
|
||||
Dictionary<Mobile, int> validEntries = new Dictionary<Mobile, int>();
|
||||
|
||||
foreach (KeyValuePair<Mobile, int> kvp in m_DamageEntries)
|
||||
{
|
||||
if (IsEligible(kvp.Key, artifact))
|
||||
{
|
||||
validEntries.Add(kvp.Key, kvp.Value);
|
||||
totalDamage += kvp.Value;
|
||||
}
|
||||
}
|
||||
|
||||
int randomDamage = Utility.RandomMinMax(1, totalDamage);
|
||||
|
||||
totalDamage = 0;
|
||||
|
||||
foreach (KeyValuePair<Mobile, int> kvp in m_DamageEntries)
|
||||
{
|
||||
totalDamage += kvp.Value;
|
||||
|
||||
if (totalDamage > randomDamage)
|
||||
{
|
||||
GiveArtifact(kvp.Key, artifact);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (artifact != null)
|
||||
artifact.Delete();
|
||||
}
|
||||
|
||||
public void GiveArtifact(Mobile to, Item artifact)
|
||||
{
|
||||
if (to == null || artifact == null)
|
||||
return;
|
||||
|
||||
Container pack = to.Backpack;
|
||||
|
||||
if (pack == null || !pack.TryDropItem(to, artifact, false))
|
||||
artifact.Delete();
|
||||
else
|
||||
to.SendLocalizedMessage(1062317); // For your valor in combating the fallen beast, a special artifact has been bestowed on you.
|
||||
}
|
||||
|
||||
public bool IsEligible(Mobile m, Item Artifact)
|
||||
{
|
||||
return m.Player && m.Alive && m.InRange(Location, 32) && m.Backpack != null && m.Backpack.CheckHold(m, Artifact, false);
|
||||
}
|
||||
|
||||
public void TryDamageBoat()
|
||||
{
|
||||
Mobile focusMob = m_Fisher;
|
||||
|
||||
if (focusMob == null || !focusMob.Alive)
|
||||
focusMob = Combatant as Mobile;
|
||||
|
||||
if (focusMob == null || focusMob.AccessLevel > AccessLevel.Player || !InRange(focusMob.Location, DamageRange) || BaseBoat.FindBoatAt(focusMob, focusMob.Map) == null)
|
||||
return;
|
||||
|
||||
BaseBoat boat = BaseBoat.FindBoatAt(focusMob, focusMob.Map);
|
||||
|
||||
if (boat != null)
|
||||
{
|
||||
int range = DamageRange;
|
||||
for (int x = X - range; x <= X + range; x++)
|
||||
{
|
||||
for (int y = Y - range; y <= Y + range; y++)
|
||||
{
|
||||
if (BaseBoat.FindBoatAt(new Point2D(x, y), Map) == boat)
|
||||
{
|
||||
DoDamageBoat(boat);
|
||||
m_NextBoatDamage = DateTime.UtcNow + BoatDamageCooldown;
|
||||
m_InDamageMode = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void DoDamageBoat(BaseBoat boat)
|
||||
{
|
||||
int damage = Utility.RandomMinMax(MinBoatDamage, MaxBoatDamage);
|
||||
|
||||
boat.OnTakenDamage(this, damage);
|
||||
|
||||
for (int x = X - 2; x <= X + 2; x++)
|
||||
{
|
||||
for (int y = Y - 2; y <= Y + 2; y++)
|
||||
{
|
||||
BaseBoat b = BaseBoat.FindBoatAt(new Point2D(x, y), Map);
|
||||
|
||||
if (b != null && boat == b)
|
||||
{
|
||||
Direction toPush = Direction.North;
|
||||
if (X < x && x - X > 1)
|
||||
toPush = Direction.West;
|
||||
else if (X > x && X - x > 1)
|
||||
toPush = Direction.East;
|
||||
else if (Y < y)
|
||||
toPush = Direction.South;
|
||||
else if (Y > y)
|
||||
toPush = Direction.North;
|
||||
|
||||
boat.StartMove(toPush, 1, 0x2, boat.SlowDriftInterval, true, false);
|
||||
//TODO: Message and Sound?
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Point3D GetValidPoint(BaseBoat boat, Map map, int distance)
|
||||
{
|
||||
if (boat == null || map == null || map == Map.Internal)
|
||||
return new Point3D(X + Utility.RandomMinMax(-1, 1), Y + Utility.RandomMinMax(-1, 1), Z);
|
||||
|
||||
if (distance < 5) distance = 5;
|
||||
if (distance > 15) distance = 15;
|
||||
|
||||
int x = boat.X;
|
||||
int y = boat.Y;
|
||||
int z = boat.Z;
|
||||
int size = boat is BritannianShip ? 4 : 3;
|
||||
|
||||
int range = distance - size;
|
||||
if (range < 1) range = 1;
|
||||
|
||||
switch (boat.Facing)
|
||||
{
|
||||
default:
|
||||
case Direction.South:
|
||||
case Direction.North:
|
||||
x = Utility.RandomBool() ? Utility.RandomMinMax(x -= distance, x -= (distance - range)) : Utility.RandomMinMax(x += (distance - range), x += distance);
|
||||
y = Utility.RandomMinMax(y - 8, y + 8);
|
||||
z = map.GetAverageZ(x, y);
|
||||
break;
|
||||
case Direction.East:
|
||||
case Direction.West:
|
||||
x = Utility.RandomMinMax(x - 8, x + 8);
|
||||
y = Utility.RandomBool() ? Utility.RandomMinMax(y -= distance, y -= (distance - range)) : Utility.RandomMinMax(y += (distance - range), y += distance);
|
||||
z = map.GetAverageZ(x, y);
|
||||
break;
|
||||
}
|
||||
return new Point3D(x, y, z);
|
||||
}
|
||||
|
||||
public BaseSeaChampion(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void OnHitByCannon(IShipCannon cannon, int damage)
|
||||
{
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
m_NextBoatDamage = DateTime.UtcNow;
|
||||
m_DamageEntries = new Dictionary<Mobile, int>();
|
||||
}
|
||||
}
|
||||
}
|
||||
776
Scripts/Services/Expansions/High Seas/Mobiles/Charybdis.cs
Normal file
776
Scripts/Services/Expansions/High Seas/Mobiles/Charybdis.cs
Normal file
@@ -0,0 +1,776 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Multis;
|
||||
using System.Collections.Generic;
|
||||
using Server.Items;
|
||||
using Server.Misc;
|
||||
using System.Linq;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class Charydbis : BaseSeaChampion
|
||||
{
|
||||
public static readonly TimeSpan SpawnRate = TimeSpan.FromSeconds(30);
|
||||
public static readonly TimeSpan TeleportRate = TimeSpan.FromSeconds(60);
|
||||
public static readonly int SpawnMax = 25;
|
||||
|
||||
private List<Mobile> m_Tentacles = new List<Mobile>();
|
||||
private DateTime m_NextSpawn;
|
||||
private DateTime m_NextTeleport;
|
||||
|
||||
public override bool CanDamageBoats { get { return true; } }
|
||||
public override TimeSpan BoatDamageCooldown { get { return TimeSpan.FromSeconds(Utility.RandomMinMax(45, 80)); } }
|
||||
public override int MinBoatDamage { get { return 5; } }
|
||||
public override int MaxBoatDamage { get { return 15; } }
|
||||
public override int DamageRange { get { return 10; } }
|
||||
|
||||
public override int Meat { get { return 5; } }
|
||||
public override double TreasureMapChance { get { return .50; } }
|
||||
public override int TreasureMapLevel { get { return 7; } }
|
||||
|
||||
public override Type[] UniqueList { get { return new Type[] { typeof(FishermansHat), typeof(FishermansVest), typeof(FishermansEelskinGloves), typeof(FishermansTrousers) }; } }
|
||||
public override Type[] SharedList { get { return new Type[] { typeof(HelmOfVengence), typeof(RingOfTheSoulbinder), typeof(RuneEngravedPegLeg), typeof(CullingBlade) }; } }
|
||||
public override Type[] DecorativeList { get { return new Type[] { typeof(EnchantedBladeDeed), typeof(EnchantedVortexDeed) }; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Tentacles { get { return m_Tentacles.Count; } }
|
||||
|
||||
[Constructable]
|
||||
public Charydbis() : this(null) { }
|
||||
|
||||
public Charydbis(Mobile fisher)
|
||||
: base(fisher, AIType.AI_Mage, FightMode.Closest)
|
||||
{
|
||||
RangeFight = 8;
|
||||
|
||||
Name = "charydbis";
|
||||
Body = 1244;
|
||||
BaseSoundID = 353;
|
||||
|
||||
m_NextSpawn = DateTime.UtcNow + SpawnRate;
|
||||
m_NextTeleport = DateTime.UtcNow + TeleportRate;
|
||||
|
||||
CanSwim = true;
|
||||
CantWalk = true;
|
||||
|
||||
SetStr(533, 586);
|
||||
SetDex(113, 131);
|
||||
SetInt(110, 155);
|
||||
|
||||
SetHits(30000);
|
||||
SetMana(8000);
|
||||
SetDamage(24, 33);
|
||||
|
||||
SetDamageType(ResistanceType.Physical, 50);
|
||||
SetDamageType(ResistanceType.Energy, 50);
|
||||
|
||||
SetResistance(ResistanceType.Physical, 70, 80);
|
||||
SetResistance(ResistanceType.Fire, 70, 80);
|
||||
SetResistance(ResistanceType.Cold, 45, 55);
|
||||
SetResistance(ResistanceType.Poison, 80, 90);
|
||||
SetResistance(ResistanceType.Energy, 60, 70);
|
||||
|
||||
SetSkill(SkillName.Wrestling, 120.1, 121.2);
|
||||
SetSkill(SkillName.Tactics, 120.15, 123.1);
|
||||
SetSkill(SkillName.MagicResist, 165.2, 178.7);
|
||||
SetSkill(SkillName.Anatomy, 111.0, 111.7);
|
||||
SetSkill(SkillName.Magery, 134.6, 140.5);
|
||||
SetSkill(SkillName.EvalInt, 200.8, 243.6);
|
||||
SetSkill(SkillName.Meditation, 565);
|
||||
|
||||
Fame = 32000;
|
||||
Karma = -32000;
|
||||
|
||||
if (IsSoulboundEnemies)
|
||||
IsSoulbound = true;
|
||||
}
|
||||
|
||||
public void AddTentacle(Mobile tent)
|
||||
{
|
||||
if (!m_Tentacles.Contains(tent))
|
||||
m_Tentacles.Add(tent);
|
||||
}
|
||||
|
||||
public void RemoveTentacle(Mobile tent)
|
||||
{
|
||||
if (m_Tentacles.Contains(tent))
|
||||
m_Tentacles.Remove(tent);
|
||||
}
|
||||
|
||||
public override void OnThink()
|
||||
{
|
||||
base.OnThink();
|
||||
|
||||
if (m_NextSpawn < DateTime.UtcNow && m_Tentacles.Count < SpawnMax)
|
||||
SpawnTentacle();
|
||||
|
||||
if (m_NextTeleport < DateTime.UtcNow)
|
||||
DoTeleport();
|
||||
}
|
||||
|
||||
private Point3D m_LastLocation;
|
||||
private Map m_LastMap;
|
||||
|
||||
public void DoTeleport()
|
||||
{
|
||||
var combatant = Combatant as Mobile;
|
||||
|
||||
if (combatant == null)
|
||||
{
|
||||
m_NextTeleport = DateTime.UtcNow + TeleportRate;
|
||||
return;
|
||||
}
|
||||
|
||||
m_LastLocation = Location;
|
||||
m_LastMap = Map;
|
||||
DoTeleportEffects(m_LastLocation, m_LastMap);
|
||||
|
||||
Hidden = true;
|
||||
Internalize();
|
||||
|
||||
DoAreaLightningAttack(combatant);
|
||||
|
||||
Timer.DelayCall<Mobile>(TimeSpan.FromSeconds(3), FinishTeleport, combatant);
|
||||
m_NextTeleport = DateTime.UtcNow + TeleportRate;
|
||||
}
|
||||
|
||||
public void FinishTeleport(Mobile combatant)
|
||||
{
|
||||
Point3D focusLoc;
|
||||
|
||||
if (combatant == null || combatant.Map == null)
|
||||
{
|
||||
focusLoc = Location;
|
||||
}
|
||||
else
|
||||
{
|
||||
focusLoc = combatant.Location;
|
||||
}
|
||||
|
||||
Map map = m_LastMap;
|
||||
Point3D newLoc = Point3D.Zero;
|
||||
BaseBoat boat = BaseBoat.FindBoatAt(focusLoc, map);
|
||||
|
||||
for (int i = 0; i < 25; i++)
|
||||
{
|
||||
if (boat != null)
|
||||
{
|
||||
newLoc = GetValidPoint(boat, map, 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
int x = focusLoc.X + Utility.RandomMinMax(-12, 12);
|
||||
int y = focusLoc.Y + Utility.RandomMinMax(-12, 12);
|
||||
int z = map.GetAverageZ(x, y);
|
||||
|
||||
newLoc = new Point3D(x, y, z);
|
||||
}
|
||||
|
||||
LandTile t = map.Tiles.GetLandTile(newLoc.X, newLoc.Y);
|
||||
|
||||
if (!Spells.SpellHelper.CheckMulti(new Point3D(newLoc.X, newLoc.Y, newLoc.Z), map) && IsSeaTile(t))
|
||||
break;
|
||||
}
|
||||
|
||||
if (newLoc == Point3D.Zero || GetDistanceToSqrt(newLoc) > 15)
|
||||
newLoc = m_LastLocation;
|
||||
|
||||
DoTeleportEffects(newLoc, map);
|
||||
Hidden = false;
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(.5), new TimerStateCallback(TimedMoveToWorld), new object[] { newLoc, map, combatant });
|
||||
}
|
||||
|
||||
public void TimedMoveToWorld(object o)
|
||||
{
|
||||
object[] ojs = (object[])o;
|
||||
Point3D pnt = (Point3D)ojs[0];
|
||||
Map map = ojs[1] as Map;
|
||||
Mobile focus = ojs[2] as Mobile;
|
||||
|
||||
MoveToWorld(pnt, map);
|
||||
Combatant = focus;
|
||||
|
||||
DoAreaLightningAttack(focus);
|
||||
}
|
||||
|
||||
public void DoAreaLightningAttack(Mobile focus)
|
||||
{
|
||||
if (focus == null)
|
||||
return;
|
||||
|
||||
BaseBoat boat = BaseBoat.FindBoatAt(focus, focus.Map);
|
||||
|
||||
if (boat != null)
|
||||
{
|
||||
foreach (var mob in boat.GetMobilesOnBoard().Where(m => CanBeHarmful(m, false) && m.Alive))
|
||||
{
|
||||
double damage = Math.Max(40, Utility.RandomMinMax(50, 100) * ((double)Hits / (double)HitsMax));
|
||||
|
||||
mob.BoltEffect(0);
|
||||
AOS.Damage((Mobile)mob, this, (int)damage, false, 0, 0, 0, 0, 0, 0, 100, false, false, false);
|
||||
mob.FixedParticles(0x36BD, 20, 10, 5044, EffectLayer.Head);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DoTeleportEffects(Point3D p, Map map)
|
||||
{
|
||||
for (int x = -2; x <= 2; x++)
|
||||
{
|
||||
for (int y = -2; y <= 2; y++)
|
||||
{
|
||||
if (Math.Abs(x) == 2 && Math.Abs(y) == 2)
|
||||
continue;
|
||||
|
||||
Point3D pnt = new Point3D(p.X + x, p.Y + y, Map.GetAverageZ(p.X + x, p.Y + y));
|
||||
Effects.SendLocationEffect(pnt, map, 0x3728, 16, 4);
|
||||
}
|
||||
}
|
||||
|
||||
Effects.PlaySound(p, map, 0x025);
|
||||
Effects.PlaySound(p, map, 0x026);
|
||||
Effects.PlaySound(p, map, 0x027);
|
||||
}
|
||||
|
||||
private bool m_HasPushed;
|
||||
|
||||
public override void DoDamageBoat(BaseBoat boat)
|
||||
{
|
||||
if (boat == null)
|
||||
return;
|
||||
|
||||
m_HasPushed = false;
|
||||
IPoint2D pnt = boat;
|
||||
|
||||
if (Combatant != null && boat.Contains(Combatant))
|
||||
pnt = Combatant;
|
||||
|
||||
Direction dir = Utility.GetDirection(this, pnt);
|
||||
Point3DList path = new Point3DList();
|
||||
|
||||
for (int i = 0; i < DamageRange; i++)
|
||||
{
|
||||
int x = 0, y = 0;
|
||||
switch ((int)dir)
|
||||
{
|
||||
case (int)Direction.Running:
|
||||
case (int)Direction.North: { y -= i; break; }
|
||||
case 129:
|
||||
case (int)Direction.Right: { y -= i; x += i; break; }
|
||||
case 130:
|
||||
case (int)Direction.East: { x += i; break; }
|
||||
case 131:
|
||||
case (int)Direction.Down: { x += i; y += i; break; }
|
||||
case 132:
|
||||
case (int)Direction.South: { y += i; break; }
|
||||
case 133:
|
||||
case (int)Direction.Left: { y += i; x -= i; break; }
|
||||
case 134:
|
||||
case (int)Direction.West: { x -= i; break; }
|
||||
case (int)Direction.ValueMask:
|
||||
case (int)Direction.Up: { x -= i; y -= i; break; }
|
||||
}
|
||||
|
||||
path.Add(X + x, Y + y, Z);
|
||||
}
|
||||
|
||||
new EffectsTimer(this, path, dir, DamageRange);
|
||||
}
|
||||
|
||||
public void OnTick(Point3DList path, Direction dir, int i)
|
||||
{
|
||||
if (path.Count > i)
|
||||
{
|
||||
Point3D point = path[i];
|
||||
int o = i - 1;
|
||||
|
||||
Server.Effects.PlaySound(point, Map, 278);
|
||||
Server.Effects.PlaySound(point, Map, 279);
|
||||
|
||||
for (int rn = 0; rn < (o * 2) + 1; rn++)
|
||||
{
|
||||
int y = 0, x = 0, y2 = 0, x2 = 0;
|
||||
bool diag = false;
|
||||
switch ((int)dir)
|
||||
{
|
||||
case (int)Direction.Running:
|
||||
case (int)Direction.North: { x = x - o + rn; break; }
|
||||
case 129:
|
||||
case (int)Direction.Right: { x = x - o + rn; y = y - o + rn; break; }
|
||||
case 130:
|
||||
case (int)Direction.East: { y = y - o + rn; break; }
|
||||
case 131:
|
||||
case (int)Direction.Down: { y = y - o + rn; x = x + o - rn; break; }
|
||||
case 132:
|
||||
case (int)Direction.South: { x = x + o - rn; break; }
|
||||
case 133:
|
||||
case (int)Direction.Left: { x = x + o - rn; y = y + o - rn; break; }
|
||||
case 134:
|
||||
case (int)Direction.West: { y = y + o - rn; break; }
|
||||
case (int)Direction.ValueMask:
|
||||
case (int)Direction.Up: { y = y + o - rn; x = x - o + rn; break; }
|
||||
}
|
||||
switch ((int)dir)
|
||||
{
|
||||
case 129:
|
||||
case (int)Direction.Right: { y2++; diag = true; break; }
|
||||
case 131:
|
||||
case (int)Direction.Down: { x2--; diag = true; break; }
|
||||
case 133:
|
||||
case (int)Direction.Left: { y2--; diag = true; break; }
|
||||
case (int)Direction.ValueMask:
|
||||
case (int)Direction.Up: { x2++; diag = true; break; }
|
||||
default: { break; }
|
||||
}
|
||||
|
||||
Point3D ep = new Point3D(point.X + x, point.Y + y, point.Z);
|
||||
Point3D ep2 = new Point3D(ep.X + x2, ep.Y + y2, ep.Z);
|
||||
|
||||
if (diag && i >= ((2 * path.Count) / 3))
|
||||
return;
|
||||
|
||||
Point3D p;
|
||||
if (diag && rn < (o * 2))
|
||||
p = ep2;
|
||||
else
|
||||
p = ep;
|
||||
|
||||
if (Spells.SpellHelper.CheckMulti(p, Map))
|
||||
{
|
||||
BaseBoat boat = BaseBoat.FindBoatAt(p, Map);
|
||||
|
||||
if (boat != null && !m_HasPushed)
|
||||
{
|
||||
int damage = Utility.RandomMinMax(MinBoatDamage, MaxBoatDamage);
|
||||
boat.OnTakenDamage(this, damage);
|
||||
|
||||
boat.StartMove(dir, 1, 0x2, boat.SlowDriftInterval, true, false);
|
||||
m_HasPushed = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
LandTile t = Map.Tiles.GetLandTile(x, y);
|
||||
|
||||
if (IsSeaTile(t))
|
||||
{
|
||||
Mobile spawn = new EffectSpawn();
|
||||
spawn.MoveToWorld(p, Map);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class EffectSpawn : BaseCreature
|
||||
{
|
||||
public EffectSpawn()
|
||||
: base(AIType.AI_Vendor, FightMode.Closest, 10, 1, 0.2, 0.4)
|
||||
{
|
||||
Body = 16;
|
||||
BaseSoundID = 278;
|
||||
CantWalk = true;
|
||||
CanSwim = false;
|
||||
Frozen = true;
|
||||
|
||||
SetHits(150000);
|
||||
|
||||
SetResistance(ResistanceType.Physical, 100);
|
||||
SetResistance(ResistanceType.Fire, 100);
|
||||
SetResistance(ResistanceType.Cold, 100);
|
||||
SetResistance(ResistanceType.Poison, 100);
|
||||
SetResistance(ResistanceType.Energy, 100);
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(2), new TimerCallback(DoDelete));
|
||||
}
|
||||
|
||||
public override bool DeleteCorpseOnDeath
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void DoDelete()
|
||||
{
|
||||
if (Alive)
|
||||
Kill();
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
Effects.SendLocationEffect(Location, Map, 0x352D, 16, 4);
|
||||
Effects.PlaySound(Location, Map, 0x364);
|
||||
|
||||
Effects.SendLocationParticles(EffectItem.Create(Location, Map, EffectItem.DefaultDuration), 0x3728, 1, 14, 0, 7, 9915, 0);
|
||||
|
||||
base.OnDelete();
|
||||
}
|
||||
|
||||
public override bool AutoDispel { get { return true; } }
|
||||
public override double AutoDispelChance { get { return 1.0; } }
|
||||
public override bool BardImmune { get { return true; } }
|
||||
public override bool Unprovokable { get { return true; } }
|
||||
public override bool Uncalmable { get { return true; } }
|
||||
public override Poison PoisonImmune { get { return Poison.Lethal; } }
|
||||
|
||||
public override int Meat { get { return 1; } }
|
||||
|
||||
public EffectSpawn(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();
|
||||
}
|
||||
}
|
||||
|
||||
private class EffectsTimer : Timer
|
||||
{
|
||||
private Direction m_Dir;
|
||||
private int m_I, m_IMax;
|
||||
private Point3DList m_Path;
|
||||
private Charydbis m_Mobile;
|
||||
|
||||
public EffectsTimer(Charydbis mobile, Point3DList path, Direction dir, int imax)
|
||||
: base(TimeSpan.FromSeconds(0.25), TimeSpan.FromSeconds(0.25))
|
||||
{
|
||||
m_Dir = dir;
|
||||
m_I = 1;
|
||||
m_IMax = imax;
|
||||
m_Path = path;
|
||||
m_Mobile = mobile;
|
||||
Priority = TimerPriority.FiftyMS;
|
||||
Start();
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Mobile.OnTick(m_Path, m_Dir, m_I);
|
||||
|
||||
if (m_I >= m_IMax)
|
||||
{
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
m_I++;
|
||||
}
|
||||
}
|
||||
|
||||
public void SpawnTentacle()
|
||||
{
|
||||
if (Combatant == null)
|
||||
{
|
||||
m_NextSpawn = DateTime.UtcNow + SpawnRate;
|
||||
return;
|
||||
}
|
||||
|
||||
Map map = Map;
|
||||
|
||||
List<Mobile> list = new List<Mobile>();
|
||||
|
||||
IPooledEnumerable eable = GetMobilesInRange(15);
|
||||
foreach (Mobile m in eable)
|
||||
{
|
||||
if (m == this || !CanBeHarmful(m))
|
||||
continue;
|
||||
|
||||
if (m is BaseCreature && (((BaseCreature)m).Controlled || ((BaseCreature)m).Summoned || ((BaseCreature)m).Team != Team))
|
||||
list.Add(m);
|
||||
else if (m.Player)
|
||||
list.Add(m);
|
||||
}
|
||||
eable.Free();
|
||||
|
||||
if (list.Count > 0)
|
||||
{
|
||||
Mobile spawn = list[Utility.Random(list.Count)];
|
||||
BaseBoat boat = BaseBoat.FindBoatAt(spawn, map);
|
||||
Point3D loc = spawn.Location;
|
||||
|
||||
for (int i = 0; i < 25; i++)
|
||||
{
|
||||
Point3D spawnLoc = Point3D.Zero;
|
||||
|
||||
if (boat != null)
|
||||
spawnLoc = GetValidPoint(boat, map, 4);
|
||||
else
|
||||
{
|
||||
int y = Utility.RandomMinMax(loc.X - 10, loc.Y + 10);
|
||||
int x = Utility.RandomMinMax(loc.X - 10, loc.Y + 10);
|
||||
int z = map.GetAverageZ(x, y);
|
||||
|
||||
spawnLoc = new Point3D(x, y, z);
|
||||
}
|
||||
|
||||
if (Spells.SpellHelper.CheckMulti(spawnLoc, map))
|
||||
continue;
|
||||
|
||||
LandTile t = map.Tiles.GetLandTile(spawnLoc.X, spawnLoc.Y);
|
||||
|
||||
if (IsSeaTile(t) && spawnLoc != Point3D.Zero)
|
||||
{
|
||||
GiantTentacle tent = new GiantTentacle(this);
|
||||
|
||||
tent.MoveToWorld(spawnLoc, map);
|
||||
tent.Home = tent.Location;
|
||||
tent.RangeHome = 15;
|
||||
tent.Team = Team;
|
||||
if (spawn != this)
|
||||
tent.Combatant = spawn;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
m_NextSpawn = DateTime.UtcNow + SpawnRate;
|
||||
}
|
||||
|
||||
public bool IsSeaTile(LandTile t)
|
||||
{
|
||||
return t.Z == -5 && ((t.ID >= 0xA8 && t.ID <= 0xAB) || (t.ID >= 0x136 && t.ID <= 0x137));
|
||||
}
|
||||
|
||||
public override bool OnBeforeDeath()
|
||||
{
|
||||
if (Map == Map.Internal)
|
||||
MoveToWorld(m_LastLocation, m_LastMap);
|
||||
|
||||
if (CharydbisSpawner.SpawnInstance != null && CharydbisSpawner.SpawnInstance.Charydbis == this)
|
||||
CharydbisSpawner.SpawnInstance.OnCharybdisKilled();
|
||||
|
||||
return base.OnBeforeDeath();
|
||||
}
|
||||
|
||||
public override void OnDeath(Container c)
|
||||
{
|
||||
base.OnDeath(c);
|
||||
|
||||
int drop = Utility.RandomMinMax(2, 5);
|
||||
|
||||
for (int i = 0; i < drop; i++)
|
||||
{
|
||||
Type pieType = m_Pies[Utility.Random(m_Pies.Length)];
|
||||
|
||||
Item pie = Loot.Construct(pieType);
|
||||
|
||||
if (pie != null)
|
||||
c.DropItem(pie);
|
||||
}
|
||||
|
||||
drop = Utility.RandomMinMax(2, 5);
|
||||
|
||||
for (int i = 0; i < drop; i++)
|
||||
{
|
||||
Type steakType = m_Steaks[Utility.Random(m_Steaks.Length)];
|
||||
|
||||
Item steak = Loot.Construct(steakType);
|
||||
|
||||
if (steak != null)
|
||||
c.DropItem(steak);
|
||||
}
|
||||
|
||||
c.DropItem(new MessageInABottle(c.Map));
|
||||
c.DropItem(new SpecialFishingNet());
|
||||
c.DropItem(new SpecialFishingNet());
|
||||
c.DropItem(new SpecialFishingNet());
|
||||
c.DropItem(new SpecialFishingNet());
|
||||
|
||||
FishingPole pole = new FishingPole();
|
||||
BaseRunicTool.ApplyAttributesTo(pole, false, 0, Utility.RandomMinMax(2, 5), 50, 100);
|
||||
c.DropItem(pole);
|
||||
|
||||
#region TOL
|
||||
if (Core.TOL)
|
||||
SkillMasteryPrimer.CheckPrimerDrop(this);
|
||||
#endregion
|
||||
}
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
if (m_Tentacles != null)
|
||||
{
|
||||
List<Mobile> tents = new List<Mobile>(m_Tentacles);
|
||||
for (int i = 0; i < tents.Count; i++)
|
||||
{
|
||||
if (tents[i] != null)
|
||||
tents[i].Kill();
|
||||
}
|
||||
}
|
||||
|
||||
base.Delete();
|
||||
}
|
||||
|
||||
private Type[] m_Pies = new Type[]
|
||||
{
|
||||
typeof(AutumnDragonfishPie),
|
||||
typeof(BlueLobsterPie),
|
||||
typeof(BullFishPie),
|
||||
typeof(CrystalFishPie),
|
||||
typeof(FairySalmonPie),
|
||||
typeof(FireFishPie),
|
||||
typeof(GiantKoiPie),
|
||||
typeof(GreatBarracudaPie),
|
||||
typeof(HolyMackerelPie),
|
||||
typeof(LavaFishPie),
|
||||
typeof(ReaperFishPie),
|
||||
typeof(SpiderCrabPie),
|
||||
typeof(StoneCrabPie),
|
||||
typeof(SummerDragonfishPie),
|
||||
typeof(UnicornFishPie),
|
||||
typeof(YellowtailBarracudaPie),
|
||||
};
|
||||
|
||||
private Type[] m_Steaks = new Type[]
|
||||
{
|
||||
typeof(AutumnDragonfishSteak),
|
||||
typeof(BlueLobsterMeat),
|
||||
typeof(BullFishSteak),
|
||||
typeof(CrystalFishSteak),
|
||||
typeof(FairySalmonSteak),
|
||||
typeof(FireFishSteak),
|
||||
typeof(GiantKoiSteak),
|
||||
typeof(GreatBarracudaSteak),
|
||||
typeof(HolyMackerelSteak),
|
||||
typeof(LavaFishSteak),
|
||||
typeof(ReaperFishSteak),
|
||||
typeof(SpiderCrabMeat),
|
||||
typeof(StoneCrabMeat),
|
||||
typeof(SummerDragonfishSteak),
|
||||
typeof(UnicornFishSteak),
|
||||
typeof(YellowtailBarracudaSteak),
|
||||
};
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot(LootPack.SuperBoss, 8);
|
||||
}
|
||||
|
||||
public Charydbis(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0);
|
||||
|
||||
writer.Write(m_Tentacles.Count);
|
||||
foreach (Mobile tent in m_Tentacles)
|
||||
writer.Write(tent);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
int cnt = reader.ReadInt();
|
||||
for (int i = 0; i < cnt; i++)
|
||||
{
|
||||
Mobile tent = reader.ReadMobile();
|
||||
if (tent != null && !tent.Deleted && tent.Alive)
|
||||
m_Tentacles.Add(tent);
|
||||
}
|
||||
|
||||
m_NextSpawn = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
|
||||
public class GiantTentacle : BaseCreature
|
||||
{
|
||||
private Mobile m_Master;
|
||||
|
||||
public GiantTentacle(Mobile master) : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4)
|
||||
{
|
||||
if (master is Charydbis)
|
||||
{
|
||||
m_Master = master;
|
||||
((Charydbis)master).AddTentacle(this);
|
||||
}
|
||||
|
||||
Name = "a giant tentacle";
|
||||
Body = 1245;
|
||||
BaseSoundID = 0x161;
|
||||
|
||||
CanSwim = true;
|
||||
|
||||
SetStr(127, 155);
|
||||
SetDex(66, 85);
|
||||
SetInt(102, 123);
|
||||
|
||||
SetHits(105, 113);
|
||||
|
||||
SetDamage(10, 15);
|
||||
|
||||
SetDamageType(ResistanceType.Physical, 50);
|
||||
SetDamageType(ResistanceType.Cold, 50);
|
||||
|
||||
SetResistance(ResistanceType.Physical, 35, 45);
|
||||
SetResistance(ResistanceType.Fire, 10, 25);
|
||||
SetResistance(ResistanceType.Cold, 10, 25);
|
||||
SetResistance(ResistanceType.Poison, 60, 70);
|
||||
SetResistance(ResistanceType.Energy, 5, 10);
|
||||
|
||||
SetSkill(SkillName.Wrestling, 52.0, 70.0);
|
||||
SetSkill(SkillName.Tactics, 0.0);
|
||||
SetSkill(SkillName.MagicResist, 100.4, 113.5);
|
||||
SetSkill(SkillName.Anatomy, 1.0, 0.0);
|
||||
SetSkill(SkillName.Magery, 60.2, 72.4);
|
||||
SetSkill(SkillName.EvalInt, 60.1, 73.4);
|
||||
SetSkill(SkillName.Meditation, 100.0);
|
||||
|
||||
Fame = 2500;
|
||||
Karma = -2500;
|
||||
|
||||
if (IsSoulboundEnemies)
|
||||
IsSoulbound = true;
|
||||
}
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot(LootPack.FilthyRich, 1);
|
||||
}
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
if (m_Master != null && m_Master is Charydbis)
|
||||
((Charydbis)m_Master).RemoveTentacle(this);
|
||||
|
||||
base.Delete();
|
||||
}
|
||||
|
||||
public GiantTentacle(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0);
|
||||
|
||||
writer.Write(m_Master);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
m_Master = reader.ReadMobile();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
using Server;
|
||||
using System;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class BoundSoul : BaseCreature
|
||||
{
|
||||
public override bool AlwaysMurderer { get { return true; } }
|
||||
|
||||
public BoundSoul()
|
||||
: base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4)
|
||||
{
|
||||
Name = "a bound soul";
|
||||
Body = 0x3CA;
|
||||
Hue = 0x4001;
|
||||
|
||||
SetStr(150, 180);
|
||||
SetDex(120, 150);
|
||||
SetInt(20, 40);
|
||||
|
||||
SetHits(600, 620);
|
||||
|
||||
SetDamage(17, 22);
|
||||
|
||||
SetDamageType(ResistanceType.Physical, 10);
|
||||
SetDamageType(ResistanceType.Cold, 30);
|
||||
SetDamageType(ResistanceType.Poison, 30);
|
||||
SetDamageType(ResistanceType.Energy, 30);
|
||||
|
||||
SetResistance(ResistanceType.Physical, 80, 95);
|
||||
SetResistance(ResistanceType.Fire, 30, 40);
|
||||
SetResistance(ResistanceType.Cold, 20, 30);
|
||||
SetResistance(ResistanceType.Poison, 70, 80);
|
||||
SetResistance(ResistanceType.Energy, 30, 40);
|
||||
|
||||
SetSkill(SkillName.Wrestling, 100.0, 110.0);
|
||||
SetSkill(SkillName.Tactics, 110.0);
|
||||
SetSkill(SkillName.MagicResist, 100.0, 115.0);
|
||||
|
||||
Fame = 5000;
|
||||
Karma = -5000;
|
||||
}
|
||||
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot(LootPack.FilthyRich, 3);
|
||||
}
|
||||
|
||||
public BoundSoul(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int TreasureMapLevel { get { return 3; } }
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,508 @@
|
||||
using Server;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Items;
|
||||
using Server.Misc;
|
||||
using Server.Regions;
|
||||
using System.Linq;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class CorgulTheSoulBinder : BaseSeaChampion
|
||||
{
|
||||
private DateTime m_NextDismount;
|
||||
private DateTime m_NextArea;
|
||||
private DateTime m_NextReturn;
|
||||
private bool m_HasDone2ndSpawn;
|
||||
private CorgulAltar m_Altar;
|
||||
private List<BaseCreature> m_Helpers = new List<BaseCreature>();
|
||||
|
||||
public override bool CanDamageBoats { get { return false; } }
|
||||
public override bool TaintedLifeAura { get { return true; } }
|
||||
public override int Meat { get { return 5; } }
|
||||
public override double TreasureMapChance { get { return .25; } }
|
||||
public override int TreasureMapLevel { get { return 7; } }
|
||||
public override Poison PoisonImmune { get { return Poison.Deadly; } }
|
||||
|
||||
public override bool TeleportsTo { get { return true; } }
|
||||
public override TimeSpan TeleportDuration { get { return TimeSpan.FromSeconds(Utility.RandomMinMax(10, 50)); } }
|
||||
public override double TeleportProb { get { return 1.0; } }
|
||||
public override bool TeleportsPets { get { return true; } }
|
||||
|
||||
public override Type[] UniqueList { get { return new Type[] { typeof(CorgulsEnchantedSash), typeof(CorgulsHandbookOnMysticism), typeof(CorgulsHandbookOnTheUndead) }; } }
|
||||
public override Type[] SharedList { get { return new Type[] { typeof(HelmOfVengence), typeof(RingOfTheSoulbinder), typeof(RuneEngravedPegLeg), typeof(CullingBlade) }; } }
|
||||
public override Type[] DecorativeList { get { return new Type[] { typeof(EnchantedBladeDeed), typeof(EnchantedVortexDeed) }; } }
|
||||
|
||||
public override bool NoGoodies { get { return true; } }
|
||||
public override bool CanGivePowerscrolls { get { return false; } }
|
||||
|
||||
private readonly int _SpawnPerLoc = 15;
|
||||
|
||||
private Point3D[] _SpawnLocs =
|
||||
{
|
||||
new Point3D(6447, 1262, 10),
|
||||
new Point3D(6424, 1279, 10),
|
||||
new Point3D(6406, 1250, 10),
|
||||
new Point3D(6423, 1220, 10),
|
||||
new Point3D(6461, 1237, 10),
|
||||
};
|
||||
|
||||
[Constructable]
|
||||
public CorgulTheSoulBinder()
|
||||
: this(null)
|
||||
{
|
||||
}
|
||||
|
||||
public CorgulTheSoulBinder(CorgulAltar altar)
|
||||
: base(null, AIType.AI_NecroMage, FightMode.Closest)
|
||||
{
|
||||
m_Altar = altar;
|
||||
Name = "Corgul the Soulbinder";
|
||||
BaseSoundID = 609;
|
||||
Body = 0x4C;
|
||||
Hue = 2076;
|
||||
|
||||
m_NextDismount = DateTime.UtcNow;
|
||||
m_NextArea = DateTime.UtcNow;
|
||||
m_HasDone2ndSpawn = false;
|
||||
|
||||
SetStr(800, 900);
|
||||
SetDex(121, 165);
|
||||
SetInt(300, 400);
|
||||
|
||||
SetMana(4500);
|
||||
SetHits(65000);
|
||||
|
||||
SetDamage(19, 24);
|
||||
|
||||
SetDamageType(ResistanceType.Physical, 10);
|
||||
SetDamageType(ResistanceType.Fire, 10);
|
||||
SetDamageType(ResistanceType.Cold, 30);
|
||||
SetDamageType(ResistanceType.Poison, 40);
|
||||
SetDamageType(ResistanceType.Energy, 10);
|
||||
|
||||
SetResistance(ResistanceType.Physical, 50, 60);
|
||||
SetResistance(ResistanceType.Fire, 80, 90);
|
||||
SetResistance(ResistanceType.Cold, 85, 95);
|
||||
SetResistance(ResistanceType.Poison, 80, 90);
|
||||
SetResistance(ResistanceType.Energy, 80, 90);
|
||||
|
||||
SetSkill(SkillName.Wrestling, 110.0, 120.0);
|
||||
SetSkill(SkillName.Tactics, 110.0, 120.0);
|
||||
SetSkill(SkillName.Magery, 110.9, 120.0);
|
||||
SetSkill(SkillName.EvalInt, 110.9, 120.0);
|
||||
SetSkill(SkillName.Meditation, 110.9, 120.0);
|
||||
SetSkill(SkillName.Necromancy, 110.9, 120.0);
|
||||
SetSkill(SkillName.SpiritSpeak, 110.9, 120.0);
|
||||
|
||||
Fame = 25000;
|
||||
Karma = -25000;
|
||||
|
||||
m_NextReturn = DateTime.UtcNow + TimeSpan.FromSeconds(Utility.RandomMinMax(120, 180));
|
||||
|
||||
if (IsSoulboundEnemies)
|
||||
IsSoulbound = true;
|
||||
}
|
||||
|
||||
public double SharedChance { get { return Map != null && Map.Rules == MapRules.FeluccaRules ? .12 : .08; } }
|
||||
public double DecorativeChance { get { return Map != null && Map.Rules == MapRules.FeluccaRules ? .40 : .25; } }
|
||||
|
||||
public override bool OnBeforeDeath()
|
||||
{
|
||||
List<DamageStore> rights = GetLootingRights();
|
||||
|
||||
Mobile winner = null;
|
||||
|
||||
if (rights != null && rights.Count > 0)
|
||||
{
|
||||
rights.Sort();
|
||||
|
||||
if(rights.Count >= 5)
|
||||
winner = rights[Utility.Random(5)].m_Mobile;
|
||||
else if(rights.Count > 1)
|
||||
winner = rights[Utility.Random(rights.Count)].m_Mobile;
|
||||
else
|
||||
winner = rights[0].m_Mobile;
|
||||
}
|
||||
|
||||
if(winner != null)
|
||||
GiveArtifact(winner, CreateArtifact(UniqueList));
|
||||
|
||||
if (IsSoulboundEnemies)
|
||||
EtherealSandShower.Do(Location, Map, 50, 100, 500);
|
||||
|
||||
return base.OnBeforeDeath();
|
||||
}
|
||||
|
||||
public override Item GetArtifact()
|
||||
{
|
||||
double random = Utility.RandomDouble();
|
||||
|
||||
if (SharedChance >= random)
|
||||
return CreateArtifact(SharedList);
|
||||
else if (DecorativeChance >= random)
|
||||
return CreateArtifact(DecorativeList);
|
||||
return null;
|
||||
}
|
||||
|
||||
public void SpawnHelpers()
|
||||
{
|
||||
foreach (var pnt in _SpawnLocs)
|
||||
{
|
||||
for (int i = 0; i < _SpawnPerLoc; i++)
|
||||
{
|
||||
BaseCreature bc;
|
||||
|
||||
switch (Utility.Random(7))
|
||||
{
|
||||
default:
|
||||
case 0: bc = new BoundSoul(); break;
|
||||
case 1: bc = new SoulboundApprenticeMage(); break;
|
||||
case 2: bc = new SoulboundBattleMage(); break;
|
||||
case 3: bc = new SoulboundPirateCaptain(); break;
|
||||
case 4: bc = new SoulboundPirateRaider(); break;
|
||||
case 5: bc = new SoulboundSpellSlinger(); break;
|
||||
case 6: bc = new SoulboundSwashbuckler(); break;
|
||||
}
|
||||
|
||||
m_Helpers.Add(bc);
|
||||
SpawnMobile(bc, pnt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SpawnMobile(BaseCreature bc, Point3D p)
|
||||
{
|
||||
if(Map == null || bc == null)
|
||||
{
|
||||
if(bc != null)
|
||||
bc.Delete();
|
||||
return;
|
||||
}
|
||||
|
||||
int x, y, z = 0;
|
||||
|
||||
for(int i = 0; i < 25; i++)
|
||||
{
|
||||
x = Utility.RandomMinMax(p.X - 4, p.X + 4);
|
||||
y = Utility.RandomMinMax(p.Y - 4, p.Y + 4);
|
||||
z = Map.GetAverageZ(x, y);
|
||||
|
||||
if (Map.CanSpawnMobile(x, y, z))
|
||||
{
|
||||
p = new Point3D(x, y, z);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bc.MoveToWorld(p, Map);
|
||||
bc.Home = p;
|
||||
bc.RangeHome = 5;
|
||||
}
|
||||
|
||||
public override void OnThink()
|
||||
{
|
||||
base.OnThink();
|
||||
|
||||
if (m_NextReturn < DateTime.UtcNow)
|
||||
{
|
||||
Point3D p = CorgulAltar.SpawnLoc;
|
||||
|
||||
if (Region.IsPartOf<CorgulRegion>() && !Utility.InRange(Location, p, 15))
|
||||
{
|
||||
PlaySound(0x1FE);
|
||||
FixedParticles(0x376A, 9, 32, 0x13AF, EffectLayer.Waist);
|
||||
|
||||
Location = p;
|
||||
ProcessDelta();
|
||||
|
||||
PlaySound(0x1FE);
|
||||
FixedParticles(0x376A, 9, 32, 0x13AF, EffectLayer.Waist);
|
||||
|
||||
m_NextReturn = DateTime.UtcNow + TimeSpan.FromSeconds(Utility.RandomMinMax(120, 180));
|
||||
}
|
||||
}
|
||||
|
||||
if (Combatant == null)
|
||||
return;
|
||||
|
||||
if (DateTime.UtcNow > m_NextDismount && 0.1 > Utility.RandomDouble())
|
||||
DoDismount();
|
||||
|
||||
else if (DateTime.UtcNow > m_NextArea && 0.1 > Utility.RandomDouble())
|
||||
DoAreaAttack();
|
||||
|
||||
if (!m_HasDone2ndSpawn && m_Helpers.Count > 0)
|
||||
{
|
||||
if (m_Helpers.Where(bc => bc.Alive && !bc.Deleted).Count() == 0)
|
||||
{
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(5), SpawnHelpers);
|
||||
m_HasDone2ndSpawn = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DoDismount()
|
||||
{
|
||||
List<Mobile> targets = new List<Mobile>();
|
||||
|
||||
IPooledEnumerable eable = GetMobilesInRange(12);
|
||||
foreach (Mobile mob in eable)
|
||||
{
|
||||
if (!CanBeHarmful(mob) || mob == this)
|
||||
continue;
|
||||
if (mob is BaseCreature && (((BaseCreature)mob).Controlled || ((BaseCreature)mob).Summoned || ((BaseCreature)mob).Team != Team))
|
||||
targets.Add(mob);
|
||||
else if (mob is PlayerMobile && mob.Alive)
|
||||
targets.Add(mob);
|
||||
}
|
||||
eable.Free();
|
||||
|
||||
PlaySound(0x2F3);
|
||||
for (int i = 0; i < targets.Count; ++i)
|
||||
{
|
||||
Mobile m = (Mobile)targets[i];
|
||||
|
||||
if (m != null && !m.Deleted && m is PlayerMobile)
|
||||
{
|
||||
PlayerMobile pm = m as PlayerMobile;
|
||||
|
||||
if (pm != null && (pm.Mounted || pm.Flying))
|
||||
{
|
||||
pm.SetMountBlock(BlockMountType.DismountRecovery, TimeSpan.FromSeconds(10), true);
|
||||
}
|
||||
}
|
||||
|
||||
double damage = m.Hits * 0.6;
|
||||
if (damage < 10.0)
|
||||
damage = 10.0;
|
||||
else if (damage > 75.0)
|
||||
damage = 75.0;
|
||||
DoHarmful(m);
|
||||
AOS.Damage(m, this, (int)damage, 100, 0, 0, 0, 0);
|
||||
if (m.Alive && m.Body.IsHuman && !m.Mounted)
|
||||
m.Animate(20, 7, 1, true, false, 0);
|
||||
}
|
||||
|
||||
|
||||
m_NextDismount = DateTime.UtcNow + TimeSpan.FromMinutes(2);
|
||||
}
|
||||
|
||||
public void DoAreaAttack()
|
||||
{
|
||||
int range = 18;
|
||||
|
||||
new InternalTimer(this, range);
|
||||
|
||||
IPooledEnumerable eable = GetMobilesInRange(range);
|
||||
foreach (Mobile m in eable)
|
||||
{
|
||||
if ((m is PlayerMobile || (m is BaseCreature && ((BaseCreature)m).GetMaster() is PlayerMobile)) && CanBeHarmful(m))
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(1), new TimerStateCallback(DoDamage_Callback), m);
|
||||
}
|
||||
eable.Free();
|
||||
|
||||
m_NextArea = DateTime.UtcNow + TimeSpan.FromSeconds(Utility.RandomMinMax(60, 180));
|
||||
}
|
||||
|
||||
public void DoDamage_Callback(object o)
|
||||
{
|
||||
Mobile m = (Mobile)o;
|
||||
|
||||
if (m != null)
|
||||
{
|
||||
DoHarmful(m);
|
||||
AOS.Damage(m, this, Utility.RandomMinMax(100, 150), 0, 100, 0, 0, 0);
|
||||
|
||||
if (Utility.RandomBool())
|
||||
{
|
||||
WeaponAbility bleed = WeaponAbility.BleedAttack;
|
||||
bleed.OnHit(this, m, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DoEffect(Point3D p, Map map)
|
||||
{
|
||||
int[] effect = new int[] { 14000, 14013 };
|
||||
Effects.PlaySound(p, map, 0x307);
|
||||
Effects.SendLocationEffect(p, map, Utility.RandomBool() ? 14000 : 14013, 20);
|
||||
}
|
||||
|
||||
private class InternalTimer : Timer
|
||||
{
|
||||
private CorgulTheSoulBinder m_Mobile;
|
||||
private int m_Tick;
|
||||
|
||||
public InternalTimer(CorgulTheSoulBinder mob, int range)
|
||||
: base(TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(100), range)
|
||||
{
|
||||
m_Tick = 1;
|
||||
m_Mobile = mob;
|
||||
Priority = TimerPriority.FiftyMS;
|
||||
Start();
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
Geometry.Circle2D(m_Mobile.Location, m_Mobile.Map, m_Tick, new DoEffect_Callback(m_Mobile.DoEffect));
|
||||
|
||||
m_Tick++;
|
||||
}
|
||||
}
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot(LootPack.SuperBoss, 6);
|
||||
}
|
||||
|
||||
public override void OnDeath(Container c)
|
||||
{
|
||||
base.OnDeath(c);
|
||||
|
||||
if (m_Altar != null)
|
||||
m_Altar.OnBossKilled();
|
||||
|
||||
c.DropItem(new MessageInABottle(c.Map));
|
||||
c.DropItem(new SpecialFishingNet());
|
||||
c.DropItem(new SpecialFishingNet());
|
||||
|
||||
if (m_Helpers != null)
|
||||
{
|
||||
foreach (BaseCreature bc in m_Helpers)
|
||||
{
|
||||
RegisterDamageTo(bc);
|
||||
|
||||
if (bc != null && bc.Alive)
|
||||
bc.Kill();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CorgulTheSoulBinder(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)1);
|
||||
writer.Write(m_HasDone2ndSpawn);
|
||||
writer.Write(m_Altar);
|
||||
writer.Write(m_Helpers.Count);
|
||||
foreach (BaseCreature bc in m_Helpers)
|
||||
writer.Write(bc);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
m_HasDone2ndSpawn = reader.ReadBool();
|
||||
goto case 0;
|
||||
case 0:
|
||||
m_Altar = reader.ReadItem() as CorgulAltar;
|
||||
|
||||
int cnt = reader.ReadInt();
|
||||
for (int i = 0; i < cnt; i++)
|
||||
{
|
||||
BaseCreature bc = reader.ReadMobile() as BaseCreature;
|
||||
if (bc != null)
|
||||
m_Helpers.Add(bc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
m_NextDismount = DateTime.UtcNow;
|
||||
m_NextArea = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
|
||||
public class EtherealSandShower
|
||||
{
|
||||
public static void Do(Point3D center, Map map, int piles, int minAmount, int maxAmount)
|
||||
{
|
||||
new GoodiesTimer(center, map, piles, minAmount, maxAmount).Start();
|
||||
}
|
||||
|
||||
private class GoodiesTimer : Timer
|
||||
{
|
||||
private readonly Map m_Map;
|
||||
private readonly Point3D m_Location;
|
||||
private readonly int m_PilesMax;
|
||||
private int m_PilesDone = 0;
|
||||
private readonly int m_MinAmount;
|
||||
private readonly int m_MaxAmount;
|
||||
|
||||
public GoodiesTimer(Point3D center, Map map, int piles, int minAmount, int maxAmount)
|
||||
: base(TimeSpan.FromSeconds(0.25d), TimeSpan.FromSeconds(0.25d))
|
||||
{
|
||||
m_Location = center;
|
||||
m_Map = map;
|
||||
m_PilesMax = piles;
|
||||
m_MinAmount = minAmount;
|
||||
m_MaxAmount = maxAmount;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if (m_PilesDone >= m_PilesMax)
|
||||
{
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
Point3D p = FindGoldLocation(m_Map, m_Location, m_PilesMax / 8);
|
||||
EtherealSand g = new EtherealSand(m_MinAmount, m_MaxAmount);
|
||||
g.MoveToWorld(p, m_Map);
|
||||
|
||||
switch (Utility.Random(3))
|
||||
{
|
||||
case 0: // Fire column
|
||||
Effects.SendLocationParticles(EffectItem.Create(g.Location, g.Map, EffectItem.DefaultDuration), 0x3709, 10, 30, 5052);
|
||||
Effects.PlaySound(g, g.Map, 0x208);
|
||||
break;
|
||||
case 1: // Explosion
|
||||
Effects.SendLocationParticles(EffectItem.Create(g.Location, g.Map, EffectItem.DefaultDuration), 0x36BD, 20, 10, 5044);
|
||||
Effects.PlaySound(g, g.Map, 0x307);
|
||||
break;
|
||||
case 2: // Ball of fire
|
||||
Effects.SendLocationParticles(EffectItem.Create(g.Location, g.Map, EffectItem.DefaultDuration), 0x36FE, 10, 10, 5052);
|
||||
break;
|
||||
}
|
||||
++m_PilesDone;
|
||||
}
|
||||
|
||||
private static Point3D FindGoldLocation(Map map, Point3D center, int range)
|
||||
{
|
||||
int cx = center.X;
|
||||
int cy = center.Y;
|
||||
|
||||
for (int i = 0; i < 20; ++i)
|
||||
{
|
||||
int x = cx + Utility.Random(range * 2) - range;
|
||||
int y = cy + Utility.Random(range * 2) - range;
|
||||
if ((cx - x) * (cx - x) + (cy - y) * (cy - y) > range * range)
|
||||
continue;
|
||||
|
||||
int z = map.GetAverageZ(x, y);
|
||||
if (!map.CanFit(x, y, z, 6, false, false))
|
||||
continue;
|
||||
|
||||
int topZ = z;
|
||||
foreach (Item item in map.GetItemsInRange(new Point3D(x, y, z), 0))
|
||||
{
|
||||
topZ = Math.Max(topZ, item.Z + item.ItemData.CalcHeight);
|
||||
}
|
||||
return new Point3D(x, y, topZ);
|
||||
}
|
||||
return center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using Server;
|
||||
using System;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class SoulboundApprenticeMage : EvilMage
|
||||
{
|
||||
[Constructable]
|
||||
public SoulboundApprenticeMage()
|
||||
{
|
||||
Title = "the soulbound apprentice mage";
|
||||
|
||||
SetStr(115);
|
||||
SetDex(97);
|
||||
SetInt(106);
|
||||
|
||||
SetHits(128);
|
||||
SetMana(210);
|
||||
|
||||
SetDamage(5, 10);
|
||||
|
||||
SetDamageType(ResistanceType.Physical, 100);
|
||||
|
||||
SetResistance(ResistanceType.Physical, 20);
|
||||
SetResistance(ResistanceType.Fire, 21);
|
||||
SetResistance(ResistanceType.Cold, 22);
|
||||
SetResistance(ResistanceType.Poison, 20);
|
||||
SetResistance(ResistanceType.Energy, 25);
|
||||
|
||||
SetSkill(SkillName.Wrestling, 40.0, 50.0);
|
||||
SetSkill(SkillName.MagicResist, 40.0, 50.0);
|
||||
SetSkill(SkillName.Magery, 60.2, 72.4);
|
||||
SetSkill(SkillName.EvalInt, 60.1, 73.4);
|
||||
SetSkill(SkillName.Meditation, 40.0, 50.0);
|
||||
|
||||
Fame = 1000;
|
||||
Karma = -1000;
|
||||
}
|
||||
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot(LootPack.Rich, 3);
|
||||
}
|
||||
|
||||
public SoulboundApprenticeMage(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
using Server;
|
||||
using System;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class SoulboundBattleMage : EvilMageLord
|
||||
{
|
||||
[Constructable]
|
||||
public SoulboundBattleMage()
|
||||
{
|
||||
Title = "the soulbound battle mage";
|
||||
|
||||
SetStr(156);
|
||||
SetDex(101);
|
||||
SetInt(181);
|
||||
|
||||
SetHits(419);
|
||||
SetMana(619);
|
||||
|
||||
SetDamage(12, 17);
|
||||
|
||||
SetDamageType(ResistanceType.Physical, 20);
|
||||
SetDamageType(ResistanceType.Fire, 20);
|
||||
SetDamageType(ResistanceType.Cold, 20);
|
||||
SetDamageType(ResistanceType.Poison, 20);
|
||||
SetDamageType(ResistanceType.Energy, 20);
|
||||
|
||||
SetResistance(ResistanceType.Physical, 50, 60);
|
||||
SetResistance(ResistanceType.Fire, 50, 60);
|
||||
SetResistance(ResistanceType.Cold, 50, 60);
|
||||
SetResistance(ResistanceType.Poison, 50, 60);
|
||||
SetResistance(ResistanceType.Energy, 50, 60);
|
||||
|
||||
SetSkill(SkillName.Wrestling, 120.0, 125.0);
|
||||
SetSkill(SkillName.Tactics, 110.0, 120.0);
|
||||
SetSkill(SkillName.MagicResist, 100.0, 110.0);
|
||||
SetSkill(SkillName.Anatomy, 1.0, 0.0);
|
||||
SetSkill(SkillName.Magery, 105.0, 110.0);
|
||||
SetSkill(SkillName.EvalInt, 95.0, 100.0);
|
||||
SetSkill(SkillName.Meditation, 20.0, 30.0);
|
||||
|
||||
Fame = 5000;
|
||||
Karma = -5000;
|
||||
}
|
||||
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot(LootPack.FilthyRich, 3);
|
||||
}
|
||||
|
||||
public SoulboundBattleMage(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
using Server;
|
||||
using System;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class SoulboundPirateCaptain : BaseCreature
|
||||
{
|
||||
public override bool ClickTitle { get { return false; } }
|
||||
public override bool AlwaysMurderer { get { return true; } }
|
||||
|
||||
public SoulboundPirateCaptain()
|
||||
: base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4)
|
||||
{
|
||||
Name = "a soulbound pirate captain";
|
||||
Body = 0x190;
|
||||
Hue = Utility.RandomSkinHue();
|
||||
Utility.AssignRandomHair(this);
|
||||
|
||||
SetStr(150, 200);
|
||||
SetDex(150);
|
||||
SetInt(95, 110);
|
||||
|
||||
SetHits(450, 600);
|
||||
|
||||
SetDamage(20, 28);
|
||||
|
||||
SetDamageType(ResistanceType.Physical, 100);
|
||||
|
||||
SetResistance(ResistanceType.Physical, 45, 55);
|
||||
SetResistance(ResistanceType.Fire, 45, 55);
|
||||
SetResistance(ResistanceType.Cold, 45, 55);
|
||||
SetResistance(ResistanceType.Poison, 45, 55);
|
||||
SetResistance(ResistanceType.Energy, 45, 55);
|
||||
|
||||
SetSkill(SkillName.MagicResist, 100.0, 120.0);
|
||||
SetSkill(SkillName.Swords, 110.0, 120.0);
|
||||
SetSkill(SkillName.Tactics, 110.0, 120.0);
|
||||
SetSkill(SkillName.Anatomy, 110.0, 120.0);
|
||||
|
||||
Fame = 8000;
|
||||
Karma = -8000;
|
||||
|
||||
AddItem(new TricorneHat(1));
|
||||
AddItem(new LeatherArms());
|
||||
AddItem(new FancyShirt(1));
|
||||
AddItem(new ShortPants(1));
|
||||
AddItem(new Cutlass());
|
||||
AddItem(new Boots(Utility.RandomNeutralHue()));
|
||||
AddItem(new GoldEarrings());
|
||||
|
||||
}
|
||||
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot(LootPack.UltraRich, 3);
|
||||
}
|
||||
|
||||
public SoulboundPirateCaptain(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
using Server;
|
||||
using System;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class SoulboundPirateRaider : BaseCreature
|
||||
{
|
||||
public override bool ClickTitle { get { return false; } }
|
||||
public override bool AlwaysMurderer { get { return true; } }
|
||||
|
||||
public override WeaponAbility GetWeaponAbility()
|
||||
{
|
||||
Item weapon = FindItemOnLayer(Layer.TwoHanded);
|
||||
|
||||
if (weapon == null)
|
||||
return null;
|
||||
|
||||
if (weapon is BaseWeapon)
|
||||
{
|
||||
if (Utility.RandomBool())
|
||||
return ((BaseWeapon)weapon).PrimaryAbility;
|
||||
else
|
||||
return ((BaseWeapon)weapon).SecondaryAbility;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public SoulboundPirateRaider()
|
||||
: base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4)
|
||||
{
|
||||
Name = "a soulbound pirate raider";
|
||||
Body = 0x190;
|
||||
Hue = Utility.RandomSkinHue();
|
||||
Utility.AssignRandomHair(this);
|
||||
|
||||
SetStr(150, 200);
|
||||
SetDex(125, 150);
|
||||
SetInt(95, 110);
|
||||
|
||||
SetHits(200, 250);
|
||||
|
||||
SetDamage(15, 25);
|
||||
|
||||
SetDamageType(ResistanceType.Physical, 100);
|
||||
|
||||
SetResistance(ResistanceType.Physical, 45, 55);
|
||||
SetResistance(ResistanceType.Fire, 45, 55);
|
||||
SetResistance(ResistanceType.Cold, 45, 55);
|
||||
SetResistance(ResistanceType.Poison, 45, 55);
|
||||
SetResistance(ResistanceType.Energy, 45, 55);
|
||||
|
||||
SetSkill(SkillName.MagicResist, 50.0, 75.5);
|
||||
SetSkill(SkillName.Archery, 90.0, 105.5);
|
||||
SetSkill(SkillName.Tactics, 90.0, 105.5);
|
||||
SetSkill(SkillName.Anatomy, 90.0, 105.5);
|
||||
|
||||
Fame = 2000;
|
||||
Karma = -2000;
|
||||
|
||||
AddItem(new TricorneHat());
|
||||
AddItem(new LeatherArms());
|
||||
AddItem(new FancyShirt());
|
||||
AddItem(new ShortPants());
|
||||
AddItem(new Cutlass());
|
||||
AddItem(new Boots(Utility.RandomNeutralHue()));
|
||||
AddItem(new GoldEarrings());
|
||||
|
||||
Item bow;
|
||||
|
||||
switch (Utility.Random(4))
|
||||
{
|
||||
default:
|
||||
case 0: bow = new CompositeBow(); PackItem(new Arrow(25)); break;
|
||||
case 1: bow = new Crossbow(); PackItem(new Bolt(25)); break;
|
||||
case 2: bow = new Bow(); PackItem(new Arrow(25)); break;
|
||||
case 3: bow = new HeavyCrossbow(); PackItem(new Bolt(25)); break;
|
||||
}
|
||||
|
||||
AddItem(bow);
|
||||
}
|
||||
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot(LootPack.FilthyRich, 2);
|
||||
}
|
||||
|
||||
public SoulboundPirateRaider(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using Server;
|
||||
using System;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class SoulboundSpellSlinger : EvilMageLord
|
||||
{
|
||||
[Constructable]
|
||||
public SoulboundSpellSlinger()
|
||||
{
|
||||
Title = "the soulbound spellslinger";
|
||||
|
||||
SetStr(120, 130);
|
||||
SetDex(90, 100);
|
||||
SetInt(120, 150);
|
||||
|
||||
SetHits(190, 200);
|
||||
SetMana(400, 500);
|
||||
|
||||
SetDamage(8, 12);
|
||||
|
||||
SetDamageType(ResistanceType.Physical, 100);
|
||||
|
||||
SetResistance(ResistanceType.Physical, 30, 40);
|
||||
SetResistance(ResistanceType.Fire, 30, 40);
|
||||
SetResistance(ResistanceType.Cold, 30, 40);
|
||||
SetResistance(ResistanceType.Poison, 30, 40);
|
||||
SetResistance(ResistanceType.Energy, 30, 40);
|
||||
|
||||
SetSkill(SkillName.Wrestling, 90.0, 100.0);
|
||||
SetSkill(SkillName.Tactics, 80.0, 90.0);
|
||||
SetSkill(SkillName.MagicResist, 90, 100.0);
|
||||
SetSkill(SkillName.Anatomy, 1.0, 0.0);
|
||||
SetSkill(SkillName.Magery, 100.0, 110.0);
|
||||
SetSkill(SkillName.EvalInt, 80.0, 90.0);
|
||||
SetSkill(SkillName.Meditation, 20.0, 30.0);
|
||||
|
||||
Fame = 3000;
|
||||
Karma = -3000;
|
||||
}
|
||||
|
||||
public override int TreasureMapLevel { get { return 3; } }
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot(LootPack.FilthyRich, 1);
|
||||
}
|
||||
|
||||
public SoulboundSpellSlinger(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using Server;
|
||||
using System;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class SoulboundSwashbuckler : BaseCreature
|
||||
{
|
||||
public override bool ClickTitle { get { return false; } }
|
||||
public override bool AlwaysMurderer { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public SoulboundSwashbuckler()
|
||||
: base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4)
|
||||
{
|
||||
Name = "a soulbound swashbuckler";
|
||||
Body = 0x190;
|
||||
Hue = Utility.RandomSkinHue();
|
||||
Utility.AssignRandomHair(this);
|
||||
|
||||
SetStr(120, 130);
|
||||
SetDex(105, 115);
|
||||
SetInt(95, 110);
|
||||
|
||||
SetHits(100, 125);
|
||||
|
||||
SetDamage(12, 18);
|
||||
|
||||
SetDamageType(ResistanceType.Physical, 100);
|
||||
|
||||
SetResistance(ResistanceType.Physical, 30, 40);
|
||||
SetResistance(ResistanceType.Fire, 30, 40);
|
||||
SetResistance(ResistanceType.Cold, 30, 40);
|
||||
SetResistance(ResistanceType.Poison, 30, 40);
|
||||
SetResistance(ResistanceType.Energy, 30, 40);
|
||||
|
||||
SetSkill(SkillName.MagicResist, 25.0, 47.5);
|
||||
SetSkill(SkillName.Swords, 65.0, 87.5);
|
||||
SetSkill(SkillName.Tactics, 65.0, 87.5);
|
||||
SetSkill(SkillName.Anatomy, 65.0, 87.5);
|
||||
|
||||
Fame = 2000;
|
||||
Karma = -2000;
|
||||
|
||||
AddItem(new Bandana());
|
||||
AddItem(new LeatherArms());
|
||||
AddItem(new FancyShirt());
|
||||
AddItem(new ShortPants());
|
||||
AddItem(new Cutlass());
|
||||
AddItem(new Boots(Utility.RandomNeutralHue()));
|
||||
AddItem(new SilverEarrings());
|
||||
|
||||
}
|
||||
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot(LootPack.FilthyRich, 1);
|
||||
}
|
||||
|
||||
public SoulboundSwashbuckler(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,374 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Multis;
|
||||
using System.Collections.Generic;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class Osiredon : BaseSeaChampion
|
||||
{
|
||||
public static readonly TimeSpan SpawnRate = TimeSpan.FromSeconds(30);
|
||||
public static readonly int SpawnMax = 25;
|
||||
|
||||
private List<Mobile> m_Eels = new List<Mobile>();
|
||||
private DateTime m_NextSpawn;
|
||||
private DateTime m_NextSpecial;
|
||||
private DateTime m_NextWaterBall;
|
||||
|
||||
public override bool CanDamageBoats { get { return true; } }
|
||||
public override bool TaintedLifeAura { get { return true; } }
|
||||
public override TimeSpan BoatDamageCooldown { get { return TimeSpan.FromSeconds(120); } }
|
||||
public override int MinBoatDamage { get { return 3; } }
|
||||
public override int MaxBoatDamage { get { return 8; } }
|
||||
public override int DamageRange { get { return 2; } }
|
||||
|
||||
public override int Meat { get { return 5; } }
|
||||
|
||||
public override ScaleType ScaleType { get { return ScaleType.All; } }
|
||||
public override int Scales { get { return 20; } }
|
||||
|
||||
public override double TreasureMapChance { get { return .50; } }
|
||||
public override int TreasureMapLevel { get { return 7; } }
|
||||
|
||||
public override Type[] UniqueList { get { return new Type[] { typeof(EnchantedCoralBracelet), typeof(WandOfThunderingGlory), typeof(LeviathanHideBracers), typeof(SmilingMoonBlade) }; } }
|
||||
public override Type[] SharedList { get { return new Type[] { typeof(MiniSoulForgeDeed) }; } }
|
||||
public override Type[] DecorativeList { get { return new Type[] { typeof(EnchantedBladeDeed), typeof(EnchantedVortexDeed) }; } }
|
||||
|
||||
public override bool NoGoodies { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public Osiredon()
|
||||
: this(null)
|
||||
{
|
||||
}
|
||||
|
||||
public Osiredon(Mobile fisher)
|
||||
: base(fisher, AIType.AI_NecroMage, FightMode.Closest)
|
||||
{
|
||||
Name = "osiredon the scalis enforcer";
|
||||
Body = 1068;
|
||||
BaseSoundID = 589;
|
||||
|
||||
Combatant = fisher;
|
||||
|
||||
m_NextSpawn = DateTime.UtcNow + SpawnRate;
|
||||
m_NextSpecial = DateTime.UtcNow;
|
||||
m_NextWaterBall = DateTime.UtcNow;
|
||||
|
||||
CanSwim = true;
|
||||
CantWalk = true;
|
||||
|
||||
SetStr(805, 900);
|
||||
SetDex(121, 165);
|
||||
SetInt(125, 137);
|
||||
|
||||
SetMana(4000);
|
||||
SetHits(75000);
|
||||
|
||||
SetDamage(19, 26);
|
||||
|
||||
SetDamageType(ResistanceType.Physical, 40);
|
||||
SetDamageType(ResistanceType.Cold, 30);
|
||||
SetDamageType(ResistanceType.Energy, 30);
|
||||
|
||||
SetResistance(ResistanceType.Physical, 80, 90);
|
||||
SetResistance(ResistanceType.Fire, 80, 90);
|
||||
SetResistance(ResistanceType.Cold, 85, 95);
|
||||
SetResistance(ResistanceType.Poison, 80, 90);
|
||||
SetResistance(ResistanceType.Energy, 80, 90);
|
||||
|
||||
SetSkill(SkillName.Wrestling, 122.9, 128.0);
|
||||
SetSkill(SkillName.Tactics, 127.7, 132.9);
|
||||
SetSkill(SkillName.MagicResist, 120.9, 129.4);
|
||||
SetSkill(SkillName.Necromancy, 122.9, 128.0);
|
||||
SetSkill(SkillName.SpiritSpeak, 160.1, 220.0);
|
||||
SetSkill(SkillName.Magery, 120.1, 129.4);
|
||||
SetSkill(SkillName.EvalInt, 100.1, 120.0);
|
||||
SetSkill(SkillName.DetectHidden, 100.0);
|
||||
|
||||
Fame = 25000;
|
||||
Karma = -25000;
|
||||
|
||||
if (IsSoulboundEnemies)
|
||||
IsSoulbound = true;
|
||||
}
|
||||
|
||||
public void AddEel(Mobile eel)
|
||||
{
|
||||
if (!m_Eels.Contains(eel) && eel is ParasiticEel)
|
||||
m_Eels.Add(eel);
|
||||
}
|
||||
|
||||
public void RemoveEel(Mobile eel)
|
||||
{
|
||||
if (m_Eels.Contains(eel))
|
||||
m_Eels.Remove(eel);
|
||||
}
|
||||
|
||||
public override void DoDamageBoat(BaseBoat boat)
|
||||
{
|
||||
DoAreaExplosion();
|
||||
base.DoDamageBoat(boat);
|
||||
}
|
||||
|
||||
public override void OnDamagedBySpell(Mobile from)
|
||||
{
|
||||
base.OnDamagedBySpell(from);
|
||||
|
||||
if (m_NextSpawn < DateTime.UtcNow && m_Eels.Count < SpawnMax && 0.25 > Utility.RandomDouble())
|
||||
SpawnEel(from);
|
||||
}
|
||||
|
||||
public override void OnGotMeleeAttack(Mobile attacker)
|
||||
{
|
||||
base.OnGotMeleeAttack(attacker);
|
||||
|
||||
if (attacker.Weapon is BaseRanged && m_NextSpawn < DateTime.UtcNow && m_Eels.Count < SpawnMax && 0.25 > Utility.RandomDouble())
|
||||
SpawnEel(attacker);
|
||||
}
|
||||
|
||||
public override void OnThink()
|
||||
{
|
||||
base.OnThink();
|
||||
|
||||
if (m_NextSpecial < DateTime.UtcNow)
|
||||
DoAreaExplosion();
|
||||
}
|
||||
|
||||
public override void OnActionCombat()
|
||||
{
|
||||
Mobile combatant = this.Combatant as Mobile;
|
||||
|
||||
if (combatant == null || combatant.Deleted || combatant.Map != this.Map || !this.InRange(combatant, 12) || !this.CanBeHarmful(combatant) || !this.InLOS(combatant))
|
||||
return;
|
||||
|
||||
if (DateTime.UtcNow >= this.m_NextWaterBall)
|
||||
{
|
||||
double damage = combatant.Hits * 0.3;
|
||||
|
||||
if (damage < 10.0)
|
||||
damage = 10.0;
|
||||
else if (damage > 40.0)
|
||||
damage = 40.0;
|
||||
|
||||
this.DoHarmful(combatant);
|
||||
this.MovingParticles(combatant, 0x36D4, 5, 0, false, false, 195, 0, 9502, 3006, 0, 0, 0);
|
||||
AOS.Damage(combatant, this, (int)damage, 100, 0, 0, 0, 0);
|
||||
|
||||
if (combatant is PlayerMobile && combatant.Mount != null)
|
||||
{
|
||||
(combatant as PlayerMobile).SetMountBlock(BlockMountType.DismountRecovery, TimeSpan.FromSeconds(10), true);
|
||||
}
|
||||
|
||||
m_NextWaterBall = DateTime.UtcNow + TimeSpan.FromMinutes(1);
|
||||
}
|
||||
}
|
||||
|
||||
public void SpawnEel(Mobile m)
|
||||
{
|
||||
Map map = this.Map;
|
||||
|
||||
int x = m.X; int y = m.Y; int z = m.Z;
|
||||
|
||||
Point3D loc = m.Location;
|
||||
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
for (int i = 0; i < 25; i++)
|
||||
{
|
||||
x = Utility.RandomMinMax(loc.X - 1, loc.X + 1);
|
||||
y = Utility.RandomMinMax(loc.Y - 1, loc.Y + 1);
|
||||
|
||||
if (Spells.SpellHelper.CheckMulti(new Point3D(x, y, m.Z), map) || map.CanSpawnMobile(x, y, z))
|
||||
{
|
||||
ParasiticEel eel = new ParasiticEel(this);
|
||||
eel.MoveToWorld(new Point3D(x, y, loc.Z), map);
|
||||
|
||||
if (m is PlayerMobile)
|
||||
eel.Combatant = m;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_NextSpawn = DateTime.UtcNow + SpawnRate;
|
||||
}
|
||||
|
||||
public void DoAreaExplosion()
|
||||
{
|
||||
List<Mobile> toExplode = new List<Mobile>();
|
||||
|
||||
IPooledEnumerable eable = this.GetMobilesInRange(8);
|
||||
foreach (Mobile mob in eable)
|
||||
{
|
||||
if (!CanBeHarmful(mob, false) || mob == this || (mob is BaseCreature && ((BaseCreature)mob).GetMaster() == this))
|
||||
continue;
|
||||
if (mob.Player)
|
||||
toExplode.Add(mob);
|
||||
if (mob is BaseCreature && (((BaseCreature)mob).Controlled || ((BaseCreature)mob).Summoned || ((BaseCreature)mob).Team != this.Team))
|
||||
toExplode.Add(mob);
|
||||
}
|
||||
eable.Free();
|
||||
|
||||
foreach (Mobile mob in toExplode)
|
||||
{
|
||||
mob.FixedParticles(0x36BD, 20, 10, 5044, EffectLayer.Head);
|
||||
mob.PlaySound(0x307);
|
||||
|
||||
int damage = Utility.RandomMinMax(50, 125);
|
||||
AOS.Damage(mob, this, damage, 0, 100, 0, 0, 0);
|
||||
}
|
||||
|
||||
m_NextSpecial = DateTime.UtcNow + TimeSpan.FromSeconds(Utility.RandomMinMax(15, 20));
|
||||
}
|
||||
|
||||
public override void OnDeath(Container c)
|
||||
{
|
||||
base.OnDeath(c);
|
||||
|
||||
FishingPole pole = new FishingPole();
|
||||
BaseRunicTool.ApplyAttributesTo(pole, false, 0, Utility.RandomMinMax(2, 5), 50, 100);
|
||||
c.DropItem(pole);
|
||||
|
||||
c.DropItem(new MessageInABottle(c.Map));
|
||||
c.DropItem(new SpecialFishingNet());
|
||||
c.DropItem(new SpecialFishingNet());
|
||||
|
||||
#region TOL
|
||||
if (Core.TOL)
|
||||
SkillMasteryPrimer.CheckPrimerDrop(this);
|
||||
#endregion
|
||||
}
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
if (m_Eels != null)
|
||||
{
|
||||
List<Mobile> eels = new List<Mobile>(m_Eels);
|
||||
for (int i = 0; i < eels.Count; i++)
|
||||
{
|
||||
if (eels[i] != null)
|
||||
eels[i].Kill();
|
||||
}
|
||||
}
|
||||
|
||||
base.Delete();
|
||||
}
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot(LootPack.SuperBoss, 5);
|
||||
}
|
||||
|
||||
public Osiredon(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();
|
||||
|
||||
m_NextSpawn = DateTime.UtcNow;
|
||||
m_NextSpecial = DateTime.UtcNow;
|
||||
m_NextWaterBall = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class ParasiticEel : BaseCreature
|
||||
{
|
||||
private Mobile m_Master;
|
||||
|
||||
public ParasiticEel(Mobile master)
|
||||
: base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4)
|
||||
{
|
||||
if (master is Osiredon)
|
||||
{
|
||||
m_Master = master;
|
||||
((Osiredon)master).AddEel(this);
|
||||
}
|
||||
|
||||
Name = "a parasitic eel";
|
||||
Body = 0x34;
|
||||
//BaseSoundID = 589;
|
||||
//TODO: soundid, Body
|
||||
|
||||
//CanSwim = true;
|
||||
//CantWalk = true;
|
||||
|
||||
SetStr(80, 125);
|
||||
SetDex(150, 250);
|
||||
SetInt(20, 40);
|
||||
|
||||
SetHits(100);
|
||||
|
||||
SetDamage(4, 12);
|
||||
|
||||
SetDamageType(ResistanceType.Physical, 25);
|
||||
SetDamageType(ResistanceType.Cold, 25);
|
||||
SetDamageType(ResistanceType.Poison, 50);
|
||||
|
||||
SetResistance(ResistanceType.Physical, 20);
|
||||
SetResistance(ResistanceType.Fire, 10, 25);
|
||||
SetResistance(ResistanceType.Cold, 10, 25);
|
||||
SetResistance(ResistanceType.Poison, 99);
|
||||
SetResistance(ResistanceType.Energy, 5, 10);
|
||||
|
||||
SetSkill(SkillName.Wrestling, 52.0, 70.0);
|
||||
SetSkill(SkillName.Tactics, 0.0);
|
||||
SetSkill(SkillName.MagicResist, 100.4, 113.5);
|
||||
SetSkill(SkillName.Anatomy, 1.0, 0.0);
|
||||
SetSkill(SkillName.Magery, 60.2, 72.4);
|
||||
SetSkill(SkillName.EvalInt, 60.1, 73.4);
|
||||
SetSkill(SkillName.Meditation, 100.0);
|
||||
|
||||
Fame = 2500;
|
||||
Karma = -2500;
|
||||
}
|
||||
|
||||
public override Poison PoisonImmune { get { return Poison.Parasitic; } }
|
||||
public override Poison HitPoison { get { return Poison.Parasitic; } }
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
if (m_Master != null && m_Master is Osiredon)
|
||||
((Osiredon)m_Master).RemoveEel(this);
|
||||
|
||||
base.Delete();
|
||||
}
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot(LootPack.FilthyRich, 1);
|
||||
}
|
||||
|
||||
public ParasiticEel(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0);
|
||||
writer.Write(m_Master);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
m_Master = reader.ReadMobile();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class BoatPainter : BaseVendor
|
||||
{
|
||||
private List<SBInfo> m_SBInfos = new List<SBInfo>();
|
||||
protected override List<SBInfo> SBInfos { get { return m_SBInfos; } }
|
||||
|
||||
[Constructable]
|
||||
public BoatPainter()
|
||||
: base("the boat painter")
|
||||
{
|
||||
SetSkill(SkillName.Carpentry, 36.0, 68.0);
|
||||
}
|
||||
|
||||
public override void InitSBInfo()
|
||||
{
|
||||
m_SBInfos.Add(new SBBoatPainter());
|
||||
}
|
||||
|
||||
public BoatPainter(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class CrabFisher : BaseVendor
|
||||
{
|
||||
private List<SBInfo> m_SBInfos = new List<SBInfo>();
|
||||
protected override List<SBInfo> SBInfos { get { return m_SBInfos; } }
|
||||
|
||||
[Constructable]
|
||||
public CrabFisher()
|
||||
: base("the crab fisher")
|
||||
{
|
||||
SetSkill(SkillName.Fishing, 36.0, 68.0);
|
||||
}
|
||||
|
||||
public override void InitSBInfo()
|
||||
{
|
||||
m_SBInfos.Add(new SBCrabFisher());
|
||||
}
|
||||
|
||||
public CrabFisher(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
using Server;
|
||||
using System;
|
||||
using Server.Items;
|
||||
using Server.ContextMenus;
|
||||
using System.Collections.Generic;
|
||||
using Server.Multis;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class DockMaster : BaseVendor
|
||||
{
|
||||
public static readonly int DryDockDistance = 300;
|
||||
public static readonly int DryDockAmount = 2500;
|
||||
|
||||
public override bool IsActiveVendor { get { return false; } }
|
||||
public override bool IsInvulnerable { get { return true; } }
|
||||
|
||||
private List<SBInfo> m_SBInfos = new List<SBInfo>();
|
||||
protected override List<SBInfo> SBInfos { get { return m_SBInfos; } }
|
||||
|
||||
public override void InitSBInfo()
|
||||
{
|
||||
m_SBInfos.Add(new SBFisherman());
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public DockMaster() : base( "the dockmaster" )
|
||||
{
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
|
||||
{
|
||||
base.GetContextMenuEntries(from, list);
|
||||
list.Add(new DryDockEntry(from, this));
|
||||
list.Add(new RetrieveHoldEntry(from, this));
|
||||
}
|
||||
|
||||
private class DryDockEntry : ContextMenuEntry
|
||||
{
|
||||
private Mobile m_From;
|
||||
private DockMaster m_DockMaster;
|
||||
|
||||
public DryDockEntry(Mobile from, DockMaster dockmaster) : base(1149575, 5)
|
||||
{
|
||||
m_From = from;
|
||||
m_DockMaster = dockmaster;
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
var boat = BaseBoat.GetBoat(m_From);
|
||||
|
||||
if (boat != null && m_DockMaster.InRange(boat.Location, 100))
|
||||
boat.BeginDryDock(m_From, m_DockMaster);
|
||||
else
|
||||
m_DockMaster.SayTo(m_From, 502581); //I cannot find the ship!
|
||||
}
|
||||
}
|
||||
|
||||
private class RetrieveHoldEntry : ContextMenuEntry
|
||||
{
|
||||
private Mobile m_From;
|
||||
private DockMaster m_DockMaster;
|
||||
|
||||
public RetrieveHoldEntry(Mobile from, DockMaster dockmaster)
|
||||
: base(1116504, 5)
|
||||
{
|
||||
m_From = from;
|
||||
m_DockMaster = dockmaster;
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
if (m_DockMaster.Map == null)
|
||||
return;
|
||||
|
||||
Container pack = m_From.Backpack;
|
||||
|
||||
if (pack != null && pack.GetAmount(typeof(Gold)) < DockMaster.DryDockAmount && Banker.GetBalance(m_From) < DryDockAmount)
|
||||
{
|
||||
m_DockMaster.PrivateOverheadMessage(MessageType.Regular, m_DockMaster.SpeechHue, 1116506, DockMaster.DryDockAmount.ToString(), m_From.NetState); //The price is ~1_price~ and I will accept nothing less!
|
||||
return;
|
||||
}
|
||||
|
||||
var boat = BaseBoat.GetBoat(m_From);
|
||||
|
||||
if (boat != null && m_DockMaster.InRange(boat.Location, 50))
|
||||
m_DockMaster.TryRetrieveHold(m_From, boat);
|
||||
else
|
||||
m_DockMaster.SayTo(m_From, 502581); //I cannot find the ship!
|
||||
}
|
||||
}
|
||||
|
||||
public void TryRetrieveHold(Mobile from, BaseBoat boat)
|
||||
{
|
||||
for (int i = 0; i < m_Crates.Count; i++) {
|
||||
if (m_Crates[i].Owner == from) {
|
||||
from.SendLocalizedMessage(1116516); //Thou must return thy current shipping crate before I can retrieve another shipment for you.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Container pack = from.Backpack;
|
||||
Container hold;
|
||||
|
||||
if (boat is BaseGalleon)
|
||||
hold = ((BaseGalleon)boat).GalleonHold;
|
||||
else
|
||||
hold = boat.Hold;
|
||||
|
||||
if (hold == null || hold.Items.Count == 0)
|
||||
{
|
||||
from.SendMessage("Your hold is empty!");
|
||||
return;
|
||||
}
|
||||
|
||||
ShipCrate crate = new ShipCrate(from, boat);
|
||||
m_Crates.Add(crate);
|
||||
|
||||
if (!pack.ConsumeTotal(typeof(Gold), DryDockAmount))
|
||||
Banker.Withdraw(from, DryDockAmount);
|
||||
|
||||
bool cantMove = false;
|
||||
List<Item> items = new List<Item>(hold.Items);
|
||||
foreach (Item item in items)
|
||||
{
|
||||
if (item.Movable)
|
||||
crate.DropItem(item);
|
||||
else
|
||||
cantMove = true;
|
||||
}
|
||||
|
||||
Point3D pnt = Point3D.Zero;
|
||||
|
||||
if (!CanDropCrate(ref pnt, this.Map))
|
||||
{
|
||||
SayTo(from, 1116517); //Arrrgh! My dock has no more room. Please come back later.
|
||||
from.BankBox.DropItem(crate);
|
||||
from.SendMessage("Your shipping crate has been placed in your bank box.");
|
||||
//from.SendMessage("You have 30 minutes to obtain the contents of your shipping crate. You can find it in the wearhouse on the westernmost tip of the floating emproiam");
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1116542, ShipCrate.DT.ToString()); //Yer ship has been unloaded to a crate inside this here warehouse. You have ~1_time~ minutes to get yer goods or it be gone.
|
||||
crate.MoveToWorld(pnt, this.Map);
|
||||
}
|
||||
|
||||
if (cantMove)
|
||||
from.SendMessage("We were unable to pack up one or more of the items in your cargo hold.");
|
||||
}
|
||||
|
||||
private Rectangle2D m_Bounds = new Rectangle2D(4561, 2298, 8, 5);
|
||||
private static List<ShipCrate> m_Crates = new List<ShipCrate>();
|
||||
|
||||
public static void RemoveCrate(ShipCrate crate)
|
||||
{
|
||||
if (m_Crates.Contains(crate))
|
||||
m_Crates.Remove(crate);
|
||||
}
|
||||
|
||||
private bool CanDropCrate(ref Point3D pnt, Map map)
|
||||
{
|
||||
for (int i = 0; i < 45; i++)
|
||||
{
|
||||
int x = Utility.Random(m_Bounds.X, m_Bounds.Width);
|
||||
int y = Utility.Random(m_Bounds.Y, m_Bounds.Height);
|
||||
int z = -2;
|
||||
|
||||
bool badSpot = false;
|
||||
Point3D p = new Point3D(x, y, z);
|
||||
IPooledEnumerable eable = map.GetItemsInRange(pnt, 0);
|
||||
|
||||
foreach (Item item in eable)
|
||||
{
|
||||
if (item != null && item is Container && !item.Movable)
|
||||
{
|
||||
badSpot = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
if (!badSpot)
|
||||
{
|
||||
pnt = p;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public BaseBoat GetBoatInRegion(Mobile from)
|
||||
{
|
||||
if (this.Map == null || this.Map == Map.Internal || this.Region == null)
|
||||
return null;
|
||||
|
||||
foreach (Rectangle3D rec in this.Region.Area)
|
||||
{
|
||||
IPooledEnumerable eable = this.Map.GetItemsInBounds(new Rectangle2D(rec.Start.X, rec.Start.Y, rec.Width, rec.Height));
|
||||
|
||||
foreach (Item item in eable)
|
||||
{
|
||||
if (item is BaseBoat && ((BaseBoat)item).Owner == from && InRange(item.Location, DryDockDistance))
|
||||
{
|
||||
eable.Free();
|
||||
return (BaseBoat)item;
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public DockMaster(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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class DocksAlchemist : BaseVendor
|
||||
{
|
||||
private List<SBInfo> m_SBInfos = new List<SBInfo>();
|
||||
protected override List<SBInfo> SBInfos { get { return m_SBInfos; } }
|
||||
|
||||
public override NpcGuild NpcGuild { get { return NpcGuild.MagesGuild; } }
|
||||
|
||||
[Constructable]
|
||||
public DocksAlchemist() : base( "the alchemist" )
|
||||
{
|
||||
SetSkill(SkillName.Alchemy, 85.0, 100.0);
|
||||
SetSkill(SkillName.TasteID, 65.0, 88.0);
|
||||
}
|
||||
|
||||
public override void InitSBInfo()
|
||||
{
|
||||
m_SBInfos.Add(new SBDocksAlchemist());
|
||||
}
|
||||
|
||||
public override VendorShoeType ShoeType
|
||||
{
|
||||
get { return Utility.RandomBool() ? VendorShoeType.Shoes : VendorShoeType.Sandals; }
|
||||
}
|
||||
|
||||
public override void InitOutfit()
|
||||
{
|
||||
base.InitOutfit();
|
||||
|
||||
AddItem( new Server.Items.HalfApron() );
|
||||
}
|
||||
|
||||
public DocksAlchemist( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class SBDocksAlchemist : SBInfo
|
||||
{
|
||||
private List<GenericBuyInfo> m_BuyInfo = new InternalBuyInfo();
|
||||
private IShopSellInfo m_SellInfo = new InternalSellInfo();
|
||||
|
||||
public SBDocksAlchemist()
|
||||
{
|
||||
}
|
||||
|
||||
public override IShopSellInfo SellInfo { get { return m_SellInfo; } }
|
||||
public override List<GenericBuyInfo> BuyInfo { get { return m_BuyInfo; } }
|
||||
|
||||
public class InternalBuyInfo : List<GenericBuyInfo>
|
||||
{
|
||||
public InternalBuyInfo()
|
||||
{
|
||||
Add( new GenericBuyInfo( "1116302", typeof( Saltpeter ), 167, 20, 16954, 1150 ) );
|
||||
|
||||
Add(new GenericBuyInfo(typeof(RefreshPotion), 15, 10, 0xF0B, 0));
|
||||
Add(new GenericBuyInfo(typeof(AgilityPotion), 15, 10, 0xF08, 0));
|
||||
Add(new GenericBuyInfo(typeof(NightSightPotion), 15, 10, 0xF06, 0));
|
||||
Add(new GenericBuyInfo(typeof(LesserHealPotion), 15, 10, 0xF0C, 0));
|
||||
Add(new GenericBuyInfo(typeof(StrengthPotion), 15, 10, 0xF09, 0));
|
||||
Add(new GenericBuyInfo(typeof(LesserPoisonPotion), 15, 10, 0xF0A, 0));
|
||||
Add(new GenericBuyInfo(typeof(LesserCurePotion), 15, 10, 0xF07, 0));
|
||||
Add(new GenericBuyInfo(typeof(LesserExplosionPotion), 21, 10, 0xF0D, 0));
|
||||
Add(new GenericBuyInfo(typeof(MortarPestle), 8, 10, 0xE9B, 0));
|
||||
|
||||
Add(new GenericBuyInfo(typeof(BlackPearl), 5, 20, 0xF7A, 0));
|
||||
Add(new GenericBuyInfo(typeof(Bloodmoss), 5, 20, 0xF7B, 0));
|
||||
Add(new GenericBuyInfo(typeof(Garlic), 3, 20, 0xF84, 0));
|
||||
Add(new GenericBuyInfo(typeof(Ginseng), 3, 20, 0xF85, 0));
|
||||
Add(new GenericBuyInfo(typeof(MandrakeRoot), 3, 20, 0xF86, 0));
|
||||
Add(new GenericBuyInfo(typeof(Nightshade), 3, 20, 0xF88, 0));
|
||||
Add(new GenericBuyInfo(typeof(SpidersSilk), 3, 20, 0xF8D, 0));
|
||||
Add(new GenericBuyInfo(typeof(SulfurousAsh), 3, 20, 0xF8C, 0));
|
||||
|
||||
Add(new GenericBuyInfo(typeof(Bottle), 5, 100, 0xF0E, 0));
|
||||
Add(new GenericBuyInfo(typeof(HeatingStand), 2, 100, 0x1849, 0));
|
||||
|
||||
Add(new GenericBuyInfo("1041060", typeof(HairDye), 37, 10, 0xEFF, 0));
|
||||
|
||||
Add(new GenericBuyInfo(typeof(HeatingStand), 2, 100, 0x1849, 0)); // This is on OSI :-P
|
||||
}
|
||||
}
|
||||
|
||||
public class InternalSellInfo : GenericSellInfo
|
||||
{
|
||||
public InternalSellInfo()
|
||||
{
|
||||
Add( typeof( Saltpeter ), 10 );
|
||||
|
||||
Add(typeof(BlackPearl), 3);
|
||||
Add(typeof(Bloodmoss), 3);
|
||||
Add(typeof(MandrakeRoot), 2);
|
||||
Add(typeof(Garlic), 2);
|
||||
Add(typeof(Ginseng), 2);
|
||||
Add(typeof(Nightshade), 2);
|
||||
Add(typeof(SpidersSilk), 2);
|
||||
Add(typeof(SulfurousAsh), 2);
|
||||
Add(typeof(Bottle), 3);
|
||||
Add(typeof(MortarPestle), 4);
|
||||
Add(typeof(HairDye), 19);
|
||||
|
||||
Add(typeof(NightSightPotion), 7);
|
||||
Add(typeof(AgilityPotion), 7);
|
||||
Add(typeof(StrengthPotion), 7);
|
||||
Add(typeof(RefreshPotion), 7);
|
||||
Add(typeof(LesserCurePotion), 7);
|
||||
Add(typeof(LesserHealPotion), 7);
|
||||
Add(typeof(LesserPoisonPotion), 7);
|
||||
Add(typeof(LesserExplosionPotion), 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Items;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class SBBoatPainter : SBInfo
|
||||
{
|
||||
private List<GenericBuyInfo> m_BuyInfo = new InternalBuyInfo();
|
||||
private IShopSellInfo m_SellInfo = new InternalSellInfo();
|
||||
|
||||
public SBBoatPainter()
|
||||
{
|
||||
}
|
||||
|
||||
public override IShopSellInfo SellInfo { get { return m_SellInfo; } }
|
||||
public override List<GenericBuyInfo> BuyInfo { get { return m_BuyInfo; } }
|
||||
|
||||
public class InternalBuyInfo : List<GenericBuyInfo>
|
||||
{
|
||||
public InternalBuyInfo()
|
||||
{
|
||||
Add(new GenericBuyInfo("Boat Paint", typeof(BoatPaint), 6256, 20, 4011, 276, new object[] { 276 }));
|
||||
Add(new GenericBuyInfo("Boat Paint", typeof(BoatPaint), 6256, 20, 4011, 396, new object[] { 396 }));
|
||||
Add(new GenericBuyInfo("Boat Paint", typeof(BoatPaint), 6256, 20, 4011, 516, new object[] { 516 }));
|
||||
Add(new GenericBuyInfo("Boat Paint", typeof(BoatPaint), 6256, 20, 4011, 1900, new object[] { 1900 }));
|
||||
Add(new GenericBuyInfo("Boat Paint", typeof(BoatPaint), 6256, 20, 4011, 251, new object[] { 251 }));
|
||||
Add(new GenericBuyInfo("Boat Paint", typeof(BoatPaint), 6256, 20, 4011, 246, new object[] { 246 }));
|
||||
Add(new GenericBuyInfo("Boat Paint", typeof(BoatPaint), 6256, 20, 4011, 2213, new object[] { 2213 }));
|
||||
Add(new GenericBuyInfo("Boat Paint", typeof(BoatPaint), 6256, 20, 4011, 36, new object[] { 36 }));
|
||||
Add(new GenericBuyInfo("Boat Paint Remover", typeof(BoatPaintRemover), 6256, 20, 4011, 0));
|
||||
}
|
||||
}
|
||||
|
||||
public class InternalSellInfo : GenericSellInfo
|
||||
{
|
||||
public InternalSellInfo()
|
||||
{
|
||||
Add(typeof(LobsterTrap), 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class SBCrabFisher : SBInfo
|
||||
{
|
||||
private List<GenericBuyInfo> m_BuyInfo = new InternalBuyInfo();
|
||||
private IShopSellInfo m_SellInfo = new InternalSellInfo();
|
||||
|
||||
public SBCrabFisher()
|
||||
{
|
||||
}
|
||||
|
||||
public override IShopSellInfo SellInfo { get { return m_SellInfo; } }
|
||||
public override List<GenericBuyInfo> BuyInfo { get { return m_BuyInfo; } }
|
||||
|
||||
public class InternalBuyInfo : List<GenericBuyInfo>
|
||||
{
|
||||
public InternalBuyInfo()
|
||||
{
|
||||
Add(new GenericBuyInfo("empty lobster trap", typeof(LobsterTrap), 137, 500, 17615, 0));
|
||||
}
|
||||
}
|
||||
|
||||
public class InternalSellInfo : GenericSellInfo
|
||||
{
|
||||
public InternalSellInfo()
|
||||
{
|
||||
Add(typeof(LobsterTrap), 10);
|
||||
Add(typeof(AppleCrab), 10);
|
||||
Add(typeof(BlueCrab), 10);
|
||||
Add(typeof(DungeonessCrab), 10);
|
||||
Add(typeof(KingCrab), 10);
|
||||
Add(typeof(RockCrab), 10);
|
||||
Add(typeof(SnowCrab), 10);
|
||||
Add(typeof(StoneCrab), 250);
|
||||
Add(typeof(SpiderCrab), 250);
|
||||
Add(typeof(TunnelCrab), 2500);
|
||||
Add(typeof(VoidCrab), 2500);
|
||||
|
||||
Add(typeof(CrustyLobster), 10);
|
||||
Add(typeof(FredLobster), 10);
|
||||
Add(typeof(HummerLobster), 10);
|
||||
Add(typeof(RockLobster), 10);
|
||||
Add(typeof(ShovelNoseLobster), 10);
|
||||
Add(typeof(SpineyLobster), 10);
|
||||
Add(typeof(BlueLobster), 250);
|
||||
Add(typeof(BloodLobster), 2500);
|
||||
Add(typeof(DreadLobster), 2500);
|
||||
Add(typeof(VoidLobster), 2500);
|
||||
|
||||
Add(typeof(StoneCrabMeat), 100);
|
||||
Add(typeof(SpiderCrabMeat), 100);
|
||||
Add(typeof(BlueLobsterMeat), 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class SBSeaMarketTavernKeeper : SBInfo
|
||||
{
|
||||
private List<GenericBuyInfo> m_BuyInfo = new InternalBuyInfo();
|
||||
private IShopSellInfo m_SellInfo = new InternalSellInfo();
|
||||
|
||||
public SBSeaMarketTavernKeeper()
|
||||
{
|
||||
}
|
||||
|
||||
public override IShopSellInfo SellInfo { get { return m_SellInfo; } }
|
||||
public override List<GenericBuyInfo> BuyInfo { get { return m_BuyInfo; } }
|
||||
|
||||
public class InternalBuyInfo : List<GenericBuyInfo>
|
||||
{
|
||||
public InternalBuyInfo()
|
||||
{
|
||||
Add(new GenericBuyInfo("1116299", typeof(MentoSeasoning), 1002, 10, 2454, 95));
|
||||
Add(new GenericBuyInfo("1116338", typeof(SamuelsSecretSauce), 1007, 10, 2463, 1461));
|
||||
Add(new GenericBuyInfo("1116300", typeof(DarkTruffle), 1001, 10, 3352, 1908));
|
||||
|
||||
Add( new BeverageBuyInfo( typeof( BeverageBottle ), BeverageType.Ale, 7, 20, 0x99F, 0 ) );
|
||||
Add( new BeverageBuyInfo( typeof( BeverageBottle ), BeverageType.Wine, 7, 20, 0x9C7, 0 ) );
|
||||
Add( new BeverageBuyInfo( typeof( BeverageBottle ), BeverageType.Liquor, 7, 20, 0x99B, 0 ) );
|
||||
Add( new BeverageBuyInfo( typeof( Jug ), BeverageType.Cider, 13, 20, 0x9C8, 0 ) );
|
||||
Add( new BeverageBuyInfo( typeof( Pitcher ), BeverageType.Milk, 7, 20, 0x9F0, 0 ) );
|
||||
Add( new BeverageBuyInfo( typeof( Pitcher ), BeverageType.Ale, 11, 20, 0x1F95, 0 ) );
|
||||
Add( new BeverageBuyInfo( typeof( Pitcher ), BeverageType.Cider, 11, 20, 0x1F97, 0 ) );
|
||||
Add( new BeverageBuyInfo( typeof( Pitcher ), BeverageType.Liquor, 11, 20, 0x1F99, 0 ) );
|
||||
Add( new BeverageBuyInfo( typeof( Pitcher ), BeverageType.Wine, 11, 20, 0x1F9B, 0 ) );
|
||||
Add( new BeverageBuyInfo( typeof( Pitcher ), BeverageType.Water, 11, 20, 0x1F9D, 0 ) );
|
||||
|
||||
Add( new GenericBuyInfo( typeof( BreadLoaf ), 6, 10, 0x103B, 0 ) );
|
||||
Add( new GenericBuyInfo( typeof( CheeseWheel ), 21, 10, 0x97E, 0 ) );
|
||||
Add( new GenericBuyInfo( typeof( CookedBird ), 17, 20, 0x9B7, 0 ) );
|
||||
Add( new GenericBuyInfo( typeof( LambLeg ), 8, 20, 0x160A, 0 ) );
|
||||
Add( new GenericBuyInfo( typeof( ChickenLeg ), 5, 20, 0x1608, 0 ) );
|
||||
Add( new GenericBuyInfo( typeof( Ribs ), 7, 20, 0x9F2, 0 ) );
|
||||
|
||||
Add( new GenericBuyInfo( typeof( WoodenBowlOfCarrots ), 3, 20, 0x15F9, 0 ) );
|
||||
Add( new GenericBuyInfo( typeof( WoodenBowlOfCorn ), 3, 20, 0x15FA, 0 ) );
|
||||
Add( new GenericBuyInfo( typeof( WoodenBowlOfLettuce ), 3, 20, 0x15FB, 0 ) );
|
||||
Add( new GenericBuyInfo( typeof( WoodenBowlOfPeas ), 3, 20, 0x15FC, 0 ) );
|
||||
Add( new GenericBuyInfo( typeof( EmptyPewterBowl ), 2, 20, 0x15FD, 0 ) );
|
||||
Add( new GenericBuyInfo( typeof( PewterBowlOfCorn ), 3, 20, 0x15FE, 0 ) );
|
||||
Add( new GenericBuyInfo( typeof( PewterBowlOfLettuce ), 3, 20, 0x15FF, 0 ) );
|
||||
Add( new GenericBuyInfo( typeof( PewterBowlOfPeas ), 3, 20, 0x1601, 0 ) );
|
||||
Add( new GenericBuyInfo( typeof( PewterBowlOfPotatos ), 3, 20, 0x1601, 0 ) );
|
||||
Add( new GenericBuyInfo( typeof( WoodenBowlOfStew ), 3, 20, 0x1604, 0 ) );
|
||||
Add( new GenericBuyInfo( typeof( WoodenBowlOfTomatoSoup ), 3, 20, 0x1606, 0 ) );
|
||||
|
||||
Add( new GenericBuyInfo( typeof( ApplePie ), 7, 20, 0x1041, 0 ) ); //OSI just has Pie, not Apple/Fruit/Meat
|
||||
|
||||
Add( new GenericBuyInfo( "1016450", typeof( Chessboard ), 2, 20, 0xFA6, 0 ) );
|
||||
Add( new GenericBuyInfo( "1016449", typeof( CheckerBoard ), 2, 20, 0xFA6, 0 ) );
|
||||
Add( new GenericBuyInfo( typeof( Backgammon ), 2, 20, 0xE1C, 0 ) );
|
||||
Add(new GenericBuyInfo(typeof(Dices), 2, 20, 0xFA7, 0));
|
||||
Add( new GenericBuyInfo( "1041243", typeof( ContractOfEmployment ), 1252, 20, 0x14F0, 0 ) );
|
||||
Add( new GenericBuyInfo( "a barkeep contract", typeof( BarkeepContract ), 1252, 20, 0x14F0, 0 ) );
|
||||
|
||||
if ( Multis.BaseHouse.NewVendorSystem )
|
||||
Add( new GenericBuyInfo( "1062332", typeof( VendorRentalContract ), 1252, 20, 0x14F0, 0x672 ) );
|
||||
|
||||
/*if ( Map == Tokuno )
|
||||
{
|
||||
Add( new GenericBuyInfo( typeof( Wasabi ), 2, 20, 0x24E8, 0 ) );
|
||||
Add( new GenericBuyInfo( typeof( Wasabi ), 2, 20, 0x24E9, 0 ) );
|
||||
Add( new GenericBuyInfo( typeof( BentoBox ), 6, 20, 0x2836, 0 ) );
|
||||
Add( new GenericBuyInfo( typeof( BentoBox ), 6, 20, 0x2837, 0 ) );
|
||||
Add( new GenericBuyInfo( typeof( GreenTeaBasket ), 2, 20, 0x284B, 0 ) );
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
public class InternalSellInfo : GenericSellInfo
|
||||
{
|
||||
public InternalSellInfo()
|
||||
{
|
||||
Add( typeof( WoodenBowlOfCarrots ), 1 );
|
||||
Add( typeof( WoodenBowlOfCorn ), 1 );
|
||||
Add( typeof( WoodenBowlOfLettuce ), 1 );
|
||||
Add( typeof( WoodenBowlOfPeas ), 1 );
|
||||
Add( typeof( EmptyPewterBowl ), 1 );
|
||||
Add( typeof( PewterBowlOfCorn ), 1 );
|
||||
Add( typeof( PewterBowlOfLettuce ), 1 );
|
||||
Add( typeof( PewterBowlOfPeas ), 1 );
|
||||
Add( typeof( PewterBowlOfPotatos ), 1 );
|
||||
Add( typeof( WoodenBowlOfStew ), 1 );
|
||||
Add( typeof( WoodenBowlOfTomatoSoup ), 1 );
|
||||
Add( typeof( BeverageBottle ), 3 );
|
||||
Add( typeof( Jug ), 6 );
|
||||
Add( typeof( Pitcher ), 5 );
|
||||
Add( typeof( GlassMug ), 1 );
|
||||
Add( typeof( BreadLoaf ), 3 );
|
||||
//Add( typeof( CheeseWheel ), 12 );
|
||||
//Add( typeof( Ribs ), 6 );
|
||||
//Add( typeof( Peach ), 1 );
|
||||
//Add( typeof( Pear ), 1 );
|
||||
//Add( typeof( Grapes ), 1 );
|
||||
//Add( typeof( Apple ), 1 );
|
||||
//Add( typeof( Banana ), 1 );
|
||||
Add( typeof( Candle ), 3 );
|
||||
Add( typeof( Chessboard ), 1 );
|
||||
Add( typeof( CheckerBoard ), 1 );
|
||||
Add( typeof( Backgammon ), 1 );
|
||||
Add( typeof( Dices ), 1 );
|
||||
Add( typeof( ContractOfEmployment ), 626 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class SeaMarketTavernKeeper : BaseVendor
|
||||
{
|
||||
private List<SBInfo> m_SBInfos = new List<SBInfo>();
|
||||
protected override List<SBInfo> SBInfos{ get { return m_SBInfos; } }
|
||||
|
||||
[Constructable]
|
||||
public SeaMarketTavernKeeper() : base( "the tavern keeper" )
|
||||
{
|
||||
}
|
||||
|
||||
public override void InitSBInfo()
|
||||
{
|
||||
m_SBInfos.Add(new SBSeaMarketTavernKeeper());
|
||||
}
|
||||
|
||||
public override void InitOutfit()
|
||||
{
|
||||
base.InitOutfit();
|
||||
|
||||
AddItem( new Server.Items.HalfApron() );
|
||||
}
|
||||
|
||||
public SeaMarketTavernKeeper( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user