Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
@@ -0,0 +1,206 @@
|
||||
using Server;
|
||||
using System;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
[CorpseName("a mongbat corpse")]
|
||||
public class DaemonMongbat : CovetousCreature
|
||||
{
|
||||
[Constructable]
|
||||
public DaemonMongbat()
|
||||
: base(AIType.AI_Necro)
|
||||
{
|
||||
Name = "a dameon mongbat";
|
||||
Body = 39;
|
||||
BaseSoundID = 422;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public DaemonMongbat(int level, bool voidSpawn)
|
||||
: base(AIType.AI_Melee, level, voidSpawn)
|
||||
{
|
||||
Name = "a dameon mongbat";
|
||||
Body = 39;
|
||||
BaseSoundID = 422;
|
||||
}
|
||||
|
||||
public DaemonMongbat(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[CorpseName("a gargoyle corpse")]
|
||||
public class GargoyleAssassin : CovetousCreature
|
||||
{
|
||||
[Constructable]
|
||||
public GargoyleAssassin()
|
||||
: base(AIType.AI_Mage)
|
||||
{
|
||||
Name = "a gargoyle assassin";
|
||||
Body = 0x4;
|
||||
BaseSoundID = 0x174;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public GargoyleAssassin(int level, bool voidSpawn)
|
||||
: base(AIType.AI_Mage, level, voidSpawn)
|
||||
{
|
||||
Name = "a gargoyle assassin";
|
||||
Body = 0x4;
|
||||
BaseSoundID = 0x174;
|
||||
}
|
||||
|
||||
public GargoyleAssassin(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[CorpseName("a doppleganger corpse")]
|
||||
public class CovetousDoppleganger : CovetousCreature
|
||||
{
|
||||
[Constructable]
|
||||
public CovetousDoppleganger()
|
||||
: base(AIType.AI_Melee)
|
||||
{
|
||||
Name = "a doppleganger";
|
||||
Body = 0x309;
|
||||
BaseSoundID = 0x451;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public CovetousDoppleganger(int level, bool voidSpawn)
|
||||
: base(AIType.AI_Melee, level, voidSpawn)
|
||||
{
|
||||
Name = "a doppleganger";
|
||||
Body = 0x309;
|
||||
BaseSoundID = 0x451;
|
||||
}
|
||||
|
||||
public CovetousDoppleganger(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[CorpseName("an oni corpse")]
|
||||
public class LesserOni : CovetousCreature
|
||||
{
|
||||
[Constructable]
|
||||
public LesserOni()
|
||||
: base(AIType.AI_Mage)
|
||||
{
|
||||
Name = "a lesser oni";
|
||||
Body = 241;
|
||||
|
||||
SetSpecialAbility(SpecialAbility.AngryFire);
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public LesserOni(int level, bool voidSpawn)
|
||||
: base(AIType.AI_Mage, level, voidSpawn)
|
||||
{
|
||||
Name = "a lesser oni";
|
||||
Body = 241;
|
||||
}
|
||||
|
||||
public override int GetAngerSound() { return 0x4E3; }
|
||||
public override int GetIdleSound() { return 0x4E2; }
|
||||
public override int GetAttackSound() { return 0x4E1; }
|
||||
public override int GetHurtSound() { return 0x4E4; }
|
||||
public override int GetDeathSound() { return 0x4E0; }
|
||||
|
||||
public LesserOni(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[CorpseName("a fire daemon corpse")]
|
||||
public class CovetousFireDaemon : CovetousCreature
|
||||
{
|
||||
[Constructable]
|
||||
public CovetousFireDaemon()
|
||||
: base(AIType.AI_Mage)
|
||||
{
|
||||
Name = "a fire daemon";
|
||||
Body = 9;
|
||||
BaseSoundID = 357;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public CovetousFireDaemon(int level, bool voidSpawn)
|
||||
: base(AIType.AI_Mage, level, voidSpawn)
|
||||
{
|
||||
Name = "a fire daemon";
|
||||
Body = 9;
|
||||
BaseSoundID = 357;
|
||||
}
|
||||
|
||||
public CovetousFireDaemon(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
using Server;
|
||||
using System;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class DazzledHarpy : Harpy
|
||||
{
|
||||
[Constructable]
|
||||
public DazzledHarpy()
|
||||
{
|
||||
Name = "a dazzled harpy";
|
||||
FightMode = FightMode.Aggressor;
|
||||
|
||||
SetHits(120, 140);
|
||||
SetStam(90, 110);
|
||||
SetMana(50, 80);
|
||||
|
||||
SetDamage(5, 7);
|
||||
|
||||
SetSkill(SkillName.MagicResist, 50, 65);
|
||||
SetSkill(SkillName.Tactics, 70, 100);
|
||||
SetSkill(SkillName.Wrestling, 60, 90);
|
||||
}
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot(LootPack.Meager);
|
||||
}
|
||||
|
||||
public DazzledHarpy(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class VampireMongbat : Mongbat
|
||||
{
|
||||
[Constructable]
|
||||
public VampireMongbat()
|
||||
{
|
||||
Name = "a vampire mongbat";
|
||||
FightMode = FightMode.Aggressor;
|
||||
Hue = 1461;
|
||||
|
||||
SetHits(76, 171);
|
||||
|
||||
SetStr(60, 100);
|
||||
SetDex(60, 80);
|
||||
SetInt(10, 30);
|
||||
|
||||
SetHits(70, 170);
|
||||
SetStam(60, 80);
|
||||
SetMana(10, 30);
|
||||
|
||||
SetDamage(5, 10);
|
||||
|
||||
SetSkill(SkillName.Wrestling, 10, 20);
|
||||
SetSkill(SkillName.Tactics, 10, 20);
|
||||
SetSkill(SkillName.MagicResist, 25, 40);
|
||||
}
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot(LootPack.Meager);
|
||||
}
|
||||
|
||||
public VampireMongbat(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class HeadlessMiner : HeadlessOne
|
||||
{
|
||||
[Constructable]
|
||||
public HeadlessMiner()
|
||||
{
|
||||
Name = "headless miner";
|
||||
FightMode = FightMode.Aggressor;
|
||||
|
||||
SetStr(60, 100);
|
||||
SetDex(40, 60);
|
||||
SetInt(10, 30);
|
||||
|
||||
SetHits(10, 40);
|
||||
SetStam(40, 60);
|
||||
SetMana(10, 35);
|
||||
|
||||
SetDamage(7, 12);
|
||||
|
||||
SetSkill(SkillName.MagicResist, 30, 40);
|
||||
SetSkill(SkillName.Tactics, 40, 60);
|
||||
SetSkill(SkillName.Wrestling, 40, 60);
|
||||
}
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot(LootPack.Meager);
|
||||
}
|
||||
|
||||
public HeadlessMiner(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class StrangeGazer : Gazer
|
||||
{
|
||||
[Constructable]
|
||||
public StrangeGazer()
|
||||
{
|
||||
Name = "a strange gazer";
|
||||
|
||||
SetStr(100, 130);
|
||||
SetDex(90, 120);
|
||||
SetInt(150, 160);
|
||||
|
||||
SetHits(60, 90);
|
||||
SetStam(90, 120);
|
||||
SetMana(153, 158);
|
||||
|
||||
SetDamage(5, 10);
|
||||
|
||||
SetSkill(SkillName.MagicResist, 60, 80);
|
||||
SetSkill(SkillName.Tactics, 50, 70);
|
||||
SetSkill(SkillName.Wrestling, 50, 70);
|
||||
SetSkill(SkillName.Magery, 50, 70);
|
||||
SetSkill(SkillName.EvalInt, 50, 70);
|
||||
SetSkill(SkillName.Meditation, 50, 100);
|
||||
}
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot(LootPack.Meager, 2);
|
||||
}
|
||||
|
||||
public StrangeGazer(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,362 @@
|
||||
using Server;
|
||||
using System;
|
||||
using Server.Items;
|
||||
using Server.Engines.VoidPool;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class CoraTheSorceress : BaseCreature, IElementalCreature, IAuraCreature
|
||||
{
|
||||
public ElementType ElementType { get { return ElementType.Chaos; } }
|
||||
|
||||
public DateTime NextManaDrain { get; set; }
|
||||
|
||||
public TimeSpan ManaDrainInterval { get { return TimeSpan.FromSeconds(Utility.RandomMinMax(15, 120)); } }
|
||||
|
||||
[Constructable]
|
||||
public CoraTheSorceress() : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.1)
|
||||
{
|
||||
Body = 0x191;
|
||||
Name = "Cora";
|
||||
Title = "the sorceress";
|
||||
|
||||
HairItemID = 0x2045;
|
||||
HairHue = 452;
|
||||
|
||||
SetStr(909, 949);
|
||||
SetDex(125);
|
||||
SetInt(903, 947);
|
||||
|
||||
SetHits(35000);
|
||||
|
||||
SetDamage(17, 25);
|
||||
|
||||
SetDamageType(ResistanceType.Physical, 50);
|
||||
SetDamageType(ResistanceType.Energy, 50);
|
||||
|
||||
SetResistance(ResistanceType.Physical, 52, 67);
|
||||
SetResistance(ResistanceType.Fire, 51, 68);
|
||||
SetResistance(ResistanceType.Cold, 51, 69);
|
||||
SetResistance(ResistanceType.Poison, 51, 70);
|
||||
SetResistance(ResistanceType.Energy, 50, 68);
|
||||
|
||||
SetSkill(SkillName.Wrestling, 100.1, 119.7);
|
||||
SetSkill(SkillName.Tactics, 102.3, 118.5);
|
||||
SetSkill(SkillName.MagicResist, 101.2, 119.6);
|
||||
SetSkill(SkillName.Anatomy, 100.1, 117.5);
|
||||
SetSkill(SkillName.Magery, 100.1, 117.5);
|
||||
SetSkill(SkillName.EvalInt, 100.1, 117.5);
|
||||
|
||||
Fame = 32000;
|
||||
Karma = -32000;
|
||||
|
||||
AddAndEquip(new WildStaff(), 1971);
|
||||
AddAndEquip(new ThighBoots(), 1910);
|
||||
AddAndEquip(new ChainLegs(), 1936);
|
||||
AddAndEquip(new LeatherGloves(), 1910);
|
||||
AddAndEquip(new LeatherBustierArms(), 1947);
|
||||
|
||||
SetSpecialAbility(SpecialAbility.DragonBreath);
|
||||
SetAreaEffect(AreaEffect.AuraDamage);
|
||||
}
|
||||
|
||||
public override bool AlwaysMurderer { get { return true; } }
|
||||
public override bool ClickTitle { get { return false; } }
|
||||
public override bool ShowFameTitle { get { return false; } }
|
||||
|
||||
public void AuraEffect(Mobile m)
|
||||
{
|
||||
int mana = Utility.Random(1, m.Mana);
|
||||
m.Mana -= mana;
|
||||
m.SendLocalizedMessage(1153114, mana.ToString()); // Cora drains ~1_VAL~ points of your mana!
|
||||
}
|
||||
|
||||
public override bool TeleportsTo { get { return true; } }
|
||||
public override TimeSpan TeleportDuration { get { return TimeSpan.FromSeconds(Utility.RandomMinMax(30, 60)); } }
|
||||
public override double TeleportProb { get { return 1.0; } }
|
||||
public override bool TeleportsPets { get { return true; } }
|
||||
|
||||
public override int GetDeathSound() { return 0x316; }
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot(LootPack.UltraRich, 3);
|
||||
AddLoot(LootPack.SuperBoss, 3);
|
||||
}
|
||||
|
||||
private void AddAndEquip(Item item, int hue = 0)
|
||||
{
|
||||
item.Movable = false;
|
||||
item.Hue = hue;
|
||||
AddItem(item);
|
||||
}
|
||||
|
||||
public override void OnThink()
|
||||
{
|
||||
base.OnThink();
|
||||
|
||||
if (NextManaDrain < DateTime.UtcNow)
|
||||
DoManaDrain();
|
||||
}
|
||||
|
||||
public void DoManaDrain()
|
||||
{
|
||||
Animate(AnimationType.Spell, 1);
|
||||
|
||||
DoEffects(Direction.North);
|
||||
DoEffects(Direction.West);
|
||||
DoEffects(Direction.South);
|
||||
DoEffects(Direction.East);
|
||||
|
||||
NextManaDrain = DateTime.UtcNow + ManaDrainInterval;
|
||||
}
|
||||
|
||||
private bool DoEffects(Direction d)
|
||||
{
|
||||
int x = this.X;
|
||||
int y = this.Y;
|
||||
int z = this.Z;
|
||||
int range = 10;
|
||||
int offset = 8;
|
||||
|
||||
switch (d)
|
||||
{
|
||||
case Direction.North:
|
||||
x = this.X + Utility.RandomMinMax(-offset, offset);
|
||||
y = this.Y - range;
|
||||
break;
|
||||
case Direction.West:
|
||||
x = this.X - range;
|
||||
y = this.Y + Utility.RandomMinMax(-offset, offset);
|
||||
break;
|
||||
case Direction.South:
|
||||
x = this.X + Utility.RandomMinMax(-offset, offset);
|
||||
y = this.Y + range;
|
||||
break;
|
||||
case Direction.East:
|
||||
x = this.X + range;
|
||||
y = this.Y + Utility.RandomMinMax(-offset, offset);
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < range; i++)
|
||||
{
|
||||
switch (d)
|
||||
{
|
||||
case Direction.North: y += i; break;
|
||||
case Direction.West: x += i; break;
|
||||
case Direction.South: y -= i; break;
|
||||
case Direction.East: x -= i; break;
|
||||
}
|
||||
|
||||
z = this.Map.GetAverageZ(x, y);
|
||||
Point3D p = new Point3D(x, y, z);
|
||||
|
||||
if (Server.Spells.SpellHelper.AdjustField(ref p, this.Map, 12, false))/*this.Map.CanFit(x, y, z, 16, false, false, true))/*this.Map.CanSpawnMobile(x, y, z)*/
|
||||
{
|
||||
MovementPath path = new MovementPath(this, p);
|
||||
|
||||
if (path.Success)
|
||||
{
|
||||
DropCrack(path);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void DropCrack(MovementPath path)
|
||||
{
|
||||
int time = 10;
|
||||
int x = this.X;
|
||||
int y = this.Y;
|
||||
|
||||
for (int i = 0; i < path.Directions.Length; ++i)
|
||||
{
|
||||
Movement.Movement.Offset(path.Directions[i], ref x, ref y);
|
||||
IPoint3D p = new Point3D(x, y, this.Map.GetAverageZ(x, y)) as IPoint3D;
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromMilliseconds(time), new TimerStateCallback(ManaDrainEffects_Callback), new object[] { p, this.Map });
|
||||
|
||||
time += 200;
|
||||
}
|
||||
}
|
||||
|
||||
private void ManaDrainEffects_Callback(object o)
|
||||
{
|
||||
object[] objs = o as object[];
|
||||
IPoint3D p = objs[0] as IPoint3D;
|
||||
Map map = objs[1] as Map;
|
||||
|
||||
var item = new ManaDrainItem(Utility.RandomList(6913, 6915, 6917, 6919), this);
|
||||
Spells.SpellHelper.GetSurfaceTop(ref p);
|
||||
|
||||
item.MoveToWorld(new Point3D(p), this.Map);
|
||||
}
|
||||
|
||||
private class ManaDrainItem : Item
|
||||
{
|
||||
public Item Static { get; private set; }
|
||||
public Mobile Owner { get; private set; }
|
||||
|
||||
public ManaDrainItem(int id, Mobile owner) : base(id)
|
||||
{
|
||||
Owner = owner;
|
||||
|
||||
Movable = false;
|
||||
Hue = 1152;
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(5), ChangeHue);
|
||||
}
|
||||
|
||||
private void ChangeHue()
|
||||
{
|
||||
Hue = 1153;
|
||||
Static.Hue = 1153;
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(0.5), Delete);
|
||||
}
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
if (Static != null)
|
||||
Static.Delete();
|
||||
|
||||
Static = null;
|
||||
base.Delete();
|
||||
}
|
||||
|
||||
public override void OnLocationChange(Point3D oldLocation)
|
||||
{
|
||||
Static = new Static(this.ItemID + 1);
|
||||
Static.MoveToWorld(this.Location, this.Map);
|
||||
|
||||
IPooledEnumerable eable = this.Map.GetMobilesInRange(this.Location, 0);
|
||||
|
||||
foreach (Mobile m in eable)
|
||||
{
|
||||
OnMoveOver(m);
|
||||
}
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public override bool OnMoveOver(Mobile m)
|
||||
{
|
||||
if ((m is PlayerMobile || (m is BaseCreature && !((BaseCreature)m).IsMonster)) && m.CanBeHarmful(Owner, false))
|
||||
{
|
||||
if (m is PlayerMobile && Services.TownCryer.TownCryerSystem.UnderMysteriousPotionEffects((PlayerMobile)m, true))
|
||||
{
|
||||
m.SayTo(m, 1158288, 1154); // *You resist Cora's attack!*
|
||||
}
|
||||
else
|
||||
{
|
||||
m.FixedParticles(0x3779, 10, 25, 5002, EffectLayer.Head);
|
||||
m.Mana = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public ManaDrainItem(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(Static);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Static = reader.ReadItem();
|
||||
|
||||
if (Static != null)
|
||||
Static.Delete();
|
||||
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDeath(Container c)
|
||||
{
|
||||
base.OnDeath(c);
|
||||
|
||||
if (0.30 > Utility.RandomDouble())
|
||||
{
|
||||
Mobile m = DemonKnight.FindRandomPlayer(this);
|
||||
|
||||
if (m != null)
|
||||
{
|
||||
Item artifact = VoidPoolRewards.DropRandomArtifact();
|
||||
|
||||
if (artifact != null)
|
||||
{
|
||||
Container pack = m.Backpack;
|
||||
|
||||
if (pack == null || !pack.TryDropItem(m, artifact, false))
|
||||
m.BankBox.DropItem(artifact);
|
||||
|
||||
m.SendLocalizedMessage(1062317); // For your valor in combating the fallen beast, a special artifact has been bestowed on you.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnKilledBy(Mobile mob)
|
||||
{
|
||||
if (Siege.SiegeShard && mob is PlayerMobile)
|
||||
{
|
||||
int chance = Server.Engines.Despise.DespiseBoss.ArtifactChance + (int)Math.Min(10, ((PlayerMobile)mob).Luck / 180);
|
||||
|
||||
if (chance >= Utility.Random(100))
|
||||
{
|
||||
Type t = Server.Engines.Despise.DespiseBoss.Artifacts[Utility.Random(Server.Engines.Despise.DespiseBoss.Artifacts.Length)];
|
||||
|
||||
if (t != null)
|
||||
{
|
||||
Item arty = Loot.Construct(t);
|
||||
|
||||
if (arty != null)
|
||||
{
|
||||
Container pack = mob.Backpack;
|
||||
|
||||
if (pack == null || !pack.TryDropItem(mob, arty, false))
|
||||
{
|
||||
mob.BankBox.DropItem(arty);
|
||||
mob.SendMessage("An artifact has been placed in your bankbox!");
|
||||
}
|
||||
else
|
||||
mob.SendLocalizedMessage(1153440); // An artifact has been placed in your backpack!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CoraTheSorceress(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
using Server;
|
||||
using System;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class CovetousCreature : BaseCreature
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool VoidSpawn { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Level { get; set; }
|
||||
|
||||
public virtual int Stage { get { return Math.Max(1, Level / 5); } }
|
||||
public virtual int MaxStage { get { return 15; } }
|
||||
|
||||
public virtual int StatRatio { get { return Utility.RandomMinMax(35, 60); } }
|
||||
|
||||
public virtual double SkillStart { get { return Utility.RandomMinMax(35, 50); } }
|
||||
public virtual double SkillMax { get { return 160.0; } }
|
||||
|
||||
public virtual int StrStart { get { return Utility.RandomMinMax(91, 100); } }
|
||||
public virtual int DexStart { get { return Utility.RandomMinMax(91, 100); } }
|
||||
public virtual int IntStart { get { return IsMagical ? Utility.RandomMinMax(91, 100) : 1; } }
|
||||
|
||||
public virtual int StrMax { get { return 410; } }
|
||||
public virtual int DexMax { get { return 422; } }
|
||||
public virtual int IntMax { get { return 250; } }
|
||||
|
||||
public virtual int MaxHits { get { return 2400; } }
|
||||
public virtual int MaxStam { get { return 3000; } }
|
||||
public virtual int MaxMana { get { return IsMagical ? 8500 : 1500; } }
|
||||
|
||||
public virtual int MinDamMax { get { return 5; } }
|
||||
public virtual int MaxDamMax { get { return 12; } }
|
||||
|
||||
public virtual int MinDamStart { get { return 5; } }
|
||||
public virtual int MaxDamStart { get { return 15; } }
|
||||
|
||||
public virtual int HitsStart { get { return StrStart + (int)((double)StrStart * ((double)StatRatio / 100.0)); } }
|
||||
public virtual int StamStart { get { return DexStart + (int)((double)DexStart * ((double)StatRatio / 100.0)); } }
|
||||
public virtual int ManaStart { get { return IntStart + (int)((double)IntStart * ((double)StatRatio / 100.0)); } }
|
||||
|
||||
public virtual bool RaiseDamage { get { return true; } }
|
||||
public virtual double RaiseDamageFactor { get { return 0.33; } }
|
||||
|
||||
public virtual int ResistStart { get { return 25; } }
|
||||
public virtual int ResistMax { get { return 95; } }
|
||||
|
||||
public virtual bool IsMagical { get { return AIObject is MageAI; } }
|
||||
|
||||
public override bool GivesFameAndKarmaAward { get { return false; } }
|
||||
public override bool PlayerRangeSensitive { get { return false; } }
|
||||
public override bool CanDestroyObstacles { get { return true; } }
|
||||
|
||||
private Tuple<WayPoint, DateTime> TimeOnWayPoint;
|
||||
|
||||
public CovetousCreature(AIType ai, int level = 60, bool voidspawn = false)
|
||||
: base(ai, FightMode.Closest, 10, 1, 0.2, 0.1)
|
||||
{
|
||||
Level = level;
|
||||
VoidSpawn = voidspawn;
|
||||
|
||||
SetSkill(SkillName.MagicResist, SkillStart);
|
||||
SetSkill(SkillName.Tactics, SkillStart);
|
||||
SetSkill(SkillName.Wrestling, SkillStart);
|
||||
SetSkill(SkillName.Anatomy, SkillStart);
|
||||
|
||||
switch (ai)
|
||||
{
|
||||
default: break;
|
||||
case AIType.AI_Mage:
|
||||
SetSkill(SkillName.Magery, SkillStart);
|
||||
SetSkill(SkillName.EvalInt, SkillStart);
|
||||
SetSkill(SkillName.Meditation, SkillStart);
|
||||
break;
|
||||
}
|
||||
|
||||
SetStr(StrStart);
|
||||
SetDex(DexStart);
|
||||
SetInt(IntStart);
|
||||
|
||||
SetHits(HitsStart);
|
||||
SetStam(StamStart);
|
||||
SetMana(ManaStart);
|
||||
|
||||
SetDamage(MinDamStart, MaxDamStart);
|
||||
|
||||
SetDamageType(ResistanceType.Physical, 100);
|
||||
|
||||
SetResistance(ResistanceType.Physical, ResistStart - 5, ResistStart + 5);
|
||||
SetResistance(ResistanceType.Fire, ResistStart - 5, ResistStart + 5);
|
||||
SetResistance(ResistanceType.Cold, ResistStart - 5, ResistStart + 5);
|
||||
SetResistance(ResistanceType.Poison, ResistStart - 5, ResistStart + 5);
|
||||
SetResistance(ResistanceType.Energy, ResistStart - 5, ResistStart + 5);
|
||||
|
||||
if (Stage > 1)
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(.5), SetPower);
|
||||
|
||||
Fame = Math.Min(8500, Level * 142);
|
||||
Karma = Math.Min(8500, Level * 142) * -1;
|
||||
}
|
||||
|
||||
public override void OnThink()
|
||||
{
|
||||
base.OnThink();
|
||||
|
||||
if (!Alive)
|
||||
return;
|
||||
|
||||
if (TimeOnWayPoint == null && CurrentWayPoint != null)
|
||||
{
|
||||
TimeOnWayPoint = new Tuple<WayPoint, DateTime>(CurrentWayPoint, DateTime.UtcNow + TimeSpan.FromMinutes(2));
|
||||
}
|
||||
else if (TimeOnWayPoint != null && TimeOnWayPoint.Item1 == CurrentWayPoint && TimeOnWayPoint.Item2 < DateTime.UtcNow)
|
||||
{
|
||||
if (CheckCanTeleport())
|
||||
MoveToWorld(CurrentWayPoint.Location, this.Map);
|
||||
}
|
||||
else if (TimeOnWayPoint != null && TimeOnWayPoint.Item1 != CurrentWayPoint)
|
||||
{
|
||||
TimeOnWayPoint = new Tuple<WayPoint, DateTime>(CurrentWayPoint, DateTime.UtcNow + TimeSpan.FromMinutes(2));
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual bool CheckCanTeleport()
|
||||
{
|
||||
if (CurrentWayPoint == null || Frozen || Paralyzed || (Combatant is Mobile && ((Mobile)Combatant).InLOS(this)))
|
||||
return false;
|
||||
|
||||
bool canTeleport = true;
|
||||
|
||||
IPooledEnumerable eable = this.Map.GetMobilesInRange(this.Location, 10);
|
||||
|
||||
foreach (Mobile m in eable)
|
||||
{
|
||||
if (m is PlayerMobile && m.AccessLevel == AccessLevel.Player)
|
||||
{
|
||||
canTeleport = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (canTeleport)
|
||||
{
|
||||
eable = this.Map.GetItemsInRange(this.Location, 8);
|
||||
|
||||
foreach (Item item in eable)
|
||||
{
|
||||
int id = item.ItemID;
|
||||
|
||||
if (id == 0x82 || id == 0x3946 || id == 0x3956 || id == 0x3967 || id == 0x3979)
|
||||
{
|
||||
canTeleport = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
return canTeleport;
|
||||
}
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
if(!VoidSpawn)
|
||||
AddLoot(LootPack.Rich, Math.Max(1, Stage / 2));
|
||||
}
|
||||
|
||||
public virtual void SetPower()
|
||||
{
|
||||
foreach (Skill skill in Skills)
|
||||
{
|
||||
if (skill != null && skill.Base > 0 && skill.Base < SkillMax)
|
||||
{
|
||||
double toRaise = ((SkillMax / MaxStage) * Stage) + Utility.RandomMinMax(-5, 5);
|
||||
|
||||
if (toRaise > skill.Base)
|
||||
skill.Base = Math.Min(SkillMax, toRaise);
|
||||
}
|
||||
}
|
||||
|
||||
SetResistance(ResistanceType.Physical, ((ResistMax / MaxStage) * Stage) + Utility.RandomMinMax(-5, 5));
|
||||
SetResistance(ResistanceType.Fire, ((ResistMax / MaxStage) * Stage) + Utility.RandomMinMax(-5, 5));
|
||||
SetResistance(ResistanceType.Cold, ((ResistMax / MaxStage) * Stage) + Utility.RandomMinMax(-5, 5));
|
||||
SetResistance(ResistanceType.Poison, ((ResistMax / MaxStage) * Stage) + Utility.RandomMinMax(-5, 5));
|
||||
SetResistance(ResistanceType.Energy, ((ResistMax / MaxStage) * Stage) + Utility.RandomMinMax(-5, 5));
|
||||
|
||||
int strRaise = ((StrMax / MaxStage) * Stage) + Utility.RandomMinMax(-5, 5);
|
||||
int dexRaise = ((DexMax / MaxStage) * Stage) + Utility.RandomMinMax(-5, 5);
|
||||
int intRaise = ((IntMax / MaxStage) * Stage) + Utility.RandomMinMax(-5, 5);
|
||||
|
||||
if (strRaise > RawStr)
|
||||
SetStr(Math.Min(StrMax, strRaise));
|
||||
|
||||
if (dexRaise > RawDex)
|
||||
SetDex(Math.Min(DexMax, dexRaise));
|
||||
|
||||
if (intRaise > RawInt)
|
||||
SetInt(Math.Min(IntMax, intRaise));
|
||||
|
||||
int hitsRaise = ((MaxHits / 60) * Level) + Utility.RandomMinMax(-5, 5);
|
||||
int stamRaise = ((MaxStam / 60) * Level) + Utility.RandomMinMax(-5, 5);
|
||||
int manaRaise = ((MaxMana / 60) * Level) + Utility.RandomMinMax(-5, 5);
|
||||
|
||||
if (hitsRaise > HitsMax)
|
||||
SetHits(Math.Min(MaxHits, hitsRaise));
|
||||
|
||||
if (stamRaise > StamMax)
|
||||
SetStam(Math.Min(MaxStam, stamRaise));
|
||||
|
||||
if (manaRaise > ManaMax)
|
||||
SetMana(Math.Min(MaxMana, manaRaise));
|
||||
|
||||
if (RaiseDamage && Utility.RandomDouble() < RaiseDamageFactor)
|
||||
{
|
||||
DamageMin = Math.Min(MinDamMax, DamageMin + 1);
|
||||
DamageMax = Math.Min(MaxDamMax, DamageMax + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDeath(Container c)
|
||||
{
|
||||
base.OnDeath(c);
|
||||
}
|
||||
|
||||
public CovetousCreature(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(Level);
|
||||
writer.Write(VoidSpawn);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Level = reader.ReadInt();
|
||||
VoidSpawn = reader.ReadBool();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
using Server;
|
||||
using System;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
[CorpseName("an earth elemental corpse")]
|
||||
public class CovetousEarthElemental : CovetousCreature
|
||||
{
|
||||
[Constructable]
|
||||
public CovetousEarthElemental() : base(AIType.AI_Melee)
|
||||
{
|
||||
Name = "an earth elemental";
|
||||
Body = 14;
|
||||
BaseSoundID = 268;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public CovetousEarthElemental(int level, bool voidSpawn) : base(AIType.AI_Melee, level, voidSpawn)
|
||||
{
|
||||
Name = "an earth elemental";
|
||||
Body = 14;
|
||||
BaseSoundID = 268;
|
||||
}
|
||||
|
||||
public CovetousEarthElemental(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[CorpseName("a water elemental corpse")]
|
||||
public class CovetousWaterElemental : CovetousCreature
|
||||
{
|
||||
[Constructable]
|
||||
public CovetousWaterElemental() : base(AIType.AI_Mage)
|
||||
{
|
||||
Name = "a water elemental";
|
||||
Body = 16;
|
||||
BaseSoundID = 278;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public CovetousWaterElemental(int level, bool voidSpawn) : base(AIType.AI_Melee, level, voidSpawn)
|
||||
{
|
||||
Name = "a water elemental";
|
||||
Body = 16;
|
||||
BaseSoundID = 278;
|
||||
}
|
||||
|
||||
public CovetousWaterElemental(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[CorpseName("a vortex elemental corpse")]
|
||||
public class VortexElemental : CovetousCreature
|
||||
{
|
||||
[Constructable]
|
||||
public VortexElemental() : base(AIType.AI_Melee)
|
||||
{
|
||||
Name = "a vortex elemental";
|
||||
Body = 13;
|
||||
Hue = 0x4001;
|
||||
BaseSoundID = 655;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public VortexElemental(int level, bool voidSpawn) : base(AIType.AI_Melee, level, voidSpawn)
|
||||
{
|
||||
Name = "a vortex elemental";
|
||||
Body = 13;
|
||||
Hue = 0x4001;
|
||||
BaseSoundID = 655;
|
||||
}
|
||||
|
||||
public VortexElemental(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[CorpseName("a searing elemental corpse")]
|
||||
public class SearingElemental : CovetousCreature
|
||||
{
|
||||
[Constructable]
|
||||
public SearingElemental() : base(AIType.AI_Mage)
|
||||
{
|
||||
Name = "a searing elemental";
|
||||
Body = 15;
|
||||
BaseSoundID = 838;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public SearingElemental(int level, bool voidSpawn) : base(AIType.AI_Mage, level, voidSpawn)
|
||||
{
|
||||
Name = "a searing elemental";
|
||||
Body = 15;
|
||||
BaseSoundID = 838;
|
||||
}
|
||||
|
||||
public SearingElemental(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[CorpseName("a venom elemental corpse")]
|
||||
public class VenomElemental : CovetousCreature
|
||||
{
|
||||
[Constructable]
|
||||
public VenomElemental() : base(AIType.AI_Mage)
|
||||
{
|
||||
Name = "a venom elemental";
|
||||
Body = 162;
|
||||
BaseSoundID = 263;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public VenomElemental(int level, bool voidSpawn) : base(AIType.AI_Mage, level, voidSpawn)
|
||||
{
|
||||
Name = "a venom elemental";
|
||||
Body = 162;
|
||||
BaseSoundID = 263;
|
||||
}
|
||||
|
||||
public override bool BleedImmune { get { return true; } }
|
||||
public override Poison PoisonImmune { get { return Poison.Lethal; } }
|
||||
public override Poison HitPoison { get { return Poison.Lethal; } }
|
||||
public override double HitPoisonChance { get { return 0.75; } }
|
||||
public override int TreasureMapLevel { get { return 5; } }
|
||||
|
||||
public VenomElemental(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
using Server;
|
||||
using System;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
[CorpseName("a lizardman corpse")]
|
||||
public class LizardmanWitchdoctor : CovetousCreature
|
||||
{
|
||||
[Constructable]
|
||||
public LizardmanWitchdoctor() : base(AIType.AI_Mage)
|
||||
{
|
||||
Name = "a lizardman witchdoctor";
|
||||
Body = Utility.RandomList(35, 36);
|
||||
BaseSoundID = 417;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public LizardmanWitchdoctor(int level, bool voidSpawn) : base(AIType.AI_Mage, level, voidSpawn)
|
||||
{
|
||||
Name = "a lizardman witchdoctor";
|
||||
Body = Utility.RandomList(35, 36);
|
||||
BaseSoundID = 417;
|
||||
}
|
||||
|
||||
public LizardmanWitchdoctor(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[CorpseName("an orcish corpse")]
|
||||
public class OrcFootSoldier : CovetousCreature
|
||||
{
|
||||
[Constructable]
|
||||
public OrcFootSoldier() : base(AIType.AI_Melee)
|
||||
{
|
||||
Name = "an orc foot soldier";
|
||||
Body = 17;
|
||||
BaseSoundID = 0x45A;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public OrcFootSoldier(int level, bool voidSpawn) : base(AIType.AI_Melee, level, voidSpawn)
|
||||
{
|
||||
Name = "an orc foot soldier";
|
||||
Body = 17;
|
||||
BaseSoundID = 0x45A;
|
||||
}
|
||||
|
||||
public OrcFootSoldier(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[CorpseName("a ratman corpse")]
|
||||
public class RatmanAssassin : CovetousCreature
|
||||
{
|
||||
[Constructable]
|
||||
public RatmanAssassin() : base(AIType.AI_Melee)
|
||||
{
|
||||
Name = "ratman assassin";
|
||||
Body = 42;
|
||||
BaseSoundID = 437;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public RatmanAssassin(int level, bool voidSpawn) : base(AIType.AI_Melee, level, voidSpawn)
|
||||
{
|
||||
Name = "ratman assassin";
|
||||
Body = 42;
|
||||
BaseSoundID = 437;
|
||||
}
|
||||
|
||||
public RatmanAssassin(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[CorpseName("an ogre corpse")]
|
||||
public class OgreBoneCrusher : CovetousCreature
|
||||
{
|
||||
[Constructable]
|
||||
public OgreBoneCrusher() : base(AIType.AI_Melee)
|
||||
{
|
||||
Name = "an ogre bone crusher";
|
||||
Body = 1;
|
||||
BaseSoundID = 427;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public OgreBoneCrusher(int level, bool voidSpawn) : base(AIType.AI_Melee, level, voidSpawn)
|
||||
{
|
||||
Name = "an ogre bone crusher";
|
||||
Body = 1;
|
||||
BaseSoundID = 427;
|
||||
}
|
||||
|
||||
public OgreBoneCrusher(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[CorpseName("a titan corpse")]
|
||||
public class TitanRockHunter : CovetousCreature
|
||||
{
|
||||
[Constructable]
|
||||
public TitanRockHunter() : base(AIType.AI_Mage)
|
||||
{
|
||||
Name = "a titan rockhurler";
|
||||
Body = 76;
|
||||
BaseSoundID = 609;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public TitanRockHunter(int level, bool voidSpawn) : base(AIType.AI_Mage, level, voidSpawn)
|
||||
{
|
||||
Name = "a titan rockhurler";
|
||||
Body = 76;
|
||||
BaseSoundID = 609;
|
||||
}
|
||||
|
||||
public TitanRockHunter(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
using Server;
|
||||
using System;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
[CorpseName("an alligator corpse")]
|
||||
public class WarAlligator : CovetousCreature
|
||||
{
|
||||
[Constructable]
|
||||
public WarAlligator() : base(AIType.AI_Melee)
|
||||
{
|
||||
Name = "a war alligator";
|
||||
Body = 0xCA;
|
||||
BaseSoundID = 660;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public WarAlligator(int level, bool voidSpawn) : base(AIType.AI_Melee, level, voidSpawn)
|
||||
{
|
||||
Name = "a war alligator";
|
||||
Body = 0xCA;
|
||||
BaseSoundID = 660;
|
||||
}
|
||||
|
||||
public WarAlligator(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[CorpseName("a magma lizard corpse")]
|
||||
public class MagmaLizard : CovetousCreature
|
||||
{
|
||||
[Constructable]
|
||||
public MagmaLizard() : base(AIType.AI_Melee)
|
||||
{
|
||||
Name = "a magma lizard";
|
||||
Body = 0xCE;
|
||||
Hue = Utility.RandomList(0x647, 0x650, 0x659, 0x662, 0x66B, 0x674);
|
||||
BaseSoundID = 0x5A;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public MagmaLizard(int level, bool voidSpawn) : base(AIType.AI_Melee, level, voidSpawn)
|
||||
{
|
||||
Name = "a magma lizard";
|
||||
Body = 0xCE;
|
||||
Hue = Utility.RandomList(0x647, 0x650, 0x659, 0x662, 0x66B, 0x674);
|
||||
BaseSoundID = 0x5A;
|
||||
}
|
||||
|
||||
public MagmaLizard(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[CorpseName("a drake corpse")]
|
||||
public class ViciousDrake : CovetousCreature
|
||||
{
|
||||
[Constructable]
|
||||
public ViciousDrake() : base(AIType.AI_Melee)
|
||||
{
|
||||
Name = "a vicious drake";
|
||||
Body = Utility.RandomList(60, 61);
|
||||
BaseSoundID = 362;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public ViciousDrake(int level, bool voidSpawn) : base(AIType.AI_Melee, level, voidSpawn)
|
||||
{
|
||||
Name = "a vicious drake";
|
||||
Body = Utility.RandomList(60, 61);
|
||||
BaseSoundID = 362;
|
||||
}
|
||||
|
||||
public ViciousDrake(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[CorpseName("a wyvern corpse")]
|
||||
public class CorruptedWyvern : CovetousCreature
|
||||
{
|
||||
[Constructable]
|
||||
public CorruptedWyvern() : base(AIType.AI_Mage)
|
||||
{
|
||||
Name = "a corrupted wyvern";
|
||||
Body = 62;
|
||||
BaseSoundID = 362;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public CorruptedWyvern(int level, bool voidSpawn) : base(AIType.AI_Mage, level, voidSpawn)
|
||||
{
|
||||
Name = "a corrupted wyvern";
|
||||
Body = 62;
|
||||
BaseSoundID = 362;
|
||||
}
|
||||
|
||||
public CorruptedWyvern(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[CorpseName("a covetous wyrm corpse")]
|
||||
public class CovetousWyrm : CovetousCreature
|
||||
{
|
||||
[Constructable]
|
||||
public CovetousWyrm()
|
||||
: base(AIType.AI_Necro)
|
||||
{
|
||||
Name = "a covetous wyrm";
|
||||
Body = 106;
|
||||
BaseSoundID = 362;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public CovetousWyrm(int level, bool voidSpawn) : base(AIType.AI_Mage, level, voidSpawn)
|
||||
{
|
||||
Name = "a covetous wyrm";
|
||||
Body = 106;
|
||||
BaseSoundID = 362;
|
||||
}
|
||||
|
||||
public CovetousWyrm(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
using Server;
|
||||
using System;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
[CorpseName("an angered spirit corpse")]
|
||||
public class AngeredSpirit : CovetousCreature
|
||||
{
|
||||
[Constructable]
|
||||
public AngeredSpirit() : base(AIType.AI_Mage)
|
||||
{
|
||||
Name = "an angered spirit";
|
||||
Body = 3;
|
||||
BaseSoundID = 471;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public AngeredSpirit(int level, bool voidSpawn) : base(AIType.AI_Mage, level, voidSpawn)
|
||||
{
|
||||
Name = "an angered spirit";
|
||||
Body = 3;
|
||||
BaseSoundID = 471;
|
||||
}
|
||||
|
||||
public AngeredSpirit(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[CorpseName("a bone swordslinger corpse")]
|
||||
public class BoneSwordSlinger : CovetousCreature
|
||||
{
|
||||
[Constructable]
|
||||
public BoneSwordSlinger() : base(AIType.AI_Melee)
|
||||
{
|
||||
Name = "a bone swordslinger";
|
||||
Body = 147;
|
||||
BaseSoundID = 451;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public BoneSwordSlinger(int level, bool voidSpawn) : base(AIType.AI_Melee, level, voidSpawn)
|
||||
{
|
||||
Name = "a bone sword slinger";
|
||||
Body = 147;
|
||||
BaseSoundID = 451;
|
||||
}
|
||||
|
||||
public BoneSwordSlinger(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[CorpseName("a vile cadaver")]
|
||||
public class VileCadaver : CovetousCreature
|
||||
{
|
||||
[Constructable]
|
||||
public VileCadaver() : base(AIType.AI_Melee)
|
||||
{
|
||||
Name = "a vile cadaver";
|
||||
Body = 154;
|
||||
BaseSoundID = 471;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public VileCadaver(int level, bool voidSpawn) : base(AIType.AI_Melee, level, voidSpawn)
|
||||
{
|
||||
Name = "a vile cadaver";
|
||||
Body = 154;
|
||||
BaseSoundID = 471;
|
||||
}
|
||||
|
||||
public VileCadaver(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[CorpseName("a liche's corpse")]
|
||||
public class DiseasedLich : CovetousCreature
|
||||
{
|
||||
[Constructable]
|
||||
public DiseasedLich() : base(AIType.AI_Mage)
|
||||
{
|
||||
Name = "a diseased lich";
|
||||
Body = 24;
|
||||
BaseSoundID = 0x3E9;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public DiseasedLich(int level, bool voidSpawn) : base(AIType.AI_Mage, level, voidSpawn)
|
||||
{
|
||||
Name = "a diseased lich";
|
||||
Body = 24;
|
||||
BaseSoundID = 0x3E9;
|
||||
}
|
||||
|
||||
public DiseasedLich(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[CorpseName("a revenant corpse")]
|
||||
public class CovetousRevenant : CovetousCreature
|
||||
{
|
||||
public override bool AlwaysMurderer { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public CovetousRevenant() : base(AIType.AI_Mage)
|
||||
{
|
||||
Name = "a covetous revenant";
|
||||
Body = 400;
|
||||
Hue = 0x847E;
|
||||
|
||||
var shroud = new Server.Items.Robe();
|
||||
shroud.ItemID = 0x2683;
|
||||
shroud.Hue = 0x4001;
|
||||
shroud.Movable = false;
|
||||
SetWearable(shroud);
|
||||
|
||||
var boots = new Server.Items.Boots();
|
||||
boots.Hue = 0x4001;
|
||||
boots.Movable = false;
|
||||
SetWearable(boots);
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public CovetousRevenant(int level, bool voidSpawn) : base(AIType.AI_Mage, level, voidSpawn)
|
||||
{
|
||||
Name = "a covetous revenant";
|
||||
Body = 400;
|
||||
//BaseSoundID = 609;
|
||||
//TODO: Soundid
|
||||
}
|
||||
|
||||
public CovetousRevenant(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
using Server;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Mobiles;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Engines.VoidPool
|
||||
{
|
||||
public class VelaTheSorceress : BaseCreature
|
||||
{
|
||||
public override bool IsInvulnerable { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public VelaTheSorceress()
|
||||
: base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2)
|
||||
{
|
||||
Name = "Vela";
|
||||
Title = "the sorceress";
|
||||
Blessed = true;
|
||||
|
||||
SetStr(110);
|
||||
SetDex(100);
|
||||
SetInt(1000);
|
||||
|
||||
Hue = Utility.RandomSkinHue();
|
||||
Body = 0x191;
|
||||
HairItemID = 0x203C;
|
||||
HairHue = 0x46D;
|
||||
|
||||
SetWearable(new FancyShirt(), 1928);
|
||||
SetWearable(new LeatherLegs(), 1928);
|
||||
SetWearable(new ThighBoots(), 1917);
|
||||
|
||||
Item item = new BraceletOfProtection();
|
||||
item.Movable = false;
|
||||
PackItem(item);
|
||||
|
||||
item = new Hephaestus();
|
||||
item.Movable = false;
|
||||
PackItem(item);
|
||||
|
||||
item = new GargishHephaestus();
|
||||
item.Movable = false;
|
||||
PackItem(item);
|
||||
|
||||
item = new BlightOfTheTundra();
|
||||
item.Movable = false;
|
||||
PackItem(item);
|
||||
|
||||
item = new GargishBlightOfTheTundra();
|
||||
item.Movable = false;
|
||||
PackItem(item);
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from is PlayerMobile && from.InRange(this.Location, 5))
|
||||
from.SendGump(new VoidPoolRewardGump(this, from as PlayerMobile));
|
||||
}
|
||||
|
||||
public VelaTheSorceress(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
list.Add(1152664); // Covetous Void Pool Reward Vendor
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(1);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if (version == 0)
|
||||
{
|
||||
Blessed = true;
|
||||
|
||||
Item item = FindItemOnLayer(Layer.Shirt);
|
||||
if (item != null)
|
||||
item.Delete();
|
||||
|
||||
item = FindItemOnLayer(Layer.Pants);
|
||||
if (item != null)
|
||||
item.Delete();
|
||||
|
||||
item = FindItemOnLayer(Layer.Shoes);
|
||||
if (item != null)
|
||||
item.Delete();
|
||||
|
||||
SetWearable(new FancyShirt(), 1928);
|
||||
SetWearable(new LeatherLegs(), 1928);
|
||||
SetWearable(new ThighBoots(), 1917);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,403 @@
|
||||
using Server;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Mobiles;
|
||||
using Server.Commands;
|
||||
using Server.Items;
|
||||
using System.Linq;
|
||||
|
||||
namespace Server.Engines.VoidPool
|
||||
{
|
||||
public static class Generate
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("SetupNewCovetous", AccessLevel.Administrator, Setup);
|
||||
CommandSystem.Register("DeleteCovetous", AccessLevel.Administrator, Delete);
|
||||
}
|
||||
|
||||
private static void Delete(CommandEventArgs e)
|
||||
{
|
||||
WeakEntityCollection.Delete("newcovetous");
|
||||
VoidPoolController.InstanceTram = null;
|
||||
VoidPoolController.InstanceFel = null;
|
||||
}
|
||||
|
||||
public static void Setup(CommandEventArgs e)
|
||||
{
|
||||
if (VoidPoolController.InstanceTram != null || VoidPoolController.InstanceFel != null)
|
||||
e.Mobile.SendMessage("This has already been setup!");
|
||||
else
|
||||
{
|
||||
var one = new VoidPoolController(Map.Trammel);
|
||||
WeakEntityCollection.Add("newcovetous", one);
|
||||
one.MoveToWorld(new Point3D(5605, 1998, 10), Map.Trammel);
|
||||
|
||||
var two = new VoidPoolController(Map.Felucca);
|
||||
WeakEntityCollection.Add("newcovetous", two);
|
||||
two.MoveToWorld(new Point3D(5605, 1998, 10), Map.Felucca);
|
||||
|
||||
int id = 0;
|
||||
int hue = 0;
|
||||
|
||||
for (int x = 5497; x <= 5503; x++)
|
||||
{
|
||||
for (int y = 1995; y <= 2001; y++)
|
||||
{
|
||||
if (x == 5497 && y == 1995) id = 1886;
|
||||
else if (x == 5497 && y == 2001) id = 1887;
|
||||
else if (x == 5503 && y == 1995) id = 1888;
|
||||
else if (x == 5503 && y == 2001) id = 1885;
|
||||
else if (x == 5497) id = 1874;
|
||||
else if (x == 5503) id = 1876;
|
||||
else if (y == 1995) id = 1873;
|
||||
else if (y == 2001) id = 1875;
|
||||
else
|
||||
{
|
||||
//id = 1168;
|
||||
id = Utility.Random(8511, 6);
|
||||
}
|
||||
|
||||
hue = id >= 8511 ? 0 : 1954;
|
||||
|
||||
var item = new Static(id);
|
||||
item.Name = "Void Pool";
|
||||
item.Hue = hue;
|
||||
WeakEntityCollection.Add("newcovetous", item);
|
||||
item.MoveToWorld(new Point3D(x, y, 5), Map.Trammel);
|
||||
|
||||
item = new Static(id);
|
||||
item.Name = "Void Pool";
|
||||
item.Hue = hue;
|
||||
WeakEntityCollection.Add("newcovetous", item);
|
||||
item.MoveToWorld(new Point3D(x, y, 5), Map.Felucca);
|
||||
}
|
||||
}
|
||||
|
||||
XmlSpawner spawner = new XmlSpawner("corathesorceress");
|
||||
WeakEntityCollection.Add("newcovetous", spawner);
|
||||
spawner.MoveToWorld(new Point3D(5457, 1808, 0), Map.Trammel);
|
||||
spawner.SpawnRange = 5;
|
||||
spawner.MinDelay = TimeSpan.FromHours(1);
|
||||
spawner.MaxDelay = TimeSpan.FromHours(1.5);
|
||||
spawner.DoRespawn = true;
|
||||
|
||||
spawner = new XmlSpawner("corathesorceress");
|
||||
WeakEntityCollection.Add("newcovetous", spawner);
|
||||
spawner.MoveToWorld(new Point3D(5457, 1808, 0), Map.Felucca);
|
||||
spawner.SpawnRange = 5;
|
||||
spawner.MinDelay = TimeSpan.FromHours(1);
|
||||
spawner.MaxDelay = TimeSpan.FromHours(1.5);
|
||||
spawner.DoRespawn = true;
|
||||
|
||||
spawner = new XmlSpawner("velathesorceress");
|
||||
WeakEntityCollection.Add("newcovetous", spawner);
|
||||
spawner.MoveToWorld(new Point3D(2254, 1207, 0), Map.Trammel);
|
||||
spawner.SpawnRange = 0;
|
||||
spawner.DoRespawn = true;
|
||||
|
||||
spawner = new XmlSpawner("velathesorceress");
|
||||
WeakEntityCollection.Add("newcovetous", spawner);
|
||||
spawner.MoveToWorld(new Point3D(2254, 1207, 0), Map.Felucca);
|
||||
spawner.SpawnRange = 0;
|
||||
spawner.DoRespawn = true;
|
||||
|
||||
AddWaypoints();
|
||||
ConvertSpawners();
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddWaypoints()
|
||||
{
|
||||
var one = VoidPoolController.InstanceTram;
|
||||
var two = VoidPoolController.InstanceFel;
|
||||
|
||||
if (one == null || two == null)
|
||||
return;
|
||||
|
||||
foreach (var w in one.WaypointsA.Where(w => w != null && !w.Deleted)) w.Delete();
|
||||
foreach (var w in one.WaypointsB.Where(w => w != null && !w.Deleted)) w.Delete();
|
||||
|
||||
foreach(var w in two.WaypointsA.Where(w => w != null && !w.Deleted)) w.Delete();
|
||||
foreach (var w in two.WaypointsB.Where(w => w != null && !w.Deleted)) w.Delete();
|
||||
|
||||
// patha
|
||||
var wp = new WayPoint();
|
||||
wp.MoveToWorld(new Point3D(5590, 2024, 0), Map.Trammel);
|
||||
one.WaypointsA.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5590, 2024, 0), Map.Felucca);
|
||||
two.WaypointsA.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5578, 2029, 0), Map.Trammel);
|
||||
one.WaypointsA.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5578, 2029, 0), Map.Felucca);
|
||||
two.WaypointsA.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5566, 2027, 0), Map.Trammel);
|
||||
one.WaypointsA.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5566, 2027, 0), Map.Felucca);
|
||||
two.WaypointsA.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5555, 2021, 0), Map.Trammel);
|
||||
one.WaypointsA.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5555, 2021, 0), Map.Felucca);
|
||||
two.WaypointsA.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
wp.MoveToWorld(new Point3D(5545, 2015, 0), Map.Trammel);
|
||||
one.WaypointsA.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5545, 2015, 0), Map.Felucca);
|
||||
two.WaypointsA.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5537, 2020, 0), Map.Trammel);
|
||||
one.WaypointsA.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5537, 2020, 0), Map.Felucca);
|
||||
two.WaypointsA.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5527, 2015, 0), Map.Trammel);
|
||||
one.WaypointsA.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5527, 2015, 0), Map.Felucca);
|
||||
two.WaypointsA.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5509, 2005, 0), Map.Trammel);
|
||||
one.WaypointsA.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5509, 2005, 0), Map.Felucca);
|
||||
two.WaypointsA.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5500, 1998, 0), Map.Trammel);
|
||||
one.WaypointsA.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5500, 1998, 0), Map.Felucca);
|
||||
two.WaypointsA.Add(wp);
|
||||
|
||||
// pathb
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5469, 2016, 0), Map.Trammel);
|
||||
one.WaypointsB.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5469, 2016, 0), Map.Felucca);
|
||||
two.WaypointsB.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5478, 2025, 0), Map.Trammel);
|
||||
one.WaypointsB.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5478, 2025, 0), Map.Felucca);
|
||||
two.WaypointsB.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5484, 2029, 0), Map.Trammel);
|
||||
one.WaypointsB.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5484, 2029, 0), Map.Felucca);
|
||||
two.WaypointsB.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5490, 2027, 0), Map.Trammel);
|
||||
one.WaypointsB.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5490, 2027, 0), Map.Felucca);
|
||||
two.WaypointsB.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5504, 2027, 0), Map.Trammel);
|
||||
one.WaypointsB.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5504, 2027, 0), Map.Felucca);
|
||||
two.WaypointsB.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5516, 2020, 0), Map.Trammel);
|
||||
one.WaypointsB.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5516, 2020, 0), Map.Felucca);
|
||||
two.WaypointsB.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5524, 2012, 0), Map.Trammel);
|
||||
one.WaypointsB.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5524, 2012, 0), Map.Felucca);
|
||||
two.WaypointsB.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5513, 2005, 0), Map.Trammel);
|
||||
one.WaypointsB.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5513, 2005, 0), Map.Felucca);
|
||||
two.WaypointsB.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5502, 2004, 0), Map.Trammel);
|
||||
one.WaypointsB.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5502, 2004, 0), Map.Felucca);
|
||||
two.WaypointsB.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5500, 1998, 0), Map.Trammel);
|
||||
one.WaypointsB.Add(wp);
|
||||
|
||||
wp = new WayPoint();
|
||||
WeakEntityCollection.Add("newcovetous", wp);
|
||||
wp.MoveToWorld(new Point3D(5500, 1998, 0), Map.Felucca);
|
||||
two.WaypointsB.Add(wp);
|
||||
|
||||
for (int i = 0; i < one.WaypointsA.Count; i++)
|
||||
{
|
||||
WayPoint waypoint = one.WaypointsA[i];
|
||||
|
||||
if (i < one.WaypointsA.Count - 1)
|
||||
waypoint.NextPoint = one.WaypointsA[i + 1];
|
||||
}
|
||||
|
||||
for (int i = 0; i < one.WaypointsB.Count; i++)
|
||||
{
|
||||
WayPoint waypoint = one.WaypointsB[i];
|
||||
|
||||
if (i < one.WaypointsB.Count - 1)
|
||||
waypoint.NextPoint = one.WaypointsB[i + 1];
|
||||
}
|
||||
|
||||
for (int i = 0; i < two.WaypointsA.Count; i++)
|
||||
{
|
||||
WayPoint waypoint = two.WaypointsA[i];
|
||||
|
||||
if (i < two.WaypointsA.Count - 1)
|
||||
waypoint.NextPoint = two.WaypointsA[i + 1];
|
||||
}
|
||||
|
||||
for (int i = 0; i < two.WaypointsB.Count; i++)
|
||||
{
|
||||
WayPoint waypoint = two.WaypointsB[i];
|
||||
|
||||
if (i < two.WaypointsB.Count - 1)
|
||||
waypoint.NextPoint = two.WaypointsB[i + 1];
|
||||
}
|
||||
|
||||
one.WaypointACount = one.WaypointsA.Count;
|
||||
one.WaypointBCount = one.WaypointsB.Count;
|
||||
|
||||
two.WaypointACount = two.WaypointsA.Count;
|
||||
two.WaypointBCount = two.WaypointsB.Count;
|
||||
}
|
||||
|
||||
private static Rectangle2D _SpawnerBounds = new Rectangle2D(5383, 1845, 125, 115);
|
||||
|
||||
public static void ConvertSpawners()
|
||||
{
|
||||
Region tram = Region.Regions.FirstOrDefault(r => r.Map == Map.Trammel && r.Name == "Covetous");
|
||||
Region fel = Region.Regions.FirstOrDefault(r => r.Map == Map.Felucca && r.Name == "Covetous");
|
||||
|
||||
ConvertRegionSpawners(tram);
|
||||
ConvertRegionSpawners(fel);
|
||||
}
|
||||
|
||||
public static void ConvertRegionSpawners(Region r)
|
||||
{
|
||||
if (r == null)
|
||||
return;
|
||||
|
||||
List<XmlSpawner> list = new List<XmlSpawner>();
|
||||
|
||||
foreach (Sector s in r.Sectors)
|
||||
{
|
||||
foreach (Item i in s.Items.Where(i => i is XmlSpawner && _SpawnerBounds.Contains(i)))
|
||||
{
|
||||
XmlSpawner spawner = i as XmlSpawner;
|
||||
|
||||
foreach (XmlSpawner.SpawnObject obj in spawner.SpawnObjects)
|
||||
{
|
||||
if (obj.TypeName != null)
|
||||
{
|
||||
string name = obj.TypeName.ToLower();
|
||||
|
||||
if (name == "gazer" || name == "gazerlarva")
|
||||
obj.TypeName = "StrangeGazer";
|
||||
else if (name == "headlessone")
|
||||
obj.TypeName = "HeadlessMiner";
|
||||
else if (name == "harpy")
|
||||
obj.TypeName = "DazzledHarpy";
|
||||
else if (name == "stoneharpy")
|
||||
obj.TypeName = "VampireMongbat";
|
||||
}
|
||||
}
|
||||
|
||||
list.Add(spawner);
|
||||
}
|
||||
}
|
||||
|
||||
list.ForEach(spawner => spawner.DoRespawn = true);
|
||||
|
||||
ColUtility.Free(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
251
Scripts/Services/Revamped Dungeons/Covetous Void Spawn/Gumps.cs
Normal file
251
Scripts/Services/Revamped Dungeons/Covetous Void Spawn/Gumps.cs
Normal file
@@ -0,0 +1,251 @@
|
||||
using Server;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Mobiles;
|
||||
using Server.Items;
|
||||
using Server.Gumps;
|
||||
using System.Linq;
|
||||
using Server.Engines.Points;
|
||||
using Server.Commands;
|
||||
|
||||
namespace Server.Engines.VoidPool
|
||||
{
|
||||
public enum ScoreType
|
||||
{
|
||||
Current,
|
||||
BestSingle,
|
||||
OverallTotal,
|
||||
BestWave
|
||||
}
|
||||
|
||||
public class VoidPoolGump : Gump
|
||||
{
|
||||
public static readonly int Red = 0x4800;
|
||||
public static readonly int Orange = 0xB104;
|
||||
|
||||
public PlayerMobile User { get; set; }
|
||||
public VoidPoolController Controller { get; set; }
|
||||
|
||||
public VoidPoolGump(VoidPoolController controller, PlayerMobile pm) : base(50, 50)
|
||||
{
|
||||
Controller = controller;
|
||||
User = pm;
|
||||
|
||||
AddGumpLayout();
|
||||
}
|
||||
|
||||
public void AddGumpLayout()
|
||||
{
|
||||
AddBackground(0, 0, 400, 565, 9350);
|
||||
|
||||
AddHtmlLocalized(10, 10, 200, 16, 1152531, Red, false, false); // The Void Pool
|
||||
AddHtmlLocalized(10, 30, 200, 16, Controller.Map == Map.Felucca ? 1012001 : 1012000, Red, false, false); // FEl/Tram
|
||||
|
||||
if(Controller.OnGoing)
|
||||
{
|
||||
AddHtmlLocalized(10, 50, 200, 16, 1152914, Orange, false, false); // Current Battle:
|
||||
AddHtmlLocalized(180, 50, 200, 16, 1152915, Controller.Wave.ToString(), Orange, false, false); // Wave ~1_WAVE~
|
||||
}
|
||||
else
|
||||
{
|
||||
AddHtmlLocalized(10, 50, 200, 16, 1152916, Orange, false, false); // Next Battle:
|
||||
|
||||
if(Controller.NextStart > DateTime.UtcNow)
|
||||
AddHtmlLocalized(180, 50, 200, 16, 1152917, ((int)(Controller.NextStart - DateTime.UtcNow).TotalMinutes).ToString(), Orange, false, false); // Starts in ~1_MIN~ min.
|
||||
}
|
||||
|
||||
AddButton(140, 70, 4005, 4006, 1, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(180, 70, 200, 16, 1152535, Orange, false, false); //Current Battle Scoreboard
|
||||
|
||||
AddButton(140, 90, 4005, 4006, 2, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(180, 90, 200, 16, 1152536, Orange, false, false); //Best Single Battle Scoreboard
|
||||
|
||||
AddButton(140, 110, 4005, 4006, 3, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(180, 110, 200, 16, 1152537, Orange, false, false); //Overall Total Scores
|
||||
|
||||
var stats = VoidPoolStats.GetStats(Controller);
|
||||
|
||||
if (stats.BestWave != null)
|
||||
{
|
||||
AddButton(140, 130, 4005, 4006, 4, GumpButtonType.Reply, 0);
|
||||
AddHtml(180, 130, 200, 16, String.Format("<basefont color=#A52A2A>Best Wave: {0}", stats.BestWave.Waves.ToString()), false, false);
|
||||
}
|
||||
|
||||
AddHtmlLocalized(10, 150, 400, 16, 1152552, Orange, false, false); // See Loyalty Menu for Reward Points
|
||||
AddHtmlLocalized(10, 170, 400, 16, 1152553, Orange, false, false); // See Vela in Cove for rewards
|
||||
|
||||
AddHtmlLocalized(10, 190, 380, 175, 1152533, Orange, true, true);
|
||||
AddHtmlLocalized(10, 375, 380, 175, 1152534, Orange, true, true);
|
||||
}
|
||||
|
||||
public override void OnResponse(Server.Network.NetState state, RelayInfo info)
|
||||
{
|
||||
var stats = VoidPoolStats.GetStats(Controller);
|
||||
|
||||
switch(info.ButtonID)
|
||||
{
|
||||
default: break;
|
||||
case 1:
|
||||
User.SendGump(new ScoresGump(Controller, User, ScoreType.Current));
|
||||
break;
|
||||
case 2:
|
||||
User.SendGump(new ScoresGump(Controller, User, ScoreType.BestSingle));
|
||||
break;
|
||||
case 3:
|
||||
User.SendGump(new ScoresGump(Controller, User, ScoreType.OverallTotal));
|
||||
break;
|
||||
case 4:
|
||||
if (stats.BestWave != null)
|
||||
User.SendGump(new ScoresGump(Controller, User, ScoreType.BestWave));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ScoresGump : Gump
|
||||
{
|
||||
public static readonly int Red = 0x4800;
|
||||
public static readonly int Orange = 0xB104;
|
||||
|
||||
public PlayerMobile User { get; private set; }
|
||||
public VoidPoolController Controller { get; private set; }
|
||||
public Dictionary<Mobile, long> Score { get; private set; }
|
||||
public ScoreType ScoreType { get; set; }
|
||||
|
||||
public ScoresGump(VoidPoolController controller, PlayerMobile pm, ScoreType type)
|
||||
: base(50, 50)
|
||||
{
|
||||
Controller = controller;
|
||||
User = pm;
|
||||
ScoreType = type;
|
||||
|
||||
AddGumpLayout();
|
||||
}
|
||||
|
||||
public void AddGumpLayout()
|
||||
{
|
||||
int page = 0;
|
||||
object loc;
|
||||
AddBackground(0, 0, 500, 620, 9350);
|
||||
AddPage(page);
|
||||
|
||||
var stats = VoidPoolStats.GetStats(Controller);
|
||||
|
||||
if (this.ScoreType == ScoreType.BestWave && stats.BestWave == null)
|
||||
return;
|
||||
|
||||
switch (this.ScoreType)
|
||||
{
|
||||
default:
|
||||
case ScoreType.Current: Score = Controller.CurrentScore; loc = 1152535; break;
|
||||
case ScoreType.BestSingle: Score = stats.BestSingle; loc = 1152536; break;
|
||||
case ScoreType.OverallTotal: Score = stats.OverallTotal; loc = 1152537; break;
|
||||
case ScoreType.BestWave: Score = stats.BestWave.Score; loc = "Best Wave Scoreboard"; break;
|
||||
}
|
||||
|
||||
AddHtmlLocalized(10, 10, 200, 16, 1152531, Red, false, false); // The Void Pool
|
||||
AddHtmlLocalized(10, 30, 200, 16, Controller.Map == Map.Felucca ? 1012001 : 1012000, Red, false, false); // FEl/Tram
|
||||
|
||||
if(loc is int)
|
||||
AddHtmlLocalized(10, 50, 200, 16, (int)loc, Red, false, false);
|
||||
else if (loc is string)
|
||||
AddHtml(10, 50, 200, 16, String.Format("<basefont color=#8B0000>{0}", (string)loc), false, false);
|
||||
|
||||
if (this.ScoreType == ScoreType.BestWave)
|
||||
{
|
||||
AddHtml(200, 30, 200, 16, String.Format("<basefont color=#8B0000>Total Waves: {0}", stats.BestWave.Waves.ToString()), false, false);
|
||||
AddHtml(200, 50, 200, 16, String.Format("<basefont color=#8B0000>Total Score: {0}", stats.BestWave.TotalScore.ToString()), false, false);
|
||||
}
|
||||
|
||||
AddHtmlLocalized(10, 90, 100, 16, 1152541, Orange, false, false); // RANK
|
||||
AddHtmlLocalized(100, 90, 300, 16, 1152542, Orange, false, false); // PLAYER
|
||||
AddHtmlLocalized(400, 90, 100, 16, 1152543, Orange, false, false); // SCORE
|
||||
|
||||
page++;
|
||||
AddPage(page);
|
||||
|
||||
if (Score != null)
|
||||
{
|
||||
int index = 0;
|
||||
int yOffset = 0;
|
||||
|
||||
foreach (KeyValuePair<Mobile, long> table in Score.OrderBy(kvp => -kvp.Value))
|
||||
{
|
||||
AddHtml(10, 130 + (20 * yOffset), 50, 16, (index + 1).ToString(), false, false);
|
||||
AddHtml(100, 130 + (20 * yOffset), 300, 16, table.Key.Name, false, false);
|
||||
AddHtml(400, 130 + (20 * yOffset), 100, 16, table.Value.ToString(), false, false);
|
||||
|
||||
index++;
|
||||
yOffset++;
|
||||
|
||||
if (index > 0 && index % 19 == 0 && index < Score.Count - 1)
|
||||
{
|
||||
page++;
|
||||
yOffset = 0;
|
||||
|
||||
AddHtmlLocalized(320, 570, 100, 16, 1044045, Orange, false, false); // NEXT PAGE
|
||||
AddButton(404, 570, 4005, 4006, 0, GumpButtonType.Page, page);
|
||||
|
||||
AddPage(page);
|
||||
|
||||
AddHtmlLocalized(120, 570, 100, 16, 1044044, Orange, false, false); // PREV PAGE
|
||||
AddButton(80, 570, 4014, 4015, 0, GumpButtonType.Page, page - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class VoidPoolRewardGump : BaseRewardGump
|
||||
{
|
||||
public VoidPoolRewardGump(Mobile owner, PlayerMobile user)
|
||||
: base(owner, user, VoidPoolRewards.Rewards, 1152531)
|
||||
{
|
||||
}
|
||||
|
||||
public override double GetPoints(Mobile m)
|
||||
{
|
||||
return PointsSystem.VoidPool.GetPoints(m);
|
||||
}
|
||||
|
||||
public override int GetItemHue(Item i, CollectionItem item)
|
||||
{
|
||||
int hue;
|
||||
|
||||
if (i != null)
|
||||
hue = Points >= item.Points ? i.Hue : 0x3E9;
|
||||
else
|
||||
hue = Points >= item.Points ? CraftResources.GetHue((CraftResource)item.Hue) : 0x3E9;
|
||||
|
||||
return hue;
|
||||
}
|
||||
|
||||
public override void OnConfirmed(CollectionItem citem, int index)
|
||||
{
|
||||
Item item;
|
||||
|
||||
if (index >= 0 && index <= 23)
|
||||
{
|
||||
item = Activator.CreateInstance(citem.Type, (CraftResource)citem.Hue) as Item;
|
||||
}
|
||||
else
|
||||
item = Activator.CreateInstance(citem.Type) as Item;
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
if (User.Backpack == null || !User.Backpack.TryDropItem(User, item, false))
|
||||
{
|
||||
User.SendLocalizedMessage(1074361); // The reward could not be given. Make sure you have room in your pack.
|
||||
item.Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
PointsSystem.VoidPool.DeductPoints(User, citem.Points);
|
||||
|
||||
User.SendLocalizedMessage(1073621); // Your reward has been placed in your backpack.
|
||||
User.PlaySound(0x5A7);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using Server;
|
||||
using System;
|
||||
using Server.Mobiles;
|
||||
using Server.Engines.VoidPool;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class BestWaveBoard : Item
|
||||
{
|
||||
public override bool ForceShowProperties { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public BestWaveBoard() : base(7774)
|
||||
{
|
||||
Name = "Void Pool - Best Wave";
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile m)
|
||||
{
|
||||
if(m is PlayerMobile && m.InRange(this.Location, 3))
|
||||
m.SendGump(new ScoresGump(m.Map == Map.Felucca ? VoidPoolController.InstanceFel : VoidPoolController.InstanceTram, m as PlayerMobile, ScoreType.BestWave));
|
||||
}
|
||||
|
||||
public BestWaveBoard(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
using Server;
|
||||
using System;
|
||||
using Server.Engines.Craft;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
[Alterable(typeof(DefBlacksmithy), typeof(GargishBlightOfTheTundra))]
|
||||
public class BlightOfTheTundra : CompositeBow
|
||||
{
|
||||
public override int LabelNumber { get { return 1152727; } } // Blight of the Tundra
|
||||
public override bool IsArtifact { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public BlightOfTheTundra() : this(true)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public BlightOfTheTundra(bool antique)
|
||||
{
|
||||
Attributes.BonusStr = 5;
|
||||
Attributes.RegenStam = 10;
|
||||
Attributes.AttackChance = 15;
|
||||
Attributes.WeaponSpeed = 45;
|
||||
Attributes.WeaponDamage = 50;
|
||||
|
||||
Slayer = BaseRunicTool.GetRandomSlayer();
|
||||
|
||||
WeaponAttributes.ResistColdBonus = 15;
|
||||
AosElementDamages.Fire = 100;
|
||||
Hue = 1165;
|
||||
|
||||
if (antique)
|
||||
{
|
||||
MaxHitPoints = 250;
|
||||
NegativeAttributes.Antique = 1;
|
||||
}
|
||||
else
|
||||
MaxHitPoints = 255;
|
||||
|
||||
HitPoints = MaxHitPoints;
|
||||
}
|
||||
|
||||
public BlightOfTheTundra(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class GargishBlightOfTheTundra : SoulGlaive
|
||||
{
|
||||
public override int LabelNumber { get { return 1152727; } } // Blight of the Tundra
|
||||
public override bool IsArtifact { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public GargishBlightOfTheTundra() : this(true)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public GargishBlightOfTheTundra(bool antique)
|
||||
{
|
||||
Attributes.BonusStr = 5;
|
||||
Attributes.RegenStam = 10;
|
||||
Attributes.AttackChance = 15;
|
||||
Attributes.WeaponSpeed = 45;
|
||||
Attributes.WeaponDamage = 50;
|
||||
|
||||
Slayer = BaseRunicTool.GetRandomSlayer();
|
||||
|
||||
WeaponAttributes.ResistColdBonus = 15;
|
||||
AosElementDamages.Fire = 100;
|
||||
Hue = 1165;
|
||||
|
||||
if (antique)
|
||||
{
|
||||
MaxHitPoints = 250;
|
||||
NegativeAttributes.Antique = 1;
|
||||
}
|
||||
else
|
||||
MaxHitPoints = 255;
|
||||
|
||||
HitPoints = MaxHitPoints;
|
||||
}
|
||||
|
||||
public GargishBlightOfTheTundra(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using Server;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class BraceletOfProtection : GoldBracelet
|
||||
{
|
||||
public override int LabelNumber { get { return 1152730; } } // Bracelet of Protection
|
||||
public override bool IsArtifact { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public BraceletOfProtection()
|
||||
: this(true)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public BraceletOfProtection(bool antique)
|
||||
{
|
||||
Hue = 1157;
|
||||
Attributes.BonusHits = 5;
|
||||
Attributes.RegenHits = 10;
|
||||
Attributes.DefendChance = 5;
|
||||
|
||||
switch (Utility.Random(6))
|
||||
{
|
||||
case 0: AbsorptionAttributes.EaterKinetic = 15; break;
|
||||
case 1: AbsorptionAttributes.EaterFire = 15; break;
|
||||
case 2: AbsorptionAttributes.EaterCold = 15; break;
|
||||
case 3: AbsorptionAttributes.EaterPoison = 15; break;
|
||||
case 4: AbsorptionAttributes.EaterEnergy = 15; break;
|
||||
case 5: AbsorptionAttributes.EaterDamage = 15; break;
|
||||
}
|
||||
|
||||
if (antique)
|
||||
{
|
||||
MaxHitPoints = 250;
|
||||
NegativeAttributes.Antique = 1;
|
||||
}
|
||||
else
|
||||
MaxHitPoints = 255;
|
||||
|
||||
HitPoints = MaxHitPoints;
|
||||
}
|
||||
|
||||
public BraceletOfProtection(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
using Server;
|
||||
using System;
|
||||
using Server.Engines.Craft;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
[Alterable(typeof(DefBlacksmithy), typeof(GargishBrightblade))]
|
||||
public class Brightblade : Katana
|
||||
{
|
||||
public override int LabelNumber { get { return 1152732; } } // Brightblade
|
||||
public override bool IsArtifact { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public Brightblade()
|
||||
{
|
||||
WeaponAttributes.HitLeechStam = 100;
|
||||
WeaponAttributes.SplinteringWeapon = 20;
|
||||
Attributes.RegenStam = 3;
|
||||
Attributes.AttackChance = 10;
|
||||
Attributes.CastSpeed = 1;
|
||||
Attributes.WeaponSpeed = 40;
|
||||
Attributes.WeaponDamage = 50;
|
||||
AosElementDamages.Fire = 100;
|
||||
Hue = 1756;
|
||||
}
|
||||
|
||||
public Brightblade(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int InitMinHits { get { return 255; } }
|
||||
public override int InitMaxHits { get { return 255; } }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class GargishBrightblade : GargishKatana
|
||||
{
|
||||
public override int LabelNumber { get { return 1152732; } } // Brightblade
|
||||
public override bool IsArtifact { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public GargishBrightblade()
|
||||
{
|
||||
WeaponAttributes.HitLeechStam = 100;
|
||||
WeaponAttributes.SplinteringWeapon = 20;
|
||||
Attributes.RegenStam = 3;
|
||||
Attributes.AttackChance = 10;
|
||||
Attributes.CastSpeed = 1;
|
||||
Attributes.WeaponSpeed = 40;
|
||||
Attributes.WeaponDamage = 50;
|
||||
AosElementDamages.Fire = 100;
|
||||
Hue = 1756;
|
||||
}
|
||||
|
||||
public GargishBrightblade(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int InitMinHits { get { return 255; } }
|
||||
public override int InitMaxHits { get { return 255; } }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,388 @@
|
||||
using Server;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
using Server.Multis;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class CauldronOfTransmutation : BaseAddon
|
||||
{
|
||||
public const int DecayPeriod = 4;
|
||||
private int _Charges;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Charges
|
||||
{
|
||||
get { return _Charges; }
|
||||
set
|
||||
{
|
||||
_Charges = value;
|
||||
|
||||
if (_Charges <= 0 && this.RootParent is Mobile)
|
||||
((Mobile)RootParent).SendLocalizedMessage(1152635); // The cauldron's magic is exhausted
|
||||
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DateTime Expires { get; set; }
|
||||
|
||||
public Timer DecayTimer { get; private set; }
|
||||
|
||||
public override bool RetainDeedHue { get { return true; } }
|
||||
|
||||
public CauldronOfTransmutation()
|
||||
{
|
||||
Charges = 5000;
|
||||
|
||||
AddComponent(new InternalComponent(2421), 0, 0, 0);
|
||||
|
||||
Expires = DateTime.UtcNow + TimeSpan.FromHours(DecayPeriod);
|
||||
BeginTimer();
|
||||
}
|
||||
|
||||
public void BeginTimer()
|
||||
{
|
||||
EndTimer();
|
||||
|
||||
DecayTimer = Timer.DelayCall(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), CheckDecay);
|
||||
DecayTimer.Start();
|
||||
}
|
||||
|
||||
public void EndTimer()
|
||||
{
|
||||
if (DecayTimer != null)
|
||||
{
|
||||
DecayTimer.Stop();
|
||||
DecayTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void CheckDecay()
|
||||
{
|
||||
if (Expires < DateTime.UtcNow)
|
||||
Decay();
|
||||
else
|
||||
InvalidateProperties();
|
||||
}
|
||||
|
||||
public void Decay()
|
||||
{
|
||||
if (RootParent is Mobile)
|
||||
{
|
||||
Mobile parent = (Mobile)RootParent;
|
||||
|
||||
if (Name == null)
|
||||
parent.SendLocalizedMessage(1072515, "#" + LabelNumber); // The ~1_name~ expired...
|
||||
else
|
||||
parent.SendLocalizedMessage(1072515, Name); // The ~1_name~ expired...
|
||||
|
||||
Effects.SendLocationParticles(EffectItem.Create(parent.Location, parent.Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
|
||||
Effects.PlaySound(parent.Location, parent.Map, 0x201);
|
||||
}
|
||||
else
|
||||
{
|
||||
Effects.SendLocationParticles(EffectItem.Create(this.Location, this.Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
|
||||
Effects.PlaySound(this.Location, this.Map, 0x201);
|
||||
}
|
||||
|
||||
Delete();
|
||||
}
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
base.Delete();
|
||||
|
||||
EndTimer();
|
||||
}
|
||||
|
||||
public override void OnComponentUsed(AddonComponent c, Mobile from)
|
||||
{
|
||||
if (from.InRange(c.Location, 3))
|
||||
{
|
||||
BaseHouse house = BaseHouse.FindHouseAt(from);
|
||||
|
||||
if (house != null && house.IsCoOwner(from))
|
||||
{
|
||||
from.Target = new InternalTarget(this);
|
||||
from.SendLocalizedMessage(1152738); // Target ingots in your backpack to transmute them.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryTransmutate(Mobile from, Item dropped)
|
||||
{
|
||||
BaseHouse house = BaseHouse.FindHouseAt(from);
|
||||
|
||||
if (house != null && house.IsOwner(from))
|
||||
{
|
||||
CraftResource res = CraftResources.GetFromType(dropped.GetType());
|
||||
|
||||
if (res == Resource)
|
||||
{
|
||||
if (dropped.Amount < 3)
|
||||
from.SendLocalizedMessage(1152634); // There is not enough to transmute
|
||||
else if (Charges <= 0)
|
||||
from.SendLocalizedMessage(1152635); // The cauldron's magic is exhausted
|
||||
else
|
||||
{
|
||||
CraftResourceInfo info = CraftResources.GetInfo(Resource + 1);
|
||||
|
||||
if (info != null && info.ResourceTypes.Length > 0)
|
||||
{
|
||||
int toDrop = Math.Min(Charges * 3, dropped.Amount);
|
||||
CraftResource newRes = (CraftResource)(int)res + 1;
|
||||
|
||||
while (toDrop % 3 != 0)
|
||||
toDrop--;
|
||||
|
||||
int newAmount = toDrop / 3;
|
||||
|
||||
if (toDrop < dropped.Amount)
|
||||
dropped.Amount -= toDrop;
|
||||
else
|
||||
dropped.Delete();
|
||||
|
||||
Item item = Loot.Construct(info.ResourceTypes[0]);
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
item.Amount = newAmount;
|
||||
from.AddToBackpack(item);
|
||||
|
||||
from.SendLocalizedMessage(1152636); // The cauldron transmutes the material
|
||||
|
||||
from.PlaySound(Utility.RandomList(0x22, 0x23));
|
||||
|
||||
Charges -= newAmount;
|
||||
Components.ForEach(c => c.InvalidateProperties());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
from.SendLocalizedMessage(1152633); // The cauldron cannot transmute that
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
from.SendLocalizedMessage(1152632); // That is not yours!
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private class InternalTarget : Target
|
||||
{
|
||||
public CauldronOfTransmutation Addon { get; set; }
|
||||
|
||||
public InternalTarget(CauldronOfTransmutation addon)
|
||||
: base(-1, false, TargetFlags.None)
|
||||
{
|
||||
Addon = addon;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (Addon == null || !from.InRange(Addon.Location, 3))
|
||||
from.SendLocalizedMessage(500295); // You are too far away to do that.
|
||||
|
||||
if (targeted is Item)
|
||||
Addon.TryTransmutate(from, (Item)targeted);
|
||||
}
|
||||
}
|
||||
|
||||
private class InternalComponent : AddonComponent
|
||||
{
|
||||
public override bool ForceShowProperties { get { return true; } }
|
||||
|
||||
public InternalComponent(int id)
|
||||
: base(id)
|
||||
{
|
||||
}
|
||||
|
||||
public override void AddNameProperty(ObjectPropertyList list)
|
||||
{
|
||||
if (Addon != null && Addon.Resource != CraftResource.None)
|
||||
list.Add(1152600, String.Format("#{0}", CraftResources.GetLocalizationNumber(Addon.Resource).ToString())); // ~1_RES~ Cauldron of Transmutation
|
||||
else
|
||||
base.AddNameProperty(list);
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
if (Addon == null || !(Addon is CauldronOfTransmutation) || Addon.Resource == CraftResource.None)
|
||||
return;
|
||||
|
||||
int left = 0;
|
||||
if (DateTime.UtcNow < ((CauldronOfTransmutation)Addon).Expires)
|
||||
left = (int)(((CauldronOfTransmutation)Addon).Expires - DateTime.UtcNow).TotalSeconds;
|
||||
|
||||
list.Add(1072517, left.ToString()); // Lifespan: ~1_val~ seconds
|
||||
|
||||
CraftResource res = Addon.Resource;
|
||||
CraftResource res2 = (CraftResource)(int)res + 1;
|
||||
|
||||
list.Add(1152630, String.Format("#{0}\t#{1}", CraftResources.GetLocalizationNumber(Addon.Resource), CraftResources.GetLocalizationNumber(res2))); // transmutes ~1_SOURCE~ to ~2_DEST~
|
||||
list.Add(1152631, String.Format("3\t1")); // ratio ~1_INPUT~ to ~2_OUTPUT~
|
||||
list.Add(1060584, ((CauldronOfTransmutation)Addon).Charges.ToString()); // uses remaining: ~1_val~
|
||||
|
||||
}
|
||||
|
||||
public InternalComponent(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public CauldronOfTransmutation(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(Expires);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Expires = reader.ReadDateTime();
|
||||
|
||||
if (Expires < DateTime.UtcNow)
|
||||
Decay();
|
||||
else
|
||||
BeginTimer();
|
||||
}
|
||||
}
|
||||
|
||||
public class CauldronOfTransmutationDeed : BaseAddonDeed
|
||||
{
|
||||
public override BaseAddon Addon { get { return new CauldronOfTransmutation(); } }
|
||||
|
||||
public const int DecayPeriod = 24;
|
||||
|
||||
private Timer m_Timer;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DateTime Expires { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public CauldronOfTransmutationDeed(CraftResource resource)
|
||||
{
|
||||
Resource = resource;
|
||||
|
||||
Expires = DateTime.UtcNow + TimeSpan.FromHours(DecayPeriod);
|
||||
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), CheckDecay);
|
||||
}
|
||||
|
||||
public void CheckDecay()
|
||||
{
|
||||
if (Expires < DateTime.UtcNow)
|
||||
Decay();
|
||||
else
|
||||
InvalidateProperties();
|
||||
}
|
||||
|
||||
public void Decay()
|
||||
{
|
||||
if (RootParent is Mobile)
|
||||
{
|
||||
Mobile parent = (Mobile)RootParent;
|
||||
|
||||
if (Name == null)
|
||||
parent.SendLocalizedMessage(1072515, "#" + LabelNumber); // The ~1_name~ expired...
|
||||
else
|
||||
parent.SendLocalizedMessage(1072515, Name); // The ~1_name~ expired...
|
||||
|
||||
Effects.SendLocationParticles(EffectItem.Create(parent.Location, parent.Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
|
||||
Effects.PlaySound(parent.Location, parent.Map, 0x201);
|
||||
}
|
||||
else
|
||||
{
|
||||
Effects.SendLocationParticles(EffectItem.Create(this.Location, this.Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
|
||||
Effects.PlaySound(this.Location, this.Map, 0x201);
|
||||
}
|
||||
|
||||
Delete();
|
||||
}
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
base.Delete();
|
||||
|
||||
if (m_Timer != null)
|
||||
{
|
||||
m_Timer.Stop();
|
||||
m_Timer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public override void AddNameProperty(ObjectPropertyList list)
|
||||
{
|
||||
list.Add(1152600, String.Format("#{0}", CraftResources.GetLocalizationNumber(Resource))); // ~1_RES~ Cauldron of Transmutation
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
int left = 0;
|
||||
if (DateTime.UtcNow < Expires)
|
||||
left = (int)(Expires - DateTime.UtcNow).TotalSeconds;
|
||||
|
||||
list.Add(1072517, left.ToString()); // Lifespan: ~1_val~ seconds
|
||||
list.Add(1152628); // cannot re-deed
|
||||
list.Add(1152629, CauldronOfTransmutation.DecayPeriod.ToString()); // lasts ~1_count~ hours
|
||||
}
|
||||
|
||||
public CauldronOfTransmutationDeed(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(Expires);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Expires = reader.ReadDateTime();
|
||||
|
||||
if (Expires < DateTime.UtcNow)
|
||||
Decay();
|
||||
else
|
||||
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), CheckDecay);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,302 @@
|
||||
using Server;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Mobiles;
|
||||
using System.IO;
|
||||
using Server.Engines.Harvest;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class HarvestMap : Item, IUsesRemaining
|
||||
{
|
||||
public const int DecayPeriod = 24;
|
||||
|
||||
private CraftResource _Resource;
|
||||
private int _UsesRemaining;
|
||||
private Timer m_Timer;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public CraftResource Resource
|
||||
{
|
||||
get { return _Resource; }
|
||||
set
|
||||
{
|
||||
if (_Resource != value)
|
||||
{
|
||||
_Resource = value;
|
||||
Hue = CraftResources.GetHue(_Resource);
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int UsesRemaining
|
||||
{
|
||||
get { return _UsesRemaining; }
|
||||
set
|
||||
{
|
||||
_UsesRemaining = value;
|
||||
|
||||
if (_UsesRemaining <= 0 && this.RootParent is Mobile)
|
||||
((Mobile)RootParent).SendMessage("Your map's magic is exhausted.");
|
||||
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool ShowUsesRemaining { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DateTime Expires { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Point2D Target { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Map TargetMap { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool IsMinerMap { get { return _Resource >= CraftResource.Iron && _Resource <= CraftResource.Valorite; } }
|
||||
|
||||
[Constructable]
|
||||
public HarvestMap(CraftResource resource)
|
||||
: base(0x14EC)
|
||||
{
|
||||
Resource = resource;
|
||||
GetRandomLocation();
|
||||
|
||||
UsesRemaining = Utility.RandomMinMax(235, 255);
|
||||
ShowUsesRemaining = true;
|
||||
|
||||
Expires = DateTime.UtcNow + TimeSpan.FromHours(DecayPeriod);
|
||||
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), CheckDecay);
|
||||
}
|
||||
|
||||
public void CheckDecay()
|
||||
{
|
||||
if (Expires < DateTime.UtcNow)
|
||||
Decay();
|
||||
else
|
||||
InvalidateProperties();
|
||||
}
|
||||
|
||||
public void Decay()
|
||||
{
|
||||
if (RootParent is Mobile)
|
||||
{
|
||||
Mobile parent = (Mobile)RootParent;
|
||||
|
||||
if (Name == null)
|
||||
parent.SendLocalizedMessage(1072515, "#" + LabelNumber); // The ~1_name~ expired...
|
||||
else
|
||||
parent.SendLocalizedMessage(1072515, Name); // The ~1_name~ expired...
|
||||
|
||||
Effects.SendLocationParticles(EffectItem.Create(parent.Location, parent.Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
|
||||
Effects.PlaySound(parent.Location, parent.Map, 0x201);
|
||||
}
|
||||
else
|
||||
{
|
||||
Effects.SendLocationParticles(EffectItem.Create(this.Location, this.Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
|
||||
Effects.PlaySound(this.Location, this.Map, 0x201);
|
||||
}
|
||||
|
||||
Delete();
|
||||
}
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
base.Delete();
|
||||
|
||||
if (m_Timer != null)
|
||||
{
|
||||
m_Timer.Stop();
|
||||
m_Timer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public override void AddNameProperty(ObjectPropertyList list)
|
||||
{
|
||||
list.Add(1152598, String.Format("#{0}\t#{1}", CraftResources.GetLocalizationNumber(Resource), IsMinerMap ? "1152604" : "1152605")); // ~1_RES~ ~2_TYPE~ Map
|
||||
}
|
||||
|
||||
public override void AddUsesRemainingProperties(ObjectPropertyList list)
|
||||
{
|
||||
list.Add(1060584, UsesRemaining.ToString()); // uses remaining: ~1_val~
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
int left = 0;
|
||||
if (DateTime.UtcNow < Expires)
|
||||
left = (int)(Expires - DateTime.UtcNow).TotalSeconds;
|
||||
|
||||
list.Add(1072517, left.ToString()); // Lifespan: ~1_val~ seconds
|
||||
list.Add(1061114, GetSextantLocation()); // Location: ~1_val~
|
||||
|
||||
if (TargetMap == null || TargetMap == Map.Internal)
|
||||
list.Add(1060800); // unknown
|
||||
else
|
||||
list.Add(TargetMap.MapID + 1150548);
|
||||
}
|
||||
|
||||
private string GetSextantLocation()
|
||||
{
|
||||
if (TargetMap == null)
|
||||
return "Unknown";
|
||||
|
||||
int x = Target.X;
|
||||
int y = Target.Y;
|
||||
|
||||
int xLong = 0, yLat = 0;
|
||||
int xMins = 0, yMins = 0;
|
||||
bool xEast = false, ySouth = false;
|
||||
|
||||
if (Sextant.Format(new Point3D(x, y, TargetMap.GetAverageZ(x, y)), TargetMap, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast, ref ySouth))
|
||||
{
|
||||
return String.Format("{0}° {1}'{2}, {3}° {4}'{5}", yLat, yMins, ySouth ? "S" : "N", xLong, xMins, xEast ? "E" : "W");
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
public void GetRandomLocation()
|
||||
{
|
||||
Map map;
|
||||
|
||||
switch (Utility.Random(6))
|
||||
{
|
||||
default:
|
||||
case 0: map = Map.Felucca; break;
|
||||
case 1: map = Map.Trammel; break;
|
||||
case 2: map = Map.Ilshenar; break;
|
||||
case 3: map = Map.Malas; break;
|
||||
case 4: map = Map.Tokuno; break;
|
||||
case 5: map = Map.TerMur; break;
|
||||
}
|
||||
|
||||
TargetMap = map;
|
||||
Dictionary<Map, List<Point2D>> table;
|
||||
|
||||
if (IsMinerMap)
|
||||
table = MinerTable;
|
||||
else
|
||||
table = LumberTable;
|
||||
|
||||
if (!table.ContainsKey(map))
|
||||
table[map] = LoadLocsFor(map, this);
|
||||
else if (table[map] == null)
|
||||
table[map] = LoadLocsFor(map, this);
|
||||
|
||||
Target = table[map][Utility.Random(table[map].Count)];
|
||||
}
|
||||
|
||||
public static HarvestMap CheckMapOnHarvest(Mobile from, object harvested, HarvestDefinition def)
|
||||
{
|
||||
Map map = from.Map;
|
||||
|
||||
if (harvested is IPoint3D && from.Backpack != null)
|
||||
{
|
||||
IPoint3D p = harvested as IPoint3D;
|
||||
|
||||
Item[] items = from.Backpack.FindItemsByType(typeof(HarvestMap));
|
||||
|
||||
foreach (Item item in items)
|
||||
{
|
||||
HarvestMap harvestmap = item as HarvestMap;
|
||||
|
||||
if (harvestmap != null && harvestmap.TargetMap == map && harvestmap.UsesRemaining > 0
|
||||
&& def.GetBank(map, p.X, p.Y) == def.GetBank(harvestmap.TargetMap, harvestmap.Target.X, harvestmap.Target.Y))
|
||||
{
|
||||
return harvestmap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Dictionary<Map, List<Point2D>> MinerTable;
|
||||
public static Dictionary<Map, List<Point2D>> LumberTable;
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
MinerTable = new Dictionary<Map, List<Point2D>>();
|
||||
LumberTable = new Dictionary<Map, List<Point2D>>();
|
||||
}
|
||||
|
||||
public static List<Point2D> LoadLocsFor(Map map, HarvestMap hMap)
|
||||
{
|
||||
string path = String.Format("Data/HarvestLocs/{0}_{1}.cfg", hMap.IsMinerMap ? "MinerLocs" : "LumberLocs", map.ToString());
|
||||
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
Console.WriteLine("Warning! {0} does not exist for harvest maps...", path);
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Point2D> list = new List<Point2D>();
|
||||
|
||||
using (StreamReader ip = new StreamReader(path))
|
||||
{
|
||||
string line;
|
||||
|
||||
while ((line = ip.ReadLine()) != null)
|
||||
{
|
||||
if (line.Length == 0 || line.StartsWith("#"))
|
||||
continue;
|
||||
|
||||
var split = line.Split('\t');
|
||||
|
||||
int x, y = 0;
|
||||
|
||||
if (int.TryParse(split[0], out x) && int.TryParse(split[1], out y) && (x > 0 || y > 0))
|
||||
{
|
||||
list.Add(new Point2D(x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public HarvestMap(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write((int)Resource);
|
||||
writer.Write(Expires);
|
||||
writer.Write(UsesRemaining);
|
||||
|
||||
writer.Write(Target);
|
||||
writer.Write(TargetMap);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Resource = (CraftResource)reader.ReadInt();
|
||||
Expires = reader.ReadDateTime();
|
||||
UsesRemaining = reader.ReadInt();
|
||||
|
||||
Target = reader.ReadPoint2D();
|
||||
TargetMap = reader.ReadMap();
|
||||
|
||||
if (Expires < DateTime.UtcNow)
|
||||
Decay();
|
||||
else
|
||||
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), CheckDecay);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
using Server;
|
||||
using System;
|
||||
using Server.Engines.Craft;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
[Alterable(typeof(DefBlacksmithy), typeof(GargishHephaestus))]
|
||||
public class Hephaestus : HeaterShield
|
||||
{
|
||||
public override int LabelNumber { get { return 1152909; } } // Hephaestus
|
||||
public override bool IsArtifact { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public Hephaestus() : this(true)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public Hephaestus(bool antique)
|
||||
{
|
||||
Hue = 1910;
|
||||
Attributes.SpellChanneling = 1;
|
||||
Attributes.ReflectPhysical = 15;
|
||||
Attributes.DefendChance = 15;
|
||||
Attributes.CastSpeed = 1;
|
||||
Attributes.LowerManaCost = 8;
|
||||
|
||||
PhysicalBonus = 15;
|
||||
ArmorAttributes.SelfRepair = 5;
|
||||
|
||||
SkillBonuses.SetValues(0, SkillName.Parry, 10.0);
|
||||
|
||||
if (antique)
|
||||
{
|
||||
MaxHitPoints = 250;
|
||||
NegativeAttributes.Antique = 1;
|
||||
}
|
||||
else
|
||||
MaxHitPoints = 255;
|
||||
|
||||
HitPoints = MaxHitPoints;
|
||||
}
|
||||
|
||||
public Hephaestus(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class GargishHephaestus : LargePlateShield
|
||||
{
|
||||
public override int LabelNumber { get { return 1152909; } } // Hephaestus
|
||||
public override bool IsArtifact { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public GargishHephaestus() : this(true)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public GargishHephaestus(bool antique)
|
||||
{
|
||||
Hue = 1910;
|
||||
Attributes.SpellChanneling = 1;
|
||||
Attributes.ReflectPhysical = 15;
|
||||
Attributes.DefendChance = 15;
|
||||
Attributes.CastSpeed = 1;
|
||||
Attributes.LowerManaCost = 8;
|
||||
|
||||
PhysicalBonus = 15;
|
||||
ArmorAttributes.SelfRepair = 5;
|
||||
|
||||
SkillBonuses.SetValues(0, SkillName.Parry, 10.0);
|
||||
|
||||
if (antique)
|
||||
{
|
||||
MaxHitPoints = 250;
|
||||
NegativeAttributes.Antique = 1;
|
||||
}
|
||||
else
|
||||
MaxHitPoints = 255;
|
||||
|
||||
HitPoints = MaxHitPoints;
|
||||
}
|
||||
|
||||
public GargishHephaestus(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
using Server;
|
||||
using System;
|
||||
using Server.Mobiles;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Server.Commands;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class MagicalFishFinder : Item
|
||||
{
|
||||
public const int DecayPeriod = 4;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DateTime Expires { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DateTime LastUpdate { get; set; }
|
||||
|
||||
private Timer m_Timer;
|
||||
|
||||
public override int LabelNumber { get { return 1152602; } } // Magical Fish Finder
|
||||
|
||||
[Constructable]
|
||||
public MagicalFishFinder() : base(5366)
|
||||
{
|
||||
Hue = 2500;
|
||||
|
||||
Expires = DateTime.UtcNow + TimeSpan.FromHours(DecayPeriod);
|
||||
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), CheckDecay);
|
||||
}
|
||||
|
||||
public void CheckDecay()
|
||||
{
|
||||
if (Expires < DateTime.UtcNow)
|
||||
Decay();
|
||||
else
|
||||
InvalidateProperties();
|
||||
}
|
||||
|
||||
public void Decay()
|
||||
{
|
||||
if (RootParent is Mobile)
|
||||
{
|
||||
Mobile parent = (Mobile)RootParent;
|
||||
|
||||
if (Name == null)
|
||||
parent.SendLocalizedMessage(1072515, "#" + LabelNumber); // The ~1_name~ expired...
|
||||
else
|
||||
parent.SendLocalizedMessage(1072515, Name); // The ~1_name~ expired...
|
||||
|
||||
Effects.SendLocationParticles(EffectItem.Create(parent.Location, parent.Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
|
||||
Effects.PlaySound(parent.Location, parent.Map, 0x201);
|
||||
}
|
||||
else
|
||||
{
|
||||
Effects.SendLocationParticles(EffectItem.Create(this.Location, this.Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
|
||||
Effects.PlaySound(this.Location, this.Map, 0x201);
|
||||
}
|
||||
|
||||
Delete();
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
int left = 0;
|
||||
|
||||
if (DateTime.UtcNow < Expires)
|
||||
left = (int)(Expires - DateTime.UtcNow).TotalSeconds;
|
||||
|
||||
list.Add(1072517, left.ToString()); // Lifespan: ~1_val~ seconds
|
||||
}
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
base.Delete();
|
||||
|
||||
if (m_Timer != null)
|
||||
{
|
||||
m_Timer.Stop();
|
||||
m_Timer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile m)
|
||||
{
|
||||
if (IsChildOf(m.Backpack))
|
||||
CheckUpdate(m);
|
||||
}
|
||||
|
||||
public void CheckUpdate(Mobile m)
|
||||
{
|
||||
if (Schools.ContainsKey(m.Map))
|
||||
{
|
||||
SchoolEntry entry = Schools[m.Map].FirstOrDefault(e => m.InRange(e.Location, SchoolRange));
|
||||
|
||||
if (entry != null)
|
||||
{
|
||||
m.SendLocalizedMessage(1152647); // Fish are schooling right here!
|
||||
return;
|
||||
}
|
||||
|
||||
entry = Schools[m.Map].FirstOrDefault(e => m.InRange(e.Location, MessageRange));
|
||||
|
||||
if (entry != null)
|
||||
{
|
||||
m.SendLocalizedMessage(1152638, GetDirectionString(Utility.GetDirection(m, entry.Location))); // The fish finder pulls you to the ~1_DIRECTION~.
|
||||
}
|
||||
else
|
||||
{
|
||||
m.SendLocalizedMessage(1152637); // The fish finder shows you nothing.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m.SendLocalizedMessage(1152637); // The fish finder shows you nothing.
|
||||
}
|
||||
}
|
||||
|
||||
public string GetDirectionString(Direction d)
|
||||
{
|
||||
return String.Format("#{0}", 1152639 + (int)d);
|
||||
}
|
||||
|
||||
public static bool HasSchool(Mobile m)
|
||||
{
|
||||
if (m == null || !m.Alive || m.Backpack == null)
|
||||
return false;
|
||||
|
||||
MagicalFishFinder finder = m.Backpack.FindItemByType<MagicalFishFinder>();
|
||||
|
||||
if (finder != null && Schools.ContainsKey(m.Map))
|
||||
{
|
||||
SchoolEntry entry = Schools[m.Map].FirstOrDefault(e => m.InRange(e.Location, SchoolRange));
|
||||
|
||||
if (entry != null)
|
||||
{
|
||||
entry.OnFish();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public MagicalFishFinder(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(Expires);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Expires = reader.ReadDateTime();
|
||||
|
||||
if (Expires < DateTime.UtcNow)
|
||||
Decay();
|
||||
else
|
||||
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), CheckDecay);
|
||||
}
|
||||
|
||||
public static int MessageRange = 100;
|
||||
public static int SchoolRange = 20;
|
||||
|
||||
public static Dictionary<Map, List<SchoolEntry>> Schools { get; set; }
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
Schools = new Dictionary<Map, List<SchoolEntry>>();
|
||||
|
||||
Schools[Map.Trammel] = new List<SchoolEntry>();
|
||||
Schools[Map.Felucca] = new List<SchoolEntry>();
|
||||
Schools[Map.Ilshenar] = new List<SchoolEntry>();
|
||||
Schools[Map.Tokuno] = new List<SchoolEntry>();
|
||||
|
||||
foreach (var kvp in Schools)
|
||||
{
|
||||
int amount = 150;
|
||||
|
||||
if (kvp.Key == Map.Ilshenar || kvp.Key == Map.Tokuno)
|
||||
amount = 50;
|
||||
|
||||
for (int i = 0; i < amount; i++)
|
||||
{
|
||||
Point3D p;
|
||||
int failsafe = 0;
|
||||
|
||||
do
|
||||
{
|
||||
p = SOS.FindLocation(kvp.Key);
|
||||
failsafe++;
|
||||
}
|
||||
while (p == Point3D.Zero && failsafe < 10);
|
||||
|
||||
kvp.Value.Add(new SchoolEntry(kvp.Key, new Point2D(p.X, p.Y)));
|
||||
}
|
||||
|
||||
if(kvp.Value.Count == 0)
|
||||
Console.WriteLine("Warning: {0} has 0 School entries!", kvp.Key);
|
||||
}
|
||||
|
||||
CommandSystem.Register("MoveToSchool", AccessLevel.GameMaster, e =>
|
||||
{
|
||||
Mobile m = e.Mobile;
|
||||
|
||||
if (Schools.ContainsKey(m.Map))
|
||||
{
|
||||
SchoolEntry entry = Schools[m.Map][Utility.Random(Schools[m.Map].Count)];
|
||||
|
||||
if (entry != null)
|
||||
{
|
||||
m.MoveToWorld(new Point3D(entry.Location.X, entry.Location.Y, m.Map.GetAverageZ(entry.Location.X, entry.Location.Y)), m.Map);
|
||||
}
|
||||
else
|
||||
m.SendMessage("Bad entry");
|
||||
}
|
||||
else
|
||||
m.SendMessage("Bad map");
|
||||
});
|
||||
}
|
||||
|
||||
public static void ExpireSchool(Map map, SchoolEntry entry)
|
||||
{
|
||||
if (Schools.ContainsKey(map) && Schools[map].Contains(entry))
|
||||
{
|
||||
Schools[map].Remove(entry);
|
||||
|
||||
Point3D p;
|
||||
int failsafe = 0;
|
||||
|
||||
do
|
||||
{
|
||||
p = SOS.FindLocation(map);
|
||||
failsafe++;
|
||||
}
|
||||
while (p == Point3D.Zero && failsafe < 10);
|
||||
|
||||
Schools[map].Add(new SchoolEntry(map, new Point2D(p.X, p.Y)));
|
||||
}
|
||||
}
|
||||
|
||||
public class SchoolEntry
|
||||
{
|
||||
public Point2D Location { get; set; }
|
||||
public bool HasFished { get; set; }
|
||||
public Map Map { get; set; }
|
||||
|
||||
public SchoolEntry(Map map, Point2D location)
|
||||
{
|
||||
Map = map;
|
||||
Location = location;
|
||||
}
|
||||
|
||||
public void OnFish()
|
||||
{
|
||||
if (!HasFished)
|
||||
{
|
||||
HasFished = true;
|
||||
Timer.DelayCall(TimeSpan.FromMinutes(Utility.RandomMinMax(5, 8)), Expire);
|
||||
}
|
||||
}
|
||||
|
||||
public void Expire()
|
||||
{
|
||||
MagicalFishFinder.ExpireSchool(Map, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using Server;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Mobiles;
|
||||
using Server.Engines.Craft;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
[Alterable(typeof(DefTinkering), typeof(GargishPrismaticLenses))]
|
||||
public class PrismaticLenses : Glasses
|
||||
{
|
||||
public override int LabelNumber { get { return 1152716; } } // Prismatic Lenses
|
||||
public override int InitMinHits { get { return 255; } }
|
||||
public override int InitMaxHits { get { return 255; } }
|
||||
|
||||
public override int BasePhysicalResistance { get { return 18; } }
|
||||
public override int BaseFireResistance { get { return 4; } }
|
||||
public override int BaseColdResistance { get { return 7; } }
|
||||
public override int BasePoisonResistance { get { return 17; } }
|
||||
public override int BaseEnergyResistance { get { return 6; } }
|
||||
|
||||
public override bool IsArtifact { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public PrismaticLenses()
|
||||
{
|
||||
Hue = 2068;
|
||||
WeaponAttributes.HitLowerDefend = 30;
|
||||
Attributes.RegenHits = 2;
|
||||
Attributes.RegenStam = 3;
|
||||
Attributes.WeaponDamage = 25;
|
||||
}
|
||||
|
||||
public PrismaticLenses(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class GargishPrismaticLenses : GargishGlasses
|
||||
{
|
||||
public override int LabelNumber { get { return 1152716; } } // Prismatic Lenses
|
||||
|
||||
public override int InitMinHits { get { return 255; } }
|
||||
public override int InitMaxHits { get { return 255; } }
|
||||
|
||||
public override int BasePhysicalResistance { get { return 18; } }
|
||||
public override int BaseFireResistance { get { return 4; } }
|
||||
public override int BaseColdResistance { get { return 7; } }
|
||||
public override int BasePoisonResistance { get { return 17; } }
|
||||
public override int BaseEnergyResistance { get { return 6; } }
|
||||
|
||||
public override bool IsArtifact { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public GargishPrismaticLenses()
|
||||
{
|
||||
Hue = 2068;
|
||||
WeaponAttributes.HitLowerDefend = 30;
|
||||
Attributes.RegenHits = 2;
|
||||
Attributes.RegenStam = 3;
|
||||
Attributes.WeaponDamage = 25;
|
||||
}
|
||||
|
||||
public GargishPrismaticLenses(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
using Server;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class SmeltersTalisman : BaseTalisman, IUsesRemaining
|
||||
{
|
||||
public const int DecayPeriod = 24;
|
||||
|
||||
private CraftResource _Resource;
|
||||
private int _UsesRemaining;
|
||||
private Timer m_Timer;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public CraftResource Resource
|
||||
{
|
||||
get { return _Resource; }
|
||||
set
|
||||
{
|
||||
if (_Resource != value)
|
||||
{
|
||||
_Resource = value;
|
||||
Hue = CraftResources.GetHue(_Resource);
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int UsesRemaining
|
||||
{
|
||||
get { return _UsesRemaining; }
|
||||
set
|
||||
{
|
||||
_UsesRemaining = value;
|
||||
|
||||
if (_UsesRemaining <= 0 && this.RootParent is Mobile)
|
||||
((Mobile)RootParent).SendLocalizedMessage(1152621); // Your talisman's magic is exhausted.
|
||||
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool ShowUsesRemaining { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DateTime Expires { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public SmeltersTalisman(CraftResource resource)
|
||||
: base(0x2F5B)
|
||||
{
|
||||
Resource = resource;
|
||||
|
||||
UsesRemaining = 6000;
|
||||
ShowUsesRemaining = true;
|
||||
|
||||
Expires = DateTime.UtcNow + TimeSpan.FromHours(DecayPeriod);
|
||||
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), CheckDecay);
|
||||
}
|
||||
|
||||
public void CheckDecay()
|
||||
{
|
||||
if (Expires < DateTime.UtcNow)
|
||||
Decay();
|
||||
else
|
||||
InvalidateProperties();
|
||||
}
|
||||
|
||||
public void Decay()
|
||||
{
|
||||
if (RootParent is Mobile)
|
||||
{
|
||||
Mobile parent = (Mobile)RootParent;
|
||||
|
||||
if (Name == null)
|
||||
parent.SendLocalizedMessage(1072515, "#" + LabelNumber); // The ~1_name~ expired...
|
||||
else
|
||||
parent.SendLocalizedMessage(1072515, Name); // The ~1_name~ expired...
|
||||
|
||||
Effects.SendLocationParticles(EffectItem.Create(parent.Location, parent.Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
|
||||
Effects.PlaySound(parent.Location, parent.Map, 0x201);
|
||||
}
|
||||
else
|
||||
{
|
||||
Effects.SendLocationParticles(EffectItem.Create(this.Location, this.Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
|
||||
Effects.PlaySound(this.Location, this.Map, 0x201);
|
||||
}
|
||||
|
||||
Delete();
|
||||
}
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
base.Delete();
|
||||
|
||||
if (m_Timer != null)
|
||||
{
|
||||
m_Timer.Stop();
|
||||
m_Timer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public override void AddNameProperty(ObjectPropertyList list)
|
||||
{
|
||||
list.Add(1152599, String.Format("#{0}\t#1152606", CraftResources.GetLocalizationNumber(_Resource))); // ~1_RES~ ~2_TYPE~ Talisman
|
||||
}
|
||||
|
||||
public override void AddUsesRemainingProperties(ObjectPropertyList list)
|
||||
{
|
||||
list.Add(1060584, UsesRemaining.ToString()); // uses remaining: ~1_val~
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
int left = 0;
|
||||
if (DateTime.UtcNow < Expires)
|
||||
left = (int)(Expires - DateTime.UtcNow).TotalSeconds;
|
||||
|
||||
list.Add(1072517, left.ToString()); // Lifespan: ~1_val~ seconds
|
||||
}
|
||||
|
||||
public SmeltersTalisman(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write((int)Resource);
|
||||
writer.Write(Expires);
|
||||
writer.Write(UsesRemaining);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Resource = (CraftResource)reader.ReadInt();
|
||||
Expires = reader.ReadDateTime();
|
||||
UsesRemaining = reader.ReadInt();
|
||||
|
||||
if (Expires < DateTime.UtcNow)
|
||||
Decay();
|
||||
else
|
||||
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), CheckDecay);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,343 @@
|
||||
using Server;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Mobiles;
|
||||
using Server.Multis;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class TemporaryForge : BaseAddon
|
||||
{
|
||||
public const int DecayPeriod = 4;
|
||||
private Timer m_Timer;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DateTime Expires { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Mobile Owner { get; set; }
|
||||
|
||||
public TemporaryForge()
|
||||
{
|
||||
AddComponent(new InternalComponent(), 0, 0, 0);
|
||||
|
||||
Expires = DateTime.UtcNow + TimeSpan.FromHours(DecayPeriod);
|
||||
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), CheckDecay);
|
||||
}
|
||||
|
||||
public override void OnChop(Mobile from)
|
||||
{
|
||||
if (BaseHouse.FindHouseAt(this) == null && Owner == from)
|
||||
{
|
||||
Effects.PlaySound(GetWorldLocation(), Map, 0x3B3);
|
||||
from.SendLocalizedMessage(500461); // You destroy the item.
|
||||
Delete();
|
||||
return;
|
||||
}
|
||||
|
||||
base.OnChop(from);
|
||||
}
|
||||
|
||||
public void CheckDecay()
|
||||
{
|
||||
if (Expires < DateTime.UtcNow)
|
||||
Decay();
|
||||
else
|
||||
InvalidateProperties();
|
||||
}
|
||||
|
||||
public void Decay()
|
||||
{
|
||||
if (RootParent is Mobile)
|
||||
{
|
||||
Mobile parent = (Mobile)RootParent;
|
||||
|
||||
if (Name == null)
|
||||
parent.SendLocalizedMessage(1072515, "#" + LabelNumber); // The ~1_name~ expired...
|
||||
else
|
||||
parent.SendLocalizedMessage(1072515, Name); // The ~1_name~ expired...
|
||||
|
||||
Effects.SendLocationParticles(EffectItem.Create(parent.Location, parent.Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
|
||||
Effects.PlaySound(parent.Location, parent.Map, 0x201);
|
||||
}
|
||||
else
|
||||
{
|
||||
Effects.SendLocationParticles(EffectItem.Create(this.Location, this.Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
|
||||
Effects.PlaySound(this.Location, this.Map, 0x201);
|
||||
}
|
||||
|
||||
Delete();
|
||||
}
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
base.Delete();
|
||||
|
||||
if (m_Timer != null)
|
||||
{
|
||||
m_Timer.Stop();
|
||||
m_Timer = null;
|
||||
}
|
||||
}
|
||||
|
||||
private class InternalComponent : ForgeComponent
|
||||
{
|
||||
public override bool ForceShowProperties { get { return true; } }
|
||||
public override int LabelNumber { get { return 1152601; } } //Temporary forge
|
||||
|
||||
public InternalComponent() : base(0xFB1)
|
||||
{
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
if (Addon == null || !(Addon is TemporaryForge))
|
||||
return;
|
||||
|
||||
int left = 0;
|
||||
if (DateTime.UtcNow < ((TemporaryForge)Addon).Expires)
|
||||
left = (int)(((TemporaryForge)Addon).Expires - DateTime.UtcNow).TotalSeconds;
|
||||
|
||||
list.Add(1072517, left.ToString()); // Lifespan: ~1_val~ seconds
|
||||
}
|
||||
|
||||
public InternalComponent(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public TemporaryForge(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(Expires);
|
||||
writer.Write(Owner);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Expires = reader.ReadDateTime();
|
||||
Owner = reader.ReadMobile();
|
||||
|
||||
if (Expires < DateTime.UtcNow)
|
||||
Decay();
|
||||
else
|
||||
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), CheckDecay);
|
||||
}
|
||||
}
|
||||
|
||||
public class TemporaryForgeDeed : BaseAddonDeed
|
||||
{
|
||||
public override BaseAddon Addon { get { return new TemporaryForge(); } }
|
||||
|
||||
public const int DecayPeriod = 24;
|
||||
|
||||
private Timer m_Timer;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DateTime Expires { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public TemporaryForgeDeed()
|
||||
{
|
||||
Expires = DateTime.UtcNow + TimeSpan.FromHours(DecayPeriod);
|
||||
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), CheckDecay);
|
||||
}
|
||||
|
||||
public void CheckDecay()
|
||||
{
|
||||
if (Expires < DateTime.UtcNow)
|
||||
Decay();
|
||||
else
|
||||
InvalidateProperties();
|
||||
}
|
||||
|
||||
public void Decay()
|
||||
{
|
||||
if (RootParent is Mobile)
|
||||
{
|
||||
Mobile parent = (Mobile)RootParent;
|
||||
|
||||
if (Name == null)
|
||||
parent.SendLocalizedMessage(1072515, "#" + LabelNumber); // The ~1_name~ expired...
|
||||
else
|
||||
parent.SendLocalizedMessage(1072515, Name); // The ~1_name~ expired...
|
||||
|
||||
Effects.SendLocationParticles(EffectItem.Create(parent.Location, parent.Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
|
||||
Effects.PlaySound(parent.Location, parent.Map, 0x201);
|
||||
}
|
||||
else
|
||||
{
|
||||
Effects.SendLocationParticles(EffectItem.Create(this.Location, this.Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
|
||||
Effects.PlaySound(this.Location, this.Map, 0x201);
|
||||
}
|
||||
|
||||
Delete();
|
||||
}
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
base.Delete();
|
||||
|
||||
if (m_Timer != null)
|
||||
{
|
||||
m_Timer.Stop();
|
||||
m_Timer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public override void AddNameProperty(ObjectPropertyList list)
|
||||
{
|
||||
list.Add(1152601); // Temporary Forge
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
int left = 0;
|
||||
if (DateTime.UtcNow < Expires)
|
||||
left = (int)(Expires - DateTime.UtcNow).TotalSeconds;
|
||||
|
||||
list.Add(1072517, left.ToString()); // Lifespan: ~1_val~ seconds
|
||||
list.Add(1152627); // no house required
|
||||
list.Add(1152628); // cannot re-deed
|
||||
list.Add(1152629, TemporaryForge.DecayPeriod.ToString()); // lasts ~1_count~ hours
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
//TODO: Finish the ontaret stuff and clilocs.
|
||||
if (!IsChildOf(from.Backpack))
|
||||
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
|
||||
else
|
||||
{
|
||||
BaseHouse house = BaseHouse.FindHouseAt(from);
|
||||
|
||||
if (house != null)
|
||||
base.OnDoubleClick(from);
|
||||
else
|
||||
{
|
||||
from.BeginTarget(10, true, Server.Targeting.TargetFlags.None, (m, targeted) =>
|
||||
{
|
||||
if (targeted is IPoint3D)
|
||||
{
|
||||
Point3D p = new Point3D((IPoint3D)targeted);
|
||||
int dist = (int)from.GetDistanceToSqrt(p);
|
||||
|
||||
if (dist < 2 || dist > 5)
|
||||
from.SendLocalizedMessage(1152736); // You must stand between 2 and 5 tiles away from the targeted location to attempt to build this.
|
||||
else if (!from.InLOS(p))
|
||||
from.SendLocalizedMessage(500237); // Target cannot be seen.
|
||||
else if (!ValidateLocation(p, from.Map))
|
||||
from.SendLocalizedMessage(1152735); // The targeted location has at least one impassable tile adjacent to the structure.
|
||||
else
|
||||
{
|
||||
BaseHouse checkHouse = BaseHouse.FindHouseAt(from);
|
||||
|
||||
if (checkHouse != null)
|
||||
from.SendLocalizedMessage(500269); // You cannot build that there.
|
||||
else
|
||||
{
|
||||
IPoint3D point = (IPoint3D)targeted;
|
||||
Server.Spells.SpellHelper.GetSurfaceTop(ref point);
|
||||
|
||||
BaseAddon addon = this.Addon;
|
||||
addon.MoveToWorld(new Point3D(point), m.Map);
|
||||
|
||||
if (addon is TemporaryForge)
|
||||
((TemporaryForge)addon).Owner = from;
|
||||
|
||||
this.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool ValidateLocation(Point3D p, Map map)
|
||||
{
|
||||
if (!TreasureMap.ValidateLocation(p.X, p.Y, map))
|
||||
return false;
|
||||
|
||||
for (int x = p.X - 1; x <= p.X + 1; x++)
|
||||
{
|
||||
for (int y = p.Y - 1; y <= p.Y + 1; y++)
|
||||
{
|
||||
if(TreasureMap.ValidateLocation(x, y, map))
|
||||
{
|
||||
int z = map.GetAverageZ(x, y);
|
||||
IPooledEnumerable eable = map.GetItemsInRange(new Point3D(x, y, z), 0);
|
||||
foreach (Item item in eable)
|
||||
{
|
||||
ItemData id = TileData.ItemTable[item.ItemID & TileData.MaxItemValue];
|
||||
|
||||
if (item.Z + id.CalcHeight >= z)
|
||||
{
|
||||
eable.Free();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
eable.Free();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public TemporaryForgeDeed(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(Expires);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Expires = reader.ReadDateTime();
|
||||
|
||||
if (Expires < DateTime.UtcNow)
|
||||
Decay();
|
||||
else
|
||||
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), CheckDecay);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
using Server;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Mobiles;
|
||||
using Server.Items;
|
||||
using System.Linq;
|
||||
using Server.Targeting;
|
||||
using Server.Engines.Quests;
|
||||
using Server.Multis;
|
||||
|
||||
namespace Server.Engines.VoidPool
|
||||
{
|
||||
public static class VoidPoolRewards
|
||||
{
|
||||
public static List<CollectionItem> Rewards { get; set; }
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
Rewards = new List<CollectionItem>();
|
||||
|
||||
Rewards.Add(new CollectionItem(typeof(CauldronOfTransmutationDeed), 0x9ED, 1152656, (int)CraftResource.Bronze, 100)); //Bronze
|
||||
Rewards.Add(new CollectionItem(typeof(CauldronOfTransmutationDeed), 0x9ED, 1152657, (int)CraftResource.Gold, 200)); //Gold
|
||||
Rewards.Add(new CollectionItem(typeof(CauldronOfTransmutationDeed), 0x9ED, 1152658, (int)CraftResource.Agapite, 500)); //Agapite
|
||||
Rewards.Add(new CollectionItem(typeof(CauldronOfTransmutationDeed), 0x9ED, 1152659, (int)CraftResource.Verite, 1000)); //Verite
|
||||
|
||||
Rewards.Add(new CollectionItem(typeof(CauldronOfTransmutationDeed), 0x9ED, 1152660, (int)CraftResource.AshWood, 100)); //Ash
|
||||
Rewards.Add(new CollectionItem(typeof(CauldronOfTransmutationDeed), 0x9ED, 1152661, (int)CraftResource.YewWood, 200)); //Yew
|
||||
Rewards.Add(new CollectionItem(typeof(CauldronOfTransmutationDeed), 0x9ED, 1152662, (int)CraftResource.Heartwood, 500)); // Heartwood
|
||||
Rewards.Add(new CollectionItem(typeof(CauldronOfTransmutationDeed), 0x9ED, 1152663, (int)CraftResource.Bloodwood, 1000)); // Bloodwood
|
||||
|
||||
Rewards.Add(new CollectionItem(typeof(HarvestMap), 0x14EC, 1152665, (int)CraftResource.Gold, 250)); //Gold
|
||||
Rewards.Add(new CollectionItem(typeof(HarvestMap), 0x14EC, 1152666, (int)CraftResource.Agapite, 500)); //Agapite
|
||||
Rewards.Add(new CollectionItem(typeof(HarvestMap), 0x14EC, 1152667, (int)CraftResource.Verite, 1000)); //Verite
|
||||
Rewards.Add(new CollectionItem(typeof(HarvestMap), 0x14EC, 1152668, (int)CraftResource.Valorite, 2000)); //Valorite
|
||||
|
||||
Rewards.Add(new CollectionItem(typeof(HarvestMap), 0x14EC, 1152669, (int)CraftResource.YewWood, 250)); //Yew
|
||||
Rewards.Add(new CollectionItem(typeof(HarvestMap), 0x14EC, 1152670, (int)CraftResource.Heartwood, 500)); //Heartwood
|
||||
Rewards.Add(new CollectionItem(typeof(HarvestMap), 0x14EC, 1152671, (int)CraftResource.Bloodwood, 1000)); //Bloodwood
|
||||
Rewards.Add(new CollectionItem(typeof(HarvestMap), 0x14EC, 1152672, (int)CraftResource.Frostwood, 2000)); //Frostwood
|
||||
|
||||
Rewards.Add(new CollectionItem(typeof(SmeltersTalisman), 0x2F5B, 1152674, (int)CraftResource.Gold, 50)); // Gold
|
||||
Rewards.Add(new CollectionItem(typeof(SmeltersTalisman), 0x2F5B, 1152675, (int)CraftResource.Agapite, 100)); // Agapite
|
||||
Rewards.Add(new CollectionItem(typeof(SmeltersTalisman), 0x2F5B, 1152676, (int)CraftResource.Verite, 200)); // Verite
|
||||
Rewards.Add(new CollectionItem(typeof(SmeltersTalisman), 0x2F5B, 1152677, (int)CraftResource.Valorite, 500)); // Valorite
|
||||
|
||||
Rewards.Add(new CollectionItem(typeof(WoodsmansTalisman), 0x2F5A, 1152678, (int)CraftResource.YewWood, 50)); // Yew
|
||||
Rewards.Add(new CollectionItem(typeof(WoodsmansTalisman), 0x2F5A, 1152679, (int)CraftResource.Heartwood, 100));// Heartwood
|
||||
Rewards.Add(new CollectionItem(typeof(WoodsmansTalisman), 0x2F5A, 1152680, (int)CraftResource.Bloodwood, 200));// Bloodwood
|
||||
Rewards.Add(new CollectionItem(typeof(WoodsmansTalisman), 0x2F5A, 1152681, (int)CraftResource.Frostwood, 500));// Frostwood
|
||||
|
||||
Rewards.Add(new CollectionItem(typeof(TemporaryForgeDeed), 0xFB1, 1152682, 0, 250));
|
||||
Rewards.Add(new CollectionItem(typeof(MagicalFishFinder), 0x14F6, 1152683, 2500, 250));
|
||||
|
||||
//TODO: Hues for below
|
||||
Rewards.Add(new CollectionItem(typeof(BraceletOfProtection), 0x1086, 1152730, 1157, 1840));
|
||||
Rewards.Add(new CollectionItem(typeof(Hephaestus), 0x1B76, 1152909, 1910, 2000));
|
||||
Rewards.Add(new CollectionItem(typeof(GargishHephaestus), 0x4204, 1152909, 1910, 2000));
|
||||
Rewards.Add(new CollectionItem(typeof(BlightOfTheTundra), 0x26C2, 1152910, 1165, 2515));
|
||||
Rewards.Add(new CollectionItem(typeof(GargishBlightOfTheTundra), 0x090A, 1152910, 1165, 2515));
|
||||
}
|
||||
|
||||
public static Item DropRandomArtifact()
|
||||
{
|
||||
switch (Utility.Random(5))
|
||||
{
|
||||
case 0: return new PrismaticLenses();
|
||||
case 1: return new Brightblade();
|
||||
case 2: return new BraceletOfProtection(false);
|
||||
case 3: return new BlightOfTheTundra(false);
|
||||
case 4: return new Hephaestus(false);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
using Server;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Mobiles;
|
||||
using Server.Engines.Harvest;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class WoodsmansTalisman : BaseTalisman, IUsesRemaining
|
||||
{
|
||||
public const int DecayPeriod = 24;
|
||||
|
||||
private CraftResource _Resource;
|
||||
private int _UsesRemaining;
|
||||
private Timer m_Timer;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public CraftResource Resource
|
||||
{
|
||||
get { return _Resource; }
|
||||
set
|
||||
{
|
||||
if (_Resource != value)
|
||||
{
|
||||
_Resource = value;
|
||||
Hue = CraftResources.GetHue(_Resource);
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int UsesRemaining
|
||||
{
|
||||
get { return _UsesRemaining; }
|
||||
set
|
||||
{
|
||||
_UsesRemaining = value;
|
||||
|
||||
if (_UsesRemaining <= 0 && this.RootParent is Mobile)
|
||||
((Mobile)RootParent).SendLocalizedMessage(1152621); // Your talisman's magic is exhausted.
|
||||
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool ShowUsesRemaining { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DateTime Expires { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public WoodsmansTalisman(CraftResource resource)
|
||||
: base(0x2F5A)
|
||||
{
|
||||
Resource = resource;
|
||||
|
||||
UsesRemaining = 300;
|
||||
ShowUsesRemaining = true;
|
||||
|
||||
Expires = DateTime.UtcNow + TimeSpan.FromHours(DecayPeriod);
|
||||
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), CheckDecay);
|
||||
}
|
||||
|
||||
public void CheckDecay()
|
||||
{
|
||||
if (Expires < DateTime.UtcNow)
|
||||
Decay();
|
||||
else
|
||||
InvalidateProperties();
|
||||
}
|
||||
|
||||
public void Decay()
|
||||
{
|
||||
if (RootParent is Mobile)
|
||||
{
|
||||
Mobile parent = (Mobile)RootParent;
|
||||
|
||||
if (Name == null)
|
||||
parent.SendLocalizedMessage(1072515, "#" + LabelNumber); // The ~1_name~ expired...
|
||||
else
|
||||
parent.SendLocalizedMessage(1072515, Name); // The ~1_name~ expired...
|
||||
|
||||
Effects.SendLocationParticles(EffectItem.Create(parent.Location, parent.Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
|
||||
Effects.PlaySound(parent.Location, parent.Map, 0x201);
|
||||
}
|
||||
else
|
||||
{
|
||||
Effects.SendLocationParticles(EffectItem.Create(this.Location, this.Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
|
||||
Effects.PlaySound(this.Location, this.Map, 0x201);
|
||||
}
|
||||
|
||||
Delete();
|
||||
}
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
base.Delete();
|
||||
|
||||
if (m_Timer != null)
|
||||
{
|
||||
m_Timer.Stop();
|
||||
m_Timer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static int CheckHarvest(Mobile from, Type type, HarvestSystem system)
|
||||
{
|
||||
if (system != Lumberjacking.System)
|
||||
return 0;
|
||||
|
||||
CraftResource res = CraftResources.GetFromType(type);
|
||||
WoodsmansTalisman talisman = from.FindItemOnLayer(Layer.Talisman) as WoodsmansTalisman;
|
||||
|
||||
if (talisman != null && talisman.UsesRemaining > 0 && res == talisman.Resource)
|
||||
{
|
||||
talisman.UsesRemaining--;
|
||||
from.SendLocalizedMessage(1152625); // The magic of your talisman guides your hands as you cut the wood.
|
||||
return Utility.RandomMinMax(2, 5);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override void AddNameProperty(ObjectPropertyList list)
|
||||
{
|
||||
list.Add(1152599, String.Format("#{0}\t#1152605", CraftResources.GetLocalizationNumber(_Resource))); // ~1_RES~ ~2_TYPE~ Talisman
|
||||
}
|
||||
|
||||
public override void AddUsesRemainingProperties(ObjectPropertyList list)
|
||||
{
|
||||
list.Add(1060584, UsesRemaining.ToString()); // uses remaining: ~1_val~
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
int left = 0;
|
||||
if (DateTime.UtcNow < Expires)
|
||||
left = (int)(Expires - DateTime.UtcNow).TotalSeconds;
|
||||
|
||||
list.Add(1072517, left.ToString()); // Lifespan: ~1_val~ seconds
|
||||
}
|
||||
|
||||
public WoodsmansTalisman(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write((int)Resource);
|
||||
writer.Write(Expires);
|
||||
writer.Write(UsesRemaining);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Resource = (CraftResource)reader.ReadInt();
|
||||
Expires = reader.ReadDateTime();
|
||||
UsesRemaining = reader.ReadInt();
|
||||
|
||||
if (Expires < DateTime.UtcNow)
|
||||
Decay();
|
||||
else
|
||||
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), CheckDecay);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,360 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
using Server.ContextMenus;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.VoidPool
|
||||
{
|
||||
[PropertyObject]
|
||||
public class Level3Spawner : ISpawner
|
||||
{
|
||||
private bool _Active;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public VoidPoolController Controller { get; set; }
|
||||
|
||||
public List<SpawnEntry> Spawns { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int EntryCount { get { return Spawns == null ? 0 : Spawns.Count; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool Active
|
||||
{
|
||||
get { return _Active; }
|
||||
set
|
||||
{
|
||||
bool active = _Active;
|
||||
|
||||
if (value != active)
|
||||
{
|
||||
_Active = value;
|
||||
|
||||
if (!_Active)
|
||||
{
|
||||
Deactivate();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Spawns != null)
|
||||
{
|
||||
Deactivate(false);
|
||||
}
|
||||
|
||||
LoadSpawns();
|
||||
StartSpawn();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region ISpawner Stuff
|
||||
public bool UnlinkOnTaming { get { return true; } }
|
||||
public Point3D HomeLocation { get { return Point3D.Zero; } }
|
||||
public int HomeRange { get { return 20; } }
|
||||
|
||||
public void Remove(ISpawnable spawnable)
|
||||
{
|
||||
RemoveFromSpawner(spawnable);
|
||||
}
|
||||
|
||||
public virtual void GetSpawnProperties(ISpawnable spawn, ObjectPropertyList list)
|
||||
{ }
|
||||
|
||||
public virtual void GetSpawnContextEntries(ISpawnable spawn, Mobile user, List<ContextMenuEntry> list)
|
||||
{ }
|
||||
#endregion
|
||||
|
||||
public Level3Spawner(VoidPoolController controller)
|
||||
{
|
||||
Controller = controller;
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(1), () =>
|
||||
{
|
||||
Active = true;
|
||||
});
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "...";
|
||||
}
|
||||
|
||||
public void LoadSpawns()
|
||||
{
|
||||
if (Spawns != null)
|
||||
Spawns.Clear();
|
||||
|
||||
Spawns = new List<SpawnEntry>();
|
||||
Spawns.Add(new SpawnEntry(this, new Rectangle2D[] { new Rectangle2D(5564, 1888, 26, 31) }));
|
||||
Spawns.Add(new SpawnEntry(this, new Rectangle2D[] { new Rectangle2D(5554, 1888, 8, 28) }));
|
||||
Spawns.Add(new SpawnEntry(this, new Rectangle2D[] { new Rectangle2D(5596, 1888, 8, 28) }));
|
||||
Spawns.Add(new SpawnEntry(this, new Rectangle2D[] { new Rectangle2D(5536, 1876, 8, 8), new Rectangle2D(5552, 1840, 11, 42) }));
|
||||
Spawns.Add(new SpawnEntry(this, new Rectangle2D[] { new Rectangle2D(5600, 1860, 8, 8), new Rectangle2D(5596, 1872, 15, 12) }));
|
||||
Spawns.Add(new SpawnEntry(this, new Rectangle2D[] { new Rectangle2D(5608, 1832, 15, 15), new Rectangle2D(5616, 1848, 11, 34) }));
|
||||
Spawns.Add(new SpawnEntry(this, new Rectangle2D[] { new Rectangle2D(5568, 1852, 22, 14) }, 15));
|
||||
Spawns.Add(new SpawnEntry(this, new Rectangle2D[] { new Rectangle2D(5568, 1824, 22, 11) }));
|
||||
Spawns.Add(new SpawnEntry(this, new Rectangle2D[] { new Rectangle2D(5501, 1800, 42, 19) }, 15));
|
||||
}
|
||||
|
||||
public void RemoveFromSpawner(ISpawnable spawnable)
|
||||
{
|
||||
BaseCreature bc = spawnable as BaseCreature;
|
||||
|
||||
if (bc != null)
|
||||
{
|
||||
var entry = FindEntryFor(bc);
|
||||
|
||||
if (entry != null)
|
||||
{
|
||||
entry.Spawn.Remove(bc);
|
||||
bc.Spawner = null;
|
||||
|
||||
if (entry.CurrentCount == 0)
|
||||
{
|
||||
Timer.DelayCall<SpawnEntry>(TimeSpan.FromMinutes(Utility.RandomMinMax(2, 5)), en =>
|
||||
{
|
||||
Reset(en);
|
||||
}, entry);
|
||||
}
|
||||
|
||||
List<DamageStore> list = bc.GetLootingRights();
|
||||
|
||||
foreach (var ds in list)
|
||||
{
|
||||
if (ds.m_HasRight)
|
||||
{
|
||||
int points = (bc.Fame / 998) / list.Count;
|
||||
|
||||
if (points > 0)
|
||||
{
|
||||
AddToOverallTotal(ds.m_Mobile, points);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AddToOverallTotal(Mobile m, int points)
|
||||
{
|
||||
var stats = VoidPoolStats.GetStats(Controller);
|
||||
|
||||
if (stats != null)
|
||||
{
|
||||
if (!stats.OverallTotal.ContainsKey(m))
|
||||
stats.OverallTotal[m] = points;
|
||||
else
|
||||
stats.OverallTotal[m] += points;
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset(SpawnEntry entry)
|
||||
{
|
||||
if (!Active)
|
||||
return;
|
||||
|
||||
var type = entry.SpawnType;
|
||||
|
||||
do
|
||||
{
|
||||
entry.SpawnType = (VoidType)Utility.RandomMinMax(0, 4);
|
||||
}
|
||||
while (entry.SpawnType == type);
|
||||
|
||||
entry.DoSpawn();
|
||||
}
|
||||
|
||||
public void StartSpawn()
|
||||
{
|
||||
foreach (var entry in Spawns)
|
||||
{
|
||||
entry.SpawnType = (VoidType)Utility.RandomMinMax(0, 4);
|
||||
entry.DoSpawn();
|
||||
}
|
||||
}
|
||||
|
||||
public SpawnEntry FindEntryFor(BaseCreature bc)
|
||||
{
|
||||
return Spawns.FirstOrDefault(sp => sp.Spawn.Contains(bc));
|
||||
}
|
||||
|
||||
public void Deactivate(bool deactivate = true)
|
||||
{
|
||||
if (deactivate)
|
||||
{
|
||||
Active = false;
|
||||
}
|
||||
|
||||
if (Spawns != null)
|
||||
{
|
||||
foreach (var entry in Spawns)
|
||||
{
|
||||
var list = new List<BaseCreature>();
|
||||
|
||||
foreach (var bc in entry.Spawn)
|
||||
{
|
||||
list.Add(bc);
|
||||
}
|
||||
|
||||
foreach (var creature in list)
|
||||
creature.Delete();
|
||||
|
||||
ColUtility.Free(list);
|
||||
}
|
||||
|
||||
Spawns.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public Level3Spawner(GenericReader reader, VoidPoolController controller)
|
||||
{
|
||||
Controller = controller;
|
||||
LoadSpawns();
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 2:
|
||||
case 1:
|
||||
{
|
||||
if (version == 1)
|
||||
Active = controller.Active;
|
||||
|
||||
_Active = reader.ReadBool();
|
||||
}
|
||||
goto case 0;
|
||||
case 0:
|
||||
{
|
||||
int count = reader.ReadInt();
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Spawns[i].Deserialize(reader);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
writer.Write(2);
|
||||
|
||||
writer.Write(_Active);
|
||||
|
||||
writer.Write(Spawns == null ? 0 : Spawns.Count);
|
||||
|
||||
if (Spawns != null)
|
||||
{
|
||||
for (int i = 0; i < Spawns.Count; i++)
|
||||
{
|
||||
Spawns[i].Serialize(writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SpawnEntry
|
||||
{
|
||||
public Level3Spawner Spawner { get; set; }
|
||||
|
||||
public Rectangle2D[] Bounds { get; private set; }
|
||||
public int MaxCount { get; private set; }
|
||||
|
||||
public int CurrentCount { get { return Spawn.Count; } }
|
||||
public VoidType SpawnType { get; set; }
|
||||
|
||||
public List<BaseCreature> Spawn { get; set; }
|
||||
|
||||
public SpawnEntry(Level3Spawner spawner, Rectangle2D[] bounds, int maxCount = 8)
|
||||
{
|
||||
Bounds = bounds;
|
||||
MaxCount = maxCount;
|
||||
Spawner = spawner;
|
||||
Spawn = new List<BaseCreature>();
|
||||
}
|
||||
|
||||
public void DoSpawn()
|
||||
{
|
||||
if (Spawner == null || Spawner.Controller == null || Spawner.Controller.Map == null || !Spawner.Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Map map = Spawner.Controller.Map;
|
||||
Type[] types = VoidPoolController.SpawnTable[(int)SpawnType];
|
||||
|
||||
for (int i = 0; i < MaxCount; i++)
|
||||
{
|
||||
BaseCreature bc = Activator.CreateInstance(types[Utility.Random(types.Length)], Utility.RandomMinMax(5, 15), false) as BaseCreature;
|
||||
|
||||
if (bc != null)
|
||||
{
|
||||
Rectangle2D rec = Bounds[Utility.Random(Bounds.Length)];
|
||||
Point3D p = Point3D.Zero;
|
||||
|
||||
for(int j = 0; j < 50; j++)
|
||||
{
|
||||
p = map.GetRandomSpawnPoint(rec);
|
||||
|
||||
if (map.CanSpawnMobile(p))
|
||||
break;
|
||||
}
|
||||
|
||||
if (p != Point3D.Zero)
|
||||
{
|
||||
bc.Spawner = Spawner;
|
||||
|
||||
bc.Home = p;
|
||||
bc.RangeHome = 20;
|
||||
|
||||
bc.OnBeforeSpawn(p, map);
|
||||
bc.MoveToWorld(p, map);
|
||||
bc.OnAfterSpawn();
|
||||
|
||||
Spawn.Add(bc);
|
||||
}
|
||||
else
|
||||
{
|
||||
bc.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(Spawn.Count);
|
||||
Spawn.ForEach(s => writer.Write(s));
|
||||
}
|
||||
|
||||
public void Deserialize(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Spawn = new List<BaseCreature>();
|
||||
int count = reader.ReadInt();
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
BaseCreature bc = reader.ReadMobile() as BaseCreature;
|
||||
|
||||
if (bc != null)
|
||||
{
|
||||
bc.Spawner = Spawner;
|
||||
Spawn.Add(bc);
|
||||
}
|
||||
}
|
||||
|
||||
if (Spawn.Count == 0)
|
||||
Timer.DelayCall(DoSpawn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
137
Scripts/Services/Revamped Dungeons/Covetous Void Spawn/Region.cs
Normal file
137
Scripts/Services/Revamped Dungeons/Covetous Void Spawn/Region.cs
Normal file
@@ -0,0 +1,137 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Items;
|
||||
using Server.Spells;
|
||||
using Server.Regions;
|
||||
|
||||
namespace Server.Engines.VoidPool
|
||||
{
|
||||
public class VoidPoolRegion : BaseRegion
|
||||
{
|
||||
private static Rectangle2D[] Bounds = new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D(5383, 1960, 236, 80),
|
||||
new Rectangle2D(5429, 1948, 12, 10),
|
||||
};
|
||||
|
||||
public VoidPoolController Controller { get; private set; }
|
||||
|
||||
public VoidPoolRegion(VoidPoolController controller, Map map) : base("Void Pool", map, Region.DefaultPriority, Bounds)
|
||||
{
|
||||
Controller = controller;
|
||||
}
|
||||
|
||||
public void SendRegionMessage(int localization)
|
||||
{
|
||||
foreach (var m in GetEnumeratedMobiles().Where(m => m.Player))
|
||||
{
|
||||
m.SendLocalizedMessage(localization);
|
||||
}
|
||||
}
|
||||
|
||||
public void SendRegionMessage(int localization, int hue)
|
||||
{
|
||||
foreach (var m in GetEnumeratedMobiles().Where(m => m.Player))
|
||||
{
|
||||
m.SendLocalizedMessage(localization, "", hue);
|
||||
}
|
||||
}
|
||||
|
||||
public void SendRegionMessage(int localization, string args)
|
||||
{
|
||||
foreach (var m in GetEnumeratedMobiles().Where(m => m.Player))
|
||||
{
|
||||
m.SendLocalizedMessage(localization, args);
|
||||
}
|
||||
}
|
||||
|
||||
public void SendRegionMessage(string message)
|
||||
{
|
||||
foreach (var m in GetEnumeratedMobiles().Where(m => m.Player))
|
||||
{
|
||||
m.SendMessage(0x25, message);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDeath(Mobile m)
|
||||
{
|
||||
if (m is BaseCreature && !((BaseCreature)m).Controlled && !((BaseCreature)m).Summoned && Controller != null && Controller.OnGoing)
|
||||
{
|
||||
Controller.OnCreatureKilled((BaseCreature)m);
|
||||
|
||||
if (m is CovetousCreature && ((CovetousCreature)m).VoidSpawn)
|
||||
{
|
||||
int wave = ((CovetousCreature)m).Level;
|
||||
double bump = wave > 10 ? ((double)Math.Min(60, wave - 10) / 1000.0) : 0;
|
||||
double chance = 0.001 + bump;
|
||||
|
||||
if (chance > Utility.RandomDouble())
|
||||
{
|
||||
Mobile mob = DemonKnight.FindRandomPlayer((BaseCreature)m);
|
||||
|
||||
if (mob != null)
|
||||
{
|
||||
Item artifact = VoidPoolRewards.DropRandomArtifact();
|
||||
|
||||
if (artifact != null)
|
||||
{
|
||||
Container pack = mob.Backpack;
|
||||
|
||||
if (pack == null || !pack.TryDropItem(mob, artifact, false))
|
||||
mob.BankBox.DropItem(artifact);
|
||||
|
||||
mob.SendLocalizedMessage(1062317); // For your valor in combating the fallen beast, a special artifact has been bestowed on you.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base.OnDeath(m);
|
||||
}
|
||||
|
||||
public override bool OnDoubleClick(Mobile m, object o)
|
||||
{
|
||||
if(o is Corpse && m.AccessLevel == AccessLevel.Player)
|
||||
{
|
||||
Corpse c = o as Corpse;
|
||||
|
||||
if(c.Owner == null || (c.Owner is CovetousCreature && ((CovetousCreature)c.Owner).VoidSpawn))
|
||||
{
|
||||
c.LabelTo(m, 1152684); // There is no loot on the corpse.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return base.OnDoubleClick(m, o);
|
||||
}
|
||||
|
||||
public override void AlterLightLevel(Mobile m, ref int global, ref int personal)
|
||||
{
|
||||
global = LightCycle.DungeonLevel;
|
||||
}
|
||||
|
||||
public override bool CanUseStuckMenu(Mobile m)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool CheckTravel(Mobile m, Point3D newLocation, TravelCheckType travelType)
|
||||
{
|
||||
if (m.AccessLevel > AccessLevel.Player)
|
||||
return true;
|
||||
|
||||
switch (travelType)
|
||||
{
|
||||
default: return true;
|
||||
case TravelCheckType.RecallTo:
|
||||
case TravelCheckType.GateTo:
|
||||
case TravelCheckType.Mark: return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,774 @@
|
||||
using Server;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Mobiles;
|
||||
using Server.Items;
|
||||
using System.Linq;
|
||||
using Server.Engines.Points;
|
||||
using Server.Engines.Quests;
|
||||
|
||||
namespace Server.Engines.VoidPool
|
||||
{
|
||||
public enum VoidType
|
||||
{
|
||||
Abyss,
|
||||
Repond,
|
||||
Undead,
|
||||
Reptile,
|
||||
Elemental
|
||||
}
|
||||
|
||||
public class VoidPoolController : Item
|
||||
{
|
||||
public static VoidPoolController InstanceTram { get; set; }
|
||||
public static VoidPoolController InstanceFel { get; set; }
|
||||
|
||||
private readonly int RestartSpan = 15;
|
||||
private readonly int PoolStartHits = 15;
|
||||
private readonly int StartPointVariance = 8;
|
||||
|
||||
private readonly Point3D StartPoint1 = new Point3D(5592, 2012, 0);
|
||||
private readonly Point3D StartPoint2 = new Point3D(5466, 2007, 0);
|
||||
|
||||
private readonly Point3D EndPoint = new Point3D(5500, 1998, 5);
|
||||
private readonly Rectangle2D PoolWalls = new Rectangle2D(5495, 1993, 10, 10);
|
||||
|
||||
private bool _Active;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool Active
|
||||
{
|
||||
get { return _Active; }
|
||||
set
|
||||
{
|
||||
if(!value)
|
||||
{
|
||||
if(Timer != null)
|
||||
{
|
||||
Timer.Stop();
|
||||
Timer = null;
|
||||
}
|
||||
|
||||
if (Region != null)
|
||||
{
|
||||
Region.Unregister();
|
||||
Region = null;
|
||||
}
|
||||
|
||||
if (Level3Spawner != null)
|
||||
{
|
||||
Level3Spawner.Deactivate();
|
||||
Level3Spawner = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Region == null)
|
||||
{
|
||||
Region = new VoidPoolRegion(this, this.Map);
|
||||
Region.Register();
|
||||
}
|
||||
|
||||
if(Timer == null)
|
||||
{
|
||||
Timer = Timer.DelayCall(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), OnTick);
|
||||
Timer.Start();
|
||||
|
||||
NextStart = DateTime.UtcNow + TimeSpan.FromMinutes(RestartSpan);
|
||||
|
||||
if(Region != null)
|
||||
Region.SendRegionMessage(1152526, RestartSpan.ToString()); // The battle for the Void Pool will begin in ~1_VALUE~ minutes.
|
||||
}
|
||||
|
||||
if (Level3Spawner == null)
|
||||
{
|
||||
Level3Spawner = new Level3Spawner(this);
|
||||
}
|
||||
}
|
||||
|
||||
_Active = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Wave { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Stage
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Wave < 2)
|
||||
return 0;
|
||||
|
||||
return Math.Max(1, Wave / 5);
|
||||
}
|
||||
}
|
||||
|
||||
public List<WaveInfo> Waves { get; set; }
|
||||
public List<WayPoint> WaypointsA { get; set; }
|
||||
public List<WayPoint> WaypointsB { get; set; }
|
||||
public int WaypointACount { get; set; }
|
||||
public int WaypointBCount { get; set; }
|
||||
|
||||
public VoidPoolRegion Region { get; set; }
|
||||
public Timer Timer { get; set; }
|
||||
public Dictionary<Mobile, long> CurrentScore { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool OnGoing { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public VoidType VoidType { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DateTime NextStart { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DateTime NextWave { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int PoolHits { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int RespawnMin { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int RespawnMax { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Level3Spawner Level3Spawner { get; set; }
|
||||
|
||||
public VoidPoolController(Map map)
|
||||
: base(3803)
|
||||
{
|
||||
Name = "Void Pool Controller";
|
||||
Visible = false;
|
||||
Movable = false;
|
||||
|
||||
PoolHits = PoolStartHits;
|
||||
|
||||
if(map == Map.Trammel)
|
||||
{
|
||||
if(InstanceTram != null)
|
||||
Delete();
|
||||
else
|
||||
InstanceTram = this;
|
||||
}
|
||||
else if(map == Map.Felucca)
|
||||
{
|
||||
if(InstanceFel != null)
|
||||
Delete();
|
||||
else
|
||||
InstanceFel = this;
|
||||
}
|
||||
else
|
||||
Delete();
|
||||
|
||||
WaypointsA = new List<WayPoint>();
|
||||
WaypointsB = new List<WayPoint>();
|
||||
|
||||
Region = new VoidPoolRegion(this, map);
|
||||
Region.Register();
|
||||
|
||||
RespawnMin = 60;
|
||||
RespawnMax = 90;
|
||||
|
||||
ClearSpawners();
|
||||
Active = true;
|
||||
|
||||
ResetLevel3Spawners();
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from.AccessLevel >= AccessLevel.GameMaster)
|
||||
from.SendGump(new Server.Gumps.PropertiesGump(from, this));
|
||||
}
|
||||
|
||||
private void OnTick()
|
||||
{
|
||||
if(!OnGoing && DateTime.UtcNow > NextStart && Region != null && Region.GetPlayerCount() > 0)
|
||||
{
|
||||
NextStart = DateTime.MaxValue;
|
||||
OnGoing = true;
|
||||
VoidType = (VoidType)Utility.Random(5);
|
||||
PoolHits = PoolStartHits;
|
||||
Wave = 0;
|
||||
|
||||
if (CurrentScore != null)
|
||||
CurrentScore.Clear();
|
||||
|
||||
if (Waves != null)
|
||||
{
|
||||
Waves.Clear();
|
||||
Waves.TrimExcess();
|
||||
}
|
||||
|
||||
CurrentScore = new Dictionary<Mobile, long>();
|
||||
Waves = new List<WaveInfo>();
|
||||
|
||||
Region.SendRegionMessage(1152527, 0x2B); // The battle for the Void Pool is beginning now!
|
||||
|
||||
if (WaypointACount != WaypointsA.Count || WaypointBCount != WaypointsB.Count)
|
||||
Generate.AddWaypoints();
|
||||
|
||||
SpawnWave();
|
||||
}
|
||||
else if(OnGoing)
|
||||
{
|
||||
if(DateTime.UtcNow > NextWave)
|
||||
{
|
||||
SpawnWave();
|
||||
}
|
||||
|
||||
IPooledEnumerable eable = this.Map.GetMobilesInBounds(PoolWalls);
|
||||
foreach(Mobile m in eable)
|
||||
{
|
||||
if (!OnGoing)
|
||||
break;
|
||||
|
||||
if(m is BaseCreature && !((BaseCreature)m).Controlled && !((BaseCreature)m).Summoned && Utility.RandomDouble() > 0.25)
|
||||
OnVoidWallDamaged(m);
|
||||
}
|
||||
eable.Free();
|
||||
}
|
||||
}
|
||||
|
||||
public void SpawnWave()
|
||||
{
|
||||
Wave++;
|
||||
|
||||
Region.SendRegionMessage(1152528, Wave.ToString());
|
||||
|
||||
int toSpawn = (int)Math.Ceiling(Math.Max(5, Math.Sqrt(Wave) * 2) * 1.5);
|
||||
List<BaseCreature> creatures = new List<BaseCreature>();
|
||||
|
||||
for (int i = 0; i < toSpawn; i++)
|
||||
{
|
||||
Point3D start = i % 2 == 0 ? StartPoint1 : StartPoint2;
|
||||
|
||||
for(int j = 0; j < 25; j++)
|
||||
{
|
||||
int x = start.X + Utility.RandomMinMax(start.X - (StartPointVariance / 2), start.X + (StartPointVariance / 2));
|
||||
int y = start.Y + Utility.RandomMinMax(start.Y - (StartPointVariance / 2), start.Y + (StartPointVariance / 2));
|
||||
int z = this.Map.GetAverageZ(x, y);
|
||||
|
||||
if(this.Map.CanSpawnMobile(x, y, z))
|
||||
{
|
||||
start = new Point3D(x, y, z);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int ran = Utility.RandomMinMax(0, Stage < 10 ? 12 : Stage < 15 ? 14 : 15);
|
||||
Type t;
|
||||
|
||||
switch(ran)
|
||||
{
|
||||
default:
|
||||
case 0: case 1: case 3: case 4: t = SpawnTable[(int)VoidType][0]; break;
|
||||
case 5: case 6: case 7: case 8: t = SpawnTable[(int)VoidType][1]; break;
|
||||
case 9: case 10: case 11: t = SpawnTable[(int)VoidType][2]; break;
|
||||
case 12: case 13: t = SpawnTable[(int)VoidType][3]; break;
|
||||
case 14: case 15: t = SpawnTable[(int)VoidType][4]; break;
|
||||
}
|
||||
|
||||
BaseCreature bc = Activator.CreateInstance(t, Wave, true) as BaseCreature;
|
||||
|
||||
if(bc != null)
|
||||
{
|
||||
bc.NoLootOnDeath = true;
|
||||
Timer.DelayCall(TimeSpan.FromSeconds((double)i * .75), () =>
|
||||
{
|
||||
if (OnGoing)
|
||||
{
|
||||
bc.MoveToWorld(start, this.Map);
|
||||
bc.Home = EndPoint;
|
||||
bc.RangeHome = 1;
|
||||
|
||||
creatures.Add(bc);
|
||||
|
||||
bc.CurrentWayPoint = GetNearestWaypoint(bc);
|
||||
}
|
||||
else
|
||||
bc.Delete();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var gate1 = new VoidPoolGate();
|
||||
gate1.MoveToWorld(StartPoint1, Map);
|
||||
Effects.PlaySound(StartPoint1, Map, 0x20E);
|
||||
|
||||
var gate2 = new VoidPoolGate();
|
||||
gate2.MoveToWorld(StartPoint2, Map);
|
||||
Effects.PlaySound(StartPoint2, Map, 0x20E);
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(toSpawn * .80), () =>
|
||||
{
|
||||
Effects.SendLocationParticles(EffectItem.Create(gate1.Location, gate1.Map, EffectItem.DefaultDuration), 0x376A, 9, 20, 5042);
|
||||
Effects.PlaySound(gate1.GetWorldLocation(), gate1.Map, 0x201);
|
||||
|
||||
Effects.SendLocationParticles(EffectItem.Create(gate2.Location, gate2.Map, EffectItem.DefaultDuration), 0x376A, 9, 20, 5042);
|
||||
Effects.PlaySound(gate2.GetWorldLocation(), gate2.Map, 0x201);
|
||||
|
||||
gate1.Delete();
|
||||
gate2.Delete();
|
||||
});
|
||||
|
||||
Waves.Add(new WaveInfo(Wave, creatures));
|
||||
NextWave = GetNextWaveTime();
|
||||
}
|
||||
|
||||
public WayPoint GetNearestWaypoint(Mobile m, int range = 15)
|
||||
{
|
||||
IPooledEnumerable eable = this.Map.GetItemsInRange(m.Location, range);
|
||||
|
||||
int closestRange = 15;
|
||||
WayPoint closest = null;
|
||||
|
||||
foreach (Item item in eable)
|
||||
{
|
||||
int dist = 0;
|
||||
if (item is WayPoint)
|
||||
{
|
||||
dist = (int)m.GetDistanceToSqrt(item);
|
||||
|
||||
if (dist < closestRange || closest == null)
|
||||
{
|
||||
closest = item as WayPoint;
|
||||
closestRange = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return closest;
|
||||
}
|
||||
|
||||
public Item GetNearestVoidPoolWall(Mobile m)
|
||||
{
|
||||
IPooledEnumerable eable = this.Map.GetItemsInRange(m.Location, 5);
|
||||
|
||||
int closestRange = 5;
|
||||
Item closest = null;
|
||||
|
||||
foreach (Item item in eable)
|
||||
{
|
||||
int dist = 0;
|
||||
if (item.Name == "Void Pool")
|
||||
{
|
||||
dist = (int)m.GetDistanceToSqrt(item);
|
||||
|
||||
if (dist < closestRange || closest == null)
|
||||
{
|
||||
closest = item;
|
||||
closestRange = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return closest;
|
||||
}
|
||||
|
||||
public DateTime GetNextWaveTime()
|
||||
{
|
||||
if(Wave == 1)
|
||||
return DateTime.UtcNow + TimeSpan.FromSeconds(10);
|
||||
|
||||
int min = Math.Max(30, RespawnMin - Wave) + Utility.RandomMinMax(0, 10);
|
||||
int max = Math.Max(45, RespawnMax - Wave) - Utility.RandomMinMax(0, 5);
|
||||
|
||||
return DateTime.UtcNow + TimeSpan.FromSeconds(Utility.RandomMinMax(min, max));
|
||||
}
|
||||
|
||||
public void OnVoidWallDamaged(Mobile damager)
|
||||
{
|
||||
if(0.5 > Utility.RandomDouble())
|
||||
PoolHits--;
|
||||
|
||||
Region.SendRegionMessage(1152529); // The Void Pool walls have been damaged! Defend the Void Pool!
|
||||
|
||||
Item item = GetNearestVoidPoolWall(damager);
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
Point3D p = new Point3D(item.X, item.Y, item.Z + 5);
|
||||
Effects.SendLocationParticles(EffectItem.Create(p, item.Map, EffectItem.DefaultDuration), Utility.RandomList(0x36BD, 0x36B0, 0x3728), 20, 10, 5044);
|
||||
Effects.PlaySound(p, item.Map, 0x307);
|
||||
}
|
||||
|
||||
if (PoolHits <= 0 && OnGoing)
|
||||
{
|
||||
OnGoing = false;
|
||||
EndInvasion();
|
||||
}
|
||||
}
|
||||
|
||||
public void EndInvasion()
|
||||
{
|
||||
Region.SendRegionMessage(1152530); // Cora's forces have destroyed the Void Pool walls. The battle is lost!
|
||||
|
||||
VoidPoolStats.OnInvasionEnd(this /*CurrentScore, Wave*/);
|
||||
|
||||
NextStart = DateTime.UtcNow + TimeSpan.FromMinutes(RestartSpan);
|
||||
|
||||
Region.SendRegionMessage(1152526, RestartSpan.ToString()); // The battle for the Void Pool will begin in ~1_VALUE~ minutes.
|
||||
|
||||
List<Mobile> list = Region.GetPlayers();
|
||||
|
||||
foreach (Mobile m in list.Where(m => GetCurrentPoints(m) > 0))
|
||||
PointsSystem.VoidPool.AwardPoints(m, GetCurrentPoints(m));
|
||||
|
||||
foreach(Mobile m in list.Where(m => CurrentScore.ContainsKey(m)))
|
||||
{
|
||||
m.SendLocalizedMessage(1152650, String.Format("{0}\t{1}\t{2}\t{3}", GetTotalWaves(m), Wave.ToString(), Wave.ToString(), CurrentScore[m]));
|
||||
// During the battle, you helped fight back ~1_COUNT~ out of ~2_TOTAL~ waves of enemy forces. Your final wave was ~3_MAX~. Your total score for the battle was ~4_SCORE~ points.
|
||||
|
||||
if (m is PlayerMobile)
|
||||
{
|
||||
var quest = QuestHelper.GetQuest<AForcedSacraficeQuest>((PlayerMobile)m);
|
||||
|
||||
if (quest != null)
|
||||
{
|
||||
quest.CompleteQuest();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColUtility.Free(list);
|
||||
ClearSpawn(true);
|
||||
}
|
||||
|
||||
public void OnCreatureKilled(BaseCreature killed)
|
||||
{
|
||||
if (Waves == null)
|
||||
return;
|
||||
|
||||
Waves.ForEach(info =>
|
||||
{
|
||||
if (info.Creatures.Contains(killed))
|
||||
{
|
||||
List<DamageStore> list = killed.GetLootingRights();
|
||||
list.Sort();
|
||||
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
DamageStore ds = list[i];
|
||||
Mobile m = ds.m_Mobile;
|
||||
|
||||
if (ds.m_Mobile is BaseCreature && ((BaseCreature)ds.m_Mobile).GetMaster() is PlayerMobile)
|
||||
m = ((BaseCreature)ds.m_Mobile).GetMaster();
|
||||
|
||||
if (!info.Credit.Contains(m))
|
||||
info.Credit.Add(m);
|
||||
|
||||
if (!CurrentScore.ContainsKey(m))
|
||||
CurrentScore[m] = killed.Fame / 998;
|
||||
else
|
||||
CurrentScore[m] += killed.Fame / 998;
|
||||
}
|
||||
|
||||
list.Clear();
|
||||
list.TrimExcess();
|
||||
|
||||
info.Creatures.Remove(killed);
|
||||
|
||||
if (info.Creatures.Count == 0)
|
||||
{
|
||||
foreach (Mobile m in info.Credit.Where(m => m.Region == this.Region && m is PlayerMobile))
|
||||
{
|
||||
double award = Math.Max(0, this.Map == Map.Felucca ? Stage * 2 : Stage);
|
||||
|
||||
if (award > 0)
|
||||
{
|
||||
//Score Bonus
|
||||
if (!CurrentScore.ContainsKey(m))
|
||||
CurrentScore[m] = Stage * 125;
|
||||
else
|
||||
CurrentScore[m] += Stage * 125;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (killed.Corpse != null && !killed.Corpse.Deleted)
|
||||
((Corpse)killed.Corpse).BeginDecay(TimeSpan.FromMinutes(1));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void ClearSpawners()
|
||||
{
|
||||
if (Region == null)
|
||||
return;
|
||||
|
||||
foreach (Item item in Region.GetEnumeratedItems().Where(i => i is ISpawner))
|
||||
{
|
||||
if (item is XmlSpawner)
|
||||
{
|
||||
((XmlSpawner)item).DoReset = true;
|
||||
}
|
||||
else if (item is Spawner)
|
||||
{
|
||||
((Spawner)item).RemoveSpawned();
|
||||
((Spawner)item).Running = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetLevel3Spawners()
|
||||
{
|
||||
ResetLevel3Spawners(Map.Trammel);
|
||||
ResetLevel3Spawners(Map.Felucca);
|
||||
}
|
||||
|
||||
public void ResetLevel3Spawners(Map map)
|
||||
{
|
||||
Server.Region r = Server.Region.Find(new Point3D(5574, 1859, 0), map);
|
||||
|
||||
foreach (Item item in r.GetEnumeratedItems().Where(i => i is ISpawner
|
||||
&& i.X >= 5501 && i.X <= 5627 && i.Y >= 1799 && i.Y <= 1927))
|
||||
{
|
||||
if (item is XmlSpawner)
|
||||
{
|
||||
((XmlSpawner)item).DoReset = true;
|
||||
}
|
||||
else if (item is Spawner)
|
||||
{
|
||||
((Spawner)item).RemoveSpawned();
|
||||
((Spawner)item).Running = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearSpawn()
|
||||
{
|
||||
ClearSpawn(false);
|
||||
}
|
||||
|
||||
public void ClearSpawn(bool effects)
|
||||
{
|
||||
if (Region == null)
|
||||
return;
|
||||
|
||||
foreach (Mobile m in Region.GetEnumeratedMobiles().Where(m => m is CovetousCreature))
|
||||
{
|
||||
if (effects)
|
||||
Effects.SendLocationEffect(m.Location, m.Map, 0xDDA, 30, 10, 0, 0);
|
||||
|
||||
m.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
public int GetCurrentPoints(Mobile from)
|
||||
{
|
||||
if (Waves == null)
|
||||
return 0;
|
||||
|
||||
int points = 0;
|
||||
|
||||
foreach (var info in Waves.Where(i => i.Credit.Contains(from)))
|
||||
{
|
||||
points += this.Map == Map.Felucca ? Stage * 2 : Stage;
|
||||
}
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
public int GetTotalWaves(Mobile from)
|
||||
{
|
||||
return Waves.Where(i => i.Wave > 2 && i.Credit.Contains(from)).Count();
|
||||
}
|
||||
|
||||
public static int GetPlayerScore(Dictionary<Mobile, long> score, Mobile m)
|
||||
{
|
||||
if(score == null || m == null || !score.ContainsKey(m))
|
||||
return 0;
|
||||
|
||||
return (int)score[m];
|
||||
}
|
||||
|
||||
public static Type[][] SpawnTable = new Type[][]
|
||||
{
|
||||
new Type[] { typeof(DaemonMongbat), typeof(GargoyleAssassin), typeof(CovetousDoppleganger), typeof(LesserOni), typeof(CovetousFireDaemon) },
|
||||
new Type[] { typeof(LizardmanWitchdoctor), typeof(OrcFootSoldier), typeof(RatmanAssassin), typeof(OgreBoneCrusher), typeof(TitanRockHunter) },
|
||||
new Type[] { typeof(AngeredSpirit), typeof(BoneSwordSlinger), typeof(VileCadaver), typeof(DiseasedLich), typeof(CovetousRevenant) },
|
||||
new Type[] { typeof(WarAlligator), typeof(MagmaLizard), typeof(ViciousDrake), typeof(CorruptedWyvern), typeof(CovetousWyrm) },
|
||||
new Type[] { typeof(CovetousEarthElemental),typeof(CovetousWaterElemental), typeof(VortexElemental), typeof(SearingElemental),typeof(VenomElemental) },
|
||||
};
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
if(OnGoing)
|
||||
EndInvasion();
|
||||
|
||||
if(Region != null)
|
||||
{
|
||||
Region.Unregister();
|
||||
Region = null;
|
||||
}
|
||||
|
||||
if(Timer != null)
|
||||
{
|
||||
Timer.Stop();
|
||||
Timer = null;
|
||||
}
|
||||
|
||||
foreach (var wp in WaypointsA.Where(w => w != null && !w.Deleted))
|
||||
wp.Delete();
|
||||
|
||||
foreach (var wp in WaypointsB.Where(w => w != null && !w.Deleted))
|
||||
wp.Delete();
|
||||
|
||||
if (Level3Spawner != null)
|
||||
{
|
||||
Level3Spawner.Deactivate();
|
||||
Level3Spawner = null;
|
||||
}
|
||||
|
||||
base.Delete();
|
||||
}
|
||||
|
||||
public VoidPoolController(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)2);
|
||||
|
||||
if (Level3Spawner != null)
|
||||
{
|
||||
writer.Write(0);
|
||||
Level3Spawner.Serialize(writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write(1);
|
||||
}
|
||||
|
||||
writer.Write(RespawnMin);
|
||||
writer.Write(RespawnMax);
|
||||
|
||||
writer.Write(_Active);
|
||||
writer.Write(WaypointsA.Count);
|
||||
writer.Write(WaypointsB.Count);
|
||||
|
||||
WaypointsA.ForEach(w => writer.Write(w));
|
||||
WaypointsB.ForEach(w => writer.Write(w));
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 2:
|
||||
case 1:
|
||||
if (version == 1 || reader.ReadInt() == 0)
|
||||
{
|
||||
Level3Spawner = new Level3Spawner(reader, this);
|
||||
}
|
||||
goto case 0;
|
||||
case 0:
|
||||
if (version == 0)
|
||||
{
|
||||
Level3Spawner = new Level3Spawner(this);
|
||||
|
||||
Timer.DelayCall(() =>
|
||||
{
|
||||
ResetLevel3Spawners();
|
||||
});
|
||||
}
|
||||
|
||||
RespawnMin = reader.ReadInt();
|
||||
RespawnMax = reader.ReadInt();
|
||||
|
||||
WaypointsA = new List<WayPoint>();
|
||||
WaypointsB = new List<WayPoint>();
|
||||
|
||||
Active = reader.ReadBool();
|
||||
NextStart = DateTime.UtcNow;
|
||||
|
||||
int counta = reader.ReadInt();
|
||||
int countb = reader.ReadInt();
|
||||
|
||||
for (int i = 0; i < counta; i++)
|
||||
{
|
||||
WayPoint wp = reader.ReadItem() as WayPoint;
|
||||
|
||||
if (wp != null)
|
||||
WaypointsA.Add(wp);
|
||||
}
|
||||
|
||||
for (int i = 0; i < countb; i++)
|
||||
{
|
||||
WayPoint wp = reader.ReadItem() as WayPoint;
|
||||
|
||||
if (wp != null)
|
||||
WaypointsB.Add(wp);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (Map == Map.Felucca)
|
||||
InstanceFel = this;
|
||||
else
|
||||
InstanceTram = this;
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(10), () => { ClearSpawn(); ClearSpawners(); } );
|
||||
}
|
||||
}
|
||||
|
||||
public class VoidPoolGate : Static
|
||||
{
|
||||
public VoidPoolGate()
|
||||
: base(0xF6C)
|
||||
{
|
||||
Light = LightType.Circle300;
|
||||
}
|
||||
|
||||
public VoidPoolGate(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
reader.ReadInt();
|
||||
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
wave 1: 13:30:00
|
||||
wave 2: 13:30:10 +10
|
||||
wave 3: 13:31:43 +93
|
||||
wave 4: 13:33:05 +83
|
||||
wave 5: 13:34:17 +75
|
||||
wave 6: 13:35:08 +51
|
||||
wave 7: 13:36:37 +89
|
||||
wave 8: 13:37:38 +61
|
||||
wave 9: 13:38:19 +41
|
||||
wave 10: 13:39:32 +73
|
||||
wave 11: 13:40:02 +30
|
||||
wave 12: 13:40:54 +52
|
||||
wave 13: 13:41:45 +51
|
||||
wave 14: 13:42:36 +51
|
||||
wave 15: 13:43:28 +52
|
||||
wave 16: 13:44:09 +41
|
||||
wave 17: 13:45:01 +52
|
||||
*/
|
||||
@@ -0,0 +1,332 @@
|
||||
using System.Collections.Generic;
|
||||
using Server.Mobiles;
|
||||
using Server.Items;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Server.Engines.VoidPool
|
||||
{
|
||||
public class VoidPoolStats
|
||||
{
|
||||
public static string FilePath = Path.Combine("Saves/VoidPoolStats", "VoidPoolStats.bin");
|
||||
|
||||
public static List<VoidPoolStats> Stats { get; set; }
|
||||
|
||||
public VoidPoolController Controller { get; set; }
|
||||
|
||||
public Dictionary<Mobile, long> BestSingle { get; set; }
|
||||
public Dictionary<Mobile, long> OverallTotal { get; set; }
|
||||
public List<Dictionary<Mobile, long>> Top20 { get; set; }
|
||||
public BestWave BestWave { get; set; }
|
||||
|
||||
public VoidPoolStats(VoidPoolController controller)
|
||||
{
|
||||
BestSingle = new Dictionary<Mobile, long>();
|
||||
OverallTotal = new Dictionary<Mobile, long>();
|
||||
Top20 = new List<Dictionary<Mobile, long>>();
|
||||
|
||||
Controller = controller;
|
||||
Stats.Add(this);
|
||||
}
|
||||
|
||||
public static VoidPoolStats GetStats(VoidPoolController controller)
|
||||
{
|
||||
var stats = Stats.FirstOrDefault(s => s.Controller == controller);
|
||||
|
||||
if (stats == null)
|
||||
stats = new VoidPoolStats(controller);
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
public VoidPoolStats(GenericReader reader, bool conversion)
|
||||
{
|
||||
BestSingle = new Dictionary<Mobile, long>();
|
||||
OverallTotal = new Dictionary<Mobile, long>();
|
||||
Top20 = new List<Dictionary<Mobile, long>>();
|
||||
|
||||
int version = conversion ? 0 : reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
Controller = reader.ReadItem() as VoidPoolController;
|
||||
goto case 0;
|
||||
case 0:
|
||||
if (version == 0)
|
||||
Timer.DelayCall(() => Controller = VoidPoolController.InstanceTram);
|
||||
|
||||
if (reader.ReadInt() == 1)
|
||||
BestWave = new BestWave(reader);
|
||||
|
||||
int count = reader.ReadInt();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Mobile m = reader.ReadMobile();
|
||||
long l = reader.ReadLong();
|
||||
|
||||
if (m != null)
|
||||
BestSingle[m] = l;
|
||||
}
|
||||
|
||||
count = reader.ReadInt();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Mobile m = reader.ReadMobile();
|
||||
long l = reader.ReadLong();
|
||||
|
||||
if (m != null)
|
||||
OverallTotal[m] = l;
|
||||
}
|
||||
|
||||
count = reader.ReadInt();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
int c = reader.ReadInt();
|
||||
Dictionary<Mobile, long> dic = new Dictionary<Mobile, long>();
|
||||
for (int j = 0; j < c; j++)
|
||||
{
|
||||
Mobile m = reader.ReadMobile();
|
||||
long l = reader.ReadLong();
|
||||
|
||||
if (m != null)
|
||||
dic[m] = l;
|
||||
}
|
||||
|
||||
if (dic.Count > 0)
|
||||
Top20.Add(dic);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
writer.Write((int)1);
|
||||
|
||||
writer.Write(Controller);
|
||||
|
||||
if (BestWave != null)
|
||||
{
|
||||
writer.Write(1);
|
||||
BestWave.Serialize(writer);
|
||||
}
|
||||
else
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(BestSingle.Count);
|
||||
foreach (KeyValuePair<Mobile, long> kvp in BestSingle)
|
||||
{
|
||||
writer.Write(kvp.Key);
|
||||
writer.Write(kvp.Value);
|
||||
}
|
||||
|
||||
writer.Write(OverallTotal.Count);
|
||||
foreach (KeyValuePair<Mobile, long> kvp in OverallTotal)
|
||||
{
|
||||
writer.Write(kvp.Key);
|
||||
writer.Write(kvp.Value);
|
||||
}
|
||||
|
||||
writer.Write(Top20.Count);
|
||||
foreach (Dictionary<Mobile, long> dic in Top20)
|
||||
{
|
||||
writer.Write(dic.Count);
|
||||
foreach (KeyValuePair<Mobile, long> kvp in dic)
|
||||
{
|
||||
writer.Write(kvp.Key);
|
||||
writer.Write(kvp.Value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static void Configure()
|
||||
{
|
||||
EventSink.WorldSave += OnSave;
|
||||
EventSink.WorldLoad += OnLoad;
|
||||
}
|
||||
|
||||
public static void OnSave(WorldSaveEventArgs e)
|
||||
{
|
||||
Persistence.Serialize(
|
||||
FilePath,
|
||||
writer =>
|
||||
{
|
||||
writer.Write((int)1);
|
||||
|
||||
writer.Write(Stats.Count);
|
||||
foreach (var stats in Stats)
|
||||
{
|
||||
stats.Serialize(writer);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void OnLoad()
|
||||
{
|
||||
Stats = new List<VoidPoolStats>();
|
||||
|
||||
Persistence.Deserialize(
|
||||
FilePath,
|
||||
reader =>
|
||||
{
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if (version == 0)
|
||||
{
|
||||
Stats.Add(new VoidPoolStats(reader, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
int count = reader.ReadInt();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var stats = new VoidPoolStats(reader, false);
|
||||
|
||||
if (stats.Controller != null)
|
||||
{
|
||||
Stats.Add(stats);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public static bool CheckBestSingle(VoidPoolController controller)
|
||||
{
|
||||
var stats = GetStats(controller);
|
||||
|
||||
foreach (KeyValuePair<Mobile, long> kvp in controller.CurrentScore)
|
||||
{
|
||||
if (!stats.BestSingle.ContainsKey(kvp.Key) || kvp.Value > stats.BestSingle[kvp.Key])
|
||||
{
|
||||
stats.BestSingle[kvp.Key] = kvp.Value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void AddToOverallTotal(VoidPoolController controller)
|
||||
{
|
||||
var stats = GetStats(controller);
|
||||
|
||||
foreach (KeyValuePair<Mobile, long> kvp in controller.CurrentScore)
|
||||
{
|
||||
if (!stats.OverallTotal.ContainsKey(kvp.Key))
|
||||
stats.OverallTotal[kvp.Key] = kvp.Value;
|
||||
else
|
||||
stats.OverallTotal[kvp.Key] += kvp.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool CheckAddTop20(VoidPoolController controller)
|
||||
{
|
||||
long total = GetCollectiveScore(controller.CurrentScore);
|
||||
var stats = GetStats(controller);
|
||||
|
||||
List<Dictionary<Mobile, long>> copy = new List<Dictionary<Mobile, long>>(stats.Top20);
|
||||
|
||||
foreach (Dictionary<Mobile, long> s in copy.OrderBy(dic => -GetCollectiveScore(dic)))
|
||||
{
|
||||
if (total > GetCollectiveScore(s))
|
||||
{
|
||||
stats.Top20.Remove(copy[copy.Count - 1]);
|
||||
stats.Top20.Add(s);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static long GetCollectiveScore(Dictionary<Mobile, long> score)
|
||||
{
|
||||
if (score == null)
|
||||
return 0;
|
||||
|
||||
long s = 0;
|
||||
|
||||
foreach (long i in score.Values)
|
||||
{
|
||||
s += i;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
public static void CheckBestWave(VoidPoolController controller)
|
||||
{
|
||||
var stats = GetStats(controller);
|
||||
int wave = controller.Wave;
|
||||
|
||||
if (stats.BestWave == null || wave > stats.BestWave.Waves)
|
||||
{
|
||||
stats.BestWave = new BestWave(controller.CurrentScore, wave);
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(1.5), () => World.Broadcast(2072, false, String.Format("A new Void Pool Invasion record has been made: {0}!", wave.ToString())));
|
||||
}
|
||||
}
|
||||
|
||||
public static void OnInvasionEnd(VoidPoolController controller)
|
||||
{
|
||||
CheckAddTop20(controller);
|
||||
CheckBestSingle(controller);
|
||||
AddToOverallTotal(controller);
|
||||
CheckBestWave(controller);
|
||||
}
|
||||
}
|
||||
|
||||
public class BestWave
|
||||
{
|
||||
public Dictionary<Mobile, long> Score { get; private set; }
|
||||
public int Waves { get; private set; }
|
||||
public long TotalScore { get; private set; }
|
||||
public string Date { get; private set; }
|
||||
|
||||
public BestWave(Dictionary<Mobile, long> score, int waves)
|
||||
{
|
||||
Score = score;
|
||||
|
||||
TotalScore = VoidPoolStats.GetCollectiveScore(score);
|
||||
Waves = waves;
|
||||
Date = DateTime.Now.ToShortDateString();
|
||||
}
|
||||
|
||||
public BestWave(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadInt();
|
||||
Waves = reader.ReadInt();
|
||||
TotalScore = reader.ReadLong();
|
||||
Date = reader.ReadString();
|
||||
|
||||
Score = new Dictionary<Mobile, long>();
|
||||
|
||||
int cnt = reader.ReadInt();
|
||||
for (int i = 0; i < cnt; i++)
|
||||
{
|
||||
Mobile m = reader.ReadMobile();
|
||||
long score = reader.ReadLong();
|
||||
if (m != null)
|
||||
Score[m] = score;
|
||||
}
|
||||
}
|
||||
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
writer.Write(0);
|
||||
writer.Write(Waves);
|
||||
writer.Write(TotalScore);
|
||||
writer.Write(Date);
|
||||
|
||||
writer.Write(Score.Count);
|
||||
foreach (KeyValuePair<Mobile, long> kvp in Score)
|
||||
{
|
||||
writer.Write(kvp.Key);
|
||||
writer.Write(kvp.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using Server;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.VoidPool
|
||||
{
|
||||
public class WaveInfo
|
||||
{
|
||||
public int Wave { get; set; }
|
||||
public bool Cleared { get; set; }
|
||||
public List<BaseCreature> Creatures { get; private set; }
|
||||
public List<Mobile> Credit { get; set; }
|
||||
|
||||
public WaveInfo(int index, List<BaseCreature> list)
|
||||
{
|
||||
Wave = index;
|
||||
Creatures = list;
|
||||
|
||||
Credit = new List<Mobile>();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user