Overwrite

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

View File

@@ -0,0 +1,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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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);
}
}
}

View 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);
}
}
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}
}

View 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;
}
}
}
}

View File

@@ -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
*/

View File

@@ -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);
}
}
}
}

View File

@@ -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>();
}
}
}