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,110 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Engines.Points;
namespace Server.Engines.Khaldun
{
public class CaddelliteVendor : BaseVendor
{
private readonly List<SBInfo> m_SBInfos = new List<SBInfo>();
protected override List<SBInfo> SBInfos { get { return this.m_SBInfos; } }
public override void InitSBInfo()
{
m_SBInfos.Add(new SBCaddelliteTinker(this));
}
public static CaddelliteVendor InstanceTram { get; set; }
public static CaddelliteVendor InstanceFel { get; set; }
[Constructable]
public CaddelliteVendor()
: base("the Tinker")
{
}
public override void InitBody()
{
base.InitBody();
Name = NameList.RandomName("male");
CantWalk = true;
Hue = Utility.RandomSkinHue();
Body = 0x190;
HairItemID = Race.RandomHair(false);
HairHue = Race.RandomHairHue();
}
public override void InitOutfit()
{
SetWearable(new SmithyHammer());
SetWearable(new LongPants(), Utility.RandomBlueHue());
SetWearable(new Shirt());
SetWearable(new FullApron());
SetWearable(new ThighBoots());
}
public CaddelliteVendor(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
if (Map == Map.Felucca)
{
InstanceFel = this;
}
if (Map == Map.Trammel)
{
InstanceTram = this;
}
}
}
public class SBCaddelliteTinker : SBInfo
{
private readonly List<GenericBuyInfo> m_BuyInfo;
private readonly IShopSellInfo m_SellInfo = new InternalSellInfo();
public SBCaddelliteTinker(BaseVendor owner)
{
m_BuyInfo = new InternalBuyInfo(owner);
}
public override IShopSellInfo SellInfo { get { return m_SellInfo; } }
public override List<GenericBuyInfo> BuyInfo { get { return m_BuyInfo; } }
public class InternalBuyInfo : List<GenericBuyInfo>
{
public InternalBuyInfo(BaseVendor owner)
{
Add(new GenericBuyInfo(typeof(CaddellitePickaxe), 101267, 500, 3718, 0));
Add(new GenericBuyInfo(typeof(CaddelliteHatchet), 101266, 500, 3907, 0));
Add(new GenericBuyInfo(typeof(CaddelliteFishingPole), 101265, 500, 3520, 0));
}
}
public class InternalSellInfo : GenericSellInfo
{
public InternalSellInfo()
{
}
}
}
}

View File

@@ -0,0 +1,202 @@
#region References
using Server.Items;
using Server.Misc;
using Server.Targeting;
using System;
#endregion
namespace Server.Mobiles
{
[CorpseName("an inhuman corpse")]
public class CultistAmbusher : BaseCreature
{
[Constructable]
public CultistAmbusher()
: base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4)
{
Name = "Cultist Ambusher";
Body = 0x190;
Hue = 2500;
BaseSoundID = 0x45A;
SetStr(150, 200);
SetDex(150);
SetInt(25, 44);
SetHits(500, 1000);
SetDamage(8, 18);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 10, 20);
SetResistance(ResistanceType.Fire, 10, 20);
SetResistance(ResistanceType.Cold, 10, 20);
SetResistance(ResistanceType.Poison, 10, 20);
SetResistance(ResistanceType.Energy, 10, 20);
SetSkill(SkillName.Fencing, 100.0, 120.0);
SetSkill(SkillName.Macing, 100.0, 120.0);
SetSkill(SkillName.MagicResist, 100.0, 120.0);
SetSkill(SkillName.Swords, 100.0, 120.0);
SetSkill(SkillName.Tactics, 100.0, 120.0);
SetSkill(SkillName.Archery, 100.0, 120.0);
SetSkill(SkillName.Parry, 100.0, 120.0);
SetSkill(SkillName.Tactics, 100.0, 120.0);
Fame = 8000;
Karma = -8000;
switch (Utility.Random(3))
{
case 0:
{
SetWearable(new RingmailChest(), 1510);
SetWearable(new ChainLegs(), 1345);
SetWearable(new Sandals(), 1345);
SetWearable(new LeatherNinjaHood(), 1345);
SetWearable(new LeatherGloves(), 1345);
SetWearable(new LeatherArms(), 1345);
break;
}
case 1:
{
SetWearable(new Robe(2306));
SetWearable(new BearMask(2683));
break;
}
case 2:
{
SetWearable(new Shirt(676));
SetWearable(new RingmailLegs());
SetWearable(new StuddedArms());
SetWearable(new StuddedGloves());
break;
}
case 3:
{
SetWearable(new SkullCap(2406));
SetWearable(new JinBaori(1001));
SetWearable(new Shirt());
SetWearable(new ShortPants(902));
break;
}
}
switch (Utility.Random(2))
{
case 0:
{
SetWearable(Loot.Construct(new Type[] { typeof(Kryss), typeof(Spear), typeof(ShortSpear), typeof(Lance), typeof(Pike), typeof(WarMace), typeof(Mace), typeof(WarHammer), typeof(WarAxe) }));
break;
}
case 1:
{
SetWearable(Loot.Construct(new Type[] { typeof(Yumi), typeof(Crossbow), typeof(RepeatingCrossbow), typeof(HeavyCrossbow) }));
RangeFight = 7;
AI = AIType.AI_Archer;
break;
}
}
}
public override void OnBeforeDamage(Mobile from, ref int totalDamage, Server.DamageType type)
{
if (Region.IsPartOf("Khaldun") && IsChampionSpawn && !Caddellite.CheckDamage(from, type))
{
totalDamage = 0;
}
base.OnBeforeDamage(from, ref totalDamage, type);
}
public override void OnGotMeleeAttack(Mobile attacker)
{
base.OnGotMeleeAttack(attacker);
if (Map != null && AI == AIType.AI_Archer && 0.4 >= Utility.RandomDouble())
{
Point3D p = FindLocation(Map, Location, 10);
Effects.SendLocationParticles(EffectItem.Create(Location, Map, EffectItem.DefaultDuration), 0x3728, 10, 10, 2023);
Location = p;
Effects.SendLocationParticles(EffectItem.Create(p, Map, EffectItem.DefaultDuration), 0x3728, 10, 10, 5023);
PlaySound(0x1FE);
}
}
private Point3D FindLocation(Map map, Point3D center, int range)
{
int cx = center.X;
int cy = center.Y;
for (int i = 0; i < 20; ++i)
{
int x = cx + Utility.Random(range * 2) - range;
int y = cy + Utility.Random(range * 2) - range;
if ((cx - x) * (cx - x) + (cy - y) * (cy - y) > range * range)
continue;
int z = map.GetAverageZ(x, y);
if (!map.CanFit(x, y, z, 6, false, false))
continue;
int topZ = z;
foreach (Item item in map.GetItemsInRange(new Point3D(x, y, z), 0))
{
topZ = Math.Max(topZ, item.Z + item.ItemData.CalcHeight);
}
return new Point3D(x, y, topZ);
}
return center;
}
public override bool AlwaysMurderer { get { return true; } }
public override bool ShowFameTitle { get { return false; } }
public CultistAmbusher(Serial serial)
: base(serial)
{
}
public override void GenerateLoot()
{
AddLoot(LootPack.Rich);
}
public override WeaponAbility GetWeaponAbility()
{
BaseWeapon wep = Weapon as BaseWeapon;
if (wep != null && !(wep is Fists))
{
if (Utility.RandomDouble() > 0.5)
return wep.PrimaryAbility;
return wep.SecondaryAbility;
}
return null;
}
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,369 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Server.Commands;
using Server.Engines.CannedEvil;
using Server.Items;
using Server.Network;
namespace Server.Mobiles
{
[CorpseName("a Khal Ankur corpse")]
public class KhalAnkur : BaseChampion
{
public ChampionSpawn Spawn { get; set; }
private DateTime m_NextSpawn;
private DateTime m_NextSay;
private DateTime m_NextAbilityTime;
[Constructable]
public KhalAnkur()
: base(AIType.AI_Necro)
{
Name = "Khal Ankur";
Body = 0x5C7;
BaseSoundID = 0x301;
SetStr(700, 800);
SetDex(500, 600);
SetInt(800, 900);
SetHits(30000);
SetDamage(28, 35);
SetDamageType(ResistanceType.Physical, 50);
SetDamageType(ResistanceType.Cold, 25);
SetDamageType(ResistanceType.Poison, 25);
SetResistance(ResistanceType.Physical, 90);
SetResistance(ResistanceType.Fire, 70, 80);
SetResistance(ResistanceType.Cold, 70, 80);
SetResistance(ResistanceType.Poison, 80, 90);
SetResistance(ResistanceType.Energy, 80, 90);
SetSkill(SkillName.Wrestling, 120.0);
SetSkill(SkillName.Tactics, 80.0, 100.0);
SetSkill(SkillName.MagicResist, 150.0);
SetSkill(SkillName.DetectHidden, 100.0);
SetSkill(SkillName.Parry, 80.0, 100.0);
SetSkill(SkillName.Necromancy, 120.0);
SetSkill(SkillName.SpiritSpeak, 120.0);
Fame = 28000;
Karma = -28000;
VirtualArmor = 80;
SetMagicalAbility(MagicalAbility.WrestlingMastery);
}
public KhalAnkur(Serial serial)
: base(serial)
{
}
public override bool Unprovokable { get { return true; } }
public override bool BleedImmune { get { return true; } }
public override Poison PoisonImmune { get { return Poison.Lethal; } }
public override bool ShowFameTitle { get { return false; } }
public override bool ClickTitle { get { return false; } }
public override bool AlwaysMurderer { get { return true; } }
public override bool AutoDispel { get { return true; } }
public override double AutoDispelChance { get { return 1.0; } }
public override ChampionSkullType SkullType { get { return ChampionSkullType.None; } }
public override Type[] UniqueList
{
get
{
return new Type[] { };
}
}
public override Type[] SharedList
{
get
{
return new Type[] { };
}
}
public override Type[] DecorativeList
{
get
{
return new Type[] { };
}
}
public override MonsterStatuetteType[] StatueTypes
{
get
{
return new MonsterStatuetteType[] { };
}
}
public override void OnBeforeDamage(Mobile from, ref int totalDamage, Server.DamageType type)
{
if (Region.IsPartOf("Khaldun") && IsChampionSpawn && !Caddellite.CheckDamage(from, type))
{
totalDamage = 0;
}
base.OnBeforeDamage(from, ref totalDamage, type);
}
public override void OnGaveMeleeAttack(Mobile defender)
{
base.OnGaveMeleeAttack(defender);
if (Hue == 0 && Hits < HitsMax * 0.60 && DateTime.UtcNow > m_NextAbilityTime && 0.2 > Utility.RandomDouble())
{
Hue = 2745;
new InternalTimer(this);
}
}
public override void OnDoubleClick(Mobile from)
{
if (Blessed)
{
from.SendLocalizedMessage(1071372); // It's covered with treasure guardian's magical power. To touch it, you need to beat them!
}
base.OnDoubleClick(from);
}
public override void OnChampPopped(ChampionSpawn spawn)
{
Blessed = true;
Spawn = spawn;
}
public override void OnThink()
{
base.OnThink();
if (Spawn == null || Map == null)
return;
if (!Utility.InRange(Location, Home, 150))
{
Timer.DelayCall(TimeSpan.FromSeconds(5), () => { Location = Home; });
}
if (Blessed)
{
if (m_NextSay < DateTime.UtcNow)
{
Say(1158752 + Utility.Random(5), 0x25);
m_NextSay = DateTime.UtcNow + TimeSpan.FromSeconds(Utility.RandomMinMax(20, 40));
}
if (m_NextSpawn < DateTime.UtcNow)
{
BaseCreature bc = new KhalAnkurWarriors(KhalAnkurWarriors.WarriorType.General);
int x, y, z = 0;
Point3D p = Location;
for (int i = 0; i < 25; i++)
{
x = Utility.RandomMinMax(p.X - 4, p.X + 4);
y = Utility.RandomMinMax(p.Y - 4, p.Y + 4);
z = Map.GetAverageZ(x, y);
if (Map.CanSpawnMobile(x, y, z))
{
p = new Point3D(x, y, z);
break;
}
}
bc.MoveToWorld(p, Map);
bc.FixedParticles(0x3709, 1, 30, 9963, 13, 3, EffectLayer.Head);
bc.Home = p;
bc.IsChampionSpawn = true;
Spawn.Creatures.Add(bc);
m_NextSpawn = DateTime.UtcNow + TimeSpan.FromSeconds(Utility.RandomMinMax(120, 180));
}
else if (Spawn.Creatures.OfType<KhalAnkurWarriors>().Where(x => x._Type == KhalAnkurWarriors.WarriorType.General && !x.Deleted).Count() <= 0)
{
Blessed = false;
return;
}
}
}
private class InternalTimer : Timer
{
private KhalAnkur m_Mobile;
private int m_Tick;
public InternalTimer(KhalAnkur mob)
: base(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(2))
{
m_Tick = 1;
m_Mobile = mob;
Start();
}
protected override void OnTick()
{
if (!m_Mobile.Alive || m_Mobile.Deleted || m_Mobile.Map == null)
{
Stop();
}
else if (m_Tick < 15)
{
Point3D p = FindLocation(m_Mobile.Map, m_Mobile.Location, 7);
Effects.SendLocationEffect(p, m_Mobile.Map, 0x3789, 30, 1, 2062, 0x4);
m_Tick++;
}
else
{
m_Mobile.ClearAround();
Stop();
}
}
private Point3D FindLocation(Map map, Point3D center, int range)
{
int cx = center.X;
int cy = center.Y;
for (int i = 0; i < 20; ++i)
{
int x = cx + Utility.Random(range * 2) - range;
int y = cy + Utility.Random(range * 2) - range;
if ((cx - x) * (cx - x) + (cy - y) * (cy - y) > range * range)
continue;
int z = map.GetAverageZ(x, y);
if (!map.CanFit(x, y, z, 6, false, false))
continue;
int topZ = z;
foreach (Item item in map.GetItemsInRange(new Point3D(x, y, z), 0))
{
topZ = Math.Max(topZ, item.Z + item.ItemData.CalcHeight);
}
return new Point3D(x, y, topZ);
}
return center;
}
}
private void ClearAround()
{
Point3D loc = Location;
Map pmmap = Map;
List<Point3D> points = new List<Point3D>();
Server.Misc.Geometry.Circle2D(loc, pmmap, 7, (pnt, map) =>
{
if (map.CanFit(pnt, 0) && InLOS(pnt))
points.Add(pnt);
});
if (pmmap != Map.Internal && pmmap != null)
{
Server.Misc.Geometry.Circle2D(loc, pmmap, 6, (pnt, map) =>
{
if (map.CanFit(pnt, 0) && InLOS(pnt) && Utility.RandomBool())
{
Effects.SendPacket(pnt, map, new ParticleEffect(EffectType.FixedXYZ, Serial, Serial.Zero, 0x3789, pnt, pnt, 1, 30, false, false, 0, 3, 0, 9502, 1, Serial, 153, 0));
Effects.SendPacket(pnt, map, new ParticleEffect(EffectType.FixedXYZ, Serial, Serial.Zero, 0x9DAC, pnt, pnt, 1, 30, false, false, 0, 0, 0, 9502, 1, Serial, 153, 0));
}
});
Server.Misc.Geometry.Circle2D(loc, pmmap, 7, (pnt, map) =>
{
if (map.CanFit(pnt, 0) && InLOS(pnt) && Utility.RandomBool())
{
Effects.SendPacket(pnt, map, new ParticleEffect(EffectType.FixedXYZ, Serial, Serial.Zero, 0x3789, pnt, pnt, 1, 30, false, false, 0, 3, 0, 9502, 1, Serial, 153, 0));
Effects.SendPacket(pnt, map, new ParticleEffect(EffectType.FixedXYZ, Serial, Serial.Zero, 0x9DAC, pnt, pnt, 1, 30, false, false, 0, 0, 0, 9502, 1, Serial, 153, 0));
}
});
}
Timer.DelayCall(TimeSpan.FromMilliseconds(500), () =>
{
IPooledEnumerable eable = GetMobilesInRange(6);
foreach (Mobile from in eable)
{
if (!from.Alive || from == this || from.AccessLevel > AccessLevel.Player)
continue;
if (from is PlayerMobile || (from is BaseCreature && (((BaseCreature)from).Controlled) || ((BaseCreature)from).Summoned))
{
Point3D point = points[Utility.Random(points.Count)];
from.MoveToWorld(point, pmmap);
from.Frozen = true;
Timer.DelayCall(TimeSpan.FromSeconds(3), () =>
{
from.Frozen = false;
from.SendLocalizedMessage(1005603); // You can move again!
});
if (CanBeHarmful(from))
{
double damage = from.Hits * 0.6;
if (damage < 10.0)
damage = 10.0;
else if (damage > 75.0)
damage = 75.0;
DoHarmful(from);
AOS.Damage(from, this, (int)damage, 100, 0, 0, 0, 0);
}
}
}
eable.Free();
});
Hue = 0;
m_NextAbilityTime = DateTime.UtcNow + TimeSpan.FromSeconds(Utility.RandomMinMax(200, 300));
}
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 3);
AddLoot(LootPack.Meager);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
writer.WriteItem<ChampionSpawn>(Spawn);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
Spawn = reader.ReadItem<ChampionSpawn>();
Hue = 0;
}
}
}

View File

@@ -0,0 +1,212 @@
using System;
using Server.Items;
using System.Linq;
namespace Server.Mobiles
{
[CorpseName("a human corpse")]
public class KhalAnkurWarriors : BaseCreature
{
public static readonly WarriorType[] Types =
Enum.GetValues(typeof(WarriorType))
.Cast<WarriorType>()
.ToArray();
public static WarriorType RandomType { get { return Types[Utility.Random(Types.Length)]; } }
public enum WarriorType
{
Scout,
Corporal,
Lieutenant,
Captain,
General
}
public WarriorType _Type { get; set; }
[Constructable]
public KhalAnkurWarriors()
: this(RandomType)
{
}
[Constructable]
public KhalAnkurWarriors(WarriorType type)
: base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4)
{
_Type = type;
if (Female = Utility.RandomBool())
{
Body = 0x191;
Name = NameList.RandomName("female");
}
else
{
Body = 0x190;
Name = NameList.RandomName("male");
}
BaseSoundID = 0x45A;
SetStr(150, 250);
SetDex(150);
SetInt(100, 150);
SetDamage(20, 30);
SetHits(600, 800);
string _title = null;
switch (_Type)
{
case WarriorType.Scout: _title = "the Scout"; break;
case WarriorType.Corporal: _title = "the Corporal"; break;
case WarriorType.Lieutenant: _title = "the Lieutenant"; break;
case WarriorType.Captain: _title = "the Captain"; SetHits(1000, 1500); break;
case WarriorType.General: _title = "the General"; SetHits(1000, 1500); break;
}
Title = _title;
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 20, 30);
SetResistance(ResistanceType.Fire, 20, 30);
SetResistance(ResistanceType.Cold, 20, 30);
SetResistance(ResistanceType.Poison, 20, 30);
SetResistance(ResistanceType.Energy, 20, 30);
SetSkill(SkillName.Fencing, 105.0, 130.0);
SetSkill(SkillName.Macing, 1105.0, 130.0);
SetSkill(SkillName.MagicResist, 105.0, 130.0);
SetSkill(SkillName.Swords, 105.0, 130.0);
SetSkill(SkillName.Tactics, 105.0, 130.0);
SetSkill(SkillName.Archery, 105.0, 130.0);
SetSkill(SkillName.Magery, 105.0, 130.0);
SetSkill(SkillName.Meditation, 105.0, 130.0);
Fame = 5000;
Karma = -5000;
switch (Utility.Random(4))
{
case 0:
{
Hue = 2697;
SetWearable(new ChainChest(), Hue);
SetWearable(new ChainCoif(), Hue);
SetWearable(new Cloak(), Hue);
break;
}
case 1:
{
Hue = 2697;
SetWearable(new PlateChest(), Hue);
SetWearable(new PlateLegs(), Hue);
SetWearable(new Cloak(), Hue);
break;
}
case 2:
{
Hue = 2684;
SetWearable(new PlateChest(), Hue);
SetWearable(new PlateLegs(), Hue);
SetWearable(new PlateArms(), Hue);
break;
}
case 3:
{
Hue = 2697;
SetWearable(new ChainChest(), Hue);
SetWearable(new ChainLegs(), Hue);
SetWearable(new Boots(Hue));
break;
}
}
switch (Utility.Random(2))
{
case 0:
{
SetWearable(Loot.Construct(new Type[] { typeof(Spear), typeof(QuarterStaff), typeof(BlackStaff), typeof(Tessen), typeof(Cleaver), typeof(Lajatang) }));
break;
}
case 1:
{
SetWearable(Loot.Construct(new Type[] { typeof(Yumi), typeof(Crossbow), typeof(RepeatingCrossbow), typeof(HeavyCrossbow) }));
RangeFight = 7;
AI = AIType.AI_Archer;
break;
}
}
int hairHue = Utility.RandomNondyedHue();
Utility.AssignRandomHair(this, hairHue);
if (Utility.Random(7) != 0)
Utility.AssignRandomFacialHair(this, hairHue);
}
public override void OnBeforeDamage(Mobile from, ref int totalDamage, Server.DamageType type)
{
if (Region.IsPartOf("Khaldun") && IsChampionSpawn && !Caddellite.CheckDamage(from, type))
{
totalDamage = 0;
}
base.OnBeforeDamage(from, ref totalDamage, type);
}
public override bool AlwaysMurderer { get { return true; } }
public override bool ShowFameTitle { get { return false; } }
public KhalAnkurWarriors(Serial serial)
: base(serial)
{
}
public override void GenerateLoot()
{
AddLoot(LootPack.Rich);
}
public override WeaponAbility GetWeaponAbility()
{
BaseWeapon wep = Weapon as BaseWeapon;
if (wep != null && !(wep is Fists))
{
if (Utility.RandomDouble() > 0.5)
return wep.PrimaryAbility;
return wep.SecondaryAbility;
}
return null;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
writer.Write((int)_Type);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
_Type = (WarriorType)reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,84 @@
using Server.Items;
using System;
namespace Server.Mobiles
{
[CorpseName("a Bloody corpse")]
public class KhaldunBlood : BaseCreature
{
[Constructable]
public KhaldunBlood()
: base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4)
{
Name = "Blood";
Body = 0x33;
BaseSoundID = 456;
Hue = Utility.RandomList(33, 1157);
SetStr(220, 286);
SetDex(125, 130);
SetInt(100, 101);
SetHits(130);
SetDamage(8, 18);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 30, 50);
SetResistance(ResistanceType.Fire, 20, 30);
SetResistance(ResistanceType.Cold, 50, 60);
SetResistance(ResistanceType.Poison, 20, 30);
SetResistance(ResistanceType.Energy, 30, 40);
SetSkill(SkillName.MagicResist, 60.0, 80.0);
SetSkill(SkillName.Tactics, 85.0, 100.0);
SetSkill(SkillName.Wrestling, 85.0, 100.0);
SetSkill(SkillName.DetectHidden, 40.0);
Fame = 300;
Karma = -300;
VirtualArmor = 8;
SetWeaponAbility(WeaponAbility.BleedAttack);
}
public KhaldunBlood(Serial serial)
: base(serial)
{
}
public override void OnBeforeDamage(Mobile from, ref int totalDamage, Server.DamageType type)
{
if (Region.IsPartOf("Khaldun") && IsChampionSpawn && !Caddellite.CheckDamage(from, type))
{
totalDamage = 0;
}
base.OnBeforeDamage(from, ref totalDamage, type);
}
public override Poison PoisonImmune { get { return Poison.Lesser; } }
public override Poison HitPoison { get { return Poison.Lesser; } }
public override void GenerateLoot()
{
AddLoot(LootPack.Poor);
AddLoot(LootPack.Gems);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,173 @@
using System;
using Server.Items;
namespace Server.Mobiles
{
[CorpseName("an incorporeal corpse")]
public class ShadowFiend : BaseCreature
{
private UnhideTimer m_Timer;
[Constructable]
public ShadowFiend()
: base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4)
{
Name = "a shadow fiend";
Body = 0x10;
Hue = 2051;
// this to allow shadow fiend to loot from corpses
Backpack backpack = new Backpack();
backpack.Movable = false;
AddItem(backpack);
SetStr(300, 400);
SetDex(200, 250);
SetInt(45, 55);
SetHits(300, 500);
SetDamage(10, 22);
SetDamageType(ResistanceType.Physical, 20);
SetDamageType(ResistanceType.Cold, 80);
SetResistance(ResistanceType.Physical, 30, 40);
SetResistance(ResistanceType.Fire, 20, 30);
SetResistance(ResistanceType.Cold, 50, 70);
SetResistance(ResistanceType.Poison, 60, 70);
SetResistance(ResistanceType.Energy, 5, 10);
SetSkill(SkillName.MagicResist, 120.0);
SetSkill(SkillName.Tactics, 100.0);
SetSkill(SkillName.Wrestling, 100.0);
SetSkill(SkillName.DetectHidden, 250.0);
SetSkill(SkillName.Hiding, 100.0);
SetSkill(SkillName.Meditation, 100.0);
SetSkill(SkillName.Focus, 0.0, 20.0);
Fame = 1000;
Karma = -1000;
m_Timer = new UnhideTimer(this);
m_Timer.Start();
}
public override void OnBeforeDamage(Mobile from, ref int totalDamage, Server.DamageType type)
{
if (Region.IsPartOf("Khaldun") && IsChampionSpawn && !Caddellite.CheckDamage(from, type))
{
totalDamage = 0;
}
base.OnBeforeDamage(from, ref totalDamage, type);
}
public ShadowFiend(Serial serial)
: base(serial)
{
}
public override bool DeleteCorpseOnDeath
{
get
{
return true;
}
}
public override bool CanRummageCorpses
{
get
{
return true;
}
}
public override int GetIdleSound()
{
return 0x37A;
}
public override int GetAngerSound()
{
return 0x379;
}
public override int GetDeathSound()
{
return 0x381;
}
public override int GetAttackSound()
{
return 0x37F;
}
public override int GetHurtSound()
{
return 0x380;
}
public override bool OnBeforeDeath()
{
if (Backpack != null)
Backpack.Destroy();
Effects.SendLocationEffect(Location, Map, 0x376A, 10, 1);
return true;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
m_Timer = new UnhideTimer(this);
m_Timer.Start();
}
public override void OnAfterDelete()
{
if (m_Timer != null)
m_Timer.Stop();
m_Timer = null;
base.OnAfterDelete();
}
private class UnhideTimer : Timer
{
private readonly ShadowFiend m_Owner;
public UnhideTimer(ShadowFiend owner)
: base(TimeSpan.FromSeconds(30.0))
{
m_Owner = owner;
Priority = TimerPriority.OneSecond;
}
protected override void OnTick()
{
if (m_Owner.Deleted)
{
Stop();
return;
}
IPooledEnumerable eable = m_Owner.GetMobilesInRange(3);
foreach (Mobile m in eable)
{
if (m != m_Owner && m.Player && m.Hidden && m_Owner.CanBeHarmful(m) && m.IsPlayer())
m.Hidden = false;
}
eable.Free();
}
}
}
}

View File

@@ -0,0 +1,161 @@
using System;
using Server.Items;
namespace Server.Mobiles
{
[CorpseName("a skeletal corpse")]
public class SkelementalKnight : BaseCreature
{
public enum SkeletalType
{
Fire,
Cold,
Poison,
Energy
}
[Constructable]
public SkelementalKnight()
: this(Utility.RandomBool() ? SkeletalType.Energy : SkeletalType.Poison)
{
}
[Constructable]
public SkelementalKnight(SkeletalType type)
: base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4)
{
Name = "Skelemental Knight";
Body = 0x93;
BaseSoundID = 451;
int fire = 100, cold = 100, poison = 100, energy = 100;
switch (type)
{
case SkeletalType.Fire:
{
Hue = 2634;
SetDamageType(ResistanceType.Fire, 100);
cold = 5;
break;
}
case SkeletalType.Cold:
{
Hue = 2581;
SetDamageType(ResistanceType.Cold, 100);
fire = 5;
break;
}
case SkeletalType.Poison:
{
Hue = 2688;
SetDamageType(ResistanceType.Poison, 100);
energy = 5;
break;
}
case SkeletalType.Energy:
{
Hue = 2717;
SetDamageType(ResistanceType.Energy, 100);
poison = 5;
break;
}
}
SetStr(200, 250);
SetDex(70, 95);
SetInt(35, 60);
SetHits(110, 150);
SetDamage(8, 18);
SetDamageType(ResistanceType.Physical, 0);
SetResistance(ResistanceType.Physical, 95);
SetResistance(ResistanceType.Fire, fire);
SetResistance(ResistanceType.Cold, cold);
SetResistance(ResistanceType.Poison, poison);
SetResistance(ResistanceType.Energy, energy);
SetSkill(SkillName.MagicResist, 60.0, 80.0);
SetSkill(SkillName.Tactics, 85.0, 100.0);
SetSkill(SkillName.Wrestling, 85.0, 100.0);
SetSkill(SkillName.DetectHidden, 40.0);
Fame = 3000;
Karma = -3000;
VirtualArmor = 40;
switch (Utility.Random(6))
{
case 0:
PackItem(new PlateArms());
break;
case 1:
PackItem(new PlateChest());
break;
case 2:
PackItem(new PlateGloves());
break;
case 3:
PackItem(new PlateGorget());
break;
case 4:
PackItem(new PlateLegs());
break;
case 5:
PackItem(new PlateHelm());
break;
}
PackItem(new Scimitar());
PackItem(new WoodenShield());
}
public override void OnBeforeDamage(Mobile from, ref int totalDamage, Server.DamageType type)
{
if (Region.IsPartOf("Khaldun") && IsChampionSpawn && !Caddellite.CheckDamage(from, type))
{
totalDamage = 0;
}
base.OnBeforeDamage(from, ref totalDamage, type);
}
public SkelementalKnight(Serial serial)
: base(serial)
{
}
public override bool BleedImmune { get { return true; } }
public override TribeType Tribe { get { return TribeType.Undead; } }
public override OppositionGroup OppositionGroup
{
get
{
return OppositionGroup.FeyAndUndead;
}
}
public override void GenerateLoot()
{
AddLoot(LootPack.Average);
AddLoot(LootPack.Meager);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,129 @@
using System;
using Server.Items;
namespace Server.Mobiles
{
[CorpseName("a skeletal corpse")]
public class SkelementalMage : BaseCreature
{
[Constructable]
public SkelementalMage()
: this(Utility.RandomBool() ? SkelementalKnight.SkeletalType.Cold : SkelementalKnight.SkeletalType.Fire)
{
}
[Constructable]
public SkelementalMage(SkelementalKnight.SkeletalType type)
: base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4)
{
Name = "Skelemental Mage";
Body = 0x32;
BaseSoundID = 451;
int fire = 100, cold = 100, poison = 100, energy = 100;
switch (type)
{
case SkelementalKnight.SkeletalType.Fire:
{
Hue = 2634;
SetDamageType(ResistanceType.Fire, 100);
cold = 5;
break;
}
case SkelementalKnight.SkeletalType.Cold:
{
Hue = 2581;
SetDamageType(ResistanceType.Cold, 100);
fire = 5;
break;
}
case SkelementalKnight.SkeletalType.Poison:
{
Hue = 2688;
SetDamageType(ResistanceType.Poison, 100);
energy = 5;
break;
}
case SkelementalKnight.SkeletalType.Energy:
{
Hue = 2717;
SetDamageType(ResistanceType.Energy, 100);
poison = 5;
break;
}
}
SetStr(200, 250);
SetDex(70, 100);
SetInt(100, 130);
SetHits(100, 150);
SetDamage(8, 18);
SetDamageType(ResistanceType.Physical, 0);
SetResistance(ResistanceType.Physical, 95);
SetResistance(ResistanceType.Fire, fire);
SetResistance(ResistanceType.Cold, cold);
SetResistance(ResistanceType.Poison, poison);
SetResistance(ResistanceType.Energy, energy);
SetSkill(SkillName.MagicResist, 60.0, 80.0);
SetSkill(SkillName.Tactics, 75.0, 100.0);
SetSkill(SkillName.Wrestling, 85.0, 100.0);
SetSkill(SkillName.DetectHidden, 50.0);
SetSkill(SkillName.Magery, 110.0, 120.0);
SetSkill(SkillName.Meditation, 150.0, 155.0);
SetSkill(SkillName.Focus, 0.0, 60.0);
Fame = 3000;
Karma = -3000;
VirtualArmor = 38;
PackReg(3);
PackNecroReg(3, 10);
PackItem(new Bone());
}
public SkelementalMage(Serial serial)
: base(serial)
{
}
public override bool BleedImmune { get { return true; } }
public override OppositionGroup OppositionGroup { get { return OppositionGroup.FeyAndUndead; } }
public override Poison PoisonImmune { get { return Poison.Regular; } }
public override TribeType Tribe { get { return TribeType.Undead; } }
public override void GenerateLoot()
{
AddLoot(LootPack.Average);
AddLoot(LootPack.LowScrolls);
AddLoot(LootPack.Potions);
}
public override void OnBeforeDamage(Mobile from, ref int totalDamage, Server.DamageType type)
{
if (Region.IsPartOf("Khaldun") && IsChampionSpawn && !Caddellite.CheckDamage(from, type))
{
totalDamage = 0;
}
base.OnBeforeDamage(from, ref totalDamage, type);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,292 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Server;
using Server.Engines.CannedEvil;
using Server.Items;
using Server.Mobiles;
using Server.Gumps;
using Server.Engines.Points;
using Server.Engines.Quests;
namespace Server.Engines.Khaldun
{
public static class TreasuresOfKhaldunGeneration
{
public static void Initialize()
{
if (Core.EJ)
{
EventSink.WorldSave += OnWorldSave;
if (!Siege.SiegeShard)
{
KhaldunCampRegion.InstanceTram = new KhaldunCampRegion(Map.Trammel);
}
KhaldunCampRegion.InstanceFel = new KhaldunCampRegion(Map.Felucca);
}
}
private static void OnWorldSave(WorldSaveEventArgs e)
{
CheckEnabled(true);
}
public static void CheckEnabled(bool timed = false)
{
var khaldun = PointsSystem.Khaldun;
if (khaldun.Enabled && !khaldun.InSeason)
{
if (timed)
{
Timer.DelayCall(TimeSpan.FromSeconds(30), () =>
{
Utility.WriteConsoleColor(ConsoleColor.Green, "Disabling Treasures of Khaldun");
Remove();
khaldun.Enabled = false;
});
}
else
{
Utility.WriteConsoleColor(ConsoleColor.Green, "Auto Disabling Treasures of Khaldun");
Remove();
khaldun.Enabled = false;
}
}
else if (!khaldun.Enabled && khaldun.InSeason)
{
if (timed)
{
Timer.DelayCall(TimeSpan.FromSeconds(30), () =>
{
Utility.WriteConsoleColor(ConsoleColor.Green, "Enabling Treasures of Khaldun");
Generate();
khaldun.Enabled = true;
});
}
else
{
Utility.WriteConsoleColor(ConsoleColor.Green, "Auto Enabling Treasures of Khaldun");
Generate();
khaldun.Enabled = true;
}
if(!khaldun.QuestContentGenerated)
{
GenerateQuestContent();
khaldun.QuestContentGenerated = true;
}
}
}
public static void Generate()
{
if (KhaldunResearcher.InstanceTram == null && !Siege.SiegeShard)
{
KhaldunResearcher.InstanceTram = new KhaldunResearcher();
KhaldunResearcher.InstanceTram.MoveToWorld(new Point3D(6009, 3771, 21), Map.Trammel);
}
if (KhaldunResearcher.InstanceFel == null)
{
KhaldunResearcher.InstanceFel = new KhaldunResearcher();
KhaldunResearcher.InstanceFel.MoveToWorld(new Point3D(6009, 3771, 21), Map.Felucca);
}
if (LeadInvestigator.InstanceTram == null && !Siege.SiegeShard)
{
LeadInvestigator.InstanceTram = new LeadInvestigator();
LeadInvestigator.InstanceTram.MoveToWorld(new Point3D(6010, 3776, 19), Map.Trammel);
}
if (LeadInvestigator.InstanceFel == null)
{
LeadInvestigator.InstanceFel = new LeadInvestigator();
LeadInvestigator.InstanceFel.MoveToWorld(new Point3D(6010, 3776, 19), Map.Felucca);
}
if (CaddelliteVendor.InstanceTram == null && !Siege.SiegeShard)
{
CaddelliteVendor.InstanceTram = new CaddelliteVendor();
CaddelliteVendor.InstanceTram.MoveToWorld(new Point3D(6018, 3749, 21), Map.Trammel);
}
if (CaddelliteVendor.InstanceFel == null)
{
CaddelliteVendor.InstanceFel = new CaddelliteVendor();
CaddelliteVendor.InstanceFel.MoveToWorld(new Point3D(6018, 3749, 21), Map.Felucca);
}
ChampionSpawn champ = null;
if (!Siege.SiegeShard)
{
champ = new ChampionSpawn();
champ.Type = ChampionSpawnType.Khaldun;
champ.MoveToWorld(new Point3D(5469, 1461, 20), Map.Trammel);
ChampionSystem.AllSpawns.Add(champ);
}
champ = new ChampionSpawn();
champ.Type = ChampionSpawnType.Khaldun;
champ.MoveToWorld(new Point3D(5469, 1461, 20), Map.Felucca);
ChampionSystem.AllSpawns.Add(champ);
}
public static void Remove()
{
ChampionSystem.AllSpawns.Where(s => s.Type == ChampionSpawnType.Khaldun && Region.Find(s.Location, s.Map).IsPartOf("Khaldun")).IterateReverse(s =>
{
s.Delete();
});
}
public static void GenerateQuestContent()
{
var map = Siege.SiegeShard ? Map.Felucca : Map.Trammel;
var addon = new KhaldunDecorationAddon();
addon.MoveToWorld(new Point3D(6232, 2887, -1), map);
// Britain
var door = new TrapDoor("boreas", new Point3D(6242, 2892, 17), map);
var book = new MysteriousBook(door);
var dust = new DustPile(door);
var teleporter = new Teleporter(new Point3D(1369, 1465, 10), map);
door.MoveToWorld(new Point3D(1369, 1465, 10), map);
book.MoveToWorld(new Point3D(6240, 2885, 8), map);
dust.MoveToWorld(new Point3D(6256, 2889, 13), map);
teleporter.MoveToWorld(new Point3D(6242, 2892, 17), map);
new GumshoeBottles().MoveToWorld(new Point3D(6154, 2901, 6), map);
new GumshoeBottles().MoveToWorld(new Point3D(6154, 2902, 6), map);
new GumshoeDeed().MoveToWorld(new Point3D(6161, 2901, 6), map);
new GumshoeRope().MoveToWorld(new Point3D(6163, 2896, 0), map);
new GumshoeRope().MoveToWorld(new Point3D(6163, 2896, 1), map);
new GumshoeMap().MoveToWorld(new Point3D(6166, 2895, 6), map);
new GumshoeMap().MoveToWorld(new Point3D(6166, 2895, 7), map);
new GumshoeTools().MoveToWorld(new Point3D(6160, 2901, 6), map);
// Moonglow
door = new TrapDoor("carthax", new Point3D(6198, 2893, 17), map);
book = new MysteriousBook(door);
dust = new DustPile(door);
teleporter = new Teleporter(new Point3D(4550, 1306, 8), map);
door.MoveToWorld(new Point3D(4550, 1306, 8), map);
book.MoveToWorld(new Point3D(6207, 2884, 7), map);
dust.MoveToWorld(new Point3D(6208, 2885, 12), map);
teleporter.MoveToWorld(new Point3D(6198, 2893, 17), map);
new GumshoeBottles().MoveToWorld(new Point3D(6198, 2888, 6), map);
new GumshoeRope().MoveToWorld(new Point3D(6200, 2887, 0), map);
new GumshoeRope().MoveToWorld(new Point3D(6200, 2887, 1), map);
new GumshoeMap().MoveToWorld(new Point3D(6198, 2887, 6), map);
new GumshoeMap().MoveToWorld(new Point3D(6198, 2887, 7), map);
new GumshoeTools().MoveToWorld(new Point3D(6198, 2889, 6), map);
// Vesper
door = new TrapDoor("moriens", new Point3D(6154, 2898, 17), map);
book = new MysteriousBook(door);
dust = new DustPile(door);
teleporter = new Teleporter(new Point3D(2762, 848, 0), map);
door.MoveToWorld(new Point3D(2762, 848, 0), map);
book.MoveToWorld(new Point3D(6167, 2896, 6), map);
dust.MoveToWorld(new Point3D(6163, 2885, 0), map);
teleporter.MoveToWorld(new Point3D(6154, 2898, 17), map);
new GumshoeBottles().MoveToWorld(new Point3D(6240, 2884, 6), map);
new GumshoeBottles().MoveToWorld(new Point3D(6239, 2885, 6), map);
new GumshoeRope().MoveToWorld(new Point3D(6241, 2884, 0), map);
new GumshoeRope().MoveToWorld(new Point3D(6241, 2884, 1), map);
new GumshoeMap().MoveToWorld(new Point3D(6240, 2885, 6), map);
new GumshoeMap().MoveToWorld(new Point3D(6240, 2885, 7), map);
new GumshoeTools().MoveToWorld(new Point3D(6239, 2886, 6), map);
// Yew
door = new TrapDoor("tenebrae", new Point3D(6294, 2891, 17), map);
book = new MysteriousBook(door);
dust = new DustPile(door);
teleporter = new Teleporter(new Point3D(712, 1104, 0), map);
door.MoveToWorld(new Point3D(712, 1104, 0), map);
book.MoveToWorld(new Point3D(6294, 2887, 6), map);
dust.MoveToWorld(new Point3D(6291, 2875, 9), map);
teleporter.MoveToWorld(new Point3D(6294, 2891, 17), map);
new GumshoeBottles().MoveToWorld(new Point3D(6303, 2887, 6), map);
new GumshoeBottles().MoveToWorld(new Point3D(6304, 2887, 6), map);
new GumshoeRope().MoveToWorld(new Point3D(6299, 2887, 0), map);
new GumshoeRope().MoveToWorld(new Point3D(6299, 2887, 1), map);
new GumshoeMap().MoveToWorld(new Point3D(6294, 2888, 6), map);
new GumshoeMap().MoveToWorld(new Point3D(6294, 2888, 7), map);
new GumshoeTools().MoveToWorld(new Point3D(6294, 2889, 6), map);
// Gravestones
var grave = new DamagedHeadstone(1158607); // brit
grave.MoveToWorld(new Point3D(1378, 1445, 10), map);
grave = new DamagedHeadstone(1158608); // vesper
grave.ItemID = 4477;
grave.MoveToWorld(new Point3D(2747, 882, 0), map);
grave = new DamagedHeadstone(1158609); // moonglow
grave.MoveToWorld(new Point3D(4545, 1316, 8), map);
grave = new DamagedHeadstone(1158610); // yew
grave.MoveToWorld(new Point3D(723, 1104, 0), map);
// footprints
var footprints = new BloodyFootPrints(0x1E06);
footprints.MoveToWorld(new Point3D(1383, 1452, 10), map);
footprints = new BloodyFootPrints(0x1E06);
footprints.MoveToWorld(new Point3D(1383, 1456, 10), map);
footprints = new BloodyFootPrints(0x1E06);
footprints.MoveToWorld(new Point3D(1383, 1461, 10), map);
footprints = new BloodyFootPrints(0x1E06);
footprints.MoveToWorld(new Point3D(1383, 1464, 10), map);
footprints = new BloodyFootPrints(0x1E03);
footprints.MoveToWorld(new Point3D(1378, 1464, 10), map);
var st = new Static(0x2006);
st.Stackable = true;
st.Amount = 0x191;
st.Hue = 0x47E;
st.MoveToWorld(new Point3D(5808, 3270, -15), map);
st.Name = "A Corpse of Liane";
st = new Static(0x2006);
st.Stackable = true;
st.Amount = 86;
st.Hue = 0x47E;
st.MoveToWorld(new Point3D(5807, 3268, -15), map);
st.Name = "A Corpse of an Ophidian Beserker";
}
}
}

View File

@@ -0,0 +1,45 @@
using Server;
using System;
using Server.Mobiles;
using Server.Gumps;
using Server.Engines.Points;
namespace Server.Engines.Khaldun
{
public class KhaldunRewardGump : BaseRewardGump
{
public KhaldunRewardGump(Mobile owner, PlayerMobile user)
: base(owner, user, KhaldunRewards.Rewards, 1158744)
{
}
public override double GetPoints(Mobile m)
{
return PointsSystem.Khaldun.GetPoints(m);
}
public override void RemovePoints(double points)
{
PointsSystem.Khaldun.DeductPoints(User, points);
}
}
public class GumshoeItemGump : Gump
{
public GumshoeItemGump(Mobile from, int itemID, int itemHue, string itemName, int cliloc, string secondLineText)
: base(50, 50)
{
AddBackground(0, 0, 454, 400, 9380);
AddItem(75, 120, itemID, itemHue);
AddHtml(177, 50, 250, 20, String.Format("<center><basefont color=#6B1010>{0}</center>", itemName), false, false);
if (!string.IsNullOrEmpty(secondLineText))
{
AddHtml(177, 77, 250, 40, String.Format("<center><basefont color=#6B1010>{0}</center>", secondLineText), false, false);
AddHtmlLocalized(177, 122, 250, 228, cliloc, true, true);
}
else
AddHtmlLocalized(177, 77, 250, 273, cliloc, true, true);
}
}
}

View File

@@ -0,0 +1,116 @@
using System;
namespace Server.Items
{
public interface ICaddelliteTool
{
}
public class CaddellitePickaxe : Pickaxe, ICaddelliteTool
{
public override int LabelNumber { get { return 1158689; } } // Caddellite Pickaxe
[Constructable]
public CaddellitePickaxe()
{
}
public CaddellitePickaxe(Serial serial)
: base(serial)
{
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
list.Add(1158692); // * Can Harvest Caddellite Infused Resources in the Lost Lands *
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class CaddelliteHatchet : Hatchet, ICaddelliteTool
{
public override int LabelNumber { get { return 1158690; } } // Caddellite Hatchet
[Constructable]
public CaddelliteHatchet()
{
}
public CaddelliteHatchet(Serial serial)
: base(serial)
{
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
list.Add(1158692); // * Can Harvest Caddellite Infused Resources in the Lost Lands *
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class CaddelliteFishingPole : FishingPole, ICaddelliteTool
{
public override int LabelNumber { get { return 1158691; } } // Caddellite Fishing Pole
[Constructable]
public CaddelliteFishingPole()
{
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
list.Add(1158692); // * Can Harvest Caddellite Infused Resources in the Lost Lands *
}
public CaddelliteFishingPole(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,36 @@
using System;
namespace Server.Items
{
public class CounterfeitPlatinum : Item
{
public override int LabelNumber { get { return 1158686; } } // counterfeit platinum
[Constructable]
public CounterfeitPlatinum()
: base(0x1BF9)
{
Hue = 2500;
}
public CounterfeitPlatinum(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,42 @@
using System;
namespace Server.Items
{
public class CultistsRitualTome : Spellbook
{
public override bool IsArtifact { get { return true; } }
public override int LabelNumber { get { return 1158717; } } // Cultist's Ritual Tome
[Constructable]
public CultistsRitualTome()
: base()
{
Hue = 2745;
LootType = LootType.Blessed;
Slayer = SlayerGroup.RandomSuperSlayerTOL();
//Caddellite Infused
Attributes.DefendChance = 5;
Attributes.SpellDamage = 25;
Attributes.CastRecovery = 2;
Attributes.LowerManaCost = 4;
}
public CultistsRitualTome(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,133 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class KhaldunCampAddon : BaseAddon
{
private static int[,] m_AddOnSimpleComponents = new int[,] {
{2879, -2, 6, 4}, {2883, 1, 10, 4}, {2879, -2, 7, 4}// 1 2 3
, {2880, 0, 6, 4}, {2880, -1, 6, 4}, {875, 5, 5, 4}// 4 5 6
, {875, -3, 5, 5}, {3014, 6, 6, 12}, {2421, 5, 8, 3}// 7 8 20
, {2884, 2, 10, 4}, {2879, -2, 8, 4}, {875, 5, 10, 5}// 21 22 23
, {2880, 0, -2, 4}, {2988, 0, -5, 20}, {2880, -2, -9, 3}// 38 41 42
, {2880, -3, -9, 3}, {2990, 2, 2, 23}, {2880, -2, -2, 4}// 45 46 47
, {2880, -3, -2, 4}, {2880, -1, -2, 4}, {2879, -5, -8, 3}// 51 53 58
, {2879, -5, -6, 3}, {2879, -5, -7, 3}, {2880, -5, -9, 3}// 59 60 65
, {880, -6, 1, 1}, {875, -6, -10, 1}, {2880, -4, -9, 3}// 68 70 71
, {2880, -4, -2, 4}, {2879, -5, 0, 4}, {2879, -5, -2, 4}// 72 73 77
, {2879, -5, -1, 4}, {875, -6, -3, 5}// 81 83
, {2880, 1, 6, 4}, {2880, 2, 6, 4}, {2980, 6, 11, 13} // 84, 85, 86
, {542, 7, 5, -1}, {542, 7, 6, -1}, {542, 7, 7, -1} // 87, 88, 89
, {542, 7, 8, -1}, {542, 7, 9, -1}, {542, 7, 10, -1},
};
public override BaseAddonDeed Deed
{
get
{
return null;
}
}
[ Constructable ]
public KhaldunCampAddon()
{
for (int i = 0; i < m_AddOnSimpleComponents.Length / 4; i++)
AddComponent( new AddonComponent( m_AddOnSimpleComponents[i,0] ), m_AddOnSimpleComponents[i,1], m_AddOnSimpleComponents[i,2], m_AddOnSimpleComponents[i,3] );
AddComplexComponent( (BaseAddon) this, 880, -3, 9, 5, 2500, -1, "", 1);// 9
AddComplexComponent( (BaseAddon) this, 880, -3, 8, 5, 1835, -1, "", 1);// 10
AddComplexComponent( (BaseAddon) this, 881, 0, 5, 5, 2500, -1, "", 1);// 11
AddComplexComponent( (BaseAddon) this, 873, -2, 10, 5, 2500, -1, "", 1);// 12
AddComplexComponent( (BaseAddon) this, 876, -3, 10, 5, 1835, -1, "", 1);// 13
AddComplexComponent( (BaseAddon) this, 881, -1, 5, 5, 1835, -1, "", 1);// 14
AddComplexComponent( (BaseAddon) this, 880, -3, 6, 5, 1835, -1, "", 1);// 15
AddComplexComponent( (BaseAddon) this, 873, 0, 10, 5, 2500, -1, "", 1);// 16
AddComplexComponent( (BaseAddon) this, 873, -1, 10, 5, 1835, -1, "", 1);// 17
AddComplexComponent( (BaseAddon) this, 880, -3, 7, 5, 2500, -1, "", 1);// 18
AddComplexComponent( (BaseAddon) this, 881, 1, 5, 5, 1835, -1, "", 1);// 19
AddComplexComponent( (BaseAddon) this, 4012, 5, 8, 3, 0, 2, "", 1);// 24
AddComplexComponent( (BaseAddon) this, 881, -2, 5, 5, 2500, -1, "", 1);// 25
AddComplexComponent( (BaseAddon) this, 881, 0, -3, 5, 1159, -1, "", 1);// 26
AddComplexComponent( (BaseAddon) this, 877, -1, -10, 0, 1911, -1, "", 1);// 27
AddComplexComponent( (BaseAddon) this, 874, -1, -9, 1, 1912, -1, "", 1);// 28
AddComplexComponent( (BaseAddon) this, 874, -1, -6, 3, 1912, -1, "", 1);// 29
AddComplexComponent( (BaseAddon) this, 881, -2, -3, 5, 1159, -1, "", 1);// 30
AddComplexComponent( (BaseAddon) this, 881, -3, -3, 5, 1917, -1, "", 1);// 31
AddComplexComponent( (BaseAddon) this, 873, -2, -5, 3, 1912, -1, "", 1);// 32
AddComplexComponent( (BaseAddon) this, 877, 1, -3, 5, 1917, -1, "", 1);// 33
AddComplexComponent( (BaseAddon) this, 872, -1, -5, 3, 1911, -1, "", 1);// 34
AddComplexComponent( (BaseAddon) this, 881, -1, -3, 5, 1917, -1, "", 1);// 35
AddComplexComponent( (BaseAddon) this, 873, -3, 2, 5, 1917, -1, "", 1);// 36
AddComplexComponent( (BaseAddon) this, 873, -2, 2, 5, 1159, -1, "", 1);// 37
AddComplexComponent( (BaseAddon) this, 873, -1, 2, 5, 1917, -1, "", 1);// 39
AddComplexComponent( (BaseAddon) this, 873, 0, 2, 5, 1159, -1, "", 1);// 40
AddComplexComponent( (BaseAddon) this, 873, -3, -5, 3, 1911, -1, "", 1);// 43
AddComplexComponent( (BaseAddon) this, 872, 1, 2, 4, 1917, -1, "", 1);// 44
AddComplexComponent( (BaseAddon) this, 874, 1, 1, 5, 1159, -1, "", 1);// 48
AddComplexComponent( (BaseAddon) this, 874, 1, -2, 5, 1159, -1, "", 1);// 49
AddComplexComponent( (BaseAddon) this, 878, -3, -10, 3, 1911, -1, "", 1);// 50
AddComplexComponent( (BaseAddon) this, 878, -2, -10, 2, 1912, -1, "", 1);// 52
AddComplexComponent( (BaseAddon) this, 876, -6, -5, 4, 1912, -1, "", 1);// 54
AddComplexComponent( (BaseAddon) this, 876, -6, 2, 5, 1159, -1, "", 1);// 55
AddComplexComponent( (BaseAddon) this, 873, -5, 2, 5, 1917, -1, "", 1);// 56
AddComplexComponent( (BaseAddon) this, 873, -4, 2, 5, 1159, -1, "", 1);// 57
AddComplexComponent( (BaseAddon) this, 873, -5, -5, 3, 1911, -1, "", 1);// 61
AddComplexComponent( (BaseAddon) this, 873, -4, -5, 3, 1912, -1, "", 1);// 62
AddComplexComponent( (BaseAddon) this, 880, -6, -1, 5, 1917, -1, "", 1);// 63
AddComplexComponent( (BaseAddon) this, 880, -6, 0, 5, 1159, -1, "", 1);// 64
AddComplexComponent( (BaseAddon) this, 881, -4, -3, 5, 1159, -1, "", 1);// 66
AddComplexComponent( (BaseAddon) this, 881, -5, -3, 4, 1917, -1, "", 1);// 67
AddComplexComponent( (BaseAddon) this, 880, -6, 1, 5, 1917, -1, "", 1);// 69
AddComplexComponent( (BaseAddon) this, 880, -6, -2, 5, 1159, -1, "", 1);// 74
AddComplexComponent( (BaseAddon) this, 880, -6, -8, 3, 1911, -1, "", 1);// 75
AddComplexComponent( (BaseAddon) this, 880, -6, -9, 3, 1912, -1, "", 1);// 76
AddComplexComponent( (BaseAddon) this, 880, -6, -7, 3, 1912, -1, "", 1);// 78
AddComplexComponent( (BaseAddon) this, 878, -4, -10, 3, 1912, -1, "", 1);// 79
AddComplexComponent( (BaseAddon) this, 878, -5, -10, 3, 1911, -1, "", 1);// 80
AddComplexComponent( (BaseAddon) this, 880, -6, -6, 4, 1911, -1, "", 1);// 82
}
public KhaldunCampAddon( Serial serial ) : base( serial )
{
}
private static void AddComplexComponent(BaseAddon addon, int item, int xoffset, int yoffset, int zoffset, int hue, int lightsource)
{
AddComplexComponent(addon, item, xoffset, yoffset, zoffset, hue, lightsource, null, 1);
}
private static void AddComplexComponent(BaseAddon addon, int item, int xoffset, int yoffset, int zoffset, int hue, int lightsource, string name, int amount)
{
AddonComponent ac;
ac = new AddonComponent(item);
if (name != null && name.Length > 0)
ac.Name = name;
if (hue != 0)
ac.Hue = hue;
if (amount > 1)
{
ac.Stackable = true;
ac.Amount = amount;
}
if (lightsource != -1)
ac.Light = (LightType) lightsource;
addon.AddComponent(ac, xoffset, yoffset, zoffset);
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 ); // Version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,202 @@
using System;
using System.Collections.Generic;
namespace Server.Items
{
public class KhaldunChest : LockableContainer, IRevealableItem
{
private Timer m_Timer;
public override int DefaultGumpID { get { return 0x49; } }
public bool CheckWhenHidden { get { return true; } }
[Constructable]
public KhaldunChest()
: base(Utility.RandomList(0xE3C, 0xE3E, 0x9a9))
{
Movable = false;
Locked = true;
Visible = false;
Hue = 2745;
LiftOverride = true;
Weight = 0.0;
LockLevel = 90;
RequiredSkill = 90;
MaxLockLevel = 100;
TrapType = TrapType.PoisonTrap;
TrapPower = 100;
Timer.DelayCall(TimeSpan.FromSeconds(1), Fill);
}
public virtual void Fill()
{
Reset();
List<Item> contains = new List<Item>(Items);
foreach (var i in contains)
{
i.Delete();
}
ColUtility.Free(contains);
for (int i = 0; i < Utility.RandomMinMax(6, 12); i++)
DropItem(Loot.RandomGem());
DropItem(new Gold(Utility.RandomMinMax(800, 1100)));
Item item = null;
if (0.30 > Utility.RandomDouble())
{
switch (Utility.Random(7))
{
case 0:
item = new Bandage(Utility.Random(10, 30)); break;
case 1:
item = new SmokeBomb();
item.Amount = Utility.Random(3, 6);
break;
case 2:
item = new InvisibilityPotion();
item.Amount = Utility.Random(1, 3);
break;
case 3:
item = new Lockpick(Utility.Random(1, 10)); break;
case 4:
item = new DreadHornMane(Utility.Random(1, 2)); break;
case 5:
item = new Corruption(Utility.Random(1, 2)); break;
case 6:
item = new Taint(Utility.Random(1, 2)); break;
}
DropItem(item);
}
if (0.25 > Utility.RandomDouble())
{
DropItem(new CounterfeitPlatinum());
}
if (0.2 > Utility.RandomDouble())
{
switch (Utility.Random(3))
{
case 0:
item = new ZombiePainting(); break;
case 1:
item = new SkeletonPortrait(); break;
case 2:
item = new LichPainting(); break;
}
DropItem(item);
}
if (0.1 > Utility.RandomDouble())
{
item = Loot.RandomArmorOrShieldOrWeaponOrJewelry(LootPackEntry.IsInTokuno(this), LootPackEntry.IsMondain(this), LootPackEntry.IsStygian(this));
if (item != null)
{
int min, max;
TreasureMapChest.GetRandomItemStat(out min, out max, 1.0);
RunicReforging.GenerateRandomItem(item, null, Utility.RandomMinMax(min, max), 0, ReforgedPrefix.None, ReforgedSuffix.Khaldun, Map);
DropItem(item);
}
}
}
public void Reset()
{
EndTimer();
Visible = false;
Locked = true;
RequiredSkill = 90;
LockLevel = RequiredSkill - Utility.Random(1, 10);
MaxLockLevel = RequiredSkill;
TrapType = TrapType.MagicTrap;
TrapPower = 100;
}
public virtual bool CheckReveal(Mobile m)
{
return m.CheckTargetSkill(SkillName.DetectHidden, this, 80.0, 100.0);
}
public virtual void OnRevealed(Mobile m)
{
Visible = true;
}
public virtual bool CheckPassiveDetect(Mobile m)
{
if (m.InRange(Location, 4))
{
int skill = (int)m.Skills[SkillName.DetectHidden].Value;
if (skill >= 80 && Utility.Random(300) < skill)
return true;
}
return false;
}
public override void LockPick(Mobile from)
{
TryDelayedLock();
base.LockPick(from);
}
public KhaldunChest(Serial serial) : base(serial)
{
}
public void TryDelayedLock()
{
if (Locked || (m_Timer != null && m_Timer.Running))
return;
EndTimer();
m_Timer = Timer.DelayCall(TimeSpan.FromMinutes(Utility.RandomMinMax(10, 15)), Fill);
}
public void EndTimer()
{
if (m_Timer != null)
{
m_Timer.Stop();
m_Timer = null;
}
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
TryDelayedLock();
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
TryDelayedLock();
}
}
}

View File

@@ -0,0 +1,104 @@
////////////////////////////////////////
// //
// Generated by CEO's YAAAG - V1.2 //
// (Yet Another Arya Addon Generator) //
// //
////////////////////////////////////////
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class KhaldunEntranceAddon : BaseAddon
{
private static int[,] m_AddOnSimpleComponents = new int[,] {
{476, 3, 5, 28}// 6
, {465, 3, 2, 8}, {465, 3, 1, 10}, {465, 3, 0, 14}// 7 8 9
, {466, 3, -1, 14}, {478, 2, 6, 28}, {476, 1, 5, 30}// 10 11 12
, {465, -1, 5, 27}, {465, -3, 2, 5}, {465, -3, 1, 6}// 13 14 15
, {465, -3, 0, 8}, {465, 2, 3, 5}, {465, 2, 2, 3}// 16 17 18
, {1313, -2, -4, 3}, {1313, 0, -4, 0}, {1313, -1, -5, 1}// 19 20 21
, {1313, 0, -6, 3}, {1313, -1, -6, 2}, {1313, -2, -6, 5}// 22 23 24
, {1929, -2, 1, 4}, {1929, -2, 0, 8}, {1929, -1, 1, 4}// 30 31 32
, {1929, 0, 1, 3}, {1929, 0, 0, 8}, {1929, 1, 1, 3}// 33 34 35
, {1929, 1, 0, 8}, {1929, -1, 0, 8}, {1928, -2, 0, 2}// 36 37 38
, {1928, -2, -1, 2}, {1928, -2, -2, 2}, {1928, -1, 0, 2}// 39 40 41
, {1928, -1, -1, 2}, {1928, -1, -2, 0}, {1928, 0, 0, 1}// 42 43 44
, {1928, 0, -1, 2}, {1928, 1, 0, 2}, {1928, 1, -1, 2}// 45 46 47
, {1928, 1, -1, 8}, {1928, 1, -2, 0}, {1928, -2, -1, 8}// 48 49 50
, {1928, -1, -1, 8}, {1928, 0, -1, 8}, {1928, 0, -2, 2}// 51 52 53
, {1931, -2, -2, 8}, {1931, -2, -3, 1}, {1931, -1, -2, 6}// 54 55 56
, {1931, -1, -3, 1}, {1931, 0, -3, 1}, {1931, 1, -2, 6}// 57 58 59
, {1931, 1, -3, 0}, {1931, 0, -2, 8}, {1931, 0, -3, 2}// 60 61 62
, {466, -3, -1, 11}, {466, 0, 5, 28}, {466, 2, 5, 24}// 63 64 65
, {6005, -3, -2, 4}, {6005, -3, -3, 2}// 66 67
};
public override BaseAddonDeed Deed
{
get
{
return null;
}
}
[ Constructable ]
public KhaldunEntranceAddon()
{
for (int i = 0; i < m_AddOnSimpleComponents.Length / 4; i++)
AddComponent( new AddonComponent( m_AddOnSimpleComponents[i,0] ), m_AddOnSimpleComponents[i,1], m_AddOnSimpleComponents[i,2], m_AddOnSimpleComponents[i,3] );
AddComplexComponent( (BaseAddon) this, 1313, 0, 1, 2, 1, -1, "", 1);// 25
AddComplexComponent( (BaseAddon) this, 1313, -1, 1, 3, 1, -1, "", 1);// 26
AddComplexComponent( (BaseAddon) this, 1313, -1, 2, 3, 1, -1, "", 1);// 27
AddComplexComponent( (BaseAddon) this, 1313, -2, 2, 5, 1, -1, "", 1);// 28
AddComplexComponent( (BaseAddon) this, 1313, 0, 2, 3, 1, -1, "", 1);// 29
}
public KhaldunEntranceAddon( Serial serial ) : base( serial )
{
}
private static void AddComplexComponent(BaseAddon addon, int item, int xoffset, int yoffset, int zoffset, int hue, int lightsource)
{
AddComplexComponent(addon, item, xoffset, yoffset, zoffset, hue, lightsource, null, 1);
}
private static void AddComplexComponent(BaseAddon addon, int item, int xoffset, int yoffset, int zoffset, int hue, int lightsource, string name, int amount)
{
AddonComponent ac;
ac = new AddonComponent(item);
if (name != null && name.Length > 0)
ac.Name = name;
if (hue != 0)
ac.Hue = hue;
if (amount > 1)
{
ac.Stackable = true;
ac.Amount = amount;
}
if (lightsource != -1)
ac.Light = (LightType) lightsource;
addon.AddComponent(ac, xoffset, yoffset, zoffset);
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 ); // Version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,34 @@
using System;
using System.Linq;
namespace Server.Items
{
public class KhaldunFirstAidBelt : FirstAidBelt
{
[Constructable]
public KhaldunFirstAidBelt()
{
LootType = LootType.Blessed;
WeightReduction = 50;
Attributes.RegenHits = 2;
HealingBonus = 10;
}
public KhaldunFirstAidBelt(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,94 @@
using System;
namespace Server.Items
{
[FlipableAttribute(0xA1DE, 0xA1DF)]
public class ZombiePainting : Item
{
public override int LabelNumber { get { return 1023744; } } // painting
[Constructable]
public ZombiePainting()
: base(0x4C62)
{
Weight = 10.0;
}
public ZombiePainting(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
[FlipableAttribute(0xA1E0, 0xA1E1)]
public class SkeletonPortrait : Item
{
public override int LabelNumber { get { return 1023744; } } // painting
[Constructable]
public SkeletonPortrait()
: base(0xA1E0)
{
Weight = 10.0;
}
public SkeletonPortrait(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
[FlipableAttribute(0xA1E2, 0xA1E3)]
public class LichPainting : Item
{
public override int LabelNumber { get { return 1023744; } } // painting
[Constructable]
public LichPainting()
: base(0xA1E2)
{
Weight = 10.0;
}
public LichPainting(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,208 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Server.Mobiles;
using Server.Targeting;
namespace Server.Items
{
public class KhaldunTastyTreat : Item
{
public const int Duration = 1; // hours
public override int LabelNumber { get { return 1158680; } } // khaldun tasty treat
[Constructable]
public KhaldunTastyTreat()
: this(1)
{
}
public KhaldunTastyTreat(int amount)
: base(2424)
{
Stackable = true;
Amount = amount;
}
public override bool DropToMobile(Mobile from, Mobile target, Point3D p)
{
TryFeed(from, target);
return false;
}
public override void OnDoubleClick(Mobile m)
{
if (IsChildOf(m.Backpack))
{
m.BeginTarget(2, false, TargetFlags.Beneficial, (from, targeted) =>
{
if (targeted is Mobile)
{
TryFeed(from, (Mobile)targeted);
}
});
}
}
private void TryFeed(Mobile from, Mobile target)
{
if (target is BaseCreature && !((BaseCreature)target).IsDeadBondedPet && ((BaseCreature)target).ControlMaster == from)
{
BaseCreature bc = (BaseCreature)target;
if (UnderInfluence(bc))
{
from.SendLocalizedMessage(1113051); //Your pet is still enjoying the last tasty treat!
}
else
{
DoEffects(bc.ControlMaster, bc);
}
}
}
public bool DoEffects(Mobile owner, BaseCreature bc)
{
owner.SendLocalizedMessage(1158685); // Your pet is now Caddellite infused by this treat.
bc.PlaySound(0x1EA);
bc.FixedParticles(0x373A, 10, 15, 5018, EffectLayer.Waist);
bc.Loyalty = BaseCreature.MaxLoyalty;
if (Table == null)
{
Table = new Dictionary<BaseCreature, DateTime>();
}
Table.Add(bc, DateTime.UtcNow + TimeSpan.FromHours(1));
Timer.DelayCall(TimeSpan.FromHours(Duration), RemoveInfluence, bc);
Caddellite.UpdateBuff(owner);
Consume();
return true;
}
public static Dictionary<BaseCreature, DateTime> Table { get; set; }
public static void Initialize()
{
EventSink.Login += OnLogin;
}
public static bool UnderInfluence(BaseCreature bc)
{
return Table != null && Table.ContainsKey(bc);
}
public static void RemoveInfluence(BaseCreature bc)
{
if (Table != null && Table.ContainsKey(bc))
{
Table.Remove(bc);
if (bc.ControlMaster != null)
{
bc.ControlMaster.SendLocalizedMessage(1158687); // Your pet is no longer Caddellite infused.
Caddellite.UpdateBuff(bc.ControlMaster);
}
if (Table.Count == 0)
{
Table = null;
}
}
}
public static BaseCreature GetPetUnderEffects(Mobile m)
{
if (m is PlayerMobile)
{
var pm = m as PlayerMobile;
foreach (var pet in pm.AllFollowers.OfType<BaseCreature>())
{
if (UnderInfluence(pet))
{
return pet;
}
}
}
return null;
}
public static void Save(GenericWriter writer)
{
writer.Write(0);
writer.Write(Table == null ? 0 : Table.Count);
if (Table != null)
{
foreach (var kpv in Table)
{
writer.Write(kpv.Key);
writer.Write(kpv.Value);
}
}
}
public static void Load(GenericReader reader)
{
reader.ReadInt(); // version
int count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
var bc = reader.ReadMobile() as BaseCreature;
var dt = reader.ReadDateTime();
if (bc != null && dt > DateTime.UtcNow)
{
if (Table == null)
Table = new Dictionary<BaseCreature, DateTime>();
Table[bc] = dt;
Timer.DelayCall(dt - DateTime.UtcNow, RemoveInfluence, bc);
}
}
}
public static void OnLogin(LoginEventArgs e)
{
var pm = e.Mobile as PlayerMobile;
if (pm != null)
{
Timer.DelayCall(() => Caddellite.UpdateBuff(pm));
}
}
public KhaldunTastyTreat(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,158 @@
using System;
using Server.Spells;
using Server.Spells.Seventh;
namespace Server.Items
{
public class MaskOfKhalAnkur : BaseHat
{
public override bool IsArtifact { get { return true; } }
public override int LabelNumber { get { return 1158701; } } // Mask of Khal Ankur
[CommandProperty(AccessLevel.GameMaster)]
public int ChargeTime { get; set; }
private int m_Charges;
[CommandProperty(AccessLevel.GameMaster)]
public int Charges
{
get { return m_Charges; }
set
{
m_Charges = value;
if (m_Charges == 0)
StartTimer();
InvalidateProperties();
}
}
[Constructable]
public MaskOfKhalAnkur()
: this(0)
{
}
[Constructable]
public MaskOfKhalAnkur(int hue)
: base(0xA1C7, hue)
{
Weight = 3;
Charges = 1;
//Caddellite Infused
Attributes.BonusHits = 10;
Attributes.BonusMana = 15;
Attributes.EnhancePotions = 35;
Attributes.LowerManaCost = 10;
}
public override void OnDoubleClick(Mobile from)
{
if (Parent != from)
{
from.SendLocalizedMessage(1116250); // That must be equipped before you can use it.
}
else if (ChargeTime > 0)
{
from.SendLocalizedMessage(1074882, ChargeTime.ToString()); // You must wait ~1_val~ seconds for this to recharge.
}
else if (SpellHelper.CheckTown(from.Location, from))
{
MeteorSwarmSpell spell = new MeteorSwarmSpell(from, null, this);
spell.Cast();
}
}
public override void OnAdded(object parent)
{
base.OnAdded(parent);
if (Charges == 0)
StartTimer();
}
public override void OnRemoved(object parent)
{
base.OnRemoved(parent);
if (Charges == 0)
StopTimer();
}
public override int BasePhysicalResistance { get { return 15; } }
public override int BaseFireResistance { get { return 15; } }
public override int BaseColdResistance { get { return 15; } }
public override int BasePoisonResistance { get { return 15; } }
public override int BaseEnergyResistance { get { return 15; } }
public override int InitMinHits { get { return 255; } }
public override int InitMaxHits { get { return 255; } }
public override void AddWeightProperty(ObjectPropertyList list)
{
base.AddWeightProperty(list);
list.Add(1158732, Charges.ToString()); // Meteor Breath Charges: ~1_VAL~
}
public MaskOfKhalAnkur(Serial serial)
: base(serial)
{
}
private Timer m_Timer;
public virtual void StartTimer()
{
ChargeTime = 300;
if (m_Timer == null || !m_Timer.Running)
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), new TimerCallback(Slice));
}
public virtual void StopTimer()
{
if (m_Timer != null)
m_Timer.Stop();
m_Timer = null;
}
public virtual void Slice()
{
if (ChargeTime > 0)
ChargeTime--;
else
{
ChargeTime = 0;
Charges = 1;
StopTimer();
}
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
writer.Write((int)m_Charges);
writer.Write((int)ChargeTime);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
m_Charges = reader.ReadInt();
ChargeTime = reader.ReadInt();
if (Parent != null && Parent is Mobile && ChargeTime > 0)
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), new TimerCallback(Slice));
}
}
}

View File

@@ -0,0 +1,91 @@
using System;
namespace Server.Items
{
public class Meteorite : Item
{
private bool _Polished;
[CommandProperty(AccessLevel.GameMaster)]
public bool Polished
{
get
{
return _Polished;
}
set
{
_Polished = value;
if (_Polished)
{
Polish();
}
else
{
UnPolish();
}
InvalidateProperties();
}
}
public override int LabelNumber { get { return _Polished ? 1125446 : 1158640; } } // Polished/Rough Meteorite
[Constructable]
public Meteorite()
: base(Utility.Random(0x1364, 3))
{
Hue = 1910;
}
public void TryPolish(Mobile from)
{
if (0.75 > Utility.RandomDouble())
{
Polished = true;
}
else
{
from.SendLocalizedMessage(1158694); // You attempt to polish the meteorite, but its delicate structure crumbles at the attempt.
Delete();
}
}
public void Polish()
{
Hue = 0;
ItemID = Utility.Random(0xA1CE, 12);
}
public void UnPolish()
{
Hue = 1910;
ItemID = Utility.Random(0x1364, 3);
}
public Meteorite(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
writer.Write(_Polished);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
_Polished = reader.ReadBool();
}
}
}

View File

@@ -0,0 +1,153 @@
using System;
using Server.Spells;
using Server.Spells.Seventh;
namespace Server.Items
{
public class PendantOfKhalAnkur : GargishNecklace
{
public override bool IsArtifact { get { return true; } }
public override int LabelNumber { get { return 1158731; } } // Pendant of Khal Ankur
[CommandProperty(AccessLevel.GameMaster)]
public int ChargeTime { get; set; }
private int m_Charges;
[CommandProperty(AccessLevel.GameMaster)]
public int Charges
{
get { return m_Charges; }
set
{
m_Charges = value;
if (m_Charges == 0)
StartTimer();
InvalidateProperties();
}
}
[Constructable]
public PendantOfKhalAnkur()
: base(0xA1C9)
{
Weight = 1;
Charges = 1;
//Caddellite Infused
Attributes.BonusHits = 10;
Attributes.BonusMana = 15;
Attributes.EnhancePotions = 35;
Attributes.LowerManaCost = 10;
ArmorAttributes.MageArmor = 1;
}
public override void OnDoubleClick(Mobile from)
{
if (Parent != from)
{
from.SendLocalizedMessage(1116250); // That must be equipped before you can use it.
}
else if (ChargeTime > 0)
{
from.SendLocalizedMessage(1074882, ChargeTime.ToString()); // You must wait ~1_val~ seconds for this to recharge.
}
else if (SpellHelper.CheckTown(from.Location, from))
{
MeteorSwarmSpell spell = new MeteorSwarmSpell(from, null, this);
spell.Cast();
}
}
public override void OnAdded(object parent)
{
base.OnAdded(parent);
if (Charges == 0)
StartTimer();
}
public override void OnRemoved(object parent)
{
base.OnRemoved(parent);
if (Charges == 0)
StopTimer();
}
public override int BasePhysicalResistance { get { return 15; } }
public override int BaseFireResistance { get { return 15; } }
public override int BaseColdResistance { get { return 15; } }
public override int BasePoisonResistance { get { return 15; } }
public override int BaseEnergyResistance { get { return 15; } }
public override int InitMinHits { get { return 255; } }
public override int InitMaxHits { get { return 255; } }
public override void AddWeightProperty(ObjectPropertyList list)
{
base.AddWeightProperty(list);
list.Add(1158732, Charges.ToString()); // Meteor Breath Charges: ~1_VAL~
}
public PendantOfKhalAnkur(Serial serial)
: base(serial)
{
}
private Timer m_Timer;
public virtual void StartTimer()
{
ChargeTime = 300;
if (m_Timer == null || !m_Timer.Running)
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), new TimerCallback(Slice));
}
public virtual void StopTimer()
{
if (m_Timer != null)
m_Timer.Stop();
m_Timer = null;
}
public virtual void Slice()
{
if (ChargeTime > 0)
ChargeTime--;
else
{
ChargeTime = 0;
Charges = 1;
StopTimer();
}
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
writer.Write((int)m_Charges);
writer.Write((int)ChargeTime);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
m_Charges = reader.ReadInt();
ChargeTime = reader.ReadInt();
if (Parent != null && Parent is Mobile && ChargeTime > 0)
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), new TimerCallback(Slice));
}
}
}

View File

@@ -0,0 +1,211 @@
using System;
using System.Collections.Generic;
using Server.Mobiles;
namespace Server.Items
{
public class PotionOfGloriousFortune : Item
{
public override int LabelNumber { get { return 1158688; } } // Potion of Glorious Fortune
public static int Bonus = 400;
[Constructable]
public PotionOfGloriousFortune()
: base(0xA1E6)
{
Hue = 1195;
LootType = LootType.Blessed;
}
public override void OnDoubleClick(Mobile m)
{
if (IsChildOf(m.Backpack))
{
if (TryAddEffects(m))
{
Consume();
}
}
}
public PotionOfGloriousFortune(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
public static Dictionary<Mobile, DateTime> Table { get; set; }
public static Timer Timer { get; set; }
public static void OnTick()
{
if (Table == null)
{
return;
}
var list = new List<Mobile>(Table.Keys);
foreach(var m in list)
{
UnderEffects(m);
}
ColUtility.Free(list);
}
public static int GetBonus(Mobile m)
{
if (UnderEffects(m))
{
return (int)(Bonus / 100);
}
return 1;
}
public static bool TryAddEffects(Mobile m)
{
if (Table == null)
{
Table = new Dictionary<Mobile, DateTime>();
}
if (!UnderEffects(m))
{
Table[m] = DateTime.UtcNow + TimeSpan.FromHours(1);
m.SendLocalizedMessage(1158719); // You are now under the effect of the Potion of Glorious Fortune.
BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.PotionGloriousFortune, 1158688, 1158720, TimeSpan.FromMinutes(60), m, Bonus.ToString(), true));
m.FixedEffect(0x375A, 10, 15);
m.PlaySound(0x1E7);
if (Timer == null)
{
Timer = Timer.DelayCall(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5), OnTick);
Timer.Start();
}
return true;
}
else
{
m.SendLocalizedMessage(1158718); // You are already under the effect of the Potion of Glorious Fortune.
}
return false;
}
public static bool UnderEffects(Mobile m)
{
if (Table != null && Table.ContainsKey(m))
{
if (Table[m] < DateTime.UtcNow)
{
ExpireBuff(m);
return false;
}
return true;
}
return false;
}
public static void ExpireBuff(Mobile m)
{
Table.Remove(m);
if (Table.Count == 0)
{
Table = null;
if (Timer != null)
{
Timer.Stop();
Timer = null;
}
}
}
public static void Save(GenericWriter writer)
{
writer.Write(0);
writer.Write(Table == null ? 0 : Table.Count);
if (Table != null)
{
foreach (var kpv in Table)
{
writer.Write(kpv.Key);
writer.Write(kpv.Value);
}
}
}
public static void Load(GenericReader reader)
{
reader.ReadInt(); // version
int count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
var bc = reader.ReadMobile();
var dt = reader.ReadDateTime();
if (bc != null && dt > DateTime.UtcNow)
{
if (Table == null)
Table = new Dictionary<Mobile, DateTime>();
Table[bc] = dt;
if (Timer == null)
{
Timer = Timer.DelayCall(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5), OnTick);
Timer.Start();
}
}
}
}
public static void Initialize()
{
EventSink.Login += OnLogin;
}
public static void OnLogin(LoginEventArgs e)
{
var pm = e.Mobile as PlayerMobile;
if (pm != null)
{
if (Table != null && UnderEffects(pm))
{
BuffInfo.AddBuff(pm, new BuffInfo(BuffIcon.PotionGloriousFortune, 1158688, 1158720, Table[pm] - DateTime.UtcNow, pm, Bonus.ToString(), true));
}
}
}
}
}

View File

@@ -0,0 +1,32 @@
using System;
using Server.Mobiles;
namespace Server.Items
{
public class ProphetTitleDeed : BaseRewardTitleDeed
{
public override TextDefinition Title { get { return 1158683; } } // Prophet
[Constructable]
public ProphetTitleDeed()
{
}
public ProphetTitleDeed(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int v = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,32 @@
using System;
using Server.Mobiles;
namespace Server.Items
{
public class SeekerOfTheFallenStarTitleDeed : BaseRewardTitleDeed
{
public override TextDefinition Title { get { return 1158682; } } // Seeker of the Fallen Star
[Constructable]
public SeekerOfTheFallenStarTitleDeed()
{
}
public SeekerOfTheFallenStarTitleDeed(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int v = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,78 @@
using System;
using Server.Gumps;
using Server.Mobiles;
using Server.Network;
namespace Server.Items
{
public class SterlingSilverRing : SilverRing
{
public override bool IsArtifact { get { return true; } }
public override int LabelNumber { get { return 1155606; } } // Stirling Silver Ring
public override int InitMinHits { get { return 255; } }
public override int InitMaxHits { get { return 255; } }
public bool HasSkillBonus
{
get { return SkillBonuses.Skill_1_Value != 0; }
}
[Constructable]
public SterlingSilverRing()
{
Attributes.RegenHits = 3;
Attributes.RegenMana = 5;
Attributes.WeaponDamage = 75;
}
public override void OnDoubleClick(Mobile m)
{
if (IsChildOf(m.Backpack) && m is PlayerMobile && !HasSkillBonus)
{
BaseGump.SendGump(new ApplySkillBonusGump((PlayerMobile)m, SkillBonuses, Skills, 20, 0));
}
else
{
base.OnDoubleClick(m);
}
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
if (!HasSkillBonus)
{
list.Add(1155609); // Double Click to Set Skill Bonus
}
}
public static SkillName[] Skills =
{
SkillName.Archery,
SkillName.Fencing,
SkillName.Macing,
SkillName.Swords,
SkillName.Throwing,
SkillName.Wrestling
};
public SterlingSilverRing(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(); // version
}
}
}

View File

@@ -0,0 +1,32 @@
using System;
using Server.Mobiles;
namespace Server.Items
{
public class ZealotOfKhalAnkurTitleDeed : BaseRewardTitleDeed
{
public override TextDefinition Title { get { return 1158684; } } // Zealot of Khal Ankur
[Constructable]
public ZealotOfKhalAnkurTitleDeed()
{
}
public ZealotOfKhalAnkurTitleDeed(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int v = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,413 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Gumps;
using Server.Regions;
using Server.Spells;
using Server.Network;
namespace Server.Engines.Khaldun
{
public class KhaldunCampRegion : BaseRegion
{
public static KhaldunCampRegion InstanceTram { get; set; }
public static KhaldunCampRegion InstanceFel { get; set; }
public KhaldunCampRegion(Map map)
: base("Khaldun Camp Region", map, Region.DefaultPriority, new Rectangle2D(5990, 3706, 52, 88))
{
Register();
}
private Point3D[] _GuardLocs =
{
new Point3D(6024, 3713, 1), new Point3D(6035, 3752, 11),
new Point3D(5999, 3726, 22), new Point3D(5992, 3752, 9),
new Point3D(6023, 3777, 20)
};
private Point3D[][] _BlockerLocs =
{
new Point3D[]
{
new Point3D(5995, 3727, 19), new Point3D(5995, 3726, 18), new Point3D(5996, 3726, 20), new Point3D(5996, 3725, 17), new Point3D(5997, 3725, 19),
new Point3D(5997, 3724, 19), new Point3D(5998, 3724, 19), new Point3D(5998, 3723, 20), new Point3D(5999, 3723, 20), new Point3D(5999, 3722, 20),
},
new Point3D[]
{
new Point3D(6023, 3710, 0), new Point3D(6024, 3710, 1), new Point3D(6025, 3710, 2), new Point3D(6026, 3710, 1), new Point3D(6027, 3710, -2),
new Point3D(6028, 3710, -2), new Point3D(6029, 3710, -1), new Point3D(6030, 3710, -1), new Point3D(6031, 3710, 0),
},
new Point3D[]
{
new Point3D(6036, 3748, 2), new Point3D(6037, 3748, 1), new Point3D(6038, 3748, 0), new Point3D(6039, 3748, 0), new Point3D(6040, 3748, 1), new Point3D(6041, 3748, -2),
},
new Point3D[]
{
new Point3D(6025, 3782, 22), new Point3D(6026, 3782, 22), new Point3D(6026, 3781, 22), new Point3D(6027, 3781, 19), new Point3D(6027, 3780, 22), new Point3D(6027, 3779, 18),
},
new Point3D[]
{
new Point3D(5991, 3755, 4), new Point3D(5991, 3754, 9), new Point3D(5991, 3753, 8), new Point3D(5991, 3752, 8), new Point3D(5991, 3751, 8), new Point3D(5991, 3750, 7), new Point3D(5991, 3749, 5),
},
new Point3D[]
{
new Point3D(5992, 3749, 9), new Point3D(5993, 3749, 10), new Point3D(5994, 3749, 10), new Point3D(5995, 3749, 10)
}
};
public override void OnRegister()
{
foreach (var p in _GuardLocs)
{
IPooledEnumerable eable = Map.GetMobilesInRange(p, 0);
bool empty = true;
foreach (var m in eable)
{
if (m is KhaldunCampGuard)
{
empty = false;
break;
}
}
eable.Free();
if (empty)
{
var guard = new KhaldunCampGuard();
guard.MoveToWorld(p, Map);
}
}
for (int i = 0; i < _BlockerLocs.Length; i++)
{
foreach (var p in _BlockerLocs[i])
{
IPooledEnumerable eable = Map.GetItemsInRange(p, 0);
bool empty = true;
foreach (var m in eable)
{
if (m is KhaldunCampBlocker)
{
empty = false;
break;
}
}
eable.Free();
if (empty)
{
var blocker = new KhaldunCampBlocker(i);
blocker.MoveToWorld(p, Map);
}
}
}
}
public override void OnUnregister()
{
GetEnumeratedMobiles().OfType<KhaldunCampGuard>().IterateReverse(g => g.Delete());
GetEnumeratedItems().OfType<KhaldunCampBlocker>().IterateReverse(b => b.Delete());
}
public override bool CheckTravel(Mobile traveller, Point3D p, TravelCheckType type)
{
return false;
}
}
public class KhaldunCampGuard : BaseVendor
{
protected readonly List<SBInfo> m_SBInfos = new List<SBInfo>();
protected override List<SBInfo> SBInfos { get { return m_SBInfos; } }
public override bool IsActiveVendor { get { return false; } }
public override void InitSBInfo()
{
}
public KhaldunCampGuard()
: base("the Guard")
{
}
public override void InitBody()
{
InitStats(100, 100, 25);
Female = Utility.RandomBool();
CantWalk = true;
Name = NameList.RandomName(Female ? "female" : "male");
Race = Race.Human;
Hue = Race.RandomSkinHue();
HairHue = Race.RandomHairHue();
FacialHairHue = Race.RandomHairHue();
HairItemID = Race.RandomHair(Female);
FacialHairItemID = Race.RandomFacialHair(Female);
}
public override void InitOutfit()
{
SetWearable(new PlateChest());
SetWearable(new PlateLegs());
SetWearable(new PlateGorget());
SetWearable(new PlateGloves());
SetWearable(new Halberd());
SetWearable(new PlateArms());
}
public KhaldunCampGuard(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class LeadInvestigator : BaseVendor
{
protected readonly List<SBInfo> m_SBInfos = new List<SBInfo>();
protected override List<SBInfo> SBInfos { get { return m_SBInfos; } }
public override bool IsActiveVendor { get { return false; } }
public override void InitSBInfo()
{
}
public static LeadInvestigator InstanceTram { get; set; }
public static LeadInvestigator InstanceFel { get; set; }
public LeadInvestigator()
: base("the Lead Investigator")
{
}
public override void InitBody()
{
InitStats(100, 100, 25);
Female = Utility.RandomBool();
CantWalk = true;
Name = NameList.RandomName(Female ? "female" : "male");
Race = Race.Human;
Hue = Race.RandomSkinHue();
HairHue = Race.RandomHairHue();
FacialHairHue = Race.RandomHairHue();
HairItemID = Race.RandomHair(Female);
FacialHairItemID = Race.RandomFacialHair(Female);
}
public override void InitOutfit()
{
SetWearable(new Shirt(), 1354);
SetWearable(new Doublet(), 1504);
SetWearable(new Kilt(), 1351);
SetWearable(new LongPants(), 1743);
SetWearable(new GoldRing());
SetWearable(new GoldBracelet());
SetWearable(new Shoes());
SetWearable(new GoldNecklace());
SetWearable(new GoldEarrings());
}
public override void OnDoubleClick(Mobile from)
{
if (InRange(from.Location, 3) && from.FindItemOnLayer(Layer.Neck) is DetectiveCredentials)
{
Direction = Utility.GetDirection(this, from);
from.SendGump(new BasicInfoGump(1158700, null, 300, 500));
/*You must be the Gumshoe who cracked this case wide open? Wow, to think we would still be worrying about these cultist
* miscreants after all this time? No matter, thanks to your instincts we may stand a fighting chance against this prophecy.
* I have to admit, I was skeptical at first, but after hearing what Sage Humbolt's had to say and seeing this, what do
* they call it - a meteorite? - was all the convincing I needed! Seems the good news is, despite numbers the cultist
* armies have and the big bad evil pulling the strings we've been keeping them inside the dungeon. It seems that once
* the meteorite impacted the lands here, it spread a material the smiths are calling "Caddellite" in everything - rocks,
* trees, fish - you name it. The artisans were clever enough to fashion weapons, spellbooks, and treats to get past the
* magics protecting the creatures in Khaldun. One thing though - seems the Caddellite is too strong for typical Britannian
* crafting tools save for those made by Krett the Tinker over there. Can't say I really blame him for making some coin
* on the situation. Lucky dog!*/
}
}
public LeadInvestigator(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
if (Map == Map.Felucca)
{
InstanceFel = this;
}
if (Map == Map.Trammel)
{
InstanceTram = this;
}
}
}
public class KhaldunCampBlocker : Item
{
public int Position { get; set; }
public KhaldunCampBlocker(int position)
: base(0x1BC3)
{
Position = position;
Name = "Khaldun Camp Blocker";
Movable = false;
Visible = false;
}
public override bool OnMoveOver(Mobile m)
{
if (m.AccessLevel > AccessLevel.Player)
{
return base.OnMoveOver(m);
}
if (m is BaseCreature && ((BaseCreature)m).GetMaster() is PlayerMobile)
{
m = ((BaseCreature)m).GetMaster();
}
bool hasCreds = m.FindItemOnLayer(Layer.Neck) is DetectiveCredentials;
bool canCross = hasCreds;
if (!canCross)
{
IPooledEnumerable eable = m.Map.GetItemsInRange(m.Location, 0);
foreach (Item item in eable)
{
if (item is KhaldunCampBlocker)
{
eable.Free();
return base.OnMoveOver(m);
}
}
eable.Free();
if (X == 5991 && Y == 3749)
{
CheckGuard(m, false);
return false;
}
Direction moving = Utility.GetDirection(m, this);
switch (Position)
{
case 0:
canCross = moving == Direction.North || moving == Direction.Up || moving == Direction.West; break;
case 1:
case 2:
canCross = moving == Direction.North || moving == Direction.Up || moving == Direction.Right; break;
case 3:
canCross = moving == Direction.South || moving == Direction.Down || moving == Direction.East; break;
case 4:
canCross = moving == Direction.West || moving == Direction.Up || moving == Direction.Left; break;
case 5:
canCross = moving == Direction.North || moving == Direction.Right || moving == Direction.North; break;
}
}
if (!canCross)
{
CheckGuard(m, false);
return false;
}
if (hasCreds)
{
CheckGuard(m, true);
}
return base.OnMoveOver(m);
}
private void CheckGuard(Mobile m, bool pass)
{
IPooledEnumerable eable = Map.GetMobilesInRange(m.Location, 10);
foreach (var g in eable.OfType<KhaldunCampGuard>())
{
if (pass)
{
g.PrivateOverheadMessage(MessageType.Regular, 0x47E, 1158716, m.NetState); // *nods* Please proceed, Detective
}
else
{
g.PrivateOverheadMessage(MessageType.Regular, 0x47E, 1158715, m.NetState); // Halt! Who goes there! Official RBG Detective personnel only!
}
break;
}
eable.Free();
}
public KhaldunCampBlocker(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
writer.Write(Position);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
Position = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,140 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Engines.SeasonalEvents;
namespace Server.Engines.Points
{
public class KhaldunData : PointsSystem
{
public override PointsType Loyalty { get { return PointsType.Khaldun; } }
public override TextDefinition Name { get { return m_Name; } }
public override bool AutoAdd { get { return true; } }
public override double MaxPoints { get { return double.MaxValue; } }
public override bool ShowOnLoyaltyGump { get { return false; } }
public bool InSeason { get { return SeasonalEventSystem.IsActive(EventType.TreasuresOfKhaldun); } }
public bool Enabled { get; set; }
public bool QuestContentGenerated { get; set; }
private TextDefinition m_Name = null;
public KhaldunData()
{
DungeonPoints = new Dictionary<Mobile, int>();
}
public override void SendMessage(PlayerMobile from, double old, double points, bool quest)
{
from.SendLocalizedMessage(1158674, ((int)points).ToString()); // You have turned in ~1_COUNT~ artifacts of the Cult
}
public override void ProcessKill(Mobile victim, Mobile damager)
{
var bc = victim as BaseCreature;
if (!InSeason || bc == null || bc.Controlled || bc.Summoned || !damager.Alive || damager.Deleted || !bc.IsChampionSpawn)
return;
Region r = bc.Region;
if (damager is PlayerMobile && r.IsPartOf("Khaldun"))
{
if (!DungeonPoints.ContainsKey(damager))
DungeonPoints[damager] = 0;
int fame = bc.Fame / 4;
int luck = Math.Max(0, ((PlayerMobile)damager).RealLuck);
DungeonPoints[damager] += (int)(fame * (1 + Math.Sqrt(luck) / 100)) * PotionOfGloriousFortune.GetBonus(damager);
int x = DungeonPoints[damager];
const double A = 0.000863316841;
const double B = 0.00000425531915;
double chance = A * Math.Pow(10, B * x);
if (chance > Utility.RandomDouble())
{
Item i = Loot.RandomArmorOrShieldOrWeaponOrJewelry(LootPackEntry.IsInTokuno(bc), LootPackEntry.IsMondain(bc), LootPackEntry.IsStygian(bc));
if (i != null)
{
RunicReforging.GenerateRandomItem(i, damager, Math.Max(100, RunicReforging.GetDifficultyFor(bc)), RunicReforging.GetLuckForKiller(bc), ReforgedPrefix.None, ReforgedSuffix.Khaldun);
damager.PlaySound(0x5B4);
damager.SendLocalizedMessage(1062317); // For your valor in combating the fallen beast, a special artifact has been bestowed on you.
if (!damager.PlaceInBackpack(i))
{
if (damager.BankBox != null && damager.BankBox.TryDropItem(damager, i, false))
damager.SendLocalizedMessage(1079730); // The item has been placed into your bank box.
else
{
damager.SendLocalizedMessage(1072523); // You find an artifact, but your backpack and bank are too full to hold it.
i.MoveToWorld(damager.Location, damager.Map);
}
}
DungeonPoints.Remove(damager);
}
}
}
}
public Dictionary<Mobile, int> DungeonPoints { get; set; }
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(2);
KhaldunTastyTreat.Save(writer);
PotionOfGloriousFortune.Save(writer);
writer.Write(Enabled);
writer.Write(QuestContentGenerated);
writer.Write(DungeonPoints.Count);
foreach (KeyValuePair<Mobile, int> kvp in DungeonPoints)
{
writer.Write(kvp.Key);
writer.Write(kvp.Value);
}
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch (version)
{
case 2:
KhaldunTastyTreat.Load(reader);
PotionOfGloriousFortune.Load(reader);
goto case 1;
case 1:
Enabled = reader.ReadBool();
QuestContentGenerated = reader.ReadBool();
goto case 0;
case 0:
int count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
Mobile m = reader.ReadMobile();
int points = reader.ReadInt();
if (m != null && points > 0)
DungeonPoints[m] = points;
}
break;
}
}
}
}

View File

@@ -0,0 +1,128 @@
using Server;
using System;
using Server.Mobiles;
using Server.Items;
using Server.Engines.Points;
namespace Server.Engines.Khaldun
{
public class KhaldunResearcher : BaseTurnInMobile
{
public override int TitleLocalization { get { return 1158744; } } // Artifacts of the Cult
public override int CancelLocalization { get { return 1158675; } } // Bring me items of the Cult and I will reward you with valuable items.
public override int TurnInLocalization { get { return 1157652; } } // Turn In Artifacts of The Cult
public override int ClaimLocalization { get { return 1155593; } } // Claim Rewards
public static KhaldunResearcher InstanceTram { get; set; }
public static KhaldunResearcher InstanceFel { get; set; }
[Constructable]
public KhaldunResearcher() : base("the Researcher")
{
}
public override void InitBody()
{
base.InitBody();
Name = NameList.RandomName("male");
Hue = Utility.RandomSkinHue();
Body = 0x190;
HairItemID = 0x2047;
HairHue = 0x46D;
}
public override void InitOutfit()
{
SetWearable(new FancyShirt(), 1255);
SetWearable(new JinBaori(), 2722);
SetWearable(new Kilt(), 2012);
SetWearable(new LongPants(), 1775);
SetWearable(new ThighBoots(1908));
SetWearable(new Necklace());
// QuiverOfInfinityBase
Item item = new SeekerOfTheFallenStarTitleDeed();
item.Movable = false;
PackItem(item);
item = new ZealotOfKhalAnkurTitleDeed();
item.Movable = false;
PackItem(item);
item = new ProphetTitleDeed();
item.Movable = false;
PackItem(item);
item = new CultistsRitualTome();
item.Movable = false;
PackItem(item);
item = new SterlingSilverRing();
item.Movable = false;
PackItem(item);
item = new TalonsOfEscaping();
item.Movable = false;
PackItem(item);
item = new BootsOfEscaping();
item.Movable = false;
PackItem(item);
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
list.Add(1158678); // Artifacts of the Cult Trader
}
public override void AwardPoints(PlayerMobile pm, Item item, int amount)
{
PointsSystem.Khaldun.AwardPoints(pm, amount);
}
public override bool IsRedeemableItem(Item item)
{
if (item is ICombatEquipment && ((ICombatEquipment)item).ReforgedSuffix == ReforgedSuffix.Khaldun)
return true;
return false;
}
public override void SendRewardGump(Mobile m)
{
if (m.Player && m.CheckAlive())
m.SendGump(new KhaldunRewardGump(this, m as PlayerMobile));
}
public KhaldunResearcher(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
if (Map == Map.Trammel)
{
InstanceTram = this;
}
if (Map == Map.Felucca)
{
InstanceFel = this;
}
}
}
}

View File

@@ -0,0 +1,34 @@
using Server;
using System;
using System.Collections.Generic;
using System.Linq;
using Server.Items;
namespace Server.Engines.Khaldun
{
public static class KhaldunRewards
{
public static List<CollectionItem> Rewards { get; set; }
public static void Initialize()
{
Rewards = new List<CollectionItem>();
Rewards.Add(new CollectionItem(typeof(KhaldunFirstAidBelt), 0xA1F6, 1158681, 0, 30));
Rewards.Add(new CollectionItem(typeof(MaskOfKhalAnkur), 0xA1C7, 1158701, 0, 50));
Rewards.Add(new CollectionItem(typeof(PendantOfKhalAnkur), 0xA1C9, 1158731, 0, 50));
Rewards.Add(new CollectionItem(typeof(SeekerOfTheFallenStarTitleDeed), 5360, 1155604, 0, 20));
Rewards.Add(new CollectionItem(typeof(ZealotOfKhalAnkurTitleDeed), 5360, 1155604, 0, 30));
Rewards.Add(new CollectionItem(typeof(ProphetTitleDeed), 5360, 1155604, 0, 50));
Rewards.Add(new CollectionItem(typeof(CultistsRitualTome), 0xEFA, 1158717, 0, 50));
Rewards.Add(new CollectionItem(typeof(SterlingSilverRing), 0x1F09, 1155606, 0, 50));
Rewards.Add(new CollectionItem(typeof(TalonsOfEscaping), 0x41D8, 1155682, 0, 50));
Rewards.Add(new CollectionItem(typeof(BootsOfEscaping), 0x1711, 1155607, 0, 50));
}
public static bool IsTokunoDyable(Type t)
{
return Rewards.FirstOrDefault(item => item.Type == t) != null;
}
}
}

View File

@@ -0,0 +1,583 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Server;
using Server.Mobiles;
using Server.Items;
using Server.Gumps;
using Server.Engines.Points;
using Server.Engines.Quests;
namespace Server.Engines.Khaldun
{
public class GoingGumshoeQuest : BaseQuest
{
public override bool DoneOnce { get { return true; } }
/* Going Gumshoe */
public override object Title { get { return 1158588; } }
/*You've heard rumblings of Pagan Cultists causing petty crimes in the more upscale sections of Britannia's cities,
* but to your understanding these are sympathizers taking advantage of fear to make some easy coin. Still, if the
* Crown is rolling out a new division of the RBG to investigate...something...you bet there's an opportunity for
* you! You should find Inspector Jasper and inquire further.*/
public override object Description { get { return 1158589; } }
/* You decide against accepting the quest. */
public override object Refuse { get { return 1158130; } }
/* Find Inspector Jasper, and inquire about the Town Cryer article at the new Detective Branch in East Britain */
public override object Uncomplete { get { return 1158590; } }
public override object Complete { get { return null; } }
public override int AcceptSound { get { return 0x2E8; } }
public override int CompleteMessage { get { return 1158616; } } // // You've found Chief Inspector Jasper! Speak to him to learn more!
public GoingGumshoeQuest()
{
AddReward(new BaseReward(1158615)); // A unique opportunity with the Detective Branch
AddObjective(new InternalObjective());
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
private class InternalObjective : BaseObjective
{
public override object ObjectiveDescription { get { return Quest.Uncomplete; } }
public InternalObjective()
: base(1)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
public class GoingGumshoeQuest2 : BaseQuest
{
public override bool DoneOnce { get { return true; } }
/* Going Gumshoe */
public override object Title { get { return 1158588; } }
/*You can drop the coffee pods with the investigators outside...*looks up*...oh, you aren't here for the delivery? I warned
* them talking with reporters was a terrible idea - we've been getting walk-ins like you since the article broke, lads
* and ladies thinking they can become renowned detectives - Ha! Think you've got the intellect? The cunning and wisdom
* to sniff a case where it leads you? Well I guess we'll see about that. I've got bigger cases to deal with, you can
* take this one. Something about vandalism and a funeral at the Britain Cemetery. Report back to me if you find anything
* worthwhile - and I do mean worthwhile! Don't come back to me with half baked theories and bogus evidence. I need facts!
* Oh - and read this, you'll need it if you even hope to break a single case.*/
public override object Description { get { return 1158592; } }
/* You decide against accepting the quest. */
public override object Refuse { get { return 1158130; } }
/*What are you still doing here? Didn't I send you to the cemetery? */
public override object Uncomplete { get { return 1158594; } }
public override object Complete { get { return null; } }
public override int AcceptSound { get { return 0x2E8; } }
public override int CompleteMessage { get { return 1158595; } } // TOIDO: This
// Note to whoever reads this: This is stupid but I find no easier way to do this...
public bool VisitedHeastone1 { get; set; }
public bool VisitedHeastone2 { get; set; }
public bool VisitedHeastone3 { get; set; }
public bool VisitedHeastone4 { get; set; }
public bool ClueBook1_1 { get; set; }
public bool ClueBook1_2 { get; set; }
public bool ClueDust1 { get; set; }
public bool ClueBook2_1 { get; set; }
public bool ClueBook2_2 { get; set; }
public bool ClueDust2 { get; set; }
public bool ClueBook3_1 { get; set; }
public bool ClueBook3_2 { get; set; }
public bool ClueDust3 { get; set; }
public bool ClueBook4_1 { get; set; }
public bool ClueBook4_2 { get; set; }
public bool ClueDust4 { get; set; }
public bool IsComplete
{
get
{
return ClueBook1_1 && ClueBook1_2 && ClueDust1 &&
ClueBook2_1 && ClueBook2_2 && ClueDust2 &&
ClueBook3_1 && ClueBook3_2 && ClueDust3 &&
ClueBook4_1 && ClueBook4_2 && ClueDust4;
}
}
public GoingGumshoeQuest2()
{
AddReward(new BaseReward(1158615)); // A unique opportunity with the Detective Branch
AddObjective(new InternalObjective());
}
public override void OnAccept()
{
base.OnAccept();
Item book = new DetectiveBook();
if (Owner.Backpack == null || !Owner.Backpack.TryDropItem(Owner, book, false))
{
Owner.BankBox.DropItem(book);
}
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
writer.Write(VisitedHeastone1);
writer.Write(VisitedHeastone2);
writer.Write(VisitedHeastone3);
writer.Write(VisitedHeastone4);
writer.Write(ClueBook1_1);
writer.Write(ClueBook1_2);
writer.Write(ClueDust1);
writer.Write(ClueBook2_1);
writer.Write(ClueBook2_2);
writer.Write(ClueDust2);
writer.Write(ClueBook3_1);
writer.Write(ClueBook3_2);
writer.Write(ClueDust3);
writer.Write(ClueBook4_1);
writer.Write(ClueBook4_2);
writer.Write(ClueDust4);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
VisitedHeastone1 = reader.ReadBool();
VisitedHeastone2 = reader.ReadBool();
VisitedHeastone3 = reader.ReadBool();
VisitedHeastone4 = reader.ReadBool();
ClueBook1_1 = reader.ReadBool();
ClueBook1_2 = reader.ReadBool();
ClueDust1 = reader.ReadBool();
ClueBook2_1 = reader.ReadBool();
ClueBook2_2 = reader.ReadBool();
ClueDust2 = reader.ReadBool();
ClueBook3_1 = reader.ReadBool();
ClueBook3_2 = reader.ReadBool();
ClueDust3 = reader.ReadBool();
ClueBook4_1 = reader.ReadBool();
ClueBook4_2 = reader.ReadBool();
ClueDust4 = reader.ReadBool();
}
private class InternalObjective : BaseObjective
{
/* You have been assigned as a probationary investigator with the Detective Branch of the RBG. Pursue leads and follow the clues where they lead you... */
public override object ObjectiveDescription { get { return 1158593; } }
public InternalObjective()
: base(1)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
public class GoingGumshoeQuest3 : BaseQuest
{
public override bool DoneOnce { get { return true; } }
/* Going Gumshoe */
public override object Title { get { return 1158588; } }
/**You approach Inspector Jasper and show him the evidence you have discovered as well as your report
* on the state of your investigation* Would you look at that, I suspect you aren't as useless as you
* look. With a little luck you may even crack this case wide open! It looks like these notes are encrypted
* - we need to find out what they say. There's a cryptologist at the Lycaeum who I've worked with in the
* past. Get his help and we should be a step closer to figuring out what all this means.*/
public override object Description { get { return 1158595; } }
/* You decide against accepting the quest. */
public override object Refuse { get { return 1158130; } }
/*What are you still doing here? Didn't I send you to the Lycaeum?*/
public override object Uncomplete { get { return 1158597; } }
public override object Complete { get { return null; } }
public override int AcceptSound { get { return 0x2E8; } }
public override int CompleteMessage { get { return 1158595; } } // TOIDO: This
public Item BookCase { get; set; }
public bool FoundCipherBook { get; set; }
public bool BegunDecrypting { get; set; }
public bool IsComplete
{
get { return BegunDecrypting; }
}
public GoingGumshoeQuest3()
{
AddReward(new BaseReward(1158615)); // A unique opportunity with the Detective Branch
AddObjective(new InternalObjective());
if (!World.Loading)
{
BookCase = GetBookcase();
}
}
private LibraryBookcase GetBookcase()
{
IPooledEnumerable eable = Map.Trammel.GetItemsInBounds(Bounds[Utility.Random(Bounds.Length)]);
List<Item> bookcases = new List<Item>();
foreach (Item item in eable)
{
if (item is LibraryBookcase)
{
bookcases.Add(item);
}
}
if (bookcases.Count > 0)
{
var bookcase = bookcases[Utility.Random(bookcases.Count)];
ColUtility.Free(bookcases);
return (LibraryBookcase)bookcase;
}
Console.WriteLine("Error: GoingGumshoeQuest3 has no bookcases. setup LibraryBookcase per EA via [CreateWorld command.");
return null;
}
public static bool CheckBookcase(Mobile from, Item item)
{
if (from is PlayerMobile)
{
var quest = QuestHelper.GetQuest<GoingGumshoeQuest3>((PlayerMobile)from);
if (quest != null && !quest.FoundCipherBook)
{
if (quest.BookCase == null)
{
quest.BookCase = quest.GetBookcase();
}
if (item == quest.BookCase)
{
quest.FoundCipherBook = true;
from.PrivateOverheadMessage(Server.Network.MessageType.Regular, 0x47E, 1158713, from.NetState);
// *You find the cipher text hidden among the books! Return to the Cryptologist to tell him where it is!*
var region = Region.Find(from.Location, from.Map);
if (region is QuestRegion)
{
((QuestRegion)region).ClearFromMessageTable(from);
}
return true;
}
}
}
return false;
}
public static Rectangle2D[] Bounds =
{
new Rectangle2D(4285, 961, 10, 18),
new Rectangle2D(4325, 961, 10, 18),
new Rectangle2D(4285, 989, 10, 18),
new Rectangle2D(4325, 989, 10, 18)
};
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
writer.Write(BookCase);
writer.Write(FoundCipherBook);
writer.Write(BegunDecrypting);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
BookCase = reader.ReadItem();
FoundCipherBook = reader.ReadBool();
BegunDecrypting = reader.ReadBool();
if (BookCase == null)
{
Timer.DelayCall(() => GetBookcase());
}
}
private class InternalObjective : BaseObjective
{
/* Go to the Lycaeum in Moonglow and enlist the assistance of the Cryptologist to help decode the evidence. Return to Inspector Jasper
* when you have more to report. */
public override object ObjectiveDescription { get { return 1158596; } }
public InternalObjective()
: base(1)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
private class QuestRegion : Region
{
public static void Initialize()
{
new QuestRegion();
}
public QuestRegion()
: base("Going Gumshoe Quest Region",
Map.Trammel,
Region.DefaultPriority,
GoingGumshoeQuest3.Bounds)
{
Register();
}
private Dictionary<Mobile, DateTime> _MessageTable;
public override void OnLocationChanged(Mobile m, Point3D oldLocation)
{
base.OnLocationChanged(m, oldLocation);
if (m is PlayerMobile)
{
var quest = QuestHelper.GetQuest<GoingGumshoeQuest3>((PlayerMobile)m);
if (quest != null && !quest.FoundCipherBook && 0.2 > Utility.RandomDouble())
{
var rec = GoingGumshoeQuest3.Bounds.FirstOrDefault(b => b.Contains(m.Location));
if (rec.Contains(quest.BookCase) && CanGiveMessage(m))
{
//m.PrivateOverheadMessage(Server.Network.MessageType.Regular, 0x47E, 1158714, m.NetState);
m.SendLocalizedMessage(1158714);
// *Your keen senses detect the books in this library have been recently disturbed...*
_MessageTable[m] = DateTime.UtcNow + TimeSpan.FromSeconds(15);
}
}
}
}
private bool CanGiveMessage(Mobile m)
{
if (_MessageTable == null)
{
_MessageTable = new Dictionary<Mobile, DateTime>();
return true;
}
if (_MessageTable.ContainsKey(m))
{
return _MessageTable[m] < DateTime.UtcNow;
}
return true;
}
public void ClearFromMessageTable(Mobile m)
{
if (_MessageTable != null && _MessageTable.ContainsKey(m))
{
_MessageTable.Remove(m);
if (_MessageTable.Count == 0)
{
_MessageTable = null;
}
}
}
}
}
public class GoingGumshoeQuest4 : BaseQuest
{
public override bool DoneOnce { get { return true; } }
/* Going Gumshoe */
public override object Title { get { return 1158588; } }
/*I must say, you've done fine work. The Cryptologist's courier arrived shortly before you did, and thanks to
* him we know what this is all about. There's one final piece of the puzzle, and hopefully for us whoever
* is at the bottom of this won't have known to look for a dead man. There is a Sage called Humbolt that
* once lived in Papua. Tragically his life was taken from us too soon, but his spirit still wanders around
* his old home. If anyone can put all the pieces together, it's him. Go to Papua and find him.*/
public override object Description { get { return 1158634; } }
/* You decide against accepting the quest. */
public override object Refuse { get { return 1158130; } }
/*Go to Papau and search for the spirit of Sage Humbolt*/
public override object Uncomplete { get { return 1158635; } }
public override object Complete { get { return null; } }
public override int AcceptSound { get { return 0x2E8; } }
public override int CompleteMessage { get { return 1158595; } } // TOIDO: This
public bool IsComplete { get; set; }
public GoingGumshoeQuest4()
{
AddReward(new BaseReward(1158615)); // A unique opportunity with the Detective Branch
AddObjective(new InternalObjective());
}
public override void GiveRewards()
{
Item reward = new DetectiveCredentials();
if (Owner.Backpack == null || !Owner.Backpack.TryDropItem(Owner, reward, false))
{
Owner.BankBox.DropItem(reward);
}
reward = new GumshoeTitleDeed();
if (Owner.Backpack == null || !Owner.Backpack.TryDropItem(Owner, reward, false))
{
Owner.BankBox.DropItem(reward);
}
base.GiveRewards();
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
writer.Write(IsComplete);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
IsComplete = reader.ReadBool();
}
private class InternalObjective : BaseObjective
{
/* Go to Papau and search for the spirit of Sage Humbolt */
public override object ObjectiveDescription { get { return 1158635; } }
public InternalObjective()
: base(1)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
}

View File

@@ -0,0 +1,42 @@
using Server;
using System;
using Server.Mobiles;
using Server.Engines.Quests;
// 0x1E06 => South
// 0x1E03 => West
// 0x1E04 => North
// 0x1E05 => East
namespace Server.Mobiles
{
public class BloodyFootPrints : Item
{
[Constructable]
public BloodyFootPrints(int itemID)
: base(itemID)
{
Movable = false;
Hue = 1975;
}
public BloodyFootPrints(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,105 @@
using System;
using Server;
using Server.Mobiles;
using Server.Items;
using Server.Network;
using Server.Gumps;
using Server.SkillHandlers;
using Server.Engines.Quests;
// 1158607 => brit
// 1158608 => vesper
// 1158609 => moonglow
// 1158610 => yew
namespace Server.Engines.Khaldun
{
public class DamagedHeadstone : Item, IForensicTarget
{
public override int LabelNumber { get { return 1158561; } } // damaged headstone
[CommandProperty(AccessLevel.GameMaster)]
public int GumpLocalization { get; private set; }
public DamagedHeadstone(int gumpLoc)
: base(0x1180)
{
GumpLocalization = gumpLoc;
Movable = false;
}
public void OnForensicEval(Mobile m)
{
if (!m.Player)
return;
var quest = QuestHelper.GetQuest<GoingGumshoeQuest2>((PlayerMobile)m);
if (quest != null)
{
m.PrivateOverheadMessage(MessageType.Regular, 0x47E, 1158571, m.NetState); // *You examine the headstone...*
m.SendLocalizedMessage(1158562, null, 0x23); // The damage to the epitaph seems deliberate. Using your training from Inspector Jasper you have found a hidden message among the scratches. You recreate the original epitaph in your mind's eye...
m.SendSound(quest.UpdateSound);
var gump = new Gump(50, 50);
gump.AddImage(0, 0, 0x66);
gump.AddHtmlLocalized(47, 60, 146, 160, GumpLocalization, false, false);
m.SendGump(gump);
SetPrerequisite(quest);
}
else
{
m.PrivateOverheadMessage(MessageType.Regular, 0x47E, 1158563, m.NetState); // *It appears to be a normal, yet oddly damaged, headstone. The epitaph is illegible..*
}
}
public override void OnDoubleClick(Mobile m)
{
if (m.InRange(GetWorldLocation(), 2))
{
m.PrivateOverheadMessage(MessageType.Regular, 0x47E, 1158563, m.NetState); // *It appears to be a normal, yet oddly damaged, headstone. The epitaph is illegible..*
}
else
m.PrivateOverheadMessage(MessageType.Regular, 0x47E, 1019045, m.NetState); // I can't reach that.
}
public void SetPrerequisite(GoingGumshoeQuest2 quest)
{
switch (GumpLocalization)
{
case 1158607: quest.VisitedHeastone1 = true; break;
case 1158608: quest.VisitedHeastone2 = true; break;
case 1158609: quest.VisitedHeastone3 = true; break;
case 1158610: quest.VisitedHeastone4 = true; break;
}
}
public DamagedHeadstone(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
writer.Write(GumpLocalization);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
GumpLocalization = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,352 @@
using System;
using Server;
using Server.Items;
namespace Server.Items
{
public class KhaldunDecorationAddon : BaseAddon
{
public static KhaldunDecorationAddon Instance { get; set; }
// Ritual Table needs to be hued 1362
// 14031 = hue 1
private static int[,] m_AddOnSimpleComponents = new int[,] {
{27, 74, 9, 1}, {28, 74, 9, 1}, {28, 73, 9, 1}// 1 2 3
, {28, 72, 9, 1}, {28, 74, -1, 1}, {28, 72, -1, 1}// 4 5 6
, {28, 73, -1, 1}, {27, 74, 6, 1}, {27, 74, 4, 1}// 7 8 9
, {27, 74, 5, 1}, {27, 74, 7, 1}, {27, 74, 8, 1}// 10 11 12
, {27, 74, 3, 1}, {27, 74, 2, 1}, {2879, 72, 0, 1}// 13 14 15
, {2501, 72, 0, 7}, {27, 74, 1, 1}, {27, 74, 0, 1}// 16 17 18
, {3644, 77, -3, 1}, {4014, 78, -3, 1}, {4014, 76, 1, 1}// 19 20 21
, {3647, 77, -3, 7}, {4014, 76, 0, 1}, {3646, 77, -3, 4}// 22 23 24
, {3644, 77, -2, 1}, {605, 72, -18, 1}, {4014, 75, -16, 1}// 25 26 27
, {3647, 76, -16, 7}, {605, 74, -18, 1}, {605, 73, -18, 1}// 28 29 30
, {4014, 73, -13, 1}, {3644, 72, -14, 1}, {605, 77, -18, 1}// 31 32 33
, {4014, 75, -15, 1}, {605, 78, -18, 1}, {605, 80, -18, 1}// 34 35 36
, {605, 79, -18, 1}, {605, 75, -18, 1}, {3644, 72, -13, 1}// 37 38 39
, {3646, 76, -16, 4}, {3644, 76, -16, 1}, {605, 76, -18, 1}// 40 41 42
, {27, 61, 9, 1}, {28, 62, 9, 1}, {28, 63, 9, 1}// 43 44 45
, {28, 64, 9, 1}, {28, 65, 9, 1}, {28, 66, 9, 1}// 46 47 48
, {28, 67, 9, 1}, {28, 68, 9, 1}, {28, 69, 9, 1}// 49 50 51
, {28, 70, 9, 1}, {28, 71, 9, 1}, {28, 71, -1, 1}// 52 53 54
, {28, 66, -1, 1}, {28, 65, -1, 1}, {28, 64, -1, 1}// 55 56 57
, {28, 64, -1, 1}, {28, 63, -1, 1}, {28, 62, -1, 1}// 58 59 60
, {4104, 64, 0, 7}, {3647, 69, -5, 7}, {3644, 69, -6, 1}// 61 62 63
, {3646, 69, -6, 4}, {27, 61, 5, 1}, {27, 61, 4, 1}// 64 65 66
, {27, 61, 3, 1}, {27, 61, 1, 1}, {27, 61, 2, 1}// 67 68 69
, /*{5368, 67, 0, 1},*/ {27, 61, 0, 1}, {4014, 70, -7, 1}// 70 71 72
, {33, 67, -1, 1}, /*{2501, 71, 0, 7},*/ {2879, 64, 0, 1}// 73 74 75
, {2879, 63, 0, 1}, {2879, 62, 1, 1}, {29, 61, -1, 1}// 76 77 78
, {2879, 62, 0, 1}, {4014, 70, -6, 1}, {3644, 69, -7, 1}// 79 80 81
, /*{7866, 62, 2, 7},*/ {3646, 69, -5, 4}, {3644, 69, -5, 1}// 82 83 84
, /*{5355, 62, 1, 7}, {5355, 62, 1, 8},*/ {2879, 71, 0, 1}// 85 86 87
, {5357, 63, 0, 7}, {2879, 62, 2, 1}, {27, 61, 6, 1}// 88 89 90
, {12254, 62, 4, 1}, {3647, 69, -6, 7}, {30, 70, -1, 1}// 91 92 93
, {27, 61, 7, 1}, {27, 61, 8, 1}, {7427, 62, -10, 1}// 94 95 96
, {7426, 62, -11, 1}, {7425, 62, -12, 1}, {7424, 62, -13, 1}// 97 98 99
, {7423, 62, -14, 1}, {7409, 61, -9, 1}, {7428, 61, -10, 1}// 100 101 102
, {7438, 61, -11, 1}, {7437, 61, -12, 1}, {7436, 61, -13, 1}// 103 104 105
, {7422, 61, -14, 1}, {7410, 60, -9, 1}, {7429, 60, -10, 1}// 106 107 108
, {7439, 60, -11, 1}, {7442, 60, -12, 1}, {7435, 60, -13, 1}// 109 110 111
, {7421, 60, -14, 1}, {7411, 59, -9, 1}, {7430, 59, -10, 1}// 112 113 114
, {7440, 59, -11, 1}, {7441, 59, -12, 1}, {7434, 59, -13, 1}// 115 116 117
, {7420, 59, -14, 1}, {7412, 58, -9, 1}, {611, 67, -18, 1}// 118 119 120
, {612, 67, -16, 1}, {4014, 65, -8, 1}, {3646, 64, -14, 4}// 122 123 124
, {605, 69, -18, 1}, {605, 70, -18, 1}, {4014, 70, -10, 1}// 125 126 127
, {605, 68, -18, 1}, {605, 65, -16, 1}, {3644, 59, -17, 1}// 128 129 130
, {3647, 64, -14, 7}, {3647, 70, -11, 7}, {605, 71, -18, 1}// 131 132 133
, {605, 66, -16, 1}, {3644, 59, -16, 1}, {605, 64, -16, 1}// 134 135 136
, {3644, 65, -13, 1}, {6667, 59, -11, 1}, {4014, 65, -9, 1}// 137 138 139
, {4014, 66, -9, 1}, {7431, 58, -10, 1}, {4014, 58, -17, 1}// 140 141 142
, {3644, 64, -14, 1}, {6668, 60, -12, 1}, {4014, 69, -14, 1}// 143 144 145
, {4014, 64, -13, 1}, {4014, 65, -14, 1}, {4014, 67, -12, 1}// 146 147 148
, {4014, 66, -8, 1}, {3644, 70, -15, 1}, {3644, 71, -10, 1}// 151 153 155
, {3646, 70, -11, 4}, {7417, 57, -13, 1}, {7416, 57, -12, 1}// 157 158 159
, {7415, 57, -11, 1}, {3647, 59, -17, 4}, {7414, 57, -10, 1}// 161 162 163
, {7413, 57, -9, 1}, {7419, 58, -14, 1}, {7418, 58, -13, 1}// 164 165 166
, {7433, 58, -12, 1}, {3644, 71, -11, 1}, {3644, 70, -11, 1}// 167 168 169
, {7432, 58, -11, 1}, {604, 67, -17, 1}, {4014, 54, -4, 1}// 170 171 172
, {604, 52, -1, 1}, {604, 52, -2, 1}, {604, 52, -3, 1}// 173 174 175
, {3644, 54, -3, 1}, {3644, 55, -3, 1}, {3644, 55, -4, 1}// 176 177 178
, {604, 52, -4, 1}, {604, 52, -5, 1}, {604, 52, -6, 1}// 179 180 181
, {604, 52, -7, 1}, {3647, 55, -3, 7}, {3646, 55, -3, 4}// 182 183 184
, {3644, 54, -16, 1}, {3644, 53, -16, 1}, {3644, 53, -17, 1}// 185 186 187
, {604, 50, -15, 1}, {604, 50, -11, 1}, {604, 50, -13, 1}// 188 189 190
, {604, 50, -14, 1}, {604, 50, -10, 1}, {604, 50, -12, 1}// 191 192 193
, {3647, 53, -16, 4}, {604, 50, -16, 1}, {4014, 54, -17, 1}// 194 195 196
, {604, 50, -17, 1}, {604, 50, -18, 1}, {4014, 54, -12, 1}// 197 198 199
, {604, 50, -9, 1}, {604, 50, -19, 1}, {41040, 28, 5, 1}// 200 201 202
, {41017, 28, 6, 1}, {41030, 25, 0, 1}, {41029, 24, 0, 1}// 203 204 205
, {41031, 26, 0, 1}, {41032, 27, 0, 1}, {41018, 27, 6, 1}// 206 207 208
, {41019, 26, 6, 1}, {41020, 25, 6, 1}, {41021, 24, 6, 1}// 209 210 211
, {607, 32, -3, 1}, {607, 31, -3, 1}, {5453, 32, 3, 1}// 212 213 214
, {5453, 32, 2, 1}, {607, 28, -3, 1}, {41039, 29, 5, 1}// 215 216 217
, {41016, 29, 6, 1}, {41038, 29, 4, 1}, {41036, 29, 2, 1}// 218 219 220
, {41035, 29, 1, 1}, {41038, 29, 3, 1}, {41037, 29, 3, 1}// 221 222 223
, {607, 30, -3, 1}, {607, 29, -3, 1}, {607, 25, -10, 1}// 224 225 226
, {607, 27, -10, 1}, {607, 24, -15, 1}, {607, 26, -10, 1}// 227 228 229
, {607, 25, -15, 1}, {28, 15, 11, 1}, {28, 14, 11, 1}// 230 231 232
, {28, 13, 11, 1}, {28, 10, 11, 1}, {5453, 21, 9, 1}// 233 234 235
, {27, 9, 10, 1}, {27, 9, 9, 1}, {28, 11, 11, 1}// 236 237 238
, {28, 12, 11, 1}, {27, 15, 11, 1}, {27, 15, 9, 1}// 239 240 241
, {27, 9, 11, 1}, {27, 15, 10, 1}, {4014, 17, -4, 1}// 242 243 244
, {4014, 20, -6, 1}, {4014, 19, -6, 1}, {4088, 8, -1, 7}// 245 246 247
, /*{2501, 8, -3, 7},*/ {41027, 23, 1, 1}, {41026, 23, 2, 1}// 248 249 250
, {41025, 23, 3, 1}, {41022, 23, 6, 1}, {41024, 23, 4, 0}// 251 252 253
, {12254, 10, 5, 1}, /*{5368, 9, -3, 1},*/ {3644, 16, -6, 1}// 254 255 256
, {3644, 17, -7, 1}, {2879, 8, 0, 1}, {2879, 8, -1, 1}// 257 258 259
, {2879, 8, -2, 1}, {2879, 8, -3, 1}, {3644, 20, -7, 1}// 260 261 262
, {33, 9, -4, 1}, {3644, 17, -3, 1}, {28, 8, -4, 1}// 263 264 265
, {28, 9, 1, 1}, {28, 8, 1, 1}, {5453, 23, -2, 1}// 266 267 268
, {5453, 22, 0, 1}, {4104, 8, 0, 7}, {3646, 18, -3, 4}// 269 270 271
, /*{5356, 8, -2, 7},*/ {5453, 20, 8, 1}, {27, 9, 8, 1}// 272 273 274
, {3646, 16, -6, 4}, {27, 9, 7, 1}, {27, 9, 6, 1}// 275 276 277
, {27, 9, 5, 1}, {27, 9, 4, 1}, {27, 9, 3, 1}// 278 279 280
, {27, 9, 2, 1}, {4014, 17, -6, 1}, {3646, 19, -7, 4}// 281 282 283
, {3646, 17, -7, 4}, {3647, 18, -3, 7}, {3644, 19, -7, 1}// 284 285 286
, {3644, 18, -3, 1}, {5453, 23, -3, 1}, {5453, 21, 1, 1}// 287 288 289
, {3646, 23, -7, 4}, /*{5356, 8, -2, 8},*/ {3647, 23, -7, 7}// 290 291 292
, {3644, 23, -7, 1}, {30, 13, -4, 1}, {28, 14, -4, 1}// 293 294 295
, {28, 15, -4, 1}, {27, 15, -3, 1}, {27, 15, -2, 1}// 296 297 298
, {32, 15, 4, 1}, {27, 15, -1, 1}, {27, 15, 0, 1}// 299 300 301
, {27, 15, 1, 1}, {31, 15, 8, 1}, {27, 15, 2, 1}// 302 303 304
, {27, 15, 3, 1}, {3644, 15, -9, 1}, {3644, 22, -14, 1}// 305 306 307
, {3644, 23, -8, 1}, {3644, 8, -10, 1}, {3644, 8, -9, 1}// 308 309 310
, {3644, 12, -9, 1}, {607, 22, -15, 1}, {607, 18, -15, 1}// 311 312 313
, {607, 15, -15, 1}, {607, 23, -15, 1}, {607, 21, -15, 1}// 314 315 316
, {607, 19, -15, 1}, {607, 20, -15, 1}, {607, 9, -11, 1}// 317 318 319
, {607, 11, -11, 1}, {4014, 11, -9, 1}, {4014, 15, -10, 1}// 320 321 322
, {4014, 17, -14, 1}, {4014, 16, -14, 1}, {612, 12, -11, 1}// 323 324 325
, {4014, 22, -13, 1}, {3647, 8, -10, 7}, {607, 14, -15, 1}// 326 327 328
, {604, 12, -14, 1}, {611, 12, -15, 1}, {607, 8, -11, 1}// 329 330 331
, {4014, 16, -10, 1}, {4014, 16, -9, 1}, {4014, 23, -13, 1}// 332 333 334
, {4014, 17, -13, 1}, {4014, 12, -10, 1}, {3646, 22, -14, 4}// 335 336 337
, {607, 10, -11, 1}, {607, 17, -15, 1}, {3646, 15, -9, 4}// 338 339 340
, {604, 12, -13, 1}, {604, 12, -12, 1}, {607, 13, -15, 1}// 341 342 343
, {607, 16, -15, 1}, {3647, 12, -9, 7}, {3646, 12, -9, 4}// 344 345 346
, {3646, 8, -10, 4}/*, {7867, 7, -1, 7}, {2501, 7, -2, 7}*/// 347 348 349
, {2879, 7, -2, 1}, {2879, 7, 0, 1}, {2879, 7, -1, 1}// 350 351 352
, {29, 6, -4, 1}, {28, 7, 1, 1}, {27, 6, -2, 1}// 353 354 355
, {27, 6, 1, 1}, {604, 6, -7, 1}, {604, 6, -6, 1}// 356 357 358
, {2879, 7, -3, 1}, {28, 7, -4, 1}, {27, 6, 0, 1}// 359 360 361
, {27, 6, -1, 1}, {27, 6, -3, 1}, {4014, 7, -10, 1}// 362 363 364
, {604, 6, -10, 1}, {604, 6, -8, 1}, {604, 6, -9, 1}// 365 366 367
, {607, 7, -11, 1}, {4014, 7, -9, 1}, {610, 6, -11, 1}// 368 369 370
, {3807, -23, 9, 1}, {4014, -19, 9, 1}, {3644, -18, 9, 1}// 371 372 373
, {6786, -24, 9, 1}, {4014, -21, 2, 1}, {4014, -20, 2, 1}// 374 379 380
, {4014, -17, 5, 1}, {3807, -21, 7, 1}, {3809, -23, 8, 1}// 381 383 384
, {3809, -21, 6, 1}, {3647, -20, 1, 7}, {3647, -19, 6, 4}// 385 386 387
, {605, -18, 2, 1}, {605, -21, -5, 1}, {605, -19, -5, 1}// 388 389 390
, {605, -20, -5, 1}, {605, -24, -5, 1}, {7848, -23, 3, 1}// 391 392 393
, {605, -23, -5, 1}, {605, -12, 2, 1}, {605, -16, 2, 1}// 394 395 396
, {605, -17, 2, 1}, {4014, -15, 3, 1}, {605, -14, 2, 1}// 397 398 399
, {605, -13, 2, 1}, {605, -15, 2, 1}, {3647, -21, 1, 7}// 400 401 402
, {3646, -21, 1, 4}, {3644, -20, 1, 1}, {3644, -21, 1, 1}// 403 404 405
, {3644, -16, 3, 1}, {6787, -24, 8, 1}, {3646, -20, 1, 4}// 406 407 408
, {3644, -16, 4, 1}, {3644, -19, 6, 1}, {605, -22, -5, 1}// 409 411 412
, {3646, -16, 3, 4}, {27, -35, 9, 1}, {27, -29, 10, 1}// 413 414 415
, {27, -35, 12, 1}, {31, -29, 9, 1}, {28, -29, 13, 1}// 416 417 418
, {27, -29, 11, 1}, {604, -29, 18, 1}, {28, -34, 13, 1}// 419 420 421
, {28, -30, 13, 1}, {604, -29, 16, 1}, {604, -29, 17, 1}// 422 423 424
, {28, -33, 13, 1}, {28, -32, 13, 1}, {604, -29, 14, 1}// 425 426 427
, {604, -29, 19, 1}, {27, -29, 13, 1}, {27, -35, 13, 1}// 428 429 430
, {3644, -27, 16, 1}, {604, -29, 15, 1}, {27, -29, 12, 1}// 431 432 433
, {27, -35, 10, 1}, {28, -31, 13, 1}, {3644, -27, 15, 1}// 434 435 436
, {4014, -28, 14, 1}, {27, -35, 11, 1}, {3646, -27, 16, 4}// 437 438 439
, {5356, -30, 0, 7}/*, {5356, -34, 0, 8}, {5356, -34, 0, 7}*/// 440 441 442
, /*{2501, -34, 1, 7},*/ {2880, -30, 0, 1}, {2880, -31, 0, 1}// 443 444 445
, {2879, -34, 3, 1}, {2879, -34, 2, 1}, {2879, -34, 1, 1}// 446 447 448
, {2879, -34, 0, 1}, {27, -29, 4, 1}, {28, -34, -1, 1}// 449 450 451
, {28, -32, -1, 1}, {27, -35, 0, 1}, {604, -28, -2, 1}// 452 453 454
, {604, -28, -3, 1}, {604, -28, -4, 1}, {605, -26, -5, 1}// 455 456 457
, {611, -28, -5, 1}, {27, -29, 0, 1}, {27, -35, 1, 1}// 458 459 460
, {3644, -27, 2, 1}, {612, -28, -1, 1}, {605, -25, -5, 1}// 461 462 463
, {3809, -26, 7, 1}, {605, -29, -1, 1}, {27, -35, 4, 1}// 464 465 466
, {3807, -26, 8, 1}, {32, -29, 5, 1}, {27, -29, 1, 1}// 467 468 469
, {27, -35, 6, 1}, {28, -33, -1, 1}, {3644, -28, 2, 1}// 470 471 472
, {27, -35, 3, 1}, {27, -35, 2, 1}, {27, -35, 7, 1}// 473 475 476
, {27, -29, 2, 1}, {27, -35, 8, 1}, {29, -35, -1, 1}// 477 478 479
, {3807, -26, 5, 1}, {605, -27, -5, 1}/*, {7867, -34, 2, 7}*/// 480 481 482
, {3809, -26, 4, 1}, {27, -29, 3, 1}, {27, -35, 5, 1}// 483 484 485
, {28, -29, -1, 1}, {12254, -34, 6, 1}, {28, -30, -1, 1}// 486 488 489
, {28, -31, -1, 1}/*, {5359, -71, 14, 7}, {7867, -72, 14, 7}*/// 490 491 492
, /*{5370, -69, 9, 1},*/ {5357, -66, 9, 7}, {5357, -72, 15, 7}// 493 494 495
, {3647, -71, 10, 7}, {3646, -71, 10, 4}, {2879, -65, 9, 1}// 496 497 498
, {2879, -66, 9, 1}, {27, -63, 11, 1}, {3644, -68, 14, 1}// 499 500 501
, {3644, -64, 13, 1}, {3644, -70, 10, 1}, {4014, -67, 11, 1}// 502 503 504
, {27, -63, 9, 1}, {3644, -71, 11, 1}, {3644, -71, 10, 1}// 505 506 507
, {4014, -63, 13, 1}, {27, -63, 10, 1}, {27, -61, 15, 1}// 508 509 510
, {27, -61, 18, 1}, {4014, -66, 16, 1}, {3644, -66, 15, 1}// 511 512 513
, {4014, -65, 16, 1}, {26, -61, 19, 1}, {4014, -65, 15, 1}// 514 515 516
, {28, -62, 19, 1}, {4014, -67, 12, 1}, {28, -61, 11, 1}// 517 518 519
, {28, -72, 19, 1}, {27, -61, 13, 1}, {28, -62, 11, 1}// 520 521 522
, {4014, -68, 15, 1}, {28, -71, 19, 1}, {28, -70, 19, 1}// 523 524 525
, {28, -69, 19, 1}, {28, -67, 19, 1}, {28, -68, 19, 1}// 526 527 528
, {27, -61, 14, 1}, {28, -66, 19, 1}, {28, -63, 19, 1}// 529 530 531
, {28, -65, 19, 1}, {27, -61, 12, 1}, {28, -64, 19, 1}// 532 533 534
, {2879, -72, 15, 1}, {2879, -71, 15, 1}, {2879, -71, 14, 1}// 535 536 537
, {2879, -72, 14, 1}, {27, -61, 16, 1}, {3644, -66, 11, 1}// 538 539 540
, {27, -61, 17, 1}/*, {5355, -66, 8, 8}, {5355, -66, 8, 7}*/// 541 542 543
, {3647, -63, -5, 7}, {3646, -63, -5, 4}, {2879, -66, 8, 1}// 555 556 557
, {2879, -65, 8, 1}, {28, -64, 7, 1}, {28, -65, 7, 1}// 558 564 565
, {28, -67, 7, 1}, {28, -66, 7, 1}, {28, -63, 7, 1}// 566 567 568
, {27, -63, 8, 1}, {4014, -68, 4, 1}, {4014, -67, 4, 1}// 569 570 571
, {27, -68, 8, 1}, {27, -63, 6, 1}, {28, -68, 8, 1}// 572 573 574
, {29, -68, 7, 1}, {27, -63, 7, 1}, {3644, -63, -4, 1}// 575 576 577
, {4014, -62, -3, 1}, {3644, -63, 2, 1}, {3644, -63, 1, 1}// 578 579 580
, {30, -69, 8, 1}, {3644, -63, -5, 1}, {3647, -69, -9, 7}// 581 582 583
, {3647, -70, -9, 7}, {3646, -69, -9, 4}, {3644, -70, -9, 1}// 584 585 586
, {3644, -69, -10, 1}, {3646, -70, -9, 4}, {605, -72, -11, 1}// 587 588 589
, {605, -69, -11, 1}, {4014, -72, -10, 1}, {4014, -72, -9, 1}// 590 591 592
, {605, -66, -11, 1}, {605, -67, -11, 1}, {605, -68, -11, 1}// 593 594 595
, {605, -70, -11, 1}, {3644, -69, -9, 1}, {605, -71, -11, 1}// 596 597 598
, /*{2501, -78, 14, 7}, {2501, -78, 15, 7},*/ {2879, -78, 15, 1}// 599 600 601
, {2879, -78, 14, 1}, {2879, -78, 13, 1}, {12254, -78, 11, 1}// 602 603 604
, {28, -78, 19, 1}, {28, -77, 19, 1}, {28, -76, 19, 1}// 605 606 607
, {28, -75, 19, 1}, {28, -74, 19, 1}, {28, -73, 19, 1}// 608 609 610
, {27, -79, 10, 1}, {27, -79, 9, 1}, {27, -79, 13, 1}// 611 612 613
, {27, -79, 14, 1}, {27, -79, 12, 1}, {27, -79, 11, 1}// 614 615 616
, {604, -78, 18, 1}, {27, -79, 16, 1}, {27, -79, 15, 1}// 617 618 619
, {604, -78, 17, 1}, {604, -78, 19, 1}, {604, -75, 6, 1}// 620 621 625
, {604, -75, 5, 1}, {604, -75, 4, 1}, {604, -75, 2, 1}// 626 627 628
, {604, -75, 3, 1}, {604, -75, -5, 1}, {604, -75, 1, 1}// 629 630 631
, {604, -75, -2, 1}, {604, -75, 0, 1}, {604, -75, -1, 1}// 632 633 634
, {604, -75, -4, 1}, {604, -75, -3, 1}, {604, -75, -6, 1}// 635 636 637
, {604, -75, -7, 1}, {29, -79, 8, 1}, {33, -75, 8, 1}// 638 639 640
, {604, -75, 7, 1}, {28, -78, 8, 1}, {28, -77, 8, 1}// 641 642 643
, {28, -76, 8, 1}, {604, -75, 8, 1}, {604, -75, -8, 1}// 644 645 646
, {604, -75, -9, 1}, {604, -75, -10, 1}, {4014, -73, -10, 1}// 647 648 649
, {605, -74, -11, 1}, {605, -73, -11, 1}, {4014, -73, -9, 1}// 650 651 652
, {611, -75, -11, 1}// 653
};
public override BaseAddonDeed Deed { get { return null; } }
[Constructable]
public KhaldunDecorationAddon()
{
Instance = this;
for (int i = 0; i < m_AddOnSimpleComponents.Length / 4; i++)
AddComponent(new AddonComponent(m_AddOnSimpleComponents[i, 0]), m_AddOnSimpleComponents[i, 1], m_AddOnSimpleComponents[i, 2], m_AddOnSimpleComponents[i, 3]);
AddComplexComponent((BaseAddon)this, 4643, 59, -12, 1, 1105, -1, "", 1);// 121
AddComplexComponent((BaseAddon)this, 8429, 60, -9, 2, 1105, -1, "", 1);// 149
AddComplexComponent((BaseAddon)this, 8429, 59, -9, 2, 1105, -1, "", 1);// 150
AddComplexComponent((BaseAddon)this, 4646, 57, -12, 2, 1105, -1, "", 1);// 152
AddComplexComponent((BaseAddon)this, 4646, 57, -11, 2, 1105, -1, "", 1);// 154
AddComplexComponent((BaseAddon)this, 4648, 62, -12, 2, 1105, -1, "", 1);// 156
AddComplexComponent((BaseAddon)this, 4648, 62, -11, 2, 1105, -1, "", 1);// 160
AddComplexComponent((BaseAddon)this, 14031, -22, 7, 1, 1, -1, "Hole", 1);// 375
AddComplexComponent((BaseAddon)this, 14031, -23, 6, 1, 1, -1, "Hole", 1);// 376
AddComplexComponent((BaseAddon)this, 18818, -24, -2, 1, 1105, -1, "", 1);// 377
AddComplexComponent((BaseAddon)this, 18819, -24, -3, 1, 1105, -1, "", 1);// 378
AddComplexComponent((BaseAddon)this, 14031, -23, 7, 1, 1, -1, "Hole", 1);// 382
AddComplexComponent((BaseAddon)this, 14031, -22, 6, 1, 1, -1, "Hole", 1);// 410
AddComplexComponent((BaseAddon)this, 18820, -25, -2, 1, 1105, -1, "", 1);// 474
AddComplexComponent((BaseAddon)this, 18821, -25, -3, 1, 1105, -1, "", 1);// 487
AddComplexComponent((BaseAddon)this, 4077, -68, -1, 1, 1105, -1, "", 1);// 544
AddComplexComponent((BaseAddon)this, 4076, -69, -1, 1, 1105, -1, "", 1);// 545
AddComplexComponent((BaseAddon)this, 4073, -70, -1, 1, 1105, -1, "", 1);// 546
AddComplexComponent((BaseAddon)this, 4078, -68, -2, 1, 1105, -1, "", 1);// 547
AddComplexComponent((BaseAddon)this, 4074, -69, -2, 1, 1105, -1, "", 1);// 548
AddComplexComponent((BaseAddon)this, 4070, -70, -2, 1, 1105, -1, "", 1);// 549
AddComplexComponent((BaseAddon)this, 4075, -68, -3, 1, 1105, -1, "", 1);// 550
AddComplexComponent((BaseAddon)this, 4072, -69, -3, 1, 1105, -1, "", 1);// 551
AddComplexComponent((BaseAddon)this, 4071, -70, -3, 1, 1105, -1, "", 1);// 552
AddComplexComponent((BaseAddon)this, 6571, -64, 2, 8, 0, 1, "", 1);// 553
AddComplexComponent((BaseAddon)this, 6571, -64, -2, 4, 0, 1, "", 1);// 554
AddComplexComponent((BaseAddon)this, 6571, -72, -4, 4, 0, 1, "", 1);// 559
AddComplexComponent((BaseAddon)this, 6571, -72, 0, 4, 0, 1, "", 1);// 560
AddComplexComponent((BaseAddon)this, 6571, -67, 0, 4, 0, 1, "", 1);// 561
AddComplexComponent((BaseAddon)this, 6571, -67, -4, 4, 0, 1, "", 1);// 562
AddComplexComponent((BaseAddon)this, 6571, -64, -6, 8, 0, 1, "", 1);// 563
AddComplexComponent((BaseAddon)this, 6571, -74, 2, 8, 0, 1, "", 1);// 622
AddComplexComponent((BaseAddon)this, 6571, -74, -2, 4, 0, 1, "", 1);// 623
AddComplexComponent((BaseAddon)this, 6571, -74, -6, 8, 0, 1, "", 1);// 624
}
public KhaldunDecorationAddon( Serial serial ) : base( serial )
{
}
private static void AddComplexComponent(BaseAddon addon, int item, int xoffset, int yoffset, int zoffset, int hue, int lightsource)
{
AddComplexComponent(addon, item, xoffset, yoffset, zoffset, hue, lightsource, null, 1);
}
private static void AddComplexComponent(BaseAddon addon, int item, int xoffset, int yoffset, int zoffset, int hue, int lightsource, string name, int amount)
{
AddonComponent ac;
ac = new AddonComponent(item);
if (name != null && name.Length > 0)
ac.Name = name;
if (hue != 0)
ac.Hue = hue;
if (amount > 1)
{
ac.Stackable = true;
ac.Amount = amount;
}
if (lightsource != -1)
ac.Light = (LightType) lightsource;
addon.AddComponent(ac, xoffset, yoffset, zoffset);
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( 0 ); // Version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
Instance = this;
}
}
public class KhaldunWorkshop : BaseAddon
{
private static int[,] m_AddOnSimpleComponents = new int[,] {
{7864, 4, 0, 12} // 7 8 9
, {4179, 4, 1, 10}, {4130, -2, -3, 10}, {9932, -2, -2, 10}// 10 11 12
, {7867, -2, 0, 12}, {7129, -2, 1, 10}, {4014, -1, 1, 4}// 13 14 15
, {4015, 1, -3, 4}, {4017, 1, -2, 4}, {4017, 1, 0, 4}// 16 17 18
, {2879, 4, 1, 4}, {2879, -2, -3, 4}, {2879, 4, 0, 4}// 19 20 21
, {2879, 4, -1, 4}, {2879, 4, -2, 4}, {2879, 4, -3, 4}// 22 23 24
, {2879, -2, 1, 4}, {2879, -2, 0, 4}, {2879, -2, -1, 4}// 25 26 27
, {2879, -2, -2, 4}// 28
};
public override BaseAddonDeed Deed { get { return null; } }
[Constructable]
public KhaldunWorkshop()
{
for (int i = 0; i < m_AddOnSimpleComponents.Length / 4; i++)
AddComponent(new AddonComponent(m_AddOnSimpleComponents[i, 0]), m_AddOnSimpleComponents[i, 1], m_AddOnSimpleComponents[i, 2], m_AddOnSimpleComponents[i, 3]);
}
public KhaldunWorkshop(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // Version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,51 @@
using System;
using Server;
using Server.Gumps;
namespace Server.Items
{
public class DetectiveBook : Item
{
[Constructable]
public DetectiveBook() : base(4082)
{
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
list.Add(1158598); // Book title
list.Add(1154760, "K. Jasper, Chief Inspector"); // By: ~1_NAME~
}
public override void OnDoubleClick(Mobile m)
{
if (IsChildOf(m.Backpack))
{
Gump g = new Gump(150, 150);
g.AddImage(0, 0, 30236);
g.AddHtmlLocalized(110, 30, 350, 630, 1158600, false, false); // Book content
m.SendGump(g);
}
}
public DetectiveBook(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,36 @@
using Server;
namespace Server.Items
{
public class DetectiveCredentials : BaseNecklace
{
public override int LabelNumber { get { return 1158641; } } // RBG Detective Branch Official Credential
[Constructable]
public DetectiveCredentials()
: base(0x1088)
{
Hue = 1176;
LootType = LootType.Blessed;
}
public DetectiveCredentials(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,116 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Prompts;
using Server.Mobiles;
using Server.Items;
using Server.SkillHandlers;
using Server.Gumps;
using Server.Network;
using Server.Engines.Quests;
namespace Server.Engines.Khaldun
{
public class DustPile : Item, IForensicTarget
{
[CommandProperty(AccessLevel.GameMaster)]
public TrapDoor Door { get; set; }
public DustPile(TrapDoor door)
: base(0x573D)
{
Movable = false;
Hue = 2044;
Name = "";
Door = door;
}
public void OnForensicEval(Mobile m)
{
if (!m.Player)
return;
var quest = QuestHelper.GetQuest<GoingGumshoeQuest2>((PlayerMobile)m);
if (quest != null)
{
if (HasFoundClue(quest))
{
m.SendLocalizedMessage(1158613); // You have already documented this clue.
}
else
{
m.PrivateOverheadMessage(MessageType.Regular, 0x47E, 1157722, "Forensics", m.NetState); // *Your proficiency in ~1_SKILL~ reveals more about the item*
m.SendLocalizedMessage(1158612, null, 0x23); // You have identified a clue! This item seems pertinent to the investigation!
m.SendSound(quest.UpdateSound);
m.SendSound(m.Female ? 0x30B : 0x41A);
m.CloseGump(typeof(GumshoeItemGump));
m.SendGump(new GumshoeItemGump(m, ItemID, Hue, "a dust pile", 1158617, null));
/*The dust seems to have have settled in a distinct pattern around whatever once was placed at this location.
* Whatever it was, it was certainly small enough to be taken away in a hurry.*/
SetFoundClue(quest);
}
}
}
private void SetFoundClue(GoingGumshoeQuest2 quest)
{
if (Door == null)
{
return;
}
switch (Door.Keyword.ToLower())
{
case "boreas": quest.ClueDust1 = true; break;
case "moriens": quest.ClueDust2 = true; break;
case "carthax": quest.ClueDust3 = true; break;
case "tenebrae": quest.ClueDust4 = true; break;
}
}
private bool HasFoundClue(GoingGumshoeQuest2 quest)
{
if (Door == null)
{
return false;
}
switch (Door.Keyword.ToLower())
{
case "boreas": return quest.ClueDust1;
case "moriens": return quest.ClueDust2;
case "carthax": return quest.ClueDust3;
case "tenebrae": return quest.ClueDust4;
}
return false;
}
public DustPile(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
writer.Write(Door);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
Door = reader.ReadItem() as TrapDoor;
}
}
}

View File

@@ -0,0 +1,220 @@
using System;
using Server;
using Server.Mobiles;
using Server.Items;
using Server.SkillHandlers;
using Server.Network;
using Server.Gumps;
using Server.Engines.Quests;
namespace Server.Engines.Khaldun
{
public class BaseGumshoeForensicItem : Item, IForensicTarget
{
public virtual string ItemName { get { return null; } }
public virtual int Cliloc { get { return 0; } }
public override bool DisplayWeight { get { return false; } }
public BaseGumshoeForensicItem(int itemID)
: base(itemID)
{
Movable = false;
}
public void OnForensicEval(Mobile m)
{
if (!m.Player)
return;
var quest = QuestHelper.GetQuest<GoingGumshoeQuest2>((PlayerMobile)m);
if (quest != null)
{
m.PrivateOverheadMessage(MessageType.Regular, 0x47E, 1157722, "Forensics", m.NetState); // *Your proficiency in ~1_SKILL~ reveals more about the item*
m.SendLocalizedMessage(1158612, null, 0x23); // You have identified a clue! This item seems pertinent to the investigation!
m.SendSound(quest.UpdateSound);
m.SendSound(m.Female ? 0x30B : 0x41A);
m.CloseGump(typeof(GumshoeItemGump));
m.SendGump(new GumshoeItemGump(m, ItemID, Hue, ItemName, Cliloc, null));
}
}
public BaseGumshoeForensicItem(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class GumshoeBottles : BaseGumshoeForensicItem
{
public override string ItemName { get { return "bottles of wine"; } }
public override int Cliloc { get { return 1158572; } }
[Constructable]
public GumshoeBottles()
: base(0x9C5)
{
}
public GumshoeBottles(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class GumshoeDeed : BaseGumshoeForensicItem
{
public override string ItemName { get { return "deed"; } }
public override int Cliloc { get { return 1158575; } }
[Constructable]
public GumshoeDeed()
: base(0x14EF)
{
}
public GumshoeDeed(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class GumshoeRope : BaseGumshoeForensicItem
{
public override string ItemName { get { return "rope"; } }
public override int Cliloc { get { return 1158573; } }
[Constructable]
public GumshoeRope()
: base(0x14FA)
{
}
public GumshoeRope(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class GumshoeMap : BaseGumshoeForensicItem
{
public override string ItemName { get { return "map"; } }
public override int Cliloc { get { return 1158574; } }
[Constructable]
public GumshoeMap()
: base(0x14EB)
{
}
public GumshoeMap(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class GumshoeTools : BaseGumshoeForensicItem
{
public override string ItemName { get { return "tools"; } }
public override int Cliloc { get { return 1158576; } }
[Constructable]
public GumshoeTools()
: base(0x1EBB)
{
}
public GumshoeTools(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,32 @@
using System;
using Server.Mobiles;
namespace Server.Items
{
public class GumshoeTitleDeed : BaseRewardTitleDeed
{
public override TextDefinition Title { get { return 1158638; } } // Gumpshoe
[Constructable]
public GumshoeTitleDeed()
{
}
public GumshoeTitleDeed(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int v = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,191 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Prompts;
using Server.Mobiles;
using Server.Items;
using Server.SkillHandlers;
using Server.Network;
using Server.Gumps;
using Server.Engines.Quests;
namespace Server.Engines.Khaldun
{
public class MysteriousBook : Item, IForensicTarget
{
public override int LabelNumber { get { return 1158583; } } // mysterious book
public static readonly Point3D SpawnLocation = new Point3D(6240, 2885, 7);
[CommandProperty(AccessLevel.GameMaster)]
public TrapDoor Door { get; set; }
public MysteriousBook(TrapDoor door)
: base(0x42b8)
{
Movable = false;
Door = door;
Hue = 1950;
}
public void OnForensicEval(Mobile m)
{
if (!m.Player)
return;
var quest = QuestHelper.GetQuest<GoingGumshoeQuest2>((PlayerMobile)m);
if (quest != null)
{
if (HasFoundClue1(quest))
{
m.SendLocalizedMessage(1158613); // You have already documented this clue.
}
else
{
m.PrivateOverheadMessage(MessageType.Regular, 0x47E, 1157722, "Forensics", m.NetState); // *Your proficiency in ~1_SKILL~ reveals more about the item*
m.SendLocalizedMessage(1158612, null, 0x23); // You have identified a clue! This item seems pertinent to the investigation!
m.SendSound(quest.UpdateSound);
m.SendSound(m.Female ? 0x30B : 0x41A);
m.CloseGump(typeof(GumshoeItemGump));
m.SendGump(new GumshoeItemGump(m, ItemID, Hue, "book", 1158577, null));
SetFoundClue1(quest);
}
}
}
public void OnInscribeTarget(Mobile m)
{
var quest = QuestHelper.GetQuest<GoingGumshoeQuest2>((PlayerMobile)m);
if (quest != null)
{
if (HasFoundClue2(quest))
{
m.SendLocalizedMessage(1158613); // You have already documented this clue.
}
else
{
m.PrivateOverheadMessage(MessageType.Regular, 0x47E, 1158582, m.NetState); // *You copy several pages onto some parchment and roll it up...*
m.SendLocalizedMessage(1158612, null, 0x23); // You have identified a clue! This item seems pertinent to the investigation!
m.AddToBackpack(new RolledParchment(GetPage()));
m.PlaySound(0x249);
m.SendSound(quest.UpdateSound);
SetFoundClue2(quest);
}
}
}
private void SetFoundClue1(GoingGumshoeQuest2 quest)
{
if (Door == null)
{
return;
}
switch (Door.Keyword.ToLower())
{
case "boreas": quest.ClueBook1_1 = true; break;
case "moriens": quest.ClueBook2_1 = true; break;
case "carthax": quest.ClueBook3_1 = true; break;
case "tenebrae": quest.ClueBook4_1 = true; break;
}
}
private void SetFoundClue2(GoingGumshoeQuest2 quest)
{
if (Door == null)
{
return;
}
switch (Door.Keyword.ToLower())
{
case "boreas": quest.ClueBook1_2 = true; break;
case "moriens": quest.ClueBook2_2 = true; break;
case "carthax": quest.ClueBook3_2 = true; break;
case "tenebrae": quest.ClueBook4_2 = true; break;
}
}
private bool HasFoundClue1(GoingGumshoeQuest2 quest)
{
if (Door == null)
{
return false;
}
switch (Door.Keyword.ToLower())
{
case "boreas": return quest.ClueBook1_1;
case "moriens": return quest.ClueBook2_1;
case "carthax": return quest.ClueBook3_1;
case "tenebrae": return quest.ClueBook4_1;
}
return false;
}
private bool HasFoundClue2(GoingGumshoeQuest2 quest)
{
if (Door == null)
{
return false;
}
switch (Door.Keyword.ToLower())
{
case "boreas": return quest.ClueBook1_2;
case "moriens": return quest.ClueBook2_2;
case "carthax": return quest.ClueBook3_2;
case "tenebrae": return quest.ClueBook4_2;
}
return false;
}
private int GetPage()
{
if (Door == null)
{
return 0;
}
switch (Door.Keyword.ToLower())
{
case "boreas": return 1158629;
case "moriens": return 1158630;
case "carthax": return 1158631;
case "tenebrae": return 1158632;
}
return 0;
}
public MysteriousBook(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
writer.Write(Door);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
Door = reader.ReadItem() as TrapDoor;
}
}
}

View File

@@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Prompts;
using Server.Mobiles;
using Server.Items;
using Server.SkillHandlers;
using Server.Network;
using Server.Gumps;
using Server.Engines.Quests;
namespace Server.Engines.Khaldun
{
public class RolledParchment : Item
{
public override int LabelNumber { get { return 1158578; } } // rolled parchment
public int Page { get; set; }
public RolledParchment(int page)
: base(0x2831)
{
Page = page;
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
list.Add(Page);
}
public override void OnDoubleClick(Mobile m)
{
m.CloseGump(typeof(GumshoeItemGump));
m.SendGump(new GumshoeItemGump(m, ItemID, Hue, "rolled parchment", 1158580, "Copied From a Book Found in a Hidden Supply Cache"));
m.PrivateOverheadMessage(MessageType.Regular, 0x47E, 1157722, "its origin", m.NetState); // *Your proficiency in ~1_SKILL~ reveals more about the item*
m.SendSound(m.Female ? 0x30B : 0x41A);
}
public RolledParchment(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
writer.Write(Page);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
Page = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,221 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Prompts;
using Server.Mobiles;
using Server.Items;
using Server.SkillHandlers;
using Server.Network;
using Server.Engines.Quests;
namespace Server.Engines.Khaldun
{
public class TrapDoor : Item, IRevealableItem, IForensicTarget
{
//public static readonly Point3D TeleportDestination1 = new Point3D(6242, 2892, 17);
public Timer HideTimer { get; set; }
public bool CheckWhenHidden { get { return true; } }
[CommandProperty(AccessLevel.GameMaster)]
public Map DestinationMap { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public Point3D Destination { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public string Keyword { get; set; }
private bool _HasBeenExamined;
[CommandProperty(AccessLevel.GameMaster)]
public bool HasBeenExamined
{
get
{
return _HasBeenExamined;
}
set
{
bool current = _HasBeenExamined;
_HasBeenExamined = value;
if (!current && _HasBeenExamined)
{
HideTimer = Timer.DelayCall(TimeSpan.FromMinutes(20), () => Hide() );
}
}
}
public TrapDoor(string keyword, Point3D dest, Map destMap)
: base(0xA1CD)
{
Keyword = keyword;
Destination = dest;
DestinationMap = destMap;
Movable = false;
Visible = false;
}
public override void Delete()
{
base.Delete();
if (HideTimer != null)
{
HideTimer.Stop();
HideTimer = null;
}
}
private void Hide()
{
Visible = false;
HasBeenExamined = false;
ItemID = 0xA1CD;
if (HideTimer != null)
{
HideTimer.Stop();
HideTimer = null;
}
}
public bool CheckReveal(Mobile m)
{
return true;
}
public bool CheckPassiveDetect(Mobile m)
{
if (m.InRange(Location, 4))
{
if (Utility.Random(100) < 10)
return true;
}
return false;
}
public void OnRevealed(Mobile m)
{
m.PrivateOverheadMessage(MessageType.Regular, 0x47E, 1158556, m.NetState); // *You notice something hidden in the floor...*
Visible = true;
}
public void OnForensicEval(Mobile m)
{
if (!m.Player)
return;
var quest = QuestHelper.GetQuest<GoingGumshoeQuest2>((PlayerMobile)m);
if (quest != null && CheckPrerequisite(quest))
{
m.PrivateOverheadMessage(MessageType.Regular, 0x47E, 1158559, m.NetState); // *You discover a hidden trap door!*
m.SendLocalizedMessage(1158611, null, 0x23); // It seems a trap door has been hidden in some false pavers. The heavy wooden door is secured with a rotating combination lock that accepts alpha-numeric characters. You'll need to figure out the passcode to unlock it...
m.SendSound(quest.UpdateSound);
HasBeenExamined = true;
ItemID = 0xA1CC;
if (HideTimer != null)
{
HideTimer.Stop();
HideTimer = null;
HideTimer = Timer.DelayCall(TimeSpan.FromMinutes(20), () => Hide());
}
}
}
private bool CheckPrerequisite(GoingGumshoeQuest2 quest)
{
switch (Keyword.ToLower())
{
case "boreas": return quest.VisitedHeastone1; // brit
case "moriens": return quest.VisitedHeastone2; // vesper
case "carthax": return quest.VisitedHeastone3; // moonglow
case "tenebrae": return quest.VisitedHeastone4; // yew
}
return false;
}
public override void OnDoubleClick(Mobile m)
{
if (Destination == Point3D.Zero || DestinationMap == null || DestinationMap == Map.Internal || String.IsNullOrEmpty(Keyword))
return;
if (m.InRange(GetWorldLocation(), 2) && _HasBeenExamined)
{
m.Prompt = new TrapDoorPrompt(this);
}
}
private class TrapDoorPrompt : Prompt
{
public override int MessageCliloc { get { return 1158557; } }
public TrapDoor Door { get; set; }
public TrapDoorPrompt(TrapDoor door)
{
Door = door;
}
public override void OnResponse(Mobile from, string text)
{
if (Door.Destination == Point3D.Zero || Door.DestinationMap == null || Door.DestinationMap == Map.Internal || String.IsNullOrEmpty(Door.Keyword))
return;
if (!string.IsNullOrEmpty(text) && text.Trim().ToLower() == Door.Keyword.ToLower())
{
Effects.SendLocationParticles(EffectItem.Create(from.Location, from.Map, EffectItem.DefaultDuration), 0x3728, 10, 10, 2023);
from.MoveToWorld(Door.Destination, Door.DestinationMap);
Effects.SendLocationParticles(EffectItem.Create(Door.Destination, Door.DestinationMap, EffectItem.DefaultDuration), 0x3728, 10, 10, 5023);
}
else
{
from.SendLocalizedMessage(1155663); // Nothign Happens
}
}
public override void OnCancel(Mobile from)
{
}
}
public TrapDoor(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
writer.Write(Keyword);
writer.Write(Destination);
writer.Write(DestinationMap);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
Keyword = reader.ReadString();
Destination = reader.ReadPoint3D();
DestinationMap = reader.ReadMap();
Hide();
}
}
}

View File

@@ -0,0 +1,151 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Gumps;
using Server.Items;
using Server.Mobiles;
using Server.Engines.Quests;
namespace Server.Engines.Khaldun
{
public class Cryptologist : BaseVendor
{
public static Cryptologist TramInstance { get; set; }
protected readonly List<SBInfo> m_SBInfos = new List<SBInfo>();
protected override List<SBInfo> SBInfos { get { return m_SBInfos; } }
public override bool IsActiveVendor { get { return false; } }
public override void InitSBInfo()
{
}
public static void Initialize()
{
if (Core.TOL)
{
if (TramInstance == null)
{
TramInstance = new Cryptologist();
TramInstance.MoveToWorld(new Point3D(4325, 949, 10), Map.Trammel);
TramInstance.Direction = Direction.South;
}
}
}
public Cryptologist()
: base("the Cryptologist")
{
}
public override void InitBody()
{
Name = NameList.RandomName("male");
InitStats(100, 100, 25);
Female = false;
CantWalk = true;
Race = Race.Human;
Hue = Race.RandomSkinHue();
HairHue = Race.RandomHairHue();
FacialHairHue = Race.RandomHairHue();
HairItemID = Race.RandomHair(false);
FacialHairItemID = Race.RandomFacialHair(false);
}
public override void InitOutfit()
{
AddItem(new Backpack());
SetWearable(new HakamaShita());
SetWearable(new ShortPants(), 1157);
SetWearable(new Obi(), 1157);
SetWearable(new Sandals());
}
public override void OnDoubleClick(Mobile m)
{
if (m is PlayerMobile && InRange(m.Location, 5))
{
GoingGumshoeQuest3 quest = QuestHelper.GetQuest<GoingGumshoeQuest3>((PlayerMobile)m);
if (quest != null)
{
if (!quest.FoundCipherBook)
{
m.SendLocalizedMessage(1158620, null, 0x23); /*You've spoken to the Cryptologist who has agreed to help you if you acquire the Cipher Text.*/
m.SendGump(new InternalGump(1158619));
}
else
{
m.SendLocalizedMessage(1158621, null, 0x23); /*The Cytologist has successfully begun decrypting the copies of the books you found. He informs you he
* will send them to Headquarters when he is finished. Return to Inspector Jasper to follow up on the case.*/
m.SendGump(new InternalGump(1158624));
m.PlaySound(quest.UpdateSound);
quest.BegunDecrypting = true;
}
}
else
{
SayTo(m, 1073989, 1154);
Effects.PlaySound(Location, Map, 0x441);
}
}
}
private class InternalGump : Gump
{
public InternalGump(int cliloc)
: base(50, 50)
{
AddBackground(0, 0, 720, 285, 9300);
AddImage(0, 0, 1744);
AddHtmlLocalized(300, 25, 408, 250, cliloc, false, false);
/*Shhh! Can't you see the students are...*the Cryptologist pauses as you explain the reason for your visit*
* Oh, Inspector Jasper sent you did he? Well my service to the RBG is something I hold in -very- high regard.
* What can I assist you with? *You show the Cryptologist your copies of the encrypted notes* Yes...yes...a
* masterful cipher if I have ever seen one, but one that can easily be cracked! The only thing we need is the
* cipher text - but just as it were a number of our texts have been hidden by some students having a bit of
* fun with the season. I've already searched the dormitories out back, but I'm certain it's somewhere in the
* Lycaeum bookcases, if you find it, I'll be happy to assist you in decrypting the texts. */
// or //
/*Wait till I catch the students who did this! Well, I must thank you for recovering this text, it's very useful
* in my daily studies. No matter, I will begin decryption of the copies of these clues you gave me. I'll send a
* courier to headquarters when I am through. Thank you again for your assistance! */
}
}
public Cryptologist(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
if (Map == Map.Trammel)
{
TramInstance = this;
}
if (!Core.TOL)
Delete();
}
}
}

View File

@@ -0,0 +1,138 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Gumps;
using Server.Items;
using Server.Mobiles;
using Server.Engines.Quests;
namespace Server.Engines.Khaldun
{
public class GraveDigger : BaseVendor
{
protected readonly List<SBInfo> m_SBInfos = new List<SBInfo>();
protected override List<SBInfo> SBInfos { get { return m_SBInfos; } }
public override bool IsActiveVendor { get { return false; } }
public override void InitSBInfo()
{
}
public static GraveDigger TramInstance { get; set; }
//public static GraveDigger FelInstance { get; set; }
public static void Initialize()
{
if (Core.TOL)
{
if (TramInstance == null)
{
TramInstance = new GraveDigger();
TramInstance.MoveToWorld(new Point3D(1382, 1447, 10), Map.Trammel);
TramInstance.Direction = Direction.South;
}
}
}
public GraveDigger()
: base("the Grave Digger")
{
}
public override void InitBody()
{
Name = NameList.RandomName("male");
InitStats(100, 100, 25);
Female = false;
CantWalk = true;
Race = Race.Human;
Hue = Race.RandomSkinHue();
HairHue = Race.RandomHairHue();
FacialHairHue = Race.RandomHairHue();
HairItemID = 0x203C;
FacialHairItemID = 0x203E;
}
public override void InitOutfit()
{
AddItem(new Backpack());
SetWearable(new Surcoat(), 1634);
SetWearable(new Kilt(), 946);
SetWearable(new FancyShirt(), 1411);
SetWearable(new ThighBoots(), 2013);
SetWearable(new GoldBracelet());
SetWearable(new GoldRing());
}
public override void OnDoubleClick(Mobile m)
{
if (m is PlayerMobile && InRange(m.Location, 5))
{
GoingGumshoeQuest2 quest = QuestHelper.GetQuest<GoingGumshoeQuest2>((PlayerMobile)m);
if (quest != null)
{
m.SendLocalizedMessage(1158606, null, 0x23); /* You've spoken to the Grave Digger and have paid your respects to those who
perished in the fight against the titans. How someone could defile a grave
stone, you have no idea. You decide to take a closer look... */
m.PlaySound(quest.UpdateSound);
m.SendGump(new InternalGump());
}
}
}
private class InternalGump : Gump
{
public InternalGump()
: base(50, 50)
{
AddBackground(0, 0, 720, 285, 9300);
AddImage(0, 0, 1743);
AddHtmlLocalized(300, 25, 408, 250, 1158570, false, false);
/*Solemn job you know, but someone has to do it. Been pretty busy since the invasions, hardly a day goes by we don't
* have the kin of someone who embraced Sacrifice and gave themselves in defense of the realm against the Titans.
* Ah well, makes me feel good knowing me shovel gives em a good final resting place. Worst part ya know though -
* plenty of people been in and out of the cemetery for sure, but I don't know why they insist on messing up the
* headstones!? To think, some people have no Shame!*/
}
}
public GraveDigger(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
if (Map == Map.Trammel)
{
TramInstance = this;
}
/*else if (Map == Map.Felucca)
{
FelInstance = this;
}*/
if (!Core.TOL)
Delete();
}
}
}

View File

@@ -0,0 +1,213 @@
using System;
using Server;
using Server.Gumps;
using Server.Items;
using Server.Mobiles;
using Server.Engines.Quests;
namespace Server.Engines.Khaldun
{
public class InspectorJasper : MondainQuester
{
public override Type[] Quests { get { return null; } }
public static InspectorJasper TramInstance { get; set; }
public static void Initialize()
{
if (Core.TOL)
{
if (TramInstance == null)
{
TramInstance = new InspectorJasper();
TramInstance.MoveToWorld(new Point3D(1675, 1584, 7), Map.Trammel);
TramInstance.Direction = Direction.South;
}
}
}
public InspectorJasper()
: base("Jasper", "the Inspector")
{
}
public override void InitBody()
{
InitStats(100, 100, 25);
Female = false;
CantWalk = true;
Race = Race.Elf;
Hue = 33770;
HairItemID = 0x2FCF;
HairHue = Race.RandomHairHue();
}
public override void InitOutfit()
{
AddItem(new Backpack());
SetWearable(new LongPants(), 1156);
SetWearable(new FancyShirt());
SetWearable(new Epaulette(), 1156);
SetWearable(new BodySash(), 1175);
SetWearable(new Obi(), 1156);
SetWearable(new Shoes(), 1910);
}
public override void OnDoubleClick(Mobile m)
{
if (m is PlayerMobile && m.InRange(Location, 5))
{
GoingGumshoeQuest quest = QuestHelper.GetQuest<GoingGumshoeQuest>((PlayerMobile)m);
if (quest != null && quest.Completed)
{
quest.GiveRewards();
BaseQuest newquest = QuestHelper.RandomQuest((PlayerMobile)m, new Type[] { typeof(GoingGumshoeQuest2) }, this);
if (newquest != null)
m.SendGump(new MondainQuestGump(newquest));
}
else
{
GoingGumshoeQuest2 quest2 = QuestHelper.GetQuest<GoingGumshoeQuest2>((PlayerMobile)m);
if (quest2 != null)
{
if (quest2.IsComplete)
{
quest2.Objectives[0].CurProgress++;
quest2.GiveRewards(); // TODO: Does this quest end here?
BaseQuest newquest = QuestHelper.RandomQuest((PlayerMobile)m, new Type[] { typeof(GoingGumshoeQuest3) }, this);
if (newquest != null)
m.SendGump(new MondainQuestGump(newquest));
}
else
{
m.SendGump(new MondainQuestGump(quest2, MondainQuestGump.Section.InProgress, false));
quest2.InProgress();
}
}
else
{
GoingGumshoeQuest3 quest3 = QuestHelper.GetQuest<GoingGumshoeQuest3>((PlayerMobile)m);
if (quest3 != null)
{
if (quest3.IsComplete)
{
quest3.Objectives[0].CurProgress++;
quest3.GiveRewards(); // TODO: Does this quest end here?
BaseQuest newquest = QuestHelper.RandomQuest((PlayerMobile)m, new Type[] { typeof(GoingGumshoeQuest4) }, this);
if (newquest != null)
m.SendGump(new MondainQuestGump(newquest));
}
else
{
m.SendGump(new MondainQuestGump(quest3, MondainQuestGump.Section.InProgress, false));
quest3.InProgress();
}
}
else
{
GoingGumshoeQuest4 quest4 = QuestHelper.GetQuest<GoingGumshoeQuest4>((PlayerMobile)m);
if (quest4 != null && !quest4.IsComplete)
{
m.SendGump(new MondainQuestGump(quest4, MondainQuestGump.Section.InProgress, false));
quest4.InProgress();
}
else if (quest4 == null)
{
SayTo(m, 1080107); // I'm sorry, I have nothing for you at this time.
}
}
}
}
}
}
public override void OnMovement(Mobile m, Point3D oldLocation)
{
if (m is PlayerMobile && InLOS(m) && InRange(m.Location, 3) && !InRange(oldLocation, 3))
{
var quest = QuestHelper.GetQuest<GoingGumshoeQuest>((PlayerMobile)m);
if (quest != null)
{
quest.Objectives[0].CurProgress++;
quest.OnCompleted();
}
else
{
var quest2 = QuestHelper.GetQuest<GoingGumshoeQuest4>((PlayerMobile)m);
if (quest2 != null && quest2.IsComplete)
{
quest2.Objectives[0].CurProgress++;
m.SendGump(new InternalGump());
m.PlaySound(quest2.CompleteSound);
quest2.GiveRewards();
}
}
}
}
private class InternalGump : Gump
{
public InternalGump()
: base(50, 50)
{
AddBackground(0, 0, 400, 600, 9300);
AddImage(58, 30, 1745);
AddHtmlLocalized(0, 340, 400, 20, 1154645, "#1158625", 0x0, false, false); // It all comes together...
AddHtmlLocalized(5, 365, 390, 200, 1158626, BaseGump.C32216(0x0D0D0D), false, true);
/**You approach Inspector Jasper and relay to him what Sage Humbolt told you...he remains expressionless*
* This is much more sinister than any of us could have ever imagined. I had little doubt your investigatory
* skills would yield anything but a major revelation - but this? Who could have thought. I have dispatched
* a team to the location Sage Humbolt spoke of. It is up to everyone now to prevent this coming evil. Here
* you go, you've earned this. Wear this title proudly. This official credential identifies you as a member
* of the RBG Detective Branch and will allow you past the guards at the site Sage Humbolt spoke of near
* 57o 7'S, 5o 20'E in the Lost Lands.*/
}
}
public InspectorJasper(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
if (Map == Map.Trammel)
{
TramInstance = this;
}
if (!Core.TOL)
Delete();
}
}
}

View File

@@ -0,0 +1,151 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Gumps;
using Server.Items;
using Server.Mobiles;
using Server.Engines.Quests;
namespace Server.Engines.Khaldun
{
public class SageHumbolt : BaseVendor
{
public static SageHumbolt TramInstance { get; set; }
protected readonly List<SBInfo> m_SBInfos = new List<SBInfo>();
protected override List<SBInfo> SBInfos { get { return m_SBInfos; } }
public override bool IsActiveVendor { get { return false; } }
public override void InitSBInfo()
{
}
public static void Initialize()
{
if (Core.TOL)
{
if (TramInstance == null)
{
TramInstance = new SageHumbolt();
TramInstance.MoveToWorld(new Point3D(5808, 3270, -15), Map.Trammel);
TramInstance.Direction = Direction.North;
}
}
}
public SageHumbolt()
: base("the Ghost")
{
IsDeadPet = true;
}
public override void InitBody()
{
Name = "Sage Humbolt";
InitStats(100, 100, 25);
Female = false;
CantWalk = true;
Race = Race.Human;
Hue = Race.RandomSkinHue();
}
public override void InitOutfit()
{
AddItem(new Backpack());
var robe = new DeathRobe();
robe.ItemID = 9863;
SetWearable(robe);
}
public bool OnSpiritSpeak(Mobile m)
{
var pm = m as PlayerMobile;
if (pm != null)
{
var quest = QuestHelper.GetQuest<GoingGumshoeQuest4>(pm);
if (quest != null && !quest.IsComplete)
{
/*You have successfully found Sage Humbolt who has opened you eyes to the entire conspiracy, and the danger that looms ahead
* if no steps are taken to alter the current course of events. Return to Inspector Jasper to report your findings.*/
m.SendLocalizedMessage(1158636, null, 0x23);
m.SendGump(new InternalGump());
m.PlaySound(quest.UpdateSound);
quest.IsComplete = true;
return true;
}
}
return false;
}
private class InternalGump : Gump
{
public InternalGump()
: base(50, 50)
{
AddBackground(0, 0, 400, 600, 9300);
AddImage(58, 30, 1746);
AddHtmlLocalized(0, 340, 400, 20, 1154645, "#1158623", 0x0, false, false); // The Prophecy
AddHtmlLocalized(5, 365, 390, 200, 1158622, BaseGump.C32216(0x0D0D0D), false, true);
/**The ghostly figure looks at you with disappointment* You've brought the cheese haven't you? Gah,
* I can never find it! *the ghost goes back to waving its hands through the barrels* You explain
* who you are, and the circumstances that have lead you to this moment. With each word the ghost
* becomes increasingly alarmed, yet an expression of expectation and satisfaction is apparent from
* their reaction. The ghost nods and begins to speak in a tongue you can understand,<br><br> "That's
* right. I am Sage Humbolt, or I was. What you speak of is especially concerning. The events you
* describe - the invasion by otherworldly cultist, the titans, all of it - it was something foretold
* long ago. But these most recent revelations, I was hopeful that, like most prophecies, this was a
* bit of embellishment by sages through the millenia. Alas, it seems this prophecy has come full
* circle.<br><br>Long ago, a great warrior named Khal Ankur lead a cult devoted to death and sacrifice
* . Like most zealots of such a twisted dogma, Khal Ankur met his end and was sealed inside a tomb deep
* in the Lost Lands. Not until four explorers uncovered the tomb did we even know for sure it existed.
* The prophecy tells of a fallen star that would allow Khal Ankur to rise again and lead an army of
* zealots against those who imprisoned him. With the strength of this fallen star Khal Ankur would be
* impossible to kill, save for with the very power the fallen star gives to Khal Ankur. You must never
* allow Khal Ankur to rise again, lest the cultists may use their power to recall the Titans to this
* world! The fallen star is rich with a material called Caddellite, which gives Khal Ankur unmatched
* power. I hope you know a good tinker, as Caddellite is a fiercely strong material that is otherwise
* impossible to harvest. With Caddellite infused resources you will be able to supply an army of the
* willing with weapons, arcana, and provisions to dispatch this threat once and for all. Go now, there
* is little time to lose. Now I've got to get back to my cheese, what a new and exciting place Papua is... */
}
}
public SageHumbolt(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
if (Map == Map.Trammel)
{
TramInstance = this;
}
if (!Core.TOL)
Delete();
}
}
}