457 lines
14 KiB
C#
457 lines
14 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
using Server.Mobiles;
|
|
using Server.Spells;
|
|
using Server.Items;
|
|
using Server.Network;
|
|
|
|
namespace Server.Engines.Quests.RitualQuest
|
|
{
|
|
public class CrystalLotusPuzzle : Item
|
|
{
|
|
public static CrystalLotusPuzzle Instance { get; set; }
|
|
|
|
public static void Initialize()
|
|
{
|
|
if (Core.SA && Instance == null)
|
|
{
|
|
Instance = new CrystalLotusPuzzle();
|
|
Instance.MoveToWorld(new Point3D(978, 2876, 37), Map.TerMur);
|
|
|
|
var s = new Static(0x283B);
|
|
s.Hue = 1152;
|
|
s.Name = "Pristine Crystal Lotus";
|
|
s.MoveToWorld(new Point3D(978, 2876, 47), Map.TerMur);
|
|
}
|
|
}
|
|
|
|
public List<PuzzleTile> Tiles { get; set; } = new List<PuzzleTile>();
|
|
public PuzzleTile[] Order { get; set; }
|
|
public bool Sequencing { get; set; }
|
|
public Region Region { get; set; }
|
|
|
|
public Dictionary<Mobile, PuzzleTile[]> PlayerOrder { get; set; }
|
|
|
|
public const int White = 1150; // hue of white tile
|
|
public const double WhiteLength = 1.2; // length tile stays white
|
|
public const double SequenceLength = 17.0;
|
|
|
|
public CrystalLotusPuzzle()
|
|
: base(0x1223)
|
|
{
|
|
Movable = false;
|
|
Visible = false;
|
|
LoadTiles();
|
|
|
|
RegisterRegion();
|
|
DoSequence();
|
|
}
|
|
|
|
private void DoSequence()
|
|
{
|
|
if (Region != null && Region.GetPlayerCount() == 0)
|
|
{
|
|
Timer.DelayCall(TimeSpan.FromSeconds(10), DoSequence);
|
|
return;
|
|
}
|
|
|
|
Sequencing = true;
|
|
|
|
var seqCount = Utility.RandomMinMax(4, 7);
|
|
Order = new PuzzleTile[seqCount];
|
|
|
|
PlayerOrder = new Dictionary<Mobile, PuzzleTile[]>();
|
|
|
|
for (int i = 0; i < seqCount; i++)
|
|
{
|
|
Order[i] = Tiles[Utility.Random(Tiles.Count)];
|
|
|
|
Timer.DelayCall<PuzzleTile, int>(TimeSpan.FromSeconds(i * WhiteLength), (tile, index) =>
|
|
{
|
|
tile.Hue = White;
|
|
|
|
Timer.DelayCall(TimeSpan.FromSeconds(WhiteLength), t =>
|
|
{
|
|
t.Hue = tile.OriginalHue;
|
|
}, tile);
|
|
|
|
if (index == seqCount - 1)
|
|
{
|
|
Sequencing = false;
|
|
|
|
IPooledEnumerable eable = Map.TerMur.GetClientsInRange(Location, 20);
|
|
|
|
foreach (NetState ns in eable)
|
|
{
|
|
if (ns.Mobile != null && ns.Mobile is PlayerMobile && QuestHelper.HasQuest<PristineCrystalLotusQuest>((PlayerMobile)ns.Mobile))
|
|
{
|
|
ns.Mobile.SendLocalizedMessage(1151300, "", White); // Complete the puzzle to obtain a Pristine Crystal Lotus.
|
|
}
|
|
}
|
|
|
|
eable.Free();
|
|
|
|
Timer.DelayCall(TimeSpan.FromSeconds(Math.Max(SequenceLength, seqCount * 3)), DoSequence);
|
|
}
|
|
}, Order[i], i);
|
|
}
|
|
}
|
|
|
|
public void OnTileClicked(Mobile from, PuzzleTile tile)
|
|
{
|
|
if (Sequencing)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (from is PlayerMobile)
|
|
{
|
|
var quest = QuestHelper.GetQuest<PristineCrystalLotusQuest>((PlayerMobile)from);
|
|
|
|
if (quest != null)
|
|
{
|
|
if (!PlayerOrder.ContainsKey(from))
|
|
{
|
|
PlayerOrder[from] = new PuzzleTile[Order.Length];
|
|
}
|
|
|
|
var list = PlayerOrder[from];
|
|
|
|
for (int i = 0; i < Order.Length; i++)
|
|
{
|
|
var actual = Order[i];
|
|
|
|
if (list[i] == null)
|
|
{
|
|
list[i] = tile;
|
|
|
|
if (i == Order.Length - 1)
|
|
{
|
|
if (CheckMatch(list))
|
|
{
|
|
from.SendLocalizedMessage(1151304); // You matched that pattern correctly.
|
|
|
|
quest.PuzzlesComplete++;
|
|
|
|
if (quest.PuzzlesComplete >= 5)
|
|
{
|
|
from.SendLocalizedMessage(1151306); // You may now retrieve a Pristine Crystal Lotus.
|
|
}
|
|
}
|
|
else
|
|
{
|
|
from.SendLocalizedMessage(1151305); // You did not complete the pattern correctly.
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private bool CheckMatch(PuzzleTile[] list)
|
|
{
|
|
for (int i = 0; i < Order.Length; i++)
|
|
{
|
|
if (Order[i] != list[i])
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public override bool HandlesOnSpeech { get { return true; } }
|
|
|
|
public override void OnSpeech(SpeechEventArgs e)
|
|
{
|
|
var pm = e.Mobile as PlayerMobile;
|
|
|
|
if (pm == null)
|
|
return;
|
|
|
|
if (e.Speech.ToLower() == "i seek the lotus")
|
|
{
|
|
var quest = QuestHelper.GetQuest<PristineCrystalLotusQuest>(pm);
|
|
|
|
if (quest != null)
|
|
{
|
|
pm.SendLocalizedMessage(1151300); // Complete the puzzle to obtain a Pristine Crystal Lotus.
|
|
}
|
|
else
|
|
{
|
|
pm.SendLocalizedMessage(1151301); // You marvel at the flashing tiles.
|
|
}
|
|
|
|
e.Handled = true;
|
|
}
|
|
else if (e.Speech.ToLower() == "give me the lotus")
|
|
{
|
|
var quest = QuestHelper.GetQuest<PristineCrystalLotusQuest>(pm);
|
|
|
|
if (quest != null)
|
|
{
|
|
if (quest.PuzzlesComplete < 5)
|
|
{
|
|
pm.SendLocalizedMessage(1151303); // You have not completed the puzzle.
|
|
}
|
|
else if (!quest.ReceivedLotus)
|
|
{
|
|
var lotus = new PristineCrystalLotus();
|
|
pm.AddToBackpack(lotus);
|
|
pm.SendLocalizedMessage(1151302); // A Pristine Crystal Lotus has been placed in your backpack.
|
|
|
|
QuestHelper.CheckRewardItem(pm, lotus);
|
|
|
|
quest.ReceivedLotus = true;
|
|
}
|
|
}
|
|
|
|
e.Handled = true;
|
|
}
|
|
|
|
}
|
|
|
|
private void LoadTiles()
|
|
{
|
|
var map = Map.TerMur;
|
|
|
|
//West
|
|
PuzzleTile tile = new PuzzleTile(this, 33, 0);
|
|
tile.MoveToWorld(new Point3D(971, 2876, 37), map);
|
|
Tiles.Add(tile);
|
|
|
|
tile = new PuzzleTile(this, 14, 0);
|
|
tile.MoveToWorld(new Point3D(971, 2878, 37), map);
|
|
Tiles.Add(tile);
|
|
|
|
tile = new PuzzleTile(this, 1195, 0);
|
|
tile.MoveToWorld(new Point3D(972, 2877, 37), map);
|
|
Tiles.Add(tile);
|
|
|
|
tile = new PuzzleTile(this, 63, 0);
|
|
tile.MoveToWorld(new Point3D(973, 2876, 37), map);
|
|
Tiles.Add(tile);
|
|
|
|
// NorthWest
|
|
tile = new PuzzleTile(this, 63, 1);
|
|
tile.MoveToWorld(new Point3D(978, 2868, 37), map);
|
|
Tiles.Add(tile);
|
|
|
|
tile = new PuzzleTile(this, 1195, 1);
|
|
tile.MoveToWorld(new Point3D(979, 2868, 37), map);
|
|
Tiles.Add(tile);
|
|
|
|
tile = new PuzzleTile(this, 14, 1);
|
|
tile.MoveToWorld(new Point3D(979, 2869, 37), map);
|
|
Tiles.Add(tile);
|
|
|
|
tile = new PuzzleTile(this, 33, 1);
|
|
tile.MoveToWorld(new Point3D(980, 2870, 37), map);
|
|
Tiles.Add(tile);
|
|
|
|
// NorthEast
|
|
tile = new PuzzleTile(this, 33, 2);
|
|
tile.MoveToWorld(new Point3D(985, 2870, 37), map);
|
|
Tiles.Add(tile);
|
|
|
|
tile = new PuzzleTile(this, 1195, 2);
|
|
tile.MoveToWorld(new Point3D(986, 2870, 37), map);
|
|
Tiles.Add(tile);
|
|
|
|
tile = new PuzzleTile(this, 63, 2);
|
|
tile.MoveToWorld(new Point3D(985, 2871, 37), map);
|
|
Tiles.Add(tile);
|
|
|
|
tile = new PuzzleTile(this, 14, 2);
|
|
tile.MoveToWorld(new Point3D(986, 2871, 37), map);
|
|
Tiles.Add(tile);
|
|
|
|
// East
|
|
tile = new PuzzleTile(this, 14, 3);
|
|
tile.MoveToWorld(new Point3D(985, 2876, 37), map);
|
|
Tiles.Add(tile);
|
|
|
|
tile = new PuzzleTile(this, 33, 3);
|
|
tile.MoveToWorld(new Point3D(986, 2877, 37), map);
|
|
Tiles.Add(tile);
|
|
|
|
tile = new PuzzleTile(this, 63, 3);
|
|
tile.MoveToWorld(new Point3D(987, 2878, 37), map);
|
|
Tiles.Add(tile);
|
|
|
|
tile = new PuzzleTile(this, 1195, 3);
|
|
tile.MoveToWorld(new Point3D(988, 2879, 37), map);
|
|
Tiles.Add(tile);
|
|
|
|
// SouthEast
|
|
tile = new PuzzleTile(this, 1195, 4);
|
|
tile.MoveToWorld(new Point3D(982, 2881, 37), map);
|
|
Tiles.Add(tile);
|
|
|
|
tile = new PuzzleTile(this, 33, 4);
|
|
tile.MoveToWorld(new Point3D(982, 2882, 37), map);
|
|
Tiles.Add(tile);
|
|
|
|
tile = new PuzzleTile(this, 63, 4);
|
|
tile.MoveToWorld(new Point3D(982, 2883, 37), map);
|
|
Tiles.Add(tile);
|
|
|
|
tile = new PuzzleTile(this, 14, 4);
|
|
tile.MoveToWorld(new Point3D(981, 2883, 37), map);
|
|
Tiles.Add(tile);
|
|
|
|
// SouthWest
|
|
tile = new PuzzleTile(this, 33, 5);
|
|
tile.MoveToWorld(new Point3D(975, 2882, 37), map);
|
|
Tiles.Add(tile);
|
|
|
|
tile = new PuzzleTile(this, 14, 5);
|
|
tile.MoveToWorld(new Point3D(976, 2883, 37), map);
|
|
Tiles.Add(tile);
|
|
|
|
tile = new PuzzleTile(this, 63, 5);
|
|
tile.MoveToWorld(new Point3D(975, 2884, 37), map);
|
|
Tiles.Add(tile);
|
|
|
|
tile = new PuzzleTile(this, 1195, 5);
|
|
tile.MoveToWorld(new Point3D(976, 2885, 37), map);
|
|
Tiles.Add(tile);
|
|
|
|
Teleporter tele = new Teleporter(new Point3D(1050, 2940, 38), map, false);
|
|
tele.MoveToWorld(new Point3D(1018, 2915, 38), map);
|
|
Static sparkles = new Static(0x373A);
|
|
sparkles.MoveToWorld(new Point3D(1018, 2915, 38), map);
|
|
|
|
tele = new Teleporter(new Point3D(1018, 2915, 38), map, false);
|
|
tele.MoveToWorld(new Point3D(1050, 2940, 38), map);
|
|
sparkles = new Static(0x373A);
|
|
sparkles.MoveToWorld(new Point3D(1050, 2940, 38), map);
|
|
}
|
|
|
|
public override void Delete()
|
|
{
|
|
base.Delete();
|
|
|
|
var s = Map.TerMur.FindItem<Static>(new Point3D(978, 2876, 47));
|
|
}
|
|
|
|
private void RegisterRegion()
|
|
{
|
|
Region = new Region("Crystal Lotus Puzzle Region", Map.TerMur, Region.DefaultPriority, new Rectangle2D(945, 2858, 66, 62));
|
|
Region.Register();
|
|
}
|
|
|
|
public CrystalLotusPuzzle(Serial serial) : base(serial)
|
|
{
|
|
}
|
|
|
|
public override void Serialize(GenericWriter writer)
|
|
{
|
|
base.Serialize(writer);
|
|
writer.Write(0);
|
|
|
|
writer.WriteItemList(Tiles, true);
|
|
}
|
|
|
|
public override void Deserialize(GenericReader reader)
|
|
{
|
|
base.Deserialize(reader);
|
|
reader.ReadInt(); // version
|
|
|
|
Tiles = reader.ReadStrongItemList<PuzzleTile>();
|
|
|
|
if (Core.SA)
|
|
{
|
|
Instance = this;
|
|
|
|
foreach (var tile in Tiles)
|
|
{
|
|
tile.Puzzle = this;
|
|
}
|
|
|
|
RegisterRegion();
|
|
DoSequence();
|
|
}
|
|
else
|
|
{
|
|
ColUtility.SafeDelete(Tiles);
|
|
ColUtility.Free(Tiles);
|
|
|
|
Delete();
|
|
}
|
|
}
|
|
}
|
|
|
|
public class PuzzleTile : Item
|
|
{
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public CrystalLotusPuzzle Puzzle { get; set; }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int OriginalHue { get; private set; }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int Group { get; private set; }
|
|
|
|
public override bool ForceShowProperties { get { return true; } }
|
|
|
|
public PuzzleTile(CrystalLotusPuzzle puzzle, int hue, int group)
|
|
: base(0x519)
|
|
{
|
|
Movable = false;
|
|
Hue = hue;
|
|
Group = group;
|
|
|
|
OriginalHue = hue;
|
|
}
|
|
|
|
public override void OnDoubleClick(Mobile m)
|
|
{
|
|
if (Puzzle == null)
|
|
return;
|
|
|
|
if (m.InRange(GetWorldLocation(), 3))
|
|
{
|
|
Puzzle.OnTileClicked(m, this);
|
|
}
|
|
else
|
|
{
|
|
m.LocalOverheadMessage(Server.Network.MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
|
|
}
|
|
}
|
|
|
|
public PuzzleTile(Serial serial) : base(serial)
|
|
{
|
|
}
|
|
|
|
public override void Serialize(GenericWriter writer)
|
|
{
|
|
base.Serialize(writer);
|
|
writer.Write(0);
|
|
|
|
writer.Write(OriginalHue);
|
|
writer.Write(Group);
|
|
}
|
|
|
|
public override void Deserialize(GenericReader reader)
|
|
{
|
|
base.Deserialize(reader);
|
|
reader.ReadInt(); // version
|
|
|
|
OriginalHue = reader.ReadInt();
|
|
Group = reader.ReadInt();
|
|
|
|
if (Hue != OriginalHue)
|
|
{
|
|
Hue = OriginalHue;
|
|
}
|
|
}
|
|
}
|
|
}
|