Reorganizes Project (#41)
This commit is contained in:
parent
08bf44af9a
commit
3614a66aee
3499 changed files with 79 additions and 55 deletions
|
|
@ -0,0 +1,55 @@
|
|||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Doom
|
||||
{
|
||||
public class AcceptConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1050027;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
System.AddObjective(new CollectBonesObjective());
|
||||
}
|
||||
}
|
||||
|
||||
public class VanquishDaemonConversation : QuestConversation
|
||||
{
|
||||
public override object Message => 1050021;
|
||||
|
||||
public override void OnRead()
|
||||
{
|
||||
Victoria victoria = ((TheSummoningQuest)System).Victoria;
|
||||
|
||||
if (victoria == null)
|
||||
{
|
||||
System.From.SendMessage("Internal error: unable to find Victoria. Quest unable to continue.");
|
||||
System.Cancel();
|
||||
}
|
||||
else
|
||||
{
|
||||
SummoningAltar altar = victoria.Altar;
|
||||
|
||||
if (altar == null)
|
||||
{
|
||||
System.From.SendMessage("Internal error: unable to find summoning altar. Quest unable to continue.");
|
||||
System.Cancel();
|
||||
}
|
||||
else if (altar.Daemon == null || !altar.Daemon.Alive)
|
||||
{
|
||||
BoneDemon daemon = new BoneDemon();
|
||||
|
||||
daemon.MoveToWorld(altar.Location, altar.Map);
|
||||
altar.Daemon = daemon;
|
||||
|
||||
System.AddObjective(new VanquishDaemonObjective(daemon));
|
||||
}
|
||||
else
|
||||
{
|
||||
victoria.SayTo(System.From, "The devourer has already been summoned.");
|
||||
|
||||
((TheSummoningQuest)System).WaitForSummon = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
using System;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.Quests.Doom
|
||||
{
|
||||
public class BellOfTheDead : Item
|
||||
{
|
||||
[Constructible]
|
||||
public BellOfTheDead() : base(0x91A)
|
||||
{
|
||||
Hue = 0x835;
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public BellOfTheDead(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1050018; // bell of the dead
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)]
|
||||
public Chyloth Chyloth{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)]
|
||||
public SkeletalDragon Dragon{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)]
|
||||
public bool Summoning{ get; set; }
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from.InRange(GetWorldLocation(), 2))
|
||||
BeginSummon(from);
|
||||
else
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
|
||||
}
|
||||
|
||||
public virtual void BeginSummon(Mobile from)
|
||||
{
|
||||
if (Chyloth?.Deleted == false)
|
||||
{
|
||||
from.SendLocalizedMessage(
|
||||
1050010); // The ferry man has already been summoned. There is no need to ring for him again.
|
||||
}
|
||||
else if (Dragon?.Deleted == false)
|
||||
{
|
||||
from.SendLocalizedMessage(
|
||||
1050017); // The ferryman has recently been summoned already. You decide against ringing the bell again so soon.
|
||||
}
|
||||
else if (!Summoning)
|
||||
{
|
||||
Summoning = true;
|
||||
|
||||
Effects.PlaySound(GetWorldLocation(), Map, 0x100);
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(8.0), () => EndSummon(from));
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void EndSummon(Mobile from)
|
||||
{
|
||||
if (Chyloth?.Deleted == false)
|
||||
{
|
||||
from.SendLocalizedMessage(
|
||||
1050010); // The ferry man has already been summoned. There is no need to ring for him again.
|
||||
}
|
||||
else if (Dragon?.Deleted == false)
|
||||
{
|
||||
from.SendLocalizedMessage(
|
||||
1050017); // The ferryman has recently been summoned already. You decide against ringing the bell again so soon.
|
||||
}
|
||||
else if (Summoning)
|
||||
{
|
||||
Summoning = false;
|
||||
|
||||
Point3D loc = GetWorldLocation();
|
||||
|
||||
loc.Z -= 16;
|
||||
|
||||
Effects.SendLocationParticles(EffectItem.Create(loc, Map, EffectItem.DefaultDuration), 0x3728, 10, 10, 0, 0,
|
||||
2023, 0);
|
||||
Effects.PlaySound(loc, Map, 0x1FE);
|
||||
|
||||
Chyloth = new Chyloth { Direction = (Direction)(7 & (4 + (int)from.GetDirectionTo(loc))) };
|
||||
|
||||
Chyloth.MoveToWorld(loc, Map);
|
||||
|
||||
Chyloth.Bell = this;
|
||||
Chyloth.AngryAt = from;
|
||||
Chyloth.BeginGiveWarning();
|
||||
Chyloth.BeginRemove(TimeSpan.FromSeconds(40.0));
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write(Chyloth);
|
||||
writer.Write(Dragon);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Chyloth = reader.ReadMobile() as Chyloth;
|
||||
Dragon = reader.ReadMobile() as SkeletalDragon;
|
||||
|
||||
Chyloth?.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
namespace Server.Engines.Quests.Doom
|
||||
{
|
||||
public class ChylothShroud : Item
|
||||
{
|
||||
[Constructible]
|
||||
public ChylothShroud() : base(0x204E)
|
||||
{
|
||||
Hue = 0x846;
|
||||
Layer = Layer.OuterTorso;
|
||||
}
|
||||
|
||||
public ChylothShroud(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
using Server.Items;
|
||||
|
||||
namespace Server.Engines.Quests.Doom
|
||||
{
|
||||
public class ChylothStaff : BlackStaff
|
||||
{
|
||||
[Constructible]
|
||||
public ChylothStaff()
|
||||
{
|
||||
Hue = 0x482;
|
||||
}
|
||||
|
||||
public ChylothStaff(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1041111; // a magic staff
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
namespace Server.Engines.Quests.Doom
|
||||
{
|
||||
public class GoldenSkull : Item
|
||||
{
|
||||
[Constructible]
|
||||
public GoldenSkull() : base(Utility.Random(0x1AE2, 3))
|
||||
{
|
||||
Weight = 1.0;
|
||||
Hue = 0x8A5;
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public GoldenSkull(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1061619; // a golden skull
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
namespace Server.Engines.Quests.Doom
|
||||
{
|
||||
public class GrandGrimoire : Item
|
||||
{
|
||||
[Constructible]
|
||||
public GrandGrimoire() : base(0xEFA)
|
||||
{
|
||||
Weight = 1.0;
|
||||
Hue = 0x835;
|
||||
Layer = Layer.OneHanded;
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public GrandGrimoire(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1060801; // The Grand Grimoire
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Doom
|
||||
{
|
||||
public class SummoningAltar : AbbatoirAddon
|
||||
{
|
||||
private BoneDemon m_Daemon;
|
||||
|
||||
[Constructible]
|
||||
public SummoningAltar()
|
||||
{
|
||||
}
|
||||
|
||||
public SummoningAltar(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public BoneDemon Daemon
|
||||
{
|
||||
get => m_Daemon;
|
||||
set
|
||||
{
|
||||
m_Daemon = value;
|
||||
CheckDaemon();
|
||||
}
|
||||
}
|
||||
|
||||
public void CheckDaemon()
|
||||
{
|
||||
if (m_Daemon == null || !m_Daemon.Alive)
|
||||
{
|
||||
m_Daemon = null;
|
||||
Hue = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Hue = 0x66D;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write(m_Daemon);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
m_Daemon = reader.ReadMobile() as BoneDemon;
|
||||
|
||||
CheckDaemon();
|
||||
}
|
||||
}
|
||||
}
|
||||
308
Projects/Scripts/Engines/Quests/The Summoning/Mobiles/Chyloth.cs
Normal file
308
Projects/Scripts/Engines/Quests/The Summoning/Mobiles/Chyloth.cs
Normal file
|
|
@ -0,0 +1,308 @@
|
|||
using System;
|
||||
using Server.Engines.PartySystem;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.Quests.Doom
|
||||
{
|
||||
public class Chyloth : BaseQuester
|
||||
{
|
||||
private static int[] m_Offsets =
|
||||
{
|
||||
-1, -1,
|
||||
-1, 0,
|
||||
-1, 1,
|
||||
0, -1,
|
||||
0, 1,
|
||||
1, -1,
|
||||
1, 0,
|
||||
1, 1
|
||||
};
|
||||
|
||||
[Constructible]
|
||||
public Chyloth() : base("the Ferryman")
|
||||
{
|
||||
}
|
||||
|
||||
public Chyloth(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "Chyloth";
|
||||
|
||||
public BellOfTheDead Bell{ get; set; }
|
||||
|
||||
public Mobile AngryAt{ get; set; }
|
||||
|
||||
public override void InitBody()
|
||||
{
|
||||
InitStats(100, 100, 25);
|
||||
|
||||
Hue = 0x8455;
|
||||
Body = 0x190;
|
||||
}
|
||||
|
||||
public override void InitOutfit()
|
||||
{
|
||||
EquipItem(new ChylothShroud());
|
||||
EquipItem(new ChylothStaff());
|
||||
}
|
||||
|
||||
public virtual void BeginGiveWarning()
|
||||
{
|
||||
if (Deleted || AngryAt == null)
|
||||
return;
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(4.0), EndGiveWarning);
|
||||
}
|
||||
|
||||
public virtual void EndGiveWarning()
|
||||
{
|
||||
if (Deleted || AngryAt == null)
|
||||
return;
|
||||
|
||||
PublicOverheadMessage(MessageType.Regular, 0x3B2, 1050013,
|
||||
AngryAt.Name); // You have summoned me in vain ~1_NAME~! Only the dead may cross!
|
||||
PublicOverheadMessage(MessageType.Regular, 0x3B2, 1050014); // Why have you disturbed me, mortal?!?
|
||||
|
||||
BeginSummonDragon();
|
||||
}
|
||||
|
||||
public virtual void BeginSummonDragon()
|
||||
{
|
||||
if (Deleted || AngryAt == null)
|
||||
return;
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(30.0), EndSummonDragon);
|
||||
}
|
||||
|
||||
public virtual void BeginRemove(TimeSpan delay)
|
||||
{
|
||||
Timer.DelayCall(delay, EndRemove);
|
||||
}
|
||||
|
||||
public virtual void EndRemove()
|
||||
{
|
||||
if (Deleted)
|
||||
return;
|
||||
|
||||
Point3D loc = Location;
|
||||
Map map = Map;
|
||||
|
||||
Effects.SendLocationParticles(EffectItem.Create(loc, map, EffectItem.DefaultDuration), 0x3728, 10, 10, 0, 0,
|
||||
2023, 0);
|
||||
Effects.PlaySound(loc, map, 0x1FE);
|
||||
|
||||
Delete();
|
||||
}
|
||||
|
||||
public virtual void EndSummonDragon()
|
||||
{
|
||||
if (Deleted || AngryAt == null)
|
||||
return;
|
||||
|
||||
Map map = AngryAt.Map;
|
||||
|
||||
if (map == null)
|
||||
return;
|
||||
|
||||
if (!AngryAt.Region.IsPartOf("Doom"))
|
||||
return;
|
||||
|
||||
PublicOverheadMessage(MessageType.Regular, 0x3B2, 1050015); // Feel the wrath of my legions!!!
|
||||
PublicOverheadMessage(MessageType.Regular, 0x3B2, false, "MUHAHAHAHA HAHAH HAHA"); // A wee bit crazy, aren't we?
|
||||
|
||||
SkeletalDragon dragon = new SkeletalDragon();
|
||||
|
||||
int offset = Utility.Random(8) * 2;
|
||||
|
||||
bool foundLoc = false;
|
||||
|
||||
for (int i = 0; i < m_Offsets.Length; i += 2)
|
||||
{
|
||||
int x = AngryAt.X + m_Offsets[(offset + i) % m_Offsets.Length];
|
||||
int y = AngryAt.Y + m_Offsets[(offset + i + 1) % m_Offsets.Length];
|
||||
|
||||
if (map.CanSpawnMobile(x, y, AngryAt.Z))
|
||||
{
|
||||
dragon.MoveToWorld(new Point3D(x, y, AngryAt.Z), map);
|
||||
foundLoc = true;
|
||||
break;
|
||||
}
|
||||
|
||||
int z = map.GetAverageZ(x, y);
|
||||
|
||||
if (map.CanSpawnMobile(x, y, z))
|
||||
{
|
||||
dragon.MoveToWorld(new Point3D(x, y, z), map);
|
||||
foundLoc = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundLoc)
|
||||
dragon.MoveToWorld(AngryAt.Location, map);
|
||||
|
||||
dragon.Combatant = AngryAt;
|
||||
|
||||
if (Bell != null)
|
||||
Bell.Dragon = dragon;
|
||||
}
|
||||
|
||||
public static void TeleportToFerry(Mobile from)
|
||||
{
|
||||
Point3D loc = new Point3D(408, 251, 2);
|
||||
Map map = Map.Malas;
|
||||
|
||||
Effects.SendLocationParticles(EffectItem.Create(loc, map, EffectItem.DefaultDuration), 0x3728, 10, 10, 0, 0,
|
||||
2023, 0);
|
||||
Effects.PlaySound(loc, map, 0x1FE);
|
||||
|
||||
TeleportPets(from, loc, map);
|
||||
|
||||
from.MoveToWorld(loc, map);
|
||||
}
|
||||
|
||||
public override bool OnDragDrop(Mobile from, Item dropped)
|
||||
{
|
||||
if (dropped is GoldenSkull)
|
||||
{
|
||||
dropped.Delete();
|
||||
|
||||
PublicOverheadMessage(MessageType.Regular, 0x3B2, 1050046,
|
||||
from.Name); // Very well, ~1_NAME~, I accept your token. You may cross.
|
||||
BeginRemove(TimeSpan.FromSeconds(4.0));
|
||||
|
||||
Party p = PartySystem.Party.Get(from);
|
||||
|
||||
for (int i = 0; i < p?.Members.Count; ++i)
|
||||
{
|
||||
PartyMemberInfo pmi = p.Members[i];
|
||||
Mobile member = pmi.Mobile;
|
||||
|
||||
if (member != from && member.Map == Map.Malas && member.Region.IsPartOf("Doom"))
|
||||
{
|
||||
if (AngryAt == member)
|
||||
AngryAt = null;
|
||||
|
||||
member.CloseGump<ChylothPartyGump>();
|
||||
member.SendGump(new ChylothPartyGump(from, member));
|
||||
}
|
||||
}
|
||||
|
||||
if (AngryAt == from)
|
||||
AngryAt = null;
|
||||
|
||||
TeleportToFerry(from);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.OnDragDrop(from, dropped);
|
||||
}
|
||||
|
||||
public override bool CanTalkTo(PlayerMobile to)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnTalk(PlayerMobile player, bool contextMenu)
|
||||
{
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
public class ChylothPartyGump : Gump
|
||||
{
|
||||
private Mobile m_Leader;
|
||||
private Mobile m_Member;
|
||||
|
||||
public ChylothPartyGump(Mobile leader, Mobile member) : base(150, 50)
|
||||
{
|
||||
m_Leader = leader;
|
||||
m_Member = member;
|
||||
|
||||
Closable = false;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
AddImage(0, 0, 3600);
|
||||
|
||||
AddImageTiled(0, 14, 15, 200, 3603);
|
||||
AddImageTiled(380, 14, 14, 200, 3605);
|
||||
AddImage(0, 201, 3606);
|
||||
AddImageTiled(15, 201, 370, 16, 3607);
|
||||
AddImageTiled(15, 0, 370, 16, 3601);
|
||||
AddImage(380, 0, 3602);
|
||||
AddImage(380, 201, 3608);
|
||||
AddImageTiled(15, 15, 365, 190, 2624);
|
||||
|
||||
AddRadio(30, 140, 9727, 9730, true, 1);
|
||||
AddHtmlLocalized(65, 145, 300, 25, 1050050, 0x7FFF); // Yes, let's go!
|
||||
|
||||
AddRadio(30, 175, 9727, 9730, false, 0);
|
||||
AddHtmlLocalized(65, 178, 300, 25, 1050049, 0x7FFF); // No thanks, I'd rather stay here.
|
||||
|
||||
AddHtmlLocalized(30, 20, 360, 35, 1050047, 0x7FFF); // Another player has paid Chyloth for your passage across lake Mortis:
|
||||
|
||||
AddHtmlLocalized(30, 105, 345, 40, 1050048, 0x5B2D); // Do you wish to accept their invitation at this time?
|
||||
|
||||
AddImage(65, 72, 5605);
|
||||
|
||||
AddImageTiled(80, 90, 200, 1, 9107);
|
||||
AddImageTiled(95, 92, 200, 1, 9157);
|
||||
|
||||
AddLabel(90, 70, 1645, leader.Name);
|
||||
|
||||
AddButton(290, 175, 247, 248, 2);
|
||||
|
||||
AddImageTiled(15, 14, 365, 1, 9107);
|
||||
AddImageTiled(380, 14, 1, 190, 9105);
|
||||
AddImageTiled(15, 205, 365, 1, 9107);
|
||||
AddImageTiled(15, 14, 1, 190, 9105);
|
||||
AddImageTiled(0, 0, 395, 1, 9157);
|
||||
AddImageTiled(394, 0, 1, 217, 9155);
|
||||
AddImageTiled(0, 216, 395, 1, 9157);
|
||||
AddImageTiled(0, 0, 1, 217, 9155);
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (info.ButtonID == 2 && info.IsSwitched(1))
|
||||
{
|
||||
if (m_Member.Region.IsPartOf("Doom"))
|
||||
{
|
||||
m_Leader.SendLocalizedMessage(1050054,
|
||||
m_Member.Name); // ~1_NAME~ has accepted your invitation to cross lake Mortis.
|
||||
|
||||
Chyloth.TeleportToFerry(m_Member);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Member.SendLocalizedMessage(1050051); // The invitation has been revoked.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Member.SendLocalizedMessage(1050052); // You have declined their invitation.
|
||||
m_Leader.SendLocalizedMessage(1050053,
|
||||
m_Member.Name); // ~1_NAME~ has declined your invitation to cross lake Mortis.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Doom
|
||||
{
|
||||
public class Victoria : BaseQuester
|
||||
{
|
||||
private const int AltarRange = 24;
|
||||
|
||||
private SummoningAltar m_Altar;
|
||||
|
||||
[Constructible]
|
||||
public Victoria() : base("the Sorceress")
|
||||
{
|
||||
}
|
||||
|
||||
public Victoria(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int TalkNumber => 6159; // Ask about Chyloth
|
||||
public override string DefaultName => "Victoria";
|
||||
public override bool ClickTitle => true;
|
||||
public override bool IsActiveVendor => true;
|
||||
public override bool DisallowAllMoves => false;
|
||||
|
||||
public SummoningAltar Altar
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_Altar?.Deleted != false || m_Altar.Map != Map ||
|
||||
!Utility.InRange(m_Altar.Location, Location, AltarRange))
|
||||
foreach (Item item in GetItemsInRange(AltarRange))
|
||||
if (item is SummoningAltar altar)
|
||||
{
|
||||
m_Altar = altar;
|
||||
break;
|
||||
}
|
||||
|
||||
return m_Altar;
|
||||
}
|
||||
}
|
||||
|
||||
public override void InitSBInfo()
|
||||
{
|
||||
m_SBInfos.Add(new SBMage());
|
||||
}
|
||||
|
||||
public override void InitBody()
|
||||
{
|
||||
InitStats(100, 100, 25);
|
||||
|
||||
Female = true;
|
||||
Hue = 0x8835;
|
||||
Body = 0x191;
|
||||
}
|
||||
|
||||
public override void InitOutfit()
|
||||
{
|
||||
EquipItem(new GrandGrimoire());
|
||||
|
||||
EquipItem(SetHue(new Sandals(), 0x455));
|
||||
EquipItem(SetHue(new SkullCap(), 0x455));
|
||||
EquipItem(SetHue(new PlainDress(), 0x455));
|
||||
|
||||
HairItemID = 0x203C;
|
||||
HairHue = 0x482;
|
||||
}
|
||||
|
||||
public override bool OnDragDrop(Mobile from, Item dropped)
|
||||
{
|
||||
if (from is PlayerMobile player)
|
||||
{
|
||||
QuestSystem qs = player.Quest;
|
||||
|
||||
if (qs is TheSummoningQuest)
|
||||
if (dropped is DaemonBone bones)
|
||||
{
|
||||
QuestObjective obj = qs.FindObjective<CollectBonesObjective>();
|
||||
|
||||
if (obj?.Completed == false)
|
||||
{
|
||||
int need = obj.MaxProgress - obj.CurProgress;
|
||||
|
||||
if (bones.Amount < need)
|
||||
{
|
||||
obj.CurProgress += bones.Amount;
|
||||
bones.Delete();
|
||||
|
||||
qs.ShowQuestLogUpdated();
|
||||
}
|
||||
else
|
||||
{
|
||||
obj.Complete();
|
||||
bones.Consume(need);
|
||||
|
||||
if (!bones.Deleted)
|
||||
SayTo(from,
|
||||
1050038); // You have already given me all the Daemon bones necessary to weave the spell. Keep these for a later time.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Accurate?
|
||||
SayTo(from,
|
||||
1050038); // You have already given me all the Daemon bones necessary to weave the spell. Keep these for a later time.
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return base.OnDragDrop(from, dropped);
|
||||
}
|
||||
|
||||
public override bool CanTalkTo(PlayerMobile to)
|
||||
{
|
||||
return to.Quest == null && QuestSystem.CanOfferQuest(to, typeof(TheSummoningQuest));
|
||||
}
|
||||
|
||||
public override void OnTalk(PlayerMobile player, bool contextMenu)
|
||||
{
|
||||
QuestSystem qs = player.Quest;
|
||||
|
||||
if (qs == null && QuestSystem.CanOfferQuest(player, typeof(TheSummoningQuest)))
|
||||
{
|
||||
Direction = GetDirectionTo(player);
|
||||
new TheSummoningQuest(this, player).SendOffer();
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
164
Projects/Scripts/Engines/Quests/The Summoning/Objectives.cs
Normal file
164
Projects/Scripts/Engines/Quests/The Summoning/Objectives.cs
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
using System.Collections.Generic;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Doom
|
||||
{
|
||||
public class CollectBonesObjective : QuestObjective
|
||||
{
|
||||
public override object Message => 1050026;
|
||||
|
||||
public override int MaxProgress => 1000;
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
Victoria victoria = ((TheSummoningQuest)System).Victoria;
|
||||
|
||||
if (victoria == null)
|
||||
{
|
||||
System.From.SendMessage("Internal error: unable to find Victoria. Quest unable to continue.");
|
||||
System.Cancel();
|
||||
}
|
||||
else
|
||||
{
|
||||
SummoningAltar altar = victoria.Altar;
|
||||
|
||||
if (altar == null)
|
||||
{
|
||||
System.From.SendMessage("Internal error: unable to find summoning altar. Quest unable to continue.");
|
||||
System.Cancel();
|
||||
}
|
||||
else if (altar.Daemon == null || !altar.Daemon.Alive)
|
||||
{
|
||||
System.AddConversation(new VanquishDaemonConversation());
|
||||
}
|
||||
else
|
||||
{
|
||||
victoria.SayTo(System.From,
|
||||
"The devourer has already been summoned. Return when the devourer has been slain and I will summon it for you.");
|
||||
((TheSummoningQuest)System).WaitForSummon = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void RenderMessage(BaseQuestGump gump)
|
||||
{
|
||||
if (CurProgress > 0 && CurProgress < MaxProgress)
|
||||
gump.AddHtmlObject(70, 130, 300, 100, 1050028, BaseQuestGump.Blue, false,
|
||||
false); // Victoria has accepted the Daemon bones, but the requirement is not yet met.
|
||||
else
|
||||
base.RenderMessage(gump);
|
||||
}
|
||||
|
||||
public override void RenderProgress(BaseQuestGump gump)
|
||||
{
|
||||
if (CurProgress > 0 && CurProgress < MaxProgress)
|
||||
{
|
||||
gump.AddHtmlObject(70, 260, 270, 100, 1050019, BaseQuestGump.Blue, false,
|
||||
false); // Number of bones collected:
|
||||
|
||||
gump.AddLabel(70, 280, 100, CurProgress.ToString());
|
||||
gump.AddLabel(100, 280, 100, "/");
|
||||
gump.AddLabel(130, 280, 100, MaxProgress.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
base.RenderProgress(gump);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class VanquishDaemonObjective : QuestObjective
|
||||
{
|
||||
private BoneDemon m_Daemon;
|
||||
|
||||
public VanquishDaemonObjective(BoneDemon daemon)
|
||||
{
|
||||
m_Daemon = daemon;
|
||||
}
|
||||
|
||||
// Serialization
|
||||
public VanquishDaemonObjective()
|
||||
{
|
||||
}
|
||||
|
||||
public Corpse CorpseWithSkull{ get; set; }
|
||||
|
||||
public override object Message => 1050037;
|
||||
|
||||
public override void CheckProgress()
|
||||
{
|
||||
if (m_Daemon == null || !m_Daemon.Alive)
|
||||
Complete();
|
||||
}
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
Victoria victoria = ((TheSummoningQuest)System).Victoria;
|
||||
|
||||
SummoningAltar altar = victoria?.Altar;
|
||||
|
||||
altar?.CheckDaemon();
|
||||
|
||||
PlayerMobile from = System.From;
|
||||
|
||||
if (!from.Alive)
|
||||
{
|
||||
from.SendLocalizedMessage(
|
||||
1050033); // The devourer lies dead, unfortunately so do you. You cannot claim your reward while dead. You will need to face him again.
|
||||
((TheSummoningQuest)System).WaitForSummon = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool hasRights = false;
|
||||
|
||||
if (m_Daemon != null)
|
||||
{
|
||||
List<DamageStore> lootingRights =
|
||||
BaseCreature.GetLootingRights(m_Daemon.DamageEntries, m_Daemon.HitsMax);
|
||||
|
||||
for (int i = 0; i < lootingRights.Count; ++i)
|
||||
{
|
||||
DamageStore ds = lootingRights[i];
|
||||
|
||||
if (ds.m_HasRight && ds.m_Mobile == from)
|
||||
{
|
||||
hasRights = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasRights)
|
||||
{
|
||||
from.SendLocalizedMessage(
|
||||
1050034); // The devourer lies dead. Unfortunately you did not sufficiently prove your worth in combating the devourer. Victoria shall summon another incarnation of the devourer to the circle of stones. Try again noble adventurer.
|
||||
((TheSummoningQuest)System).WaitForSummon = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1050035); // The devourer lies dead. Search his corpse to claim your prize!
|
||||
|
||||
if (m_Daemon != null)
|
||||
CorpseWithSkull = m_Daemon.Corpse as Corpse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void ChildDeserialize(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
m_Daemon = reader.ReadMobile() as BoneDemon;
|
||||
CorpseWithSkull = reader.ReadItem() as Corpse;
|
||||
}
|
||||
|
||||
public override void ChildSerialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.Write(m_Daemon);
|
||||
writer.Write(CorpseWithSkull);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
using System;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Quests.Doom
|
||||
{
|
||||
public class TheSummoningQuest : QuestSystem
|
||||
{
|
||||
private static Type[] m_TypeReferenceTable =
|
||||
{
|
||||
typeof(AcceptConversation),
|
||||
typeof(CollectBonesObjective),
|
||||
typeof(VanquishDaemonConversation),
|
||||
typeof(VanquishDaemonObjective)
|
||||
};
|
||||
|
||||
public TheSummoningQuest(Victoria victoria, PlayerMobile from) : base(from)
|
||||
{
|
||||
Victoria = victoria;
|
||||
}
|
||||
|
||||
public TheSummoningQuest()
|
||||
{
|
||||
}
|
||||
|
||||
public override Type[] TypeReferenceTable => m_TypeReferenceTable;
|
||||
|
||||
public Victoria Victoria{ get; private set; }
|
||||
|
||||
public bool WaitForSummon{ get; set; }
|
||||
|
||||
public override object Name => 1050025;
|
||||
|
||||
public override object OfferMessage => 1050020;
|
||||
|
||||
public override bool IsTutorial => false;
|
||||
public override TimeSpan RestartDelay => TimeSpan.Zero;
|
||||
public override int Picture => 0x15B5;
|
||||
|
||||
// NOTE: Quest not entirely OSI-accurate: some changes made to prevent numerous OSI bugs
|
||||
|
||||
public override void Slice()
|
||||
{
|
||||
if (WaitForSummon && Victoria != null)
|
||||
{
|
||||
SummoningAltar altar = Victoria.Altar;
|
||||
|
||||
if (altar != null && (altar.Daemon == null || !altar.Daemon.Alive))
|
||||
if (From.Map == Victoria.Map && From.InRange(Victoria, 8))
|
||||
{
|
||||
WaitForSummon = false;
|
||||
|
||||
AddConversation(new VanquishDaemonConversation());
|
||||
}
|
||||
}
|
||||
|
||||
base.Slice();
|
||||
}
|
||||
|
||||
public static int GetDaemonBonesFor(BaseCreature creature)
|
||||
{
|
||||
if (creature == null || creature.Controlled || creature.Summoned)
|
||||
return 0;
|
||||
|
||||
int fame = creature.Fame;
|
||||
|
||||
if (fame < 1500)
|
||||
return Utility.Dice(2, 5, -1);
|
||||
if (fame < 20000)
|
||||
return Utility.Dice(2, 4, 8);
|
||||
return 50;
|
||||
}
|
||||
|
||||
public override void Cancel()
|
||||
{
|
||||
base.Cancel();
|
||||
|
||||
QuestObjective obj = FindObjective<CollectBonesObjective>();
|
||||
|
||||
if (obj?.CurProgress > 0)
|
||||
{
|
||||
From.BankBox.DropItem(new DaemonBone(obj.CurProgress));
|
||||
|
||||
From.SendLocalizedMessage(
|
||||
1050030); // The Daemon bones that you have thus far given to Victoria have been returned to you.
|
||||
}
|
||||
}
|
||||
|
||||
public override void Accept()
|
||||
{
|
||||
base.Accept();
|
||||
|
||||
AddConversation(new AcceptConversation());
|
||||
}
|
||||
|
||||
public override void ChildDeserialize(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
Victoria = reader.ReadMobile() as Victoria;
|
||||
WaitForSummon = reader.ReadBool();
|
||||
}
|
||||
|
||||
public override void ChildSerialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.Write(Victoria);
|
||||
writer.Write(WaitForSummon);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue