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,84 @@
using Server;
using System;
namespace Server.Items
{
public class ExperimentalBook : BrownBook
{
public override int LabelNumber { get { return 1113479; } } //
[Constructable]
public ExperimentalBook() : base(false)
{
ItemID = 4030;
}
public static readonly BookContent Content = new BookContent(
"Read Me!", "Sir Wilber",
new BookPageInfo(
"Hello again!",
"This is Part II of my",
"experiment. Beyond these",
"doors is a challenge for",
"those carrying an ",
"Experimental Gem."),
new BookPageInfo(
"INSTRUCTIONS:",
"Activate the Gem to start",
"the self-destruct timer.",
"You have 30 minutes to",
"reach the final room."),
new BookPageInfo(
"Each room has colored",
"areas matching various states:",
"White = Cold",
"Pink = Warm",
"Blue = Freezing",
"Red = Blazing"),
new BookPageInfo(
"Green = Poison",
"Orange = Cure",
"Dark Green= Lethal",
"Brown=Greater Cure",
"Your gem's state will cycle",
"randomly through these"),
new BookPageInfo(
"colors. Each time the gem",
"shifts, you must enter the",
"colored region that will",
"bring your gem back to neutral",
"state (grey). "),
new BookPageInfo(
"Failing when the gem reaches",
"the extreme of any state get you",
"expelled from the room and you",
"will have to start over. The",
"self-destruct"),
new BookPageInfo(
"timer will not reset. Once you",
"reach the final room, place your",
"gem in the box to receive",
"your reward."));
public override BookContent DefaultContent { get { return Content; } }
public ExperimentalBook(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // ver
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,721 @@
using Server;
using System;
using Server.Mobiles;
using Server.Network;
using Server.Gumps;
namespace Server.Items
{
public enum Room
{
RoomZero = 0,
RoomOne = 1,
RoomTwo = 2,
RoomThree = 3,
RoomFour = 4
}
public class ExperimentalGem : BaseDecayingItem
{
private static readonly int Neutral = 0x356;
private static readonly int Red = 0x26;
private static readonly int White = 0x481;
private static readonly int Blue = 0x4;
private static readonly int Pink = 0x4B2;
private static readonly int Orange = 0x30;
private static readonly int LightGreen = 0x3D;
private static readonly int DarkGreen = 0x557;
private static readonly int Brown = 0x747;
private static readonly TimeSpan HueToHueDelay = TimeSpan.FromSeconds(4);
private static readonly TimeSpan HueToLocDelay = TimeSpan.FromSeconds(4);
private static readonly TimeSpan RoomToRoomDelay = TimeSpan.FromSeconds(20);
private static readonly Rectangle2D m_Entrance = new Rectangle2D(980, 1117, 17, 3);
private bool m_Active;
private bool m_IsExtremeHue;
private bool m_Complete;
private Room m_CurrentRoom;
private double m_Completed;
private double m_ToComplete;
private int m_LastIndex;
private int m_CurrentHue;
private int m_Span;
private Timer m_Timer;
private DateTime m_Expire;
private Mobile m_Owner;
[CommandProperty(AccessLevel.GameMaster)]
public bool Active { get { return m_Active; } }
[CommandProperty(AccessLevel.GameMaster)]
public bool IsExtremeHue { get { return m_IsExtremeHue; } }
[CommandProperty(AccessLevel.GameMaster)]
public bool Complete { get { return m_Complete; } set { m_Complete = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public Room CurrentRoom { get { return m_CurrentRoom; } set { m_CurrentRoom = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public double Completed { get { return m_Completed; } set { m_Completed = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public double ToComplete { get { return m_ToComplete; } set { m_ToComplete = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public int CurrentHue { get { return m_CurrentHue; } }
[CommandProperty(AccessLevel.GameMaster)]
public int LastIndex { get { return m_LastIndex; } }
[CommandProperty(AccessLevel.GameMaster)]
public Mobile Owner { get { return m_Owner; } set { m_Owner = value; } }
public override int Lifespan { get { return m_Span; } }
public override int LabelNumber
{
get
{
if (m_Active)
return 1113409; // An Experimental Gem [Activated]
return 1113380; //An Experimental Gem
}
}
[Constructable]
public ExperimentalGem() : base(6463)
{
m_LastIndex = -1;
m_IsExtremeHue = false;
m_CurrentHue = Neutral;
m_CurrentRoom = Room.RoomZero;
m_Active = false;
m_Expire = DateTime.MaxValue;
m_Span = 0;
m_Completed = 0;
m_ToComplete = 0;
Hue = Neutral;
}
public override void OnDoubleClick(Mobile from)
{
if (!IsChildOf(from.Backpack))
from.SendLocalizedMessage(1054107); // This item must be in your backpack.
else if (ExperimentalRoomController.IsInCooldown(from))
from.SendLocalizedMessage(1113413); // You have recently participated in this challenge. You must wait 24 hours to try again.
else if (!m_Active && m_Entrance.Contains(from.Location) && from.Map == Map.TerMur)
{
if (from.HasGump(typeof(ExperimentalGem.InternalGump)))
from.CloseGump(typeof(ExperimentalGem.InternalGump));
from.SendGump(new InternalGump(this));
}
else if (m_Active)
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1113408); // The gem is already active. You must clear the rooms before it is destroyed!
}
public override void Decay()
{
}
public void Activate(Mobile from)
{
m_Active = true;
StartTimer();
m_CurrentRoom = Room.RoomOne;
m_ToComplete = Utility.RandomMinMax(5, 8);
Timer.DelayCall(TimeSpan.FromSeconds(5), new TimerCallback(BeginRoom_Callback));
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1113405); // Your gem is now active. You may enter the Experimental Room.
InvalidateProperties();
}
public void BeginRoom_Callback()
{
m_Timer = new InternalTimer(this);
m_LastIndex = -1;
SelectNewHue();
}
public override void StartTimer()
{
if (m_Span == 0)
{
TimeLeft = 1800;
m_Span = 1800;
base.StartTimer();
InvalidateProperties();
}
}
private void SelectNewHue()
{
int index = -1;
int[] list = GetRoomHues();
do
{
index = Utility.Random(list.Length);
}
while(index == m_LastIndex);
m_Expire = DateTime.UtcNow + HueToLocDelay;
m_Holding = false;
m_LastIndex = index;
if (IsExtreme(list[index]))
m_IsExtremeHue = true;
Hue = list[index];
m_CurrentHue = Hue;
}
private bool m_Holding;
public void OnTick()
{
if (m_Holding || m_Expire > DateTime.UtcNow)
return;
Mobile m = (Mobile)RootParent;
int floorHue = GetFloorHue(m);
int nextHue = GetRevertedHue(m, m_CurrentHue, floorHue);
if (m != null && nextHue >= 0) //Standing in the right spot
{
if (m_IsExtremeHue && nextHue != Neutral) // from extreme back to regular
{
m_Completed += 0.5;
Hue = nextHue;
m_CurrentHue = Hue;
m_IsExtremeHue = false;
m_LastIndex = GetIndexFor(nextHue);
m_Expire = DateTime.UtcNow + HueToLocDelay;
m.PlaySound(0x51);
m_Completed += 0.5;
}
else // Neutralized, new color
{
m_Completed++;
m_IsExtremeHue = false;
m_Holding = true;
Hue = Neutral;
m_CurrentHue = Neutral;
if (m_Completed < m_ToComplete)
{
Timer.DelayCall(HueToHueDelay, new TimerCallback(SelectNewHue));
m.PlaySound(0x51);
}
}
if (m_Completed >= m_ToComplete) // next room or complete!
{
if (m_CurrentRoom == Room.RoomThree) // puzzle completed
{
m_Holding = true;
Hue = Neutral;
m_CurrentHue = Neutral;
CompletePuzzle(m);
m.PlaySound(0x1FF);
m.LocalOverheadMessage(MessageType.Regular, 0x21, 1113403); // Congratulations!! The last room has been unlocked!! Hurry through to claim your reward!
}
else // on to the next room!
{
m_CurrentRoom++;
m_Holding = true;
Hue = Neutral;
m_CurrentHue = Neutral;
m_Completed = 0;
switch (m_CurrentRoom)
{
default:
case Room.RoomOne:
m_ToComplete = Utility.RandomMinMax(5, 8);
break;
case Room.RoomTwo:
m_ToComplete = Utility.RandomMinMax(10, 15);
break;
case Room.RoomThree:
m_ToComplete = Utility.RandomMinMax(15, 25);
break;
}
m_LastIndex = -1;
Timer.DelayCall(RoomToRoomDelay, new TimerCallback(SelectNewHue));
m.PlaySound(0x1FF);
m.LocalOverheadMessage(MessageType.Regular, 0x21, 1113402); // The next room has been unlocked! Hurry through the door before your gem's state changes again!
}
}
}
else if (m_IsExtremeHue) //Already extreme, failed
{
if (m != null && m.AccessLevel == AccessLevel.Player)
OnPuzzleFailed(m);
else
{
if (m != null)
m.SendMessage("As a GM, you get another chance!");
m_Expire = DateTime.UtcNow + HueToLocDelay;
}
if (m != null)
m.LocalOverheadMessage(MessageType.Regular, 0x21, 1113400); // You fail to neutralize the gem in time and are expelled from the room!!
}
else if (Hue != -1) //set to extreme hue
{
int hue = GetExtreme(m_CurrentHue);
Hue = hue;
m_CurrentHue = hue;
m_IsExtremeHue = true;
m_LastIndex = GetIndexFor(hue);
if (m != null)
m.LocalOverheadMessage(MessageType.Regular, 0x21, 1113401); // The state of your gem worsens!!
m_Expire = DateTime.UtcNow + HueToLocDelay;
}
}
private string GetFloorString(int hue)
{
switch (hue)
{
case 0x481: //White
return "white";
case 0x4B2: //Pink
return "pink";
case 0x30: //Orange
return "orange";
case 0x3D: //LightGreen
return "light green";
case 0x26: //Red
return "red";
case 0x4: //Blue
return "blue";
case 0x557: //Dark Green
return "dark green";
case 0x747: //Brown
return "brown";
}
return "NOT STANDING ON A COLOR";
}
private void CompletePuzzle(Mobile m)
{
if(m_Timer != null)
{
m_Timer.Stop();
m_Timer = null;
}
m_Complete = true;
Hue = Neutral;
m_CurrentHue = Hue;
m_CurrentRoom = Room.RoomFour;
}
private void OnPuzzleFailed(Mobile m)
{
if (m != null)
{
int x = Utility.RandomMinMax(m_Entrance.X, m_Entrance.X + m_Entrance.Width);
int y = Utility.RandomMinMax(m_Entrance.Y, m_Entrance.Y + m_Entrance.Height);
int z = m.Map.GetAverageZ(x, y);
Point3D from = m.Location;
Point3D p = new Point3D(x, y, z);
m.PlaySound(0x1FE);
Effects.SendLocationParticles(EffectItem.Create(from, m.Map, EffectItem.DefaultDuration), 0x3728, 10, 10, 2023);
Effects.SendLocationParticles(EffectItem.Create(p, m.Map, EffectItem.DefaultDuration), 0x3728, 10, 10, 5023);
BaseCreature.TeleportPets(m, p, Map.TerMur);
m.MoveToWorld(p, Map.TerMur);
}
Reset();
}
private void Reset()
{
if(m_Timer != null)
{
m_Timer.Stop();
m_Timer = null;
}
m_Complete = false;
m_Completed = 0;
m_ToComplete = 0;
m_IsExtremeHue = false;
m_Active = false;
m_CurrentRoom = Room.RoomOne;
m_LastIndex = -1;
m_Expire = DateTime.MaxValue;
m_CurrentHue = Neutral;
Hue = Neutral;
InvalidateProperties();
}
public override void Delete()
{
if(m_Timer != null)
m_Timer.Stop();
if(m_Owner != null)
ExperimentalRoomController.AddToTable(m_Owner);
base.Delete();
}
private class InternalTimer : Timer
{
private ExperimentalGem m_Gem;
public InternalTimer(ExperimentalGem gem) : base(TimeSpan.FromSeconds(.5), TimeSpan.FromSeconds(.5))
{
m_Gem = gem;
Start();
}
protected override void OnTick()
{
if(m_Gem != null)
m_Gem.OnTick();
else
Stop();
}
}
private int[] GetRoomHues()
{
switch(m_CurrentRoom)
{
default:
case Room.RoomOne:
return m_RoomHues[0];
case Room.RoomTwo:
return m_RoomHues[1];
case Room.RoomThree:
return m_RoomHues[2];
}
}
private Rectangle2D GetRoomRec()
{
switch(m_CurrentRoom)
{
default:
case Room.RoomOne:
return m_RoomRecs[0];
case Room.RoomTwo:
return m_RoomRecs[1];
case Room.RoomThree:
return m_RoomRecs[2];
}
}
public int GetIndexFor(int hue)
{
int[] hues = GetRoomHues();
for (int i = 0; i < hues.Length; i++)
{
if (hue == hues[i])
return i;
}
return White; //Oops, something happened, this should never happened.
}
public static int GetExtreme(int hue)
{
switch (hue)
{
case 0x4B2: return Red; // Pink to Red
case 0x481: return Blue; // White to Blue
case 0x30: return Brown; // Orange to Brown
case 0x3D: return DarkGreen;// LightGreen to DarkGreen
}
return -1;
}
public static int GetRegular(int hue)
{
switch (hue)
{
case 0x26: return Pink; // Red to Pink
case 0x4: return White; // Blue to White
case 0x747: return Orange; // Brown to Orange
case 0x557: return LightGreen; // DarkGreen to LightGreen
}
return -1;
}
/* Extreme Normal SlowOpposite FastOpposite
*
* Red Pink White Blue
* Blue White Pink Red
* Brown Orange LightGreen DarkGreen
* DarkGreen LightGreen Orange Brown
*/
/// <summary>
/// Checks locations the player is standing, in relation to the gem hue.
/// </summary>
/// <param name="oldHue">current gem hue</param>
/// <param name="floorHue">where they are standing</param>
/// <returns>-1 if they are in the wrong spot, the new gem hue if in the correct spot</returns>
public int GetRevertedHue(Mobile from, int oldHue, int floorHue)
{
if (from == null)
return -1;
if (!GetRoomRec().Contains(from.Location))
return -1;
switch (oldHue)
{
case 0x481: //White
if (floorHue == Pink || floorHue == Red)
return Neutral;
break;
case 0x4B2: //Pink
if (floorHue == White || floorHue == Blue)
return Neutral;
break;
case 0x30: //Orange
if (floorHue == LightGreen || floorHue == DarkGreen)
return Neutral;
break;
case 0x3D: //LightGreen
if (floorHue == Orange || floorHue == Brown)
return Neutral;
break;
case 0x26: //Red
if (floorHue == White)
return Pink;
if (floorHue == Blue)
return Neutral;
break;
case 0x4: //Blue
if (floorHue == Pink)
return White;
if (floorHue == Red)
return Neutral;
break;
case 0x557: //Dark Green
if (floorHue == Orange)
return Orange;
if (floorHue == Brown)
return Neutral;
break;
case 0x747: //Brown
if (floorHue == LightGreen)
return Orange;
if (floorHue == DarkGreen)
return Neutral;
break;
}
return -1;
}
public static int GetFloorHue(Mobile from)
{
if (from == null || from.Map != Map.TerMur)
return 0;
for (int i = 0; i < m_FloorRecs.Length; i++)
{
if (m_FloorRecs[i].Contains(from.Location))
return m_FloorHues[i];
}
return 0;
}
public bool IsExtreme(int hue)
{
foreach (int i in ExtremeHues)
{
if (i == hue)
return true;
}
return false;
}
public int[] RegularHues = new int[]
{
White,
Pink,
LightGreen,
Orange,
};
private int[] ExtremeHues = new int[]
{
Red,
Blue,
Brown,
DarkGreen
};
private static int[][] m_RoomHues = new int[][]
{
//Room One
new int[] { White, Pink, Red, Blue },
//Room Two
new int[] { Pink, Blue, Red, Orange, LightGreen, White },
//Room Three
new int[] { Blue, Pink, DarkGreen, Orange, Brown, LightGreen, Red, White },
};
private static Rectangle2D[] m_FloorRecs = new Rectangle2D[]
{
//Room One
new Rectangle2D(977, 1104, 5, 5), // White, opposite of pink
new Rectangle2D(987, 1104, 5, 5), // Pink, opposite of white
new Rectangle2D(977, 1109, 5, 5), // Blue, opposite of red
new Rectangle2D(987, 1109, 5, 5), // Red, opposite of Blue
//Room Two
new Rectangle2D(977, 1092, 6, 3), // White, opposite of pink
new Rectangle2D(986, 1092, 6, 3), //Red, opposite of Blue
new Rectangle2D(977, 1095, 6, 3), //Blue, opposite of red
new Rectangle2D(986, 1095, 6, 3), //LightGreen, oppostie of Orange
new Rectangle2D(977, 1098, 6, 3), //Orange, opposite of LightGreen
new Rectangle2D(986, 1098, 6, 3), //Pink, opposite of white
//Room Three
new Rectangle2D(977, 1074, 3, 5), //Red, opposite of Blue
new Rectangle2D(980, 1074, 3, 5), //White, oppostie of Pink
new Rectangle2D(986, 1074, 3, 5), //Brown, oppostie of DarkGreen
new Rectangle2D(989, 1074, 3, 5), //LightGreen, opposite of Orange
new Rectangle2D(977, 1079, 3, 5), //DarkGreen, opposite of Brown
new Rectangle2D(980, 1079, 3, 5), //Orange, opposite of LightGreen
new Rectangle2D(986, 1079, 3, 5), //Blue, opposite of red
new Rectangle2D(989, 1079, 3, 5), //Pink, opposite of White
};
private static int[] m_FloorHues = new int[]
{
//Room One
White,
Pink,
Red,
Blue,
//Room Two
White,
Red,
Blue,
LightGreen,
Orange,
Pink,
//Room Three
Red,
White,
Brown,
LightGreen,
DarkGreen,
Orange,
Blue,
Pink
};
private static Rectangle2D[] m_RoomRecs = new Rectangle2D[]
{
new Rectangle2D(977, 1104, 15, 10), //RoomOne
new Rectangle2D(977, 1092, 15, 9), //RoomTwo
new Rectangle2D(977, 1074, 15, 10), //RoomThree
};
public ExperimentalGem(Serial serial) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)1);
writer.Write(m_Owner);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int v = reader.ReadInt();
switch (v)
{
case 1:
m_Owner = reader.ReadMobile();
goto case 0;
case 0:
break;
}
Reset();
}
private class InternalGump : Gump
{
private ExperimentalGem m_Gem;
public InternalGump(ExperimentalGem gem) : base(50, 50)
{
m_Gem = gem;
AddPage(0);
AddBackground(0, 0, 297, 115, 9200);
AddImageTiled(5, 10, 285, 25, 2624);
AddHtmlLocalized(10, 15, 275, 25, 1113407, 0x7FFF, false, false); // Experimental Room Access
AddImageTiled(5, 40, 285, 40, 2624);
AddHtmlLocalized(10, 40, 275, 40, 1113391, 0x7FFF, false, false); // Click CANCEL to read the instruction book or OK to start the timer now.
AddButton(5, 85, 4017, 4018, 0, GumpButtonType.Reply, 0);
AddHtmlLocalized(40, 87, 80, 25, 1011012, 0x7FFF, false, false); //CANCEL
AddButton(215, 85, 4023, 4024, 1, GumpButtonType.Reply, 0);
AddHtmlLocalized(250, 87, 80, 25, 1006044, 0x7FFF, false, false); //OK
}
public override void OnResponse(Server.Network.NetState state, RelayInfo info)
{
if (info.ButtonID == 1)
m_Gem.Activate(state.Mobile);
}
}
}
}

View File

@@ -0,0 +1,177 @@
using Server;
using System;
using Server.Mobiles;
using System.Collections.Generic;
namespace Server.Items {
public class ExperimentalRoomChest : MetalBox
{
private Dictionary<Item, Mobile> m_Instancing;
public override bool DisplayWeight { get { return false; } }
public override bool DisplaysContent{ get{ return false; } }
public override bool Decays { get { return true; } }
public override TimeSpan DecayTime { get { return TimeSpan.FromMinutes(10.0); } }
[Constructable]
public ExperimentalRoomChest()
{
Movable = false;
m_Instancing = new Dictionary<Item, Mobile>();
LiftOverride = true;
}
public override void OnDoubleClick(Mobile from)
{
Container pack = from.Backpack;
if(pack != null)
{
Item item = pack.FindItemByType(typeof(ExperimentalGem));
if(item != null && item is ExperimentalGem && ((ExperimentalGem)item).Complete)
{
item.Delete();
Item toDrop = GetRandomDrop();
if(toDrop != null)
AddItemFor(toDrop, from);
}
}
base.OnDoubleClick(from);
}
public override bool TryDropItem(Mobile from, Item dropped, bool message)
{
if(dropped is ExperimentalGem && ((ExperimentalGem)dropped).Complete && from.InRange(this.Location, 2))
{
dropped.Delete();
Item toDrop = GetRandomDrop();
if(toDrop != null)
AddItemFor(toDrop, from);
base.OnDoubleClick(from);
}
return false;
}
public void AddItemFor(Item item, Mobile mob)
{
if (item == null || mob == null)
return;
DropItem(item);
item.SetLastMoved();
if (m_Instancing == null)
m_Instancing = new Dictionary<Item, Mobile>();
m_Instancing[item] = mob;
}
public override bool IsChildVisibleTo( Mobile m, Item child )
{
if (m.AccessLevel > AccessLevel.Player)
return true;
if (m_Instancing != null)
{
if (!m_Instancing.ContainsKey(child))
return true;
if (m_Instancing[child] == m)
return true;
}
else
{
return true;
}
return false;
}
public override bool OnDecay()
{
List<Item> items = new List<Item>( this.Items );
foreach(Item i in items)
{
if (i.Decays && i.LastMoved.Add(DecayTime) < DateTime.UtcNow)
{
i.Delete();
if(m_Instancing.ContainsKey(i))
m_Instancing.Remove(i);
}
}
return false;
}
public override void RemoveItem(Item item)
{
if (m_Instancing != null && m_Instancing.ContainsKey(item))
m_Instancing.Remove(item);
base.RemoveItem(item);
}
public Item GetRandomDrop()
{
Item item = null;
switch(Utility.Random(17))
{
case 0: case 1: case 2: case 3: case 4: case 5: case 6:
item = new Stalagmite();
break;
case 7: case 8: case 9: case 10:
item = new Flowstone();
break;
case 11:
item = new CanvaslessEasel();
break;
case 12:
item = new HangingChainmailLegs();
break;
case 13:
item = new HangingRingmailTunic();
break;
case 14:
item = new PluckedChicken();
break;
case 15:
item = new ColorfulTapestry();
break;
case 16:
item = new TwoStoryBanner();
break;
}
return item;
}
public ExperimentalRoomChest( Serial serial ) : base(serial) {
}
public override void Serialize(GenericWriter writer) {
base.Serialize(writer);
writer.Write((int)0); // ver
}
public override void Deserialize(GenericReader reader) {
base.Deserialize(reader);
int version = reader.ReadInt();
m_Instancing = new Dictionary<Item, Mobile>();
}
}
}

View File

@@ -0,0 +1,87 @@
using Server;
using System;
using Server.Mobiles;
using System.Collections.Generic;
using Server.Commands;
namespace Server.Items
{
public class ExperimentalRoomController : Item
{
private static ExperimentalRoomController m_Instance;
public static ExperimentalRoomController Instance { get { return m_Instance; } }
private static Dictionary<Mobile, DateTime> m_Table;
public ExperimentalRoomController() : base(7107)
{
m_Table = new Dictionary<Mobile, DateTime>();
Visible = false;
Movable = false;
m_Instance = this;
}
public static void AddToTable(Mobile from)
{
if (from == null)
return;
m_Table[from] = DateTime.UtcNow + TimeSpan.FromHours(24);
}
public static bool IsInCooldown(Mobile from)
{
Defrag();
return m_Table.ContainsKey(from);
}
public static void Defrag()
{
List<Mobile> list = new List<Mobile>();
foreach (KeyValuePair<Mobile, DateTime> kvp in m_Table)
{
if (kvp.Value <= DateTime.UtcNow)
list.Add(kvp.Key);
}
foreach (Mobile m in list)
m_Table.Remove(m);
}
public static bool HasItem(Mobile from, Type type)
{
if (from == null || from.Backpack == null)
return false;
Item item = from.Backpack.FindItemByType(type);
return item != null;
}
public ExperimentalRoomController(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
Defrag();
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
m_Table = new Dictionary<Mobile, DateTime>();
m_Instance = this;
}
}
}

View File

@@ -0,0 +1,145 @@
using Server;
using System;
using Server.Mobiles;
namespace Server.Items {
public class ExperimentalRoomDoor : MetalDoor2 {
public override string DefaultName { get { return "a door"; } }
private Room m_Room;
[CommandProperty(AccessLevel.GameMaster)]
public Room Room {
get { return m_Room; }
set { m_Room = value; }
}
[Constructable]
public ExperimentalRoomDoor( Room room, DoorFacing facing ) : base(facing) {
m_Room = room;
}
public ExperimentalRoomDoor( Serial serial ) : base(serial) {
}
public override void Use(Mobile from)
{
if (from.AccessLevel > AccessLevel.Player)
{
from.SendMessage("You open the door with your godly powers.");
base.Use(from);
return;
}
Container pack = from.Backpack;
bool hasGem = false;
if (pack != null)
{
Item[] items = pack.FindItemsByType(typeof(ExperimentalGem));
if (items != null && items.Length > 0)
{
hasGem = true;
foreach (Item item in items)
{
ExperimentalGem gem = (ExperimentalGem)item;
if (gem.Active && (gem.CurrentRoom > m_Room || m_Room == Room.RoomZero))
{
base.Use(from);
return;
}
}
}
else
from.SendLocalizedMessage(1113410); // You must have an active Experimental Gem to enter that room.
}
if(hasGem)
from.SendLocalizedMessage(1113411); // You have not yet earned access to that room!
}
public override void Serialize(GenericWriter writer) {
base.Serialize(writer);
writer.Write((int)0); // ver
writer.Write((int)m_Room);
}
public override void Deserialize(GenericReader reader) {
base.Deserialize(reader);
int version = reader.ReadInt();
m_Room = (Room)reader.ReadInt();
}
}
}
namespace Server.Items {
public class ExperimentalRoomBlocker : Item
{
private Room m_Room;
[CommandProperty(AccessLevel.GameMaster)]
public Room Room {
get { return m_Room; }
set { m_Room = value; }
}
[Constructable]
public ExperimentalRoomBlocker( Room room ) : base(7107)
{
m_Room = room;
Visible = false;
Movable = false;
}
public ExperimentalRoomBlocker( Serial serial ) : base(serial) {
}
public override bool OnMoveOver(Mobile from)
{
if(from.AccessLevel > AccessLevel.Player)
return true;
Container pack = from.Backpack;
if(pack != null)
{
Item[] items = pack.FindItemsByType(typeof(ExperimentalGem));
if(items != null)
{
foreach(Item item in items)
{
ExperimentalGem gem = (ExperimentalGem)item;
if(gem.Active && (gem.CurrentRoom > m_Room || m_Room == Room.RoomZero))
return true;
}
}
}
//TODO: Message?
return false;
}
public override void Serialize(GenericWriter writer) {
base.Serialize(writer);
writer.Write((int)0); // ver
writer.Write((int)m_Room);
}
public override void Deserialize(GenericReader reader) {
base.Deserialize(reader);
int version = reader.ReadInt();
m_Room = (Room)reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,207 @@
using Server;
using System;
namespace Server.Items
{
[Flipable(12287, 12288)]
public class TwoStoryBanner : Item
{
[Constructable]
public TwoStoryBanner() : base(12287)
{
}
public TwoStoryBanner( Serial serial ) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // ver
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class Stalagmite : Item
{
[Constructable]
public Stalagmite() : base(Utility.RandomList(2272, 2273, 2276, 2277, 2279, 2281, 2282))
{
}
public Stalagmite( Serial serial ) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // ver
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class Flowstone : Item
{
[Constructable]
public Flowstone() : base(Utility.RandomList(2274, 2275, 2278, 2280))
{
}
public Flowstone( Serial serial ) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // ver
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class HangingChainmailLegs : Item
{
[Constructable]
public HangingChainmailLegs() : base(5052)
{
}
public HangingChainmailLegs( Serial serial ) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // ver
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class HangingRingmailTunic : Item
{
[Constructable]
public HangingRingmailTunic() : base(5095)
{
}
public HangingRingmailTunic( Serial serial ) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // ver
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class PluckedChicken : Item
{
[Constructable]
public PluckedChicken() : base(7819)
{
}
public PluckedChicken( Serial serial ) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // ver
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class ColorfulTapestry : Item
{
[Constructable]
public ColorfulTapestry() : base(17092)
{
}
public ColorfulTapestry( Serial serial ) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // ver
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class CanvaslessEasel : Item
{
public override int LabelNumber { get { return 123467; } }
[Constructable]
public CanvaslessEasel() : base(Utility.RandomBool() ? 3943 : 3945)
{
}
public CanvaslessEasel( Serial serial ) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // ver
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,82 @@
using Server;
using System;
using Server.Mobiles;
using System.Xml;
using Server.Items;
namespace Server.Regions
{
public class ExperimentalRoomRegion : DungeonRegion
{
public ExperimentalRoomRegion(XmlElement xml, Map map, Region parent)
: base(xml, map, parent)
{
}
private static Rectangle2D m_Entrance = new Rectangle2D(994, 1114, 4, 4);
public override void OnLocationChanged(Mobile m, Point3D oldLocation)
{
if (m is BaseCreature && (((BaseCreature)m).Controlled || ((BaseCreature)m).Summoned))
{
foreach (Rectangle2D rec in m_RoomRecs)
{
if (rec.Contains(m.Location))
{
KickToEntrance(m);
Mobile master = ((BaseCreature)m).GetMaster();
if (master != null && master.NetState != null)
master.SendLocalizedMessage(1113472); // Your pet has been kicked out of the room. This is not a stable!
}
}
}
else if (m is PlayerMobile && m.AccessLevel == AccessLevel.Player)
{
if (m.Backpack == null)
KickToEntrance(m);
else
{
Item item = m.Backpack.FindItemByType(typeof(ExperimentalGem));
if (item == null)
{
foreach (Rectangle2D rec in m_RoomRecs)
{
if (rec.Contains(m.Location))
KickToEntrance(m);
}
}
}
}
}
public void KickToEntrance(Mobile from)
{
if (from == null || from.Map == null)
return;
int x = Utility.RandomMinMax(m_Entrance.X, m_Entrance.X + m_Entrance.Width);
int y = Utility.RandomMinMax(m_Entrance.Y, m_Entrance.Y + m_Entrance.Height);
int z = from.Map.GetAverageZ(x, y);
Point3D loc = from.Location;
Point3D p = new Point3D(x, y, z);
if(from is PlayerMobile)
BaseCreature.TeleportPets(from, p, Map.TerMur);
from.MoveToWorld(p, Map.TerMur);
Effects.SendLocationParticles(EffectItem.Create(loc, from.Map, EffectItem.DefaultDuration), 0x3728, 10, 10, 2023);
Effects.SendLocationParticles(EffectItem.Create(p, from.Map, EffectItem.DefaultDuration), 0x3728, 10, 10, 5023);
}
private static Rectangle2D[] m_RoomRecs = new Rectangle2D[]
{
new Rectangle2D(977, 1104, 15, 10), //RoomOne
new Rectangle2D(977, 1092, 15, 9), //RoomTwo
new Rectangle2D(977, 1074, 15, 10), //RoomThree
};
}
}

View File

@@ -0,0 +1,343 @@
using Server;
using System;
using System.Collections.Generic;
using Server.Mobiles;
using Server.Gumps;
using Server.Engines.Quests.Haven;
namespace Server.Items
{
public static class GenerateUnderworldRooms
{
public static void Generate()
{
ExperimentalRoomController controller = new ExperimentalRoomController();
controller.MoveToWorld(new Point3D(980, 1117, -42), Map.TerMur);
//Room 0 to 1
ExperimentalRoomDoor door = new ExperimentalRoomDoor(Room.RoomZero, DoorFacing.WestCCW);
ExperimentalRoomBlocker blocker = new ExperimentalRoomBlocker(Room.RoomZero);
door.Hue = 1109;
door.MoveToWorld(new Point3D(984, 1116, -42), Map.TerMur);
blocker.MoveToWorld(new Point3D(984, 1116, -42), Map.TerMur);
WeakEntityCollection.Add("sa", door);
WeakEntityCollection.Add("sa", blocker);
door = new ExperimentalRoomDoor(Room.RoomZero, DoorFacing.EastCW);
blocker = new ExperimentalRoomBlocker(Room.RoomZero);
door.Hue = 1109;
door.MoveToWorld(new Point3D(985, 1116, -42), Map.TerMur);
blocker.MoveToWorld(new Point3D(985, 1116, -42), Map.TerMur);
WeakEntityCollection.Add("sa", door);
WeakEntityCollection.Add("sa", blocker);
//Room 1 to 2
door = new ExperimentalRoomDoor(Room.RoomOne, DoorFacing.WestCCW);
blocker = new ExperimentalRoomBlocker(Room.RoomOne);
door.Hue = 1109;
door.MoveToWorld(new Point3D(984, 1102, -42), Map.TerMur);
blocker.MoveToWorld(new Point3D(984, 1102, -42), Map.TerMur);
WeakEntityCollection.Add("sa", door);
WeakEntityCollection.Add("sa", blocker);
door = new ExperimentalRoomDoor(Room.RoomOne, DoorFacing.EastCW);
blocker = new ExperimentalRoomBlocker(Room.RoomOne);
door.Hue = 1109;
door.MoveToWorld(new Point3D(985, 1102, -42), Map.TerMur);
blocker.MoveToWorld(new Point3D(985, 1102, -42), Map.TerMur);
WeakEntityCollection.Add("sa", door);
WeakEntityCollection.Add("sa", blocker);
//Room 2 to 3
door = new ExperimentalRoomDoor(Room.RoomTwo, DoorFacing.WestCCW);
blocker = new ExperimentalRoomBlocker(Room.RoomTwo);
door.Hue = 1109;
door.MoveToWorld(new Point3D(984, 1090, -42), Map.TerMur);
blocker.MoveToWorld(new Point3D(984, 1090, -42), Map.TerMur);
WeakEntityCollection.Add("sa", door);
WeakEntityCollection.Add("sa", blocker);
door = new ExperimentalRoomDoor(Room.RoomTwo, DoorFacing.EastCW);
blocker = new ExperimentalRoomBlocker(Room.RoomTwo);
door.Hue = 1109;
door.MoveToWorld(new Point3D(985, 1090, -42), Map.TerMur);
blocker.MoveToWorld(new Point3D(985, 1090, -42), Map.TerMur);
WeakEntityCollection.Add("sa", door);
WeakEntityCollection.Add("sa", blocker);
//Room 3 to 4
door = new ExperimentalRoomDoor(Room.RoomTwo, DoorFacing.WestCCW);
blocker = new ExperimentalRoomBlocker(Room.RoomThree);
door.Hue = 1109;
door.MoveToWorld(new Point3D(984, 1072, -42), Map.TerMur);
blocker.MoveToWorld(new Point3D(984, 1072, -42), Map.TerMur);
WeakEntityCollection.Add("sa", door);
WeakEntityCollection.Add("sa", blocker);
door = new ExperimentalRoomDoor(Room.RoomTwo, DoorFacing.EastCW);
blocker = new ExperimentalRoomBlocker(Room.RoomThree);
door.Hue = 1109;
door.MoveToWorld(new Point3D(985, 1072, -42), Map.TerMur);
blocker.MoveToWorld(new Point3D(985, 1072, -42), Map.TerMur);
WeakEntityCollection.Add("sa", door);
WeakEntityCollection.Add("sa", blocker);
ExperimentalRoomChest chest = new ExperimentalRoomChest();
chest.MoveToWorld(new Point3D(984, 1064, -37), Map.TerMur);
WeakEntityCollection.Add("sa", chest);
ExperimentalBook instr = new ExperimentalBook();
instr.Movable = false;
instr.MoveToWorld(new Point3D(995, 1114, -36), Map.TerMur);
WeakEntityCollection.Add("sa", instr);
SecretDungeonDoor dd = new SecretDungeonDoor(DoorFacing.NorthCCW);
dd.ClosedID = 87;
dd.OpenedID = 88;
dd.MoveToWorld(new Point3D(1007, 1119, -42), Map.TerMur);
WeakEntityCollection.Add("sa", dd);
LocalizedSign sign = new LocalizedSign(3026, 1113407); // Experimental Room Access
sign.Movable = false;
sign.MoveToWorld(new Point3D(980, 1119, -37), Map.TerMur);
WeakEntityCollection.Add("sa", sign);
//Puzze Room
PuzzleBox box = new PuzzleBox(PuzzleType.WestBox);
box.MoveToWorld(new Point3D(1090, 1171, 11), Map.TerMur);
WeakEntityCollection.Add("sa", box);
box = new PuzzleBox(PuzzleType.EastBox);
box.MoveToWorld(new Point3D(1104, 1171, 11), Map.TerMur);
WeakEntityCollection.Add("sa", box);
box = new PuzzleBox(PuzzleType.NorthBox);
box.MoveToWorld(new Point3D(1097, 1163, 11), Map.TerMur);
WeakEntityCollection.Add("sa", box);
PuzzleBook book = new PuzzleBook();
book.Movable = false;
book.MoveToWorld(new Point3D(1109, 1153, -17), Map.TerMur);
WeakEntityCollection.Add("sa", book);
PuzzleRoomTeleporter tele = new PuzzleRoomTeleporter();
tele.PointDest = new Point3D(1097, 1173, 1);
tele.MapDest = Map.TerMur;
tele.MoveToWorld(new Point3D(1097, 1175, 0), Map.TerMur);
WeakEntityCollection.Add("sa", tele);
tele = new PuzzleRoomTeleporter();
tele.PointDest = new Point3D(1098, 1173, 1);
tele.MapDest = Map.TerMur;
tele.MoveToWorld(new Point3D(1098, 1175, 0), Map.TerMur);
WeakEntityCollection.Add("sa", tele);
MetalDoor2 door2 = new MetalDoor2(DoorFacing.WestCCW);
door2.Locked = true;
door2.KeyValue = 50000;
door2.MoveToWorld(new Point3D(1097, 1174, 1), Map.TerMur);
WeakEntityCollection.Add("sa", door2);
door2 = new MetalDoor2(DoorFacing.EastCW);
door2.Locked = true;
door2.KeyValue = 50000;
door2.MoveToWorld(new Point3D(1098, 1174, 1), Map.TerMur);
WeakEntityCollection.Add("sa", door);
Teleporter telep = new Teleporter();
telep.PointDest = new Point3D(1097, 1175, 0);
telep.MapDest = Map.TerMur;
telep.MoveToWorld(new Point3D(1097, 1173, 1), Map.TerMur);
WeakEntityCollection.Add("sa", telep);
telep = new Teleporter();
telep.PointDest = new Point3D(1098, 1175, 0);
telep.MapDest = Map.TerMur;
telep.MoveToWorld(new Point3D(1098, 1173, 1), Map.TerMur);
WeakEntityCollection.Add("sa", telep);
telep = new Teleporter();
telep.PointDest = new Point3D(996, 1117, -42);
telep.MapDest = Map.TerMur;
telep.MoveToWorld(new Point3D(980, 1064, -42), Map.TerMur);
WeakEntityCollection.Add("sa", telep);
Static sparkle = new Static(14138);
sparkle.MoveToWorld(new Point3D(980, 1064, -42), Map.TerMur);
WeakEntityCollection.Add("sa", sparkle);
//Maze of Death
UnderworldPuzzleBox pBox = new UnderworldPuzzleBox();
pBox.MoveToWorld(new Point3D(1068, 1026, -37), Map.TerMur);
WeakEntityCollection.Add("sa", pBox);
GoldenCompass compass = new GoldenCompass();
compass.MoveToWorld(new Point3D(1070, 1055, -34), Map.TerMur);
WeakEntityCollection.Add("sa", compass);
Item map = new RolledMapOfTheUnderworld();
map.MoveToWorld(new Point3D(1072, 1055, -36), Map.TerMur);
map.Movable = false;
WeakEntityCollection.Add("sa", map);
FountainOfFortune f = new FountainOfFortune();
f.MoveToWorld(new Point3D(1121, 957, -42), Map.TerMur);
WeakEntityCollection.Add("sa", f);
Item tile = new InvisibleTile();
tile.MoveToWorld(new Point3D(1121, 965, -41), Map.TerMur);
WeakEntityCollection.Add("sa", tile);
tile = new InvisibleTile();
tile.MoveToWorld(new Point3D(1122, 965, -40), Map.TerMur);
WeakEntityCollection.Add("sa", tile);
tile = new InvisibleTile();
tile.MoveToWorld(new Point3D(1123, 965, -41), Map.TerMur);
WeakEntityCollection.Add("sa", tile);
tile = new InvisibleTile();
tile.MoveToWorld(new Point3D(1124, 965, -41), Map.TerMur);
WeakEntityCollection.Add("sa", tile);
tile = new InvisibleTile();
tile.MoveToWorld(new Point3D(1122, 964, -41), Map.TerMur);
WeakEntityCollection.Add("sa", tile);
tile = new InvisibleTile();
tile.MoveToWorld(new Point3D(1123, 964, -41), Map.TerMur);
WeakEntityCollection.Add("sa", tile);
tile = new InvisibleTile();
tile.MoveToWorld(new Point3D(1123, 963, -40), Map.TerMur);
WeakEntityCollection.Add("sa", tile);
tile = new InvisibleTile();
tile.MoveToWorld(new Point3D(1123, 962, -40), Map.TerMur);
WeakEntityCollection.Add("sa", tile);
tile = new InvisibleTile();
tile.MoveToWorld(new Point3D(1123, 961, -41), Map.TerMur);
WeakEntityCollection.Add("sa", tile);
tile = new InvisibleTile();
tile.MoveToWorld(new Point3D(1122, 961, -41), Map.TerMur);
WeakEntityCollection.Add("sa", tile);
tile = new InvisibleTile();
tile.MoveToWorld(new Point3D(1122, 960, -41), Map.TerMur);
WeakEntityCollection.Add("sa", tile);
tile = new InvisibleTile();
tile.MoveToWorld(new Point3D(1121, 960, -41), Map.TerMur);
WeakEntityCollection.Add("sa", tile);
tile = new InvisibleTile();
tile.MoveToWorld(new Point3D(1121, 959, -41), Map.TerMur);
WeakEntityCollection.Add("sa", tile);
GenerateRevealTiles();
CheckCannoneers();
Console.WriteLine("Experimental Room, Puzzle Room and Maze of Death initialized.");
}
public static void GenerateRevealTiles()
{
Map map = Map.TerMur;
for (int x = 1182; x <= 1192; x++)
{
for (int y = 1120; y <= 1134; y++)
{
if (map != null && map.CanSpawnMobile(x, y, -42))
{
var t = new RevealTile();
t.MoveToWorld(new Point3D(x, y, -42), map);
WeakEntityCollection.Add("sa", t);
}
}
}
var tile = new RevealTile();
tile.MoveToWorld(new Point3D(1180, 883, 0), map);
WeakEntityCollection.Add("sa", tile);
tile = new RevealTile();
tile.MoveToWorld(new Point3D(1180, 882, 0), map);
WeakEntityCollection.Add("sa", tile);
tile = new RevealTile();
tile.MoveToWorld(new Point3D(1180, 881, 0), map);
WeakEntityCollection.Add("sa", tile);
tile = new RevealTile();
tile.MoveToWorld(new Point3D(1180, 880, 0), map);
WeakEntityCollection.Add("sa", tile);
tile = new RevealTile();
tile.MoveToWorld(new Point3D(1180, 879, 0), map);
WeakEntityCollection.Add("sa", tile);
}
public static void CheckCannoneers()
{
Cannon cannon = Map.TerMur.FindItem<Cannon>(new Point3D(1126, 1200, -2));
MilitiaCanoneer cannoneer = null;
if (cannon == null)
{
cannon = new Cannon(CannonDirection.North);
cannon.MoveToWorld(new Point3D(1126, 1200, -2), Map.TerMur);
WeakEntityCollection.Add("sa", cannon);
}
cannoneer = Map.TerMur.FindMobile<MilitiaCanoneer>(new Point3D(1126, 1203, -2));
if (cannoneer == null)
{
cannoneer = new MilitiaCanoneer();
cannoneer.MoveToWorld(new Point3D(1126, 1203, -2), Map.TerMur);
WeakEntityCollection.Add("sa", cannoneer);
}
cannon.Canoneer = cannoneer;
cannon = Map.TerMur.FindItem<Cannon>(new Point3D(1131, 1200, -2));
cannoneer = null;
if (cannon == null)
{
cannon = new Cannon(CannonDirection.North);
cannon.MoveToWorld(new Point3D(1131, 1200, -2), Map.TerMur);
WeakEntityCollection.Add("sa", cannon);
}
cannoneer = Map.TerMur.FindMobile<MilitiaCanoneer>(new Point3D(1131, 1203, -2));
if (cannoneer == null)
{
cannoneer = new MilitiaCanoneer();
cannoneer.MoveToWorld(new Point3D(1131, 1203, -2), Map.TerMur);
WeakEntityCollection.Add("sa", cannoneer);
}
cannon.Canoneer = cannoneer;
}
private static bool FindItem(Point3D p, Map map)
{
IPooledEnumerable eable = map.GetItemsInRange(p, 0);
foreach (Item item in eable)
{
eable.Free();
return true;
}
eable.Free();
return false;
}
}
}

View File

@@ -0,0 +1,43 @@
using Server;
using System;
using Server.Mobiles;
using Server.Items;
using System.Collections.Generic;
namespace Server.Gumps
{
public class CompassDirectionGump : Gump
{
private Mobile m_From;
public CompassDirectionGump(Mobile from) : base(120, 50)
{
m_From = from;
List<Point3D> pointList = Server.Regions.MazeOfDeathRegion.Path;
Point3D cur = m_From.Location;
Point3D northLoc = new Point3D(cur.X, cur.Y - 1, cur.Z);
Point3D eastLoc = new Point3D(cur.X + 1, cur.Y, cur.Z);
Point3D southLoc = new Point3D(cur.X, cur.Y + 1, cur.Z);
Point3D westLoc = new Point3D(cur.X - 1, cur.Y, cur.Z);
//this.Closable = false;
//Empty radar
AddImage(0, 0, 9007);
//Arrows
if(pointList.Contains(northLoc))
AddImage(100, 50, 4501);
if(pointList.Contains(eastLoc))
AddImage(100, 100, 4503);
if(pointList.Contains(southLoc))
AddImage(50, 100, 4505);
if(pointList.Contains(westLoc))
AddImage(50, 50, 4507);
}
}
}

View File

@@ -0,0 +1,86 @@
using Server;
using System;
using Server.Gumps;
using Server.Regions;
using Server.Mobiles;
namespace Server.Items
{
public class GoldenCompass : BaseDecayingItem
{
private int m_Span;
public override int Lifespan { get { return m_Span; } }
public override int LabelNumber { get { return 1113578; } } // a golden compass
[Constructable]
public GoldenCompass() : base(459)
{
Weight = 1;
Hue = 0x501;
m_Span = 0;
Movable = false;
}
public override void OnDoubleClick(Mobile from)
{
if (IsChildOf(from.Backpack) && from.Region != null && from.Region.IsPartOf<MazeOfDeathRegion>())
{
from.CloseGump(typeof(CompassDirectionGump));
from.SendGump(new CompassDirectionGump(from));
}
else if (RootParent == null && from.InRange(GetWorldLocation(), 3) && !Movable && !IsLockedDown && !IsSecure)
{
if (from.Backpack != null && m_Span == 0 && from.Backpack.FindItemByType(typeof(GoldenCompass)) == null)
{
GoldenCompass c = new GoldenCompass();
c.StartTimer();
from.Backpack.DropItem(c);
from.SendLocalizedMessage(1113584); // Please return what you borrow!
}
}
}
public override void StartTimer()
{
TimeLeft = 1800;
m_Span = 1800;
Movable = true;
base.StartTimer();
InvalidateProperties();
}
public override void OnDelete()
{
base.OnDelete();
Mobile m = this.RootParent as Mobile;
if (m != null)
m.CloseGump(typeof(Server.Gumps.CompassDirectionGump));
}
public GoldenCompass(Serial serial) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
writer.Write(m_Span);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int v = reader.ReadInt();
m_Span = reader.ReadInt();
if(m_Span > 0)
{
StartTimer();
}
}
}
}

View File

@@ -0,0 +1,372 @@
using Server;
using System;
using Server.Mobiles;
using Server.Gumps;
using System.Collections.Generic;
using Server.Targeting;
using Server.Items;
namespace Server.Regions
{
public class MazeOfDeathRegion : Region
{
public static void Initialize()
{
new MazeOfDeathRegion();
m_Path = new List<Point3D>();
m_Path.Add(new Point3D(1062, 1060, -42));
m_Path.Add(new Point3D(1062, 1059, -42));
m_Path.Add(new Point3D(1062, 1058, -42));
m_Path.Add(new Point3D(1061, 1058, -42));
m_Path.Add(new Point3D(1060, 1058, -42));
m_Path.Add(new Point3D(1060, 1057, -42));
m_Path.Add(new Point3D(1059, 1057, -42));
m_Path.Add(new Point3D(1059, 1056, -42));
m_Path.Add(new Point3D(1059, 1055, -42));
m_Path.Add(new Point3D(1060, 1055, -42));
m_Path.Add(new Point3D(1060, 1054, -42));
m_Path.Add(new Point3D(1060, 1053, -42));
m_Path.Add(new Point3D(1059, 1053, -42));
m_Path.Add(new Point3D(1059, 1052, -42));
m_Path.Add(new Point3D(1059, 1051, -42));
m_Path.Add(new Point3D(1059, 1050, -42));
m_Path.Add(new Point3D(1058, 1050, -42));
m_Path.Add(new Point3D(1058, 1049, -42));
m_Path.Add(new Point3D(1057, 1049, -42));
m_Path.Add(new Point3D(1057, 1048, -42));
m_Path.Add(new Point3D(1057, 1047, -42));
m_Path.Add(new Point3D(1057, 1046, -42));
m_Path.Add(new Point3D(1058, 1047, -42));
m_Path.Add(new Point3D(1059, 1047, -42));
m_Path.Add(new Point3D(1059, 1046, -42));
m_Path.Add(new Point3D(1059, 1045, -42));
m_Path.Add(new Point3D(1059, 1044, -42));
m_Path.Add(new Point3D(1060, 1044, -42));
m_Path.Add(new Point3D(1061, 1044, -42));
m_Path.Add(new Point3D(1061, 1043, -42));
m_Path.Add(new Point3D(1060, 1042, -42));
m_Path.Add(new Point3D(1059, 1042, -42));
m_Path.Add(new Point3D(1058, 1042, -42));
m_Path.Add(new Point3D(1057, 1042, -42));
m_Path.Add(new Point3D(1061, 1042, -42));
m_Path.Add(new Point3D(1061, 1041, -42));
m_Path.Add(new Point3D(1061, 1042, -42));
m_Path.Add(new Point3D(1062, 1042, -42));
m_Path.Add(new Point3D(1062, 1041, -42));
m_Path.Add(new Point3D(1062, 1040, -42));
m_Path.Add(new Point3D(1063, 1040, -42));
m_Path.Add(new Point3D(1063, 1041, -42));
m_Path.Add(new Point3D(1063, 1040, -42));
m_Path.Add(new Point3D(1063, 1039, -42));
m_Path.Add(new Point3D(1062, 1039, -42));
m_Path.Add(new Point3D(1062, 1038, -42));
m_Path.Add(new Point3D(1061, 1038, -42));
m_Path.Add(new Point3D(1061, 1037, -42));
m_Path.Add(new Point3D(1060, 1037, -42));
m_Path.Add(new Point3D(1059, 1037, -42));
m_Path.Add(new Point3D(1058, 1037, -42));
m_Path.Add(new Point3D(1057, 1037, -42));
m_Path.Add(new Point3D(1057, 1036, -42));
m_Path.Add(new Point3D(1057, 1035, -42));
m_Path.Add(new Point3D(1058, 1035, -42));
m_Path.Add(new Point3D(1059, 1035, -42));
m_Path.Add(new Point3D(1057, 1034, -42));
m_Path.Add(new Point3D(1057, 1033, -42));
m_Path.Add(new Point3D(1057, 1032, -42));
m_Path.Add(new Point3D(1058, 1032, -42));
m_Path.Add(new Point3D(1059, 1032, -42));
m_Path.Add(new Point3D(1060, 1032, -42));
m_Path.Add(new Point3D(1060, 1031, -42));
m_Path.Add(new Point3D(1060, 1030, -42));
m_Path.Add(new Point3D(1060, 1029, -42));
m_Path.Add(new Point3D(1061, 1029, -42));
m_Path.Add(new Point3D(1061, 1028, -42));
m_Path.Add(new Point3D(1061, 1027, -42));
m_Path.Add(new Point3D(1062, 1027, -42));
m_Path.Add(new Point3D(1063, 1027, -42));
m_Path.Add(new Point3D(1064, 1027, -42));
m_Path.Add(new Point3D(1061, 1026, -42));
m_Path.Add(new Point3D(1062, 1026, -42));
m_Path.Add(new Point3D(1063, 1026, -42));
m_Path.Add(new Point3D(1064, 1026, -42));
m_Path.Add(new Point3D(1061, 1026, -42));
m_Path.Add(new Point3D(1061, 1025, -42));
m_Path.Add(new Point3D(1061, 1024, -42));
m_Path.Add(new Point3D(1061, 1023, -42));
m_Path.Add(new Point3D(1061, 1022, -42));
m_Path.Add(new Point3D(1060, 1026, -42));
m_Path.Add(new Point3D(1059, 1026, -42));
m_Path.Add(new Point3D(1058, 1026, -42));
m_Path.Add(new Point3D(1058, 1025, -42));
m_Path.Add(new Point3D(1058, 1024, -42));
m_Path.Add(new Point3D(1058, 1023, -42));
m_Path.Add(new Point3D(1058, 1022, -42));
m_Path.Add(new Point3D(1058, 1021, -42));
m_Path.Add(new Point3D(1057, 1021, -42));
m_Path.Add(new Point3D(1057, 1020, -42));
m_Path.Add(new Point3D(1057, 1019, -42));
m_Path.Add(new Point3D(1057, 1018, -42));
m_Path.Add(new Point3D(1058, 1018, -42));
m_Path.Add(new Point3D(1059, 1018, -42));
m_Path.Add(new Point3D(1060, 1018, -42));
m_Path.Add(new Point3D(1061, 1018, -42));
m_Path.Add(new Point3D(1061, 1017, -42));
m_Path.Add(new Point3D(1061, 1016, -42));
m_Path.Add(new Point3D(1061, 1015, -42));
m_Path.Add(new Point3D(1061, 1014, -42));
m_Path.Add(new Point3D(1061, 1013, -42));
m_Path.Add(new Point3D(1061, 1012, -42));
m_Path.Add(new Point3D(1061, 1011, -42));
m_Path.Add(new Point3D(1061, 1010, -42));
m_Path.Add(new Point3D(1060, 1010, -42));
m_Path.Add(new Point3D(1059, 1010, -42));
m_Path.Add(new Point3D(1059, 1009, -42));
m_Path.Add(new Point3D(1059, 1008, -42));
m_Path.Add(new Point3D(1059, 1007, -42));
m_Path.Add(new Point3D(1059, 1006, -42));
m_Path.Add(new Point3D(1059, 1005, -42));
m_Path.Add(new Point3D(1059, 1004, -42));
m_Path.Add(new Point3D(1058, 1004, -42));
m_Path.Add(new Point3D(1057, 1004, -42));
m_Path.Add(new Point3D(1057, 1003, -42));
m_Path.Add(new Point3D(1057, 1002, -42));
m_Path.Add(new Point3D(1057, 1001, -42));
m_Path.Add(new Point3D(1057, 1000, -42));
m_Path.Add(new Point3D(1057, 999, -42));
m_Path.Add(new Point3D(1058, 999, -42));
m_Path.Add(new Point3D(1059, 999, -42));
m_Path.Add(new Point3D(1060, 999, -42));
m_Path.Add(new Point3D(1061, 999, -42));
m_Path.Add(new Point3D(1062, 999, -42));
m_Path.Add(new Point3D(1063, 999, -42));
m_Path.Add(new Point3D(1063, 998, -42));
m_Path.Add(new Point3D(1063, 997, -42));
m_Path.Add(new Point3D(1063, 996, -42));
m_Path.Add(new Point3D(1063, 995, -42));
m_Path.Add(new Point3D(1063, 994, -42));
m_Path.Add(new Point3D(1062, 994, -42));
m_Path.Add(new Point3D(1061, 994, -42));
m_Path.Add(new Point3D(1061, 993, -42));
m_Path.Add(new Point3D(1061, 992, -42));
m_Path.Add(new Point3D(1061, 991, -42));
m_Path.Add(new Point3D(1061, 990, -42));
//Add some randoms
int toAdd = 33;
while (toAdd > 0)
{
int x = Utility.RandomMinMax(m_TrapBounds.X, m_TrapBounds.X + m_TrapBounds.Width);
int y = Utility.RandomMinMax(m_TrapBounds.Y, m_TrapBounds.Y + m_TrapBounds.Height);
int z = -42;
Point3D p = new Point3D(x, y, z);
if (!m_Path.Contains(p))
{
m_Path.Add(p);
toAdd--;
}
}
}
private static Rectangle2D[] m_Bounds = new Rectangle2D[]
{
new Rectangle2D(1057, 1028, 16, 40),
new Rectangle2D(1057, 990, 16, 38)
};
private static Rectangle2D m_TrapBounds = new Rectangle2D(1057, 990, 7, 71);
private static List<Point3D> m_Path;
public static List<Point3D> Path { get { return m_Path; } }
private static Rectangle2D m_Entrance = new Rectangle2D(1057, 1062, 7, 5);
public MazeOfDeathRegion() : base("Maze of Death", Map.TerMur, Region.DefaultPriority, m_Bounds)
{
Register();
}
public override bool OnBeginSpellCast(Mobile m, ISpell s)
{
if (m.AccessLevel > AccessLevel.Player)
return true;
if (s is Spells.Sixth.MarkSpell || s is Spells.Seventh.GateTravelSpell || s is Spells.Third.TeleportSpell)
{
m.SendLocalizedMessage(501802); // that spell doesn't seem to work.
return false;
}
return base.OnBeginSpellCast(m, s);
}
public override bool OnTarget( Mobile m, Target t, object o )
{
if(m.AccessLevel == AccessLevel.Player && t is Server.Spells.Third.TeleportSpell.InternalTarget)
{
m.SendLocalizedMessage(501802); // that spell doesn't seem to work.
return false;
}
return base.OnTarget(m, t, o);
}
public override void OnEnter( Mobile m )
{
if(m.Backpack == null)
return;
if (m.NetState != null)
{
m.Paralyze(TimeSpan.FromSeconds(2));
m.PrivateOverheadMessage(Server.Network.MessageType.Regular, 33, 1113580, m.NetState); // You are filled with a sense of dread and impending doom!
m.PrivateOverheadMessage(Server.Network.MessageType.Regular, 0x3B2, 1113581, m.NetState); // I might need something to help me navigate through this.
if (m.Backpack.FindItemByType(typeof(GoldenCompass)) != null)
{
m.CloseGump(typeof(CompassDirectionGump));
m.SendGump(new CompassDirectionGump(m));
}
}
base.OnEnter(m);
}
public override void OnExit( Mobile m )
{
m.CloseGump(typeof(CompassDirectionGump));
base.OnExit(m);
}
public override void OnLocationChanged( Mobile m, Point3D oldLocation )
{
base.OnLocationChanged(m, oldLocation);
if (oldLocation.X > 1063 && m.Location.X <= 1063)
{
if (m.Backpack != null && m.Backpack.FindItemByType(typeof(GoldenCompass)) != null)
m.SendLocalizedMessage(1113582); // I better proceed with caution.
else
m.SendLocalizedMessage(1113581); // I might need something to help me navigate through this.
}
else if (oldLocation.Y == 991 && m.Location.Y == 990)
{
if(m.HasGump(typeof(CompassDirectionGump)))
m.SendLocalizedMessage(1113585); // The compass' arrows flicker. You must be near the right location.
}
if(m != null && m.Backpack != null)
{
Item item = m.Backpack.FindItemByType(typeof(GoldenCompass));
if (m.Alive && !m_Path.Contains(m.Location) && m_TrapBounds.Contains(m.Location))
SpringTrap(m);
else if (m.Alive && m.HasGump(typeof(CompassDirectionGump)))
{
//May need to check old gump to get x,y so new gump opens in same spot!
m.CloseGump(typeof(CompassDirectionGump));
m.SendGump(new CompassDirectionGump(m));
}
}
}
public override void OnDeath( Mobile m )
{
base.OnDeath(m);
if(m.Player && m_TrapBounds.Contains(m.Location))
Timer.DelayCall(TimeSpan.FromSeconds(3), new TimerStateCallback(Kick_Callback), m);
}
public void SpringTrap(Mobile from)
{
if (from == null || !from.Alive)
return;
int cliloc;
int damage = Utility.RandomMinMax(75, 150);
switch (Utility.Random(4))
{
default:
case 0:
Effects.SendLocationEffect( from, from.Map, 0x3709, 30 );
from.PlaySound( 0x54 );
cliloc = 1010524; // Searing heat scorches thy skin.
AOS.Damage(from, damage, 0, 100, 0, 0, 0);
break;
case 1:
from.PlaySound(0x223);
cliloc = 1010525; // Pain lances through thee from a sharp metal blade.
AOS.Damage(from, damage, 100, 0, 0, 0, 0);
break;
case 2:
from.BoltEffect(0);
cliloc = 1010526; // Lightning arcs through thy body.
AOS.Damage(from, damage, 0, 0, 0, 0, 100);
break;
case 3:
Effects.SendLocationEffect( from, from.Map, 0x113A, 20, 10 );
from.PlaySound( 0x231 );
from.ApplyPoison(from, Poison.Deadly);
cliloc = 1010523; // A toxic vapor envelops thee.
AOS.Damage(from, damage, 0, 0, 0, 100, 0);
break;
}
from.LocalOverheadMessage(Server.Network.MessageType.Regular, 0xEE, cliloc);
}
public void Kick_Callback(object o)
{
Mobile m = (Mobile)o;
if(m != null)
KickToEntrance(m);
}
public void KickToEntrance(Mobile from)
{
if(from == null || from.Map == null)
return;
int x = Utility.RandomMinMax(m_Entrance.X, m_Entrance.X + m_Entrance.Width);
int y = Utility.RandomMinMax(m_Entrance.Y, m_Entrance.Y + m_Entrance.Height);
int z = from.Map.GetAverageZ(x, y);
Point3D p = new Point3D(x, y, z);
from.MoveToWorld(p, Map.TerMur);
if(from.Player && !from.Alive && from.Corpse != null)
from.Corpse.MoveToWorld(p, Map.TerMur);
from.SendMessage("You have been teleported to the beginning of the maze.");
}
}
}

View File

@@ -0,0 +1,201 @@
using System;
using Server;
namespace Server.Items
{
[Flipable(5353, 5354)]
public class MouldingBoard : Item
{
[Constructable]
public MouldingBoard () : base(5353)
{
}
public MouldingBoard ( Serial serial ) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // ver
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class DoughBowl : Item
{
[Constructable]
public DoughBowl () : base(4323)
{
}
public DoughBowl ( Serial serial ) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // ver
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class HornedTotemPole : Item
{
[Constructable]
public HornedTotemPole () : base(12289)
{
}
public HornedTotemPole ( Serial serial ) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // ver
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class LargeSquarePillow : Item
{
[Constructable]
public LargeSquarePillow () : base(5691)
{
}
public LargeSquarePillow ( Serial serial ) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // ver
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class LargeDiamondPillow : Item
{
[Constructable]
public LargeDiamondPillow () : base(5690)
{
}
public LargeDiamondPillow ( Serial serial ) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // ver
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class DustyPillow : Item
{
public override int LabelNumber { get { return 1113638; } } // dusty pillow
[Constructable]
public DustyPillow () : base(Utility.RandomList(5690, 5691))
{
}
public DustyPillow ( Serial serial ) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // ver
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class StatuePedestal : Item
{
[Constructable]
public StatuePedestal () : base(13042)
{
Weight = 5;
}
public StatuePedestal ( Serial serial ) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // ver
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
/*public class FlouredBreadBoard : Item
{
[Constructable]
public FlouredBreadBoard () : base(1234)
{
}
public FlouredBreadBoard ( Serial serial ) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // ver
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}*/
}

View File

@@ -0,0 +1,49 @@
using Server;
using System;
using Server.Gumps;
using Server.Mobiles;
namespace Server.Items
{
public class RolledMapOfTheUnderworld : Item
{
[Constructable]
public RolledMapOfTheUnderworld() : base(5357)
{
}
public override void OnDoubleClick(Mobile from)
{
if (from.InRange(GetWorldLocation(), 3))
{
from.CloseGump(typeof(InternalGump));
from.SendGump(new InternalGump());
}
}
public RolledMapOfTheUnderworld(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();
}
private class InternalGump : Gump
{
public InternalGump()
: base(75, 75)
{
AddImage(0, 0, 0x7739);
}
}
}
}

View File

@@ -0,0 +1,902 @@
using System;
using Server;
using Server.Gumps;
using Server.Network;
namespace Server.Items
{
public class UnderworldPuzzleItem : BaseDecayingItem
{
public static readonly int MaxAttempts = 8;
private UnderworldPuzzleSolution m_Solution;
private UnderworldPuzzleSolution m_CurrentSolution;
private int m_Attempts;
public UnderworldPuzzleSolution Solution { get { return m_Solution; } }
public UnderworldPuzzleSolution CurrentSolution { get { return m_CurrentSolution; } set { m_CurrentSolution = value; } }
public override int LabelNumber { get { return 1113379; } } // Puzzle Board
[CommandProperty(AccessLevel.GameMaster)]
public int Attempts
{
get { return m_Attempts; }
set
{
m_Attempts = value;
/*if (m_Solution != null && m_Attempts >= m_Solution.MaxAttempts)
{
m_Solution = new UnderworldPuzzleSolution();
m_CurrentSolution = new UnderworldPuzzleSolution(m_Solution.Index);
m_Attempts = 0;
Mobile m = (Mobile)RootParent;
if (m != null)
m.SendMessage("You failed to complete the puzzle board.");
}*/
}
}
public override int Lifespan { get { return 1800; } }
[Constructable]
public UnderworldPuzzleItem()
: base(0x2AAA)
{
Hue = 914;
m_Attempts = 0;
m_Solution = new UnderworldPuzzleSolution();
m_CurrentSolution = new UnderworldPuzzleSolution(m_Solution.Index);
}
public override void OnDoubleClick(Mobile from)
{
if (!IsChildOf(from.Backpack))
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
else
{
from.CloseGump(typeof(UnderworldPuzzleGump));
from.SendGump(new UnderworldPuzzleGump(from, this));
}
}
public bool SubmitSolution(Mobile m, UnderworldPuzzleSolution solution)
{
if (solution.Matches(m_Solution))
{
Item item = Loot.Construct(m_Rewards[Utility.Random(m_Rewards.Length)]);
if (item != null)
{
if (item is VoidEssence || item is SilverSerpentVenom || item is ToxicVenomSac)
item.Amount = 30;
if (item is LuckyCoin)
item.Amount = Utility.RandomMinMax(2, 6);
if (m.Backpack == null || !m.Backpack.TryDropItem(m, item, false))
m.BankBox.DropItem(item);
}
m.PlaySound(0x3D);
m.SendLocalizedMessage(1113579); // Correct Code Entered. Crystal Lock Disengaged.
Delete();
return true;
}
return false;
}
private Type[] m_Rewards = new Type[]
{
typeof(VoidEssence), typeof(SilverSerpentVenom), typeof(ScouringToxin),
typeof(ToxicVenomSac), typeof(MouldingBoard), typeof(DoughBowl),
typeof(HornedTotemPole), typeof(LargeSquarePillow), typeof(LargeDiamondPillow),
typeof(DustyPillow), typeof(StatuePedestal), /*typeof(FlouredBreadBoard),*/
typeof(LuckyCoin),
};
public override void OnDelete()
{
base.OnDelete();
Mobile m = this.RootParent as Mobile;
if (m != null)
m.CloseGump(typeof(UnderworldPuzzleGump));
}
public UnderworldPuzzleItem(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();
Delete();
}
}
public enum PuzzlePiece
{
None,
RedSingle,
RedDouble,
RedTriple,
RedBar,
BlueSingle,
BlueDouble,
BlueTriple,
BlueBar,
GreenSingle,
GreenDouble,
GreenTriple,
GreenBar
}
public enum PuzzleColor
{
Red,
Blue,
Green
}
public class UnderworldPuzzleSolution
{
public const int Length = 4;
private PuzzlePiece[] m_Rows = new PuzzlePiece[Length];
public PuzzlePiece[] Rows { get { return m_Rows; } }
private int m_Index;
private int m_MaxAttempts;
public int Index { get { return m_Index; } }
public int MaxAttempts { get { return m_MaxAttempts; } }
public PuzzlePiece First { get { return m_Rows[0]; } set { m_Rows[0] = value; } }
public PuzzlePiece Second { get { return m_Rows[1]; } set { m_Rows[1] = value; } }
public PuzzlePiece Third { get { return m_Rows[2]; } set { m_Rows[2] = value; } }
public PuzzlePiece Fourth { get { return m_Rows[3]; } set { m_Rows[3] = value; } }
public UnderworldPuzzleSolution()
{
PickRandom();
}
public UnderworldPuzzleSolution(int index)
{
LoadStartSolution(index);
}
public UnderworldPuzzleSolution(PuzzlePiece first, PuzzlePiece second, PuzzlePiece third, PuzzlePiece fourth)
{
First = first;
Second = second;
Third = third;
Fourth = fourth;
}
public bool Matches(UnderworldPuzzleSolution check)
{
return GetMatches(check) >= 4;
}
public int GetMatches(UnderworldPuzzleSolution check)
{
int matches = 0;
for (int i = 0; i < m_Rows.Length; i++)
{
if (m_Rows[i] == check.Rows[i])
matches++;
}
return matches;
}
public void PickRandom()
{
m_Index = Utility.Random(16);
switch (m_Index)
{
case 0: //Good To Go
First = PuzzlePiece.RedSingle;
Second = PuzzlePiece.BlueSingle;
Third = PuzzlePiece.RedSingle;
Fourth = PuzzlePiece.GreenSingle;
m_MaxAttempts = 6;
break;
case 1: //Good To Go
First = PuzzlePiece.GreenDouble;
Second = PuzzlePiece.RedBar;
Third = PuzzlePiece.None;
Fourth = PuzzlePiece.BlueTriple;
m_MaxAttempts = 6;
break;
case 2: //Good To Go
First = PuzzlePiece.None;
Second = PuzzlePiece.None;
Third = PuzzlePiece.RedBar;
Fourth = PuzzlePiece.RedTriple;
m_MaxAttempts = 4;
break;
case 3: //Good To Go
First = PuzzlePiece.BlueDouble;
Second = PuzzlePiece.None;
Third = PuzzlePiece.GreenDouble;
Fourth = PuzzlePiece.GreenDouble;
m_MaxAttempts = 7;
break;
case 4: //Good To Go
First = PuzzlePiece.BlueSingle;
Second = PuzzlePiece.GreenSingle;
Third = PuzzlePiece.GreenDouble;
Fourth = PuzzlePiece.RedBar;
m_MaxAttempts = 7;
break;
case 5: //Good To Go
First = PuzzlePiece.GreenDouble;
Second = PuzzlePiece.BlueBar;
Third = PuzzlePiece.RedSingle;
Fourth = PuzzlePiece.BlueSingle;
m_MaxAttempts = 8;
break;
case 6: //Good To Go
First = PuzzlePiece.GreenSingle;
Second = PuzzlePiece.RedSingle;
Third = PuzzlePiece.BlueDouble;
Fourth = PuzzlePiece.GreenBar;
m_MaxAttempts = 5;
break;
case 7: //Good To Go
First = PuzzlePiece.BlueDouble;
Second = PuzzlePiece.None;
Third = PuzzlePiece.BlueTriple;
Fourth = PuzzlePiece.None;
m_MaxAttempts = 4;
break;
case 8: //Good To Go
First = PuzzlePiece.GreenSingle;
Second = PuzzlePiece.GreenBar;
Third = PuzzlePiece.RedDouble;
Fourth = PuzzlePiece.RedSingle;
m_MaxAttempts = 7;
break;
case 9: //Good to Go
First = PuzzlePiece.BlueSingle;
Second = PuzzlePiece.GreenDouble;
Third = PuzzlePiece.None;
Fourth = PuzzlePiece.GreenTriple;
m_MaxAttempts = 6;
break;
case 10: //Good To Go
First = PuzzlePiece.BlueSingle;
Second = PuzzlePiece.RedSingle;
Third = PuzzlePiece.RedTriple;
Fourth = PuzzlePiece.None;
m_MaxAttempts = 6;
break;
case 11: //Good To Go
First = PuzzlePiece.GreenSingle;
Second = PuzzlePiece.None;
Third = PuzzlePiece.GreenTriple;
Fourth = PuzzlePiece.GreenDouble;
m_MaxAttempts = 5;
break;
case 12: //Good to Go
First = PuzzlePiece.RedTriple;
Second = PuzzlePiece.None;
Third = PuzzlePiece.None;
Fourth = PuzzlePiece.RedTriple;
m_MaxAttempts = 6;
break;
case 13: //Good To Go
First = PuzzlePiece.None;
Second = PuzzlePiece.BlueTriple;
Third = PuzzlePiece.GreenSingle;
Fourth = PuzzlePiece.BlueDouble;
m_MaxAttempts = 7;
break;
case 14: //Good To Go
First = PuzzlePiece.BlueTriple;
Second = PuzzlePiece.None;
Third = PuzzlePiece.BlueTriple;
Fourth = PuzzlePiece.None;
m_MaxAttempts = 6;
break;
case 15: //Good to Go
First = PuzzlePiece.RedSingle;
Second = PuzzlePiece.BlueDouble;
Third = PuzzlePiece.RedDouble;
Fourth = PuzzlePiece.GreenSingle;
m_MaxAttempts = 6;
break;
}
}
public void LoadStartSolution(int index)
{
m_Index = index;
switch (index)
{
case 0:
First = PuzzlePiece.RedSingle;
Second = PuzzlePiece.RedSingle;
Third = PuzzlePiece.RedSingle;
Fourth = PuzzlePiece.RedSingle;
break;
case 1:
First = PuzzlePiece.BlueBar;
Second = PuzzlePiece.RedDouble;
Third = PuzzlePiece.RedBar;
Fourth = PuzzlePiece.BlueSingle;
break;
case 2:
First = PuzzlePiece.GreenBar;
Second = PuzzlePiece.BlueDouble;
Third = PuzzlePiece.RedTriple;
Fourth = PuzzlePiece.RedBar;
break;
case 3:
First = PuzzlePiece.RedSingle;
Second = PuzzlePiece.GreenDouble;
Third = PuzzlePiece.BlueTriple;
Fourth = PuzzlePiece.RedBar;
break;
case 4:
First = PuzzlePiece.GreenSingle;
Second = PuzzlePiece.RedBar;
Third = PuzzlePiece.RedDouble;
Fourth = PuzzlePiece.GreenSingle;
break;
case 5:
First = PuzzlePiece.RedBar;
Second = PuzzlePiece.GreenBar;
Third = PuzzlePiece.RedBar;
Fourth = PuzzlePiece.BlueBar;
break;
case 6:
First = PuzzlePiece.RedBar;
Second = PuzzlePiece.GreenDouble;
Third = PuzzlePiece.GreenDouble;
Fourth = PuzzlePiece.RedBar;
break;
case 7:
First = PuzzlePiece.GreenBar;
Second = PuzzlePiece.BlueSingle;
Third = PuzzlePiece.BlueTriple;
Fourth = PuzzlePiece.RedSingle;
break;
case 8:
First = PuzzlePiece.GreenBar;
Second = PuzzlePiece.None;
Third = PuzzlePiece.GreenTriple;
Fourth = PuzzlePiece.GreenSingle;
break;
case 9:
First = PuzzlePiece.RedBar;
Second = PuzzlePiece.RedBar;
Third = PuzzlePiece.RedBar;
Fourth = PuzzlePiece.RedBar;
break;
case 10:
First = PuzzlePiece.RedSingle;
Second = PuzzlePiece.None;
Third = PuzzlePiece.BlueDouble;
Fourth = PuzzlePiece.RedBar;
break;
case 11:
First = PuzzlePiece.RedDouble;
Second = PuzzlePiece.GreenDouble;
Third = PuzzlePiece.RedDouble;
Fourth = PuzzlePiece.BlueDouble;
break;
case 12:
First = PuzzlePiece.GreenTriple;
Second = PuzzlePiece.BlueBar;
Third = PuzzlePiece.GreenTriple;
Fourth = PuzzlePiece.RedBar;
break;
case 13:
First = PuzzlePiece.RedSingle;
Second = PuzzlePiece.GreenBar;
Third = PuzzlePiece.GreenBar;
Fourth = PuzzlePiece.RedSingle;
break;
case 14:
First = PuzzlePiece.GreenTriple;
Second = PuzzlePiece.GreenBar;
Third = PuzzlePiece.BlueBar;
Fourth = PuzzlePiece.GreenSingle;
break;
case 15:
First = PuzzlePiece.BlueTriple;
Second = PuzzlePiece.GreenDouble;
Third = PuzzlePiece.BlueSingle;
Fourth = PuzzlePiece.RedDouble;
break;
}
}
}
public class UnderworldPuzzleGump : Gump
{
private Mobile m_From;
private UnderworldPuzzleItem m_Item;
private UnderworldPuzzleSolution m_Solution;
private UnderworldPuzzleSolution m_CurrentSolution;
private int m_Row;
public UnderworldPuzzleGump(Mobile from, UnderworldPuzzleItem item)
: this(from, item, 0)
{
}
public UnderworldPuzzleGump(Mobile from, UnderworldPuzzleItem item, int row)
: base(45, 45)
{
if (row > 3) row = 3;
if (row < 0) row = 0;
m_From = from;
m_Item = item;
m_Row = row;
m_Solution = item.Solution;
m_CurrentSolution = item.CurrentSolution;
AddBackground(50, 50, 500, 200, 9250);
AddImageTiled(85, 210, 17, 150, 9255);
AddImageTiled(110, 63, 17, 150, 9255);
AddImageTiled(140, 90, 250, 17, 9251);
AddImageTiled(60, 125, 350, 17, 9251);
AddImageTiled(140, 160, 250, 17, 9251);
AddImageTiled(60, 195, 350, 17, 9251);
AddBackground(70, 70, 90, 155, 9250);
AddBackground(200, 70, 140, 155, 9250);
AddBackground(390, 70, 140, 155, 9250);
AddBackground(50, 280, 200, 120, 9250);
AddImage(0, 0, 10400);
AddImage(0, 170, 10401);
AddImage(0, 350, 10402);
AddButton(105, 87, row == 0 ? 208 : 209, row == 0 ? 209 : 208, 1, GumpButtonType.Reply, 0);
AddButton(105, 122, row == 1 ? 208 : 209, row == 0 ? 209 : 208, 2, GumpButtonType.Reply, 0);
AddButton(105, 157, row == 2 ? 208 : 209, row == 0 ? 209 : 208, 3, GumpButtonType.Reply, 0);
AddButton(105, 192, row == 3 ? 208 : 209, row == 0 ? 209 : 208, 4, GumpButtonType.Reply, 0);
AddPiece(0, true, m_Solution.First);
AddPiece(1, true, m_Solution.Second);
AddPiece(2, true, m_Solution.Third);
AddPiece(3, true, m_Solution.Fourth);
AddPiece(0, false, m_CurrentSolution.First);
AddPiece(1, false, m_CurrentSolution.Second);
AddPiece(2, false, m_CurrentSolution.Third);
AddPiece(3, false, m_CurrentSolution.Fourth);
for (int i = 0; i < 4; i++)
{
if (i == row && m_CurrentSolution.Rows[i] != PuzzlePiece.None && m_Item.Attempts < m_Solution.MaxAttempts)
{
AddButton(85, 87 + (i * 35), 2650, 2650, 5, GumpButtonType.Reply, 0); //Up
AddButton(125, 87 + (i * 35), 2648, 2648, 6, GumpButtonType.Reply, 0); //Down
}
else
{
AddImage(85, 87 + (i * 35), 2709);
AddImage(125, 87 + (i * 35), 2709);
}
}
AddButton(85, 87 + (row * 35), 2650, 2650, 5, GumpButtonType.Reply, 0); //Up
AddButton(125, 87 + (row * 35), 2648, 2648, 6, GumpButtonType.Reply, 0); //Down
AddHtmlLocalized(65, 295, 130, 16, 1150180, false, false); // Command Functions:
AddLabel(200, 295, 0, String.Format("{0}/{1}", m_Item.Attempts, m_Solution.MaxAttempts));
if(from.Skills[SkillName.Lockpicking].Base >= 100.0)
{
int locked = m_Solution.GetMatches(m_CurrentSolution);
AddHtmlLocalized(65, 310, 120, 16, 1150179, false, false); // Crystals Locked :
AddLabel(190, 310, 0, locked.ToString());
}
AddButton(80, 335, 2124, 2123, 7, GumpButtonType.Reply, 0); // Okay
AddButton(160, 335, 2073, 2072, 8, GumpButtonType.Reply, 0); // Cancel
AddButton(120, 360, 2011, 2010, 0, GumpButtonType.Reply, 0); // Logout
}
private void AddPiece(int row, bool right, PuzzlePiece piece)
{
int id = GetPuzzlePieceID(piece);
int x = right ? 405 : 215;
int y = 82 + (35 * row );
switch(piece)
{
case PuzzlePiece.None:
break;
case PuzzlePiece.RedSingle:
case PuzzlePiece.BlueSingle:
case PuzzlePiece.GreenSingle:
AddImage(x + 40, y, id);
break;
case PuzzlePiece.RedDouble:
case PuzzlePiece.BlueDouble:
case PuzzlePiece.GreenDouble:
AddImage(x, y, id);
AddImage(x + 80, y, id);
break;
case PuzzlePiece.RedTriple:
case PuzzlePiece.BlueTriple:
case PuzzlePiece.GreenTriple:
AddImage(x, y, id);
AddImage(x + 40, y, id);
AddImage(x + 80, y, id);
break;
case PuzzlePiece.RedBar:
case PuzzlePiece.BlueBar:
case PuzzlePiece.GreenBar:
AddImage(x, y, id);
break;
}
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (m_Item.Deleted || info.ButtonID == 0 || !m_From.CheckAlive())
return;
if (m_From.AccessLevel == AccessLevel.Player && !m_Item.IsChildOf(m_From.Backpack))
{
m_From.LocalOverheadMessage(MessageType.Regular, 0x3B2, 500446); // That is too far away.
return;
}
switch (info.ButtonID)
{
case 0: break;
default:
{
m_Row = info.ButtonID - 1;
break;
}
case 5:
{
int nextRow = m_Row - 1;
if (nextRow < 0) nextRow = 3;
PuzzlePiece movingPiece = m_CurrentSolution.Rows[m_Row];
PuzzlePiece movingToPiece = m_CurrentSolution.Rows[nextRow];
//Can't move empty spaces
if (movingPiece == PuzzlePiece.None || m_Item.Attempts >= m_Solution.MaxAttempts)
break;
SplitPiecesUp(ref movingPiece, ref movingToPiece);
if (movingPiece != m_CurrentSolution.Rows[m_Row] || movingToPiece != m_CurrentSolution.Rows[nextRow])
{
m_CurrentSolution.Rows[m_Row] = movingPiece;
m_CurrentSolution.Rows[nextRow] = movingToPiece;
m_Item.CurrentSolution = m_CurrentSolution;
m_Item.Attempts++;
}
break;
}
case 6:
{
int nextRow = m_Row + 1;
if (nextRow > 3) nextRow = 0;
PuzzlePiece movingPiece = m_CurrentSolution.Rows[m_Row];
PuzzlePiece movingToPiece = m_CurrentSolution.Rows[nextRow];
//Can't Move Empty Spaces
if (movingPiece == PuzzlePiece.None || m_Item.Attempts >= m_Solution.MaxAttempts)
break;
SplitPiecesDown(ref movingPiece, ref movingToPiece);
if (movingPiece != m_CurrentSolution.Rows[m_Row] || movingToPiece != m_CurrentSolution.Rows[nextRow])
{
m_CurrentSolution.Rows[m_Row] = movingPiece;
m_CurrentSolution.Rows[nextRow] = movingToPiece;
m_Item.Attempts++;
m_Item.CurrentSolution = m_CurrentSolution;
}
break;
}
case 7:
{
if (m_Item.SubmitSolution(m_From, m_CurrentSolution))
return;
break;
}
case 8:
{
int index = m_Item.Solution.Index;
m_Item.CurrentSolution = new UnderworldPuzzleSolution(index);
m_Item.Attempts = 0;
break;
}
}
m_From.SendGump(new UnderworldPuzzleGump(m_From, m_Item, m_Row));
}
private int GetTotalPieces(PuzzlePiece piece)
{
switch(piece)
{
default:
return 0;
case PuzzlePiece.RedSingle: case PuzzlePiece.BlueSingle: case PuzzlePiece.GreenSingle: return 1;
case PuzzlePiece.RedDouble: case PuzzlePiece.BlueDouble: case PuzzlePiece.GreenDouble: return 2;
case PuzzlePiece.RedTriple: case PuzzlePiece.BlueTriple: case PuzzlePiece.GreenTriple: return 3;
case PuzzlePiece.RedBar: case PuzzlePiece.BlueBar: case PuzzlePiece.GreenBar: return 4;
}
}
private void SplitPiecesUp(ref PuzzlePiece movingPiece, ref PuzzlePiece movingToPiece)
{
int movingAmount = GetTotalPieces(movingPiece);
int moveToAmount = GetTotalPieces(movingToPiece);
if (movingToPiece == PuzzlePiece.None)
{
if ((movingAmount == 2 || movingAmount == 4))
{
switch (movingPiece)
{
case PuzzlePiece.RedDouble:
movingToPiece = PuzzlePiece.BlueSingle;
movingPiece = PuzzlePiece.GreenSingle;
break;
case PuzzlePiece.BlueDouble:
movingToPiece = PuzzlePiece.GreenSingle;
movingPiece = PuzzlePiece.RedSingle;
break;
case PuzzlePiece.GreenDouble:
movingToPiece = PuzzlePiece.RedSingle;
movingPiece = PuzzlePiece.BlueSingle;
break;
case PuzzlePiece.RedBar:
movingToPiece = PuzzlePiece.BlueDouble;
movingPiece = PuzzlePiece.GreenDouble;
break;
case PuzzlePiece.BlueBar:
movingToPiece = PuzzlePiece.GreenDouble;
movingPiece = PuzzlePiece.RedDouble;
break;
case PuzzlePiece.GreenBar:
movingToPiece = PuzzlePiece.RedDouble;
movingPiece = PuzzlePiece.BlueDouble;
break;
}
}
return;
}
if(movingAmount + moveToAmount > 4)
{
PuzzlePiece movingTemp = movingPiece;
PuzzlePiece movingToTemp = movingToPiece;
movingPiece = movingToTemp;
movingToPiece = movingTemp;
return;
}
movingToPiece = CombinePieces(movingPiece, movingToPiece);
movingPiece = PuzzlePiece.None;
}
private void SplitPiecesDown(ref PuzzlePiece movingPiece, ref PuzzlePiece movingToPiece)
{
int movingAmount = GetTotalPieces(movingPiece);
int moveToAmount = GetTotalPieces(movingToPiece);
if (movingToPiece == PuzzlePiece.None)
{
if ((movingAmount == 2 || movingAmount == 4))
{
switch (movingPiece)
{
case PuzzlePiece.RedDouble:
movingToPiece = PuzzlePiece.BlueSingle;
movingPiece = PuzzlePiece.GreenSingle;
break;
case PuzzlePiece.BlueDouble:
movingToPiece = PuzzlePiece.GreenSingle;
movingPiece = PuzzlePiece.RedSingle;
break;
case PuzzlePiece.GreenDouble:
movingToPiece = PuzzlePiece.RedSingle;
movingPiece = PuzzlePiece.BlueSingle;
break;
case PuzzlePiece.RedBar:
movingToPiece = PuzzlePiece.BlueDouble;
movingPiece = PuzzlePiece.GreenDouble;
break;
case PuzzlePiece.BlueBar:
movingToPiece = PuzzlePiece.GreenDouble;
movingPiece = PuzzlePiece.RedDouble;
break;
case PuzzlePiece.GreenBar:
movingToPiece = PuzzlePiece.RedDouble;
movingPiece = PuzzlePiece.BlueDouble;
break;
}
}
return;
}
int t = 0;
//PuzzlePiece greater = movingPiece;
if (moveToAmount > movingAmount)
{
//greater = movingToPiece;
t = (int)movingToPiece - movingAmount;
}
else if (movingAmount > moveToAmount)
{
//greater = movingPiece;
//t = (int)movingToPiece + (movingAmount - moveToAmount);
//t -= 1;
if (movingAmount == 4 && moveToAmount == 3)
t = (int)movingToPiece - 2;
else if (movingAmount == 4 && moveToAmount == 2)
t = (int)movingToPiece;
else if (movingAmount == 4 && moveToAmount == 1)
t = (int)movingToPiece + 2;
else if (movingAmount == 2 && moveToAmount == 1)
t = (int)movingToPiece;
else if (movingAmount == 3 && moveToAmount == 2)
t = (int)movingToPiece - 1;
else if (movingAmount == 3 && moveToAmount == 1)
t = (int)movingToPiece + 1;
}
else
{
movingPiece = PuzzlePiece.None;
movingToPiece = PuzzlePiece.None;
return;
}
movingToPiece = (PuzzlePiece)t;
movingPiece = PuzzlePiece.None;
}
private PuzzlePiece CombinePieces(PuzzlePiece moving, PuzzlePiece movingInto)
{
int movingAmount = GetTotalPieces(moving);
int moveToAmount = GetTotalPieces(movingInto);
int combined = movingAmount + moveToAmount;
if (movingAmount != moveToAmount)
{
int t = (int)movingInto + movingAmount; //combined + (int)moving;
return (PuzzlePiece)t;
}
combined--;
PuzzleColor movingCol = GetColor(moving);
PuzzleColor movingIntoCol = GetColor(movingInto);
switch (movingCol)
{
case PuzzleColor.Red:
switch (movingIntoCol)
{
case PuzzleColor.Red:
return PuzzlePiece.RedSingle + combined;
case PuzzleColor.Blue:
return PuzzlePiece.GreenSingle + combined;
case PuzzleColor.Green:
return PuzzlePiece.BlueSingle + combined;
}
break;
case PuzzleColor.Blue:
switch (movingIntoCol)
{
case PuzzleColor.Red:
return PuzzlePiece.GreenSingle + combined;
case PuzzleColor.Blue:
return PuzzlePiece.BlueSingle + combined;
case PuzzleColor.Green:
return PuzzlePiece.RedSingle + combined;
}
break;
case PuzzleColor.Green:
switch (movingIntoCol)
{
case PuzzleColor.Red:
return PuzzlePiece.BlueSingle + combined;
case PuzzleColor.Blue:
return PuzzlePiece.RedSingle + combined;
case PuzzleColor.Green:
return PuzzlePiece.GreenSingle + combined;
}
break;
}
return moving;
}
private PuzzleColor GetColor(PuzzlePiece piece)
{
switch (piece)
{
default:
case PuzzlePiece.RedSingle:
case PuzzlePiece.RedDouble:
case PuzzlePiece.RedTriple:
case PuzzlePiece.RedBar:
return PuzzleColor.Red;
case PuzzlePiece.BlueSingle:
case PuzzlePiece.BlueDouble:
case PuzzlePiece.BlueTriple:
case PuzzlePiece.BlueBar:
return PuzzleColor.Blue;
case PuzzlePiece.GreenSingle:
case PuzzlePiece.GreenDouble:
case PuzzlePiece.GreenTriple:
case PuzzlePiece.GreenBar:
return PuzzleColor.Green;
}
}
private int GetPuzzlePieceID(PuzzlePiece piece)
{
switch (piece)
{
default:
case PuzzlePiece.None: return 0x0;
case PuzzlePiece.RedSingle:
case PuzzlePiece.RedDouble:
case PuzzlePiece.RedTriple: return 0x2A62;
case PuzzlePiece.BlueSingle:
case PuzzlePiece.BlueDouble:
case PuzzlePiece.BlueTriple: return 0x2A3A;
case PuzzlePiece.GreenSingle:
case PuzzlePiece.GreenDouble:
case PuzzlePiece.GreenTriple: return 0x2A4E;
case PuzzlePiece.RedBar: return 0x2A58;
case PuzzlePiece.BlueBar: return 0x2A30;
case PuzzlePiece.GreenBar: return 0x2A44;
}
}
}
}

View File

@@ -0,0 +1,69 @@
using System;
using Server;
using System.Collections.Generic;
namespace Server.Items
{
public class UnderworldPuzzleBox : MetalChest
{
private static Dictionary<Mobile, DateTime> m_Table = new Dictionary<Mobile, DateTime>();
[Constructable]
public UnderworldPuzzleBox()
{
Movable = false;
ItemID = 3712;
}
public override void OnDoubleClick(Mobile from)
{
if (from.InRange(this.Location, 3))
{
if (from.AccessLevel == AccessLevel.Player && IsInCooldown(from))
from.SendLocalizedMessage(1113413); // You have recently participated in this challenge. You must wait 24 hours to try again.
else if (from.Backpack != null)
{
Item item = from.Backpack.FindItemByType(typeof(UnderworldPuzzleItem));
if (item != null)
from.SendMessage("You already have a puzzle board.");
else
{
from.AddToBackpack(new UnderworldPuzzleItem());
from.SendMessage("You recieve a puzzle piece.");
if (from.AccessLevel == AccessLevel.Player)
m_Table[from] = DateTime.UtcNow + TimeSpan.FromHours(24);
}
}
}
}
public static bool IsInCooldown(Mobile from)
{
if(m_Table.ContainsKey(from))
{
if(m_Table[from] < DateTime.UtcNow)
m_Table.Remove(from);
}
return m_Table.ContainsKey(from);
}
public UnderworldPuzzleBox(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,291 @@
using System;
using Server.Commands;
using Server.Mobiles;
using Server.Network;
using System.Linq;
namespace Server.Items
{
public class NavreysController : Item
{
#region Generation
public static void Initialize()
{
CommandSystem.Register("GenNavrey", AccessLevel.Developer, new CommandEventHandler(GenNavrey_Command));
}
[Usage("GenNavrey")]
private static void GenNavrey_Command(CommandEventArgs e)
{
GenNavery(e.Mobile);
}
public static void GenNavery(Mobile m)
{
if (Check())
{
m.SendMessage("Navrey spawner is already present.");
}
else
{
m.SendMessage("Creating Navrey Night-Eyes Lair...");
NavreysController controller = new NavreysController();
m.SendMessage("Generation completed!");
}
}
private static bool Check()
{
foreach (Item item in World.Items.Values)
if (item is NavreysController && !item.Deleted)
return true;
return false;
}
#endregion
private NavreysPillar[] m_Pillars;
private Navrey m_Navrey;
private DateTime m_TypeRestart;
[CommandProperty(AccessLevel.GameMaster)]
public TimeSpan TypeRestart
{
get
{
TimeSpan ts = m_TypeRestart - DateTime.UtcNow;
if (ts < TimeSpan.Zero)
{
ts = TimeSpan.Zero;
for (int i = 0; i < m_Pillars.Length; i++)
{
NavreysPillar pillar = m_Pillars[i];
if (pillar.Type != PillarType.Nine)
pillar.m_Type++;
else
pillar.Type = PillarType.Three;
}
this.TypeRestart = TimeSpan.FromHours(24.0); // The timers rotate among the three stone ruins randomly once a day
}
return ts;
}
set
{
try
{
m_TypeRestart = DateTime.UtcNow + value;
}
catch
{ }
}
}
public bool AllPillarsHot
{
get
{
for (int i = 0; i < m_Pillars.Length; i++)
{
NavreysPillar pillar = m_Pillars[i];
if (pillar == null || pillar.Deleted || pillar.State != NavreysPillarState.Hot)
return false;
}
return true;
}
}
public NavreysController()
: base(0x1F13)
{
Name = "Navrey Spawner - Do not remove !!";
Visible = false;
Movable = false;
MoveToWorld(new Point3D(1054, 861, -31), Map.TerMur);
m_Pillars = new NavreysPillar[3];
m_Pillars[0] = new NavreysPillar(this, PillarType.Three);
m_Pillars[0].MoveToWorld(new Point3D(1071, 847, 0), Map.TerMur);
m_Pillars[1] = new NavreysPillar(this, PillarType.Six);
m_Pillars[1].MoveToWorld(new Point3D(1039, 879, 0), Map.TerMur);
m_Pillars[2] = new NavreysPillar(this, PillarType.Nine);
m_Pillars[2].MoveToWorld(new Point3D(1039, 850, 0), Map.TerMur);
Respawn();
}
public void OnNavreyKilled()
{
SetAllPillars(NavreysPillarState.Off);
Timer.DelayCall(TimeSpan.FromMinutes(10.0), new TimerCallback(Respawn));
}
public void Respawn()
{
Navrey navrey = new Navrey(this);
navrey.RangeHome = 20;
navrey.MoveToWorld(Map.GetSpawnPosition(Location, 10), Map);
SetAllPillars(NavreysPillarState.On);
m_Navrey = navrey;
}
public void ResetPillars()
{
if (m_Navrey != null && !m_Navrey.Deleted && m_Navrey.Alive)
SetAllPillars(NavreysPillarState.On);
}
public override void Delete()
{
base.Delete();
for (int i = 0; i < m_Pillars.Length; i++)
{
NavreysPillar pillar = m_Pillars[i];
pillar.Delete();
}
m_Navrey.Delete();
}
public void CheckPillars()
{
if (AllPillarsHot)
{
m_Navrey.UsedPillars = true;
Timer t = new RockRainTimer(m_Navrey);
t.Start();
SetAllPillars(NavreysPillarState.Off);
Timer.DelayCall(TimeSpan.FromMinutes(5.0), new TimerCallback(ResetPillars));
}
}
private void SetAllPillars(NavreysPillarState state)
{
for (int i = 0; i < m_Pillars.Length; i++)
{
NavreysPillar pillar = m_Pillars[i];
pillar.State = state;
}
}
public NavreysController(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
writer.Write((Mobile)m_Navrey);
writer.Write((Item)m_Pillars[0]);
writer.Write((Item)m_Pillars[1]);
writer.Write((Item)m_Pillars[2]);
writer.Write(TypeRestart);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
m_Navrey = (Navrey)reader.ReadMobile();
m_Pillars = new NavreysPillar[3];
m_Pillars[0] = (NavreysPillar)reader.ReadItem();
m_Pillars[1] = (NavreysPillar)reader.ReadItem();
m_Pillars[2] = (NavreysPillar)reader.ReadItem();
TypeRestart = reader.ReadTimeSpan();
if (m_Navrey == null)
Timer.DelayCall(TimeSpan.Zero, new TimerCallback(Respawn));
else
SetAllPillars(NavreysPillarState.On);
}
private class RockRainTimer : Timer
{
private Navrey m_Navrey;
private int m_Ticks;
public RockRainTimer(Navrey navrey)
: base(TimeSpan.Zero, TimeSpan.FromSeconds(0.25))
{
m_Navrey = navrey;
m_Ticks = 120;
m_Navrey.CantWalk = true;
}
protected override void OnTick()
{
m_Ticks--;
Point3D dest = m_Navrey.Location;
Point3D orig = new Point3D(dest.X - Utility.RandomMinMax(3, 4), dest.Y - Utility.RandomMinMax(8, 9), dest.Z + Utility.RandomMinMax(41, 43));
int itemId = Utility.RandomMinMax(0x1362, 0x136D);
int speed = Utility.RandomMinMax(5, 10);
int hue = Utility.RandomBool() ? 0 : Utility.RandomMinMax(0x456, 0x45F);
Effects.SendPacket(orig, m_Navrey.Map, new HuedEffect(EffectType.Moving, Serial.Zero, Serial.Zero, itemId, orig, dest, speed, 0, false, false, hue, 4));
Effects.SendPacket(orig, m_Navrey.Map, new HuedEffect(EffectType.Moving, Serial.Zero, Serial.Zero, itemId, orig, dest, speed, 0, false, false, hue, 4));
Effects.PlaySound(m_Navrey.Location, m_Navrey.Map, 0x15E + Utility.Random(3));
Effects.PlaySound(m_Navrey.Location, m_Navrey.Map, Utility.RandomList(0x305, 0x306, 0x307, 0x309));
int amount = Utility.RandomMinMax(100, 150);
IPooledEnumerable eable = m_Navrey.GetMobilesInRange(1);
foreach (Mobile m in eable)
{
if (m == null || !m.Alive)
continue;
if (m is Navrey)
{
m.Damage(amount);
m.SendDamageToAll(amount);
}
else
{
m.RevealingAction();
AOS.Damage(m, amount, 100, 0, 0, 0, 0);
}
}
eable.Free();
if (m_Ticks == 0 || !m_Navrey.Alive)
{
m_Navrey.CantWalk = false;
Stop();
}
}
}
}
}

View File

@@ -0,0 +1,135 @@
using System;
namespace Server.Items
{
public enum NavreysPillarState
{
Off,
On,
Hot
}
public enum PillarType
{
Three = 1,
Six,
Nine
}
public class NavreysPillar : Item
{
private NavreysPillarState m_State;
private InternalTimer m_Timer;
private NavreysController m_Controller;
public PillarType m_Type;
[CommandProperty(AccessLevel.GameMaster)]
public PillarType Type
{
get { return m_Type; }
set { m_Type = value; }
}
public NavreysPillarState State
{
get { return m_State; }
set
{
m_State = value;
if (m_Timer != null)
{
m_Timer.Stop();
m_Timer = null;
}
switch (m_State)
{
case NavreysPillarState.Off:
Hue = 0x456;
break;
case NavreysPillarState.On:
Hue = 0;
break;
case NavreysPillarState.Hot:
m_Timer = new InternalTimer(this);
m_Timer.Start();
break;
}
}
}
public NavreysPillar(NavreysController controller, PillarType type)
: base(0x3BF)
{
m_Controller = controller;
m_Type = type;
Movable = false;
}
public override void OnDoubleClick(Mobile from)
{
if (from.InRange(this, 3) && m_State == NavreysPillarState.On)
{
State = NavreysPillarState.Hot;
m_Controller.CheckPillars();
}
}
public NavreysPillar(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
writer.Write((int)m_State);
writer.Write((Item)m_Controller);
writer.Write((int)m_Type);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
State = (NavreysPillarState)reader.ReadInt();
m_Controller = (NavreysController)reader.ReadItem();
m_Type = (PillarType)reader.ReadInt();
}
private class InternalTimer : Timer
{
private NavreysPillar m_Pillar;
private int m_Ticks;
public InternalTimer(NavreysPillar pillar)
: base(TimeSpan.Zero, TimeSpan.FromSeconds(0.5))
{
m_Pillar = pillar;
m_Ticks = 6 * (int)pillar.Type; // 3, 6, 9 seconds
}
protected override void OnTick()
{
m_Ticks--;
m_Pillar.Hue = 0x461 + (m_Ticks % 2);
if (m_Ticks == 0)
{
Stop();
m_Pillar.State = NavreysPillarState.On;
}
}
}
}
}

View File

@@ -0,0 +1,32 @@
using System;
using Server;
namespace Server.Items
{
public class CopperPuzzleKey : BaseDecayingItem
{
public override int Lifespan { get { return 1800; } }
public override int LabelNumber { get { return 1024110; } } // copper key
[Constructable]
public CopperPuzzleKey() : base(4115)
{
}
public CopperPuzzleKey(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 version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,33 @@
using System;
using Server;
namespace Server.Items
{
public class GoldPuzzleKey : BaseDecayingItem
{
public override int Lifespan { get { return 1800; } }
public override int LabelNumber { get { return 1024111; } } // gold key
[Constructable]
public GoldPuzzleKey() : base(4114)
{
Hue = 1174;
}
public GoldPuzzleKey(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 version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,152 @@
using System;
using Server;
using Server.Mobiles;
using System.Collections.Generic;
using Server.Gumps;
namespace Server.Items
{
public class MagicKey : BaseDecayingItem
{
private int m_Span;
public override int LabelNumber { get { return 1024114; } } // magic key
public override int Lifespan { get { return m_Span; } }
[Constructable]
public MagicKey() : base(4114)
{
m_Span = 0;
Movable = false;
}
public override void OnDoubleClick(Mobile from)
{
if(RootParent != null || !from.InRange(GetWorldLocation(), 3) || Movable || IsLockedDown || IsSecure)
return;
else if (from.Backpack != null && m_Span == 0)
{
Item key = from.Backpack.FindItemByType(typeof(MagicKey));
if(key == null)
{
if(from.HasGump(typeof(MagicKey.MagicKeyConfirmGump)))
from.CloseGump(typeof(MagicKey.MagicKeyConfirmGump));
from.SendGump(new MagicKeyConfirmGump(this));
}
}
}
public override void StartTimer()
{
TimeLeft = 1800;
m_Span = 1800;
Movable = true;
base.StartTimer();
InvalidateProperties();
}
public override void Decay()
{
if (RootParent is Mobile)
{
Mobile m = (Mobile)RootParent;
if (m != null && m.Map != Map.Internal)
{
if (m_PuzzleRoom.Contains(m.Location))
{
int x = Utility.RandomMinMax(1096, 1098);
int y = Utility.RandomMinMax(1175, 1177);
int z = Map.GetAverageZ(x, y);
Point3D loc = m.Location;
Point3D p = new Point3D(x, y, z);
BaseCreature.TeleportPets(m, p, Map.TerMur);
m.MoveToWorld(p, Map.TerMur);
Effects.SendLocationParticles(EffectItem.Create(loc, m.Map, EffectItem.DefaultDuration), 0x3728, 10, 10, 2023);
Effects.SendLocationParticles(EffectItem.Create(p, m.Map, EffectItem.DefaultDuration), 0x3728, 10, 10, 5023);
}
Container pack = m.Backpack;
if (pack != null)
{
List<Item> list = new List<Item>(pack.Items);
foreach (Item item in list)
{
if (item is CopperPuzzleKey || item is GoldPuzzleKey || item is MazePuzzleItem || item is MastermindPuzzleItem)
item.Delete();
}
}
}
}
base.Decay();
}
private Rectangle2D m_PuzzleRoom = new Rectangle2D(1234, 1234, 10, 10);
private class MagicKeyConfirmGump : Gump
{
private MagicKey m_Key;
public MagicKeyConfirmGump(MagicKey key) : base(50, 50)
{
m_Key = key;
AddPage(0);
AddBackground(0, 0, 297, 115, 9200);
AddImageTiled(5, 10, 285, 25, 2624);
AddHtmlLocalized(10, 15, 275, 25, 1113390, 0x7FFF, false, false); // Puzzle Room Timer
AddImageTiled(5, 40, 285, 40, 2624);
AddHtmlLocalized(10, 40, 275, 40, 1113391, 0x7FFF, false, false); // Click CANCEL to read the instruction book or OK to start the timer now.
AddButton(5, 85, 4017, 4018, 0, GumpButtonType.Reply, 0);
AddHtmlLocalized(40, 87, 80, 25, 1011012, 0x7FFF, false, false); //CANCEL
AddButton(215, 85, 4023, 4024, 1, GumpButtonType.Reply, 0);
AddHtmlLocalized(250, 87, 80, 25, 1006044, 0x7FFF, false, false); //OK
}
public override void OnResponse(Server.Network.NetState state, RelayInfo info)
{
Mobile from = state.Mobile;
if (info.ButtonID == 1)
{
MagicKey key = new MagicKey();
from.AddToBackpack(key);
key.Movable = true;
key.StartTimer();
from.SendLocalizedMessage(1113389); // As long as you carry this key, you will be granted access to the Puzzle Room.
}
}
}
public MagicKey(Serial serial) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
writer.Write(m_Span);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
m_Span = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,141 @@
using Server;
using System;
using Server.Mobiles;
using System.Collections.Generic;
namespace Server.Items
{
public class MastermindPuzzleItem : PuzzleChest
{
private MagicKey m_Key;
private Timer m_Timer;
private int m_Lifespan;
[CommandProperty(AccessLevel.GameMaster)]
public MagicKey Key { get { return m_Key; } set { m_Key = value; } }
public override int LabelNumber { get { return 1113379; } } // Puzzle Board
[Constructable]
public MastermindPuzzleItem(MagicKey key) : base(0x2AAA)
{
Hue = 914;
m_Key = key;
m_Lifespan = 600;
Movable = true;
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), new TimerCallback(Slice));
m_Timer.Start();
LootType = LootType.Blessed;
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
list.Add(1072517, m_Lifespan.ToString()); // Lifespan: ~1_val~ seconds
}
public override void OnDoubleClick(Mobile from)
{
if (MazePuzzleItem.IsInPuzzleRoom(from))
base.OnDoubleClick(from);
}
/*public override void OnDoubleClick(Mobile from)
{
PuzzleChestSolution solution = GetLastGuess(from);
if (solution != null)
solution = new PuzzleChestSolution(solution);
else
solution = new PuzzleChestSolution(PuzzleChestCylinder.None, PuzzleChestCylinder.None, PuzzleChestCylinder.None, PuzzleChestCylinder.None, PuzzleChestCylinder.None);
from.CloseGump(typeof(PuzzleChest.PuzzleGump));
from.CloseGump(typeof(PuzzleChest.StatusGump));
from.SendGump(new PuzzleChest.PuzzleGump(from, this, solution, 0));
}*/
public virtual void Slice()
{
m_Lifespan -= 10;
InvalidateProperties();
if (m_Lifespan <= 0)
Decay();
}
public virtual void Decay()
{
if (RootParent is Mobile)
{
Mobile parent = (Mobile)RootParent;
if (Name == null)
parent.SendLocalizedMessage(1072515, "#" + LabelNumber); // The ~1_name~ expired...
else
parent.SendLocalizedMessage(1072515, Name); // The ~1_name~ expired...
Effects.SendLocationParticles(EffectItem.Create(parent.Location, parent.Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
Effects.PlaySound(parent.Location, parent.Map, 0x201);
parent.CloseGump(typeof(PuzzleChest.PuzzleGump));
parent.CloseGump(typeof(PuzzleChest.StatusGump));
}
else
{
Effects.SendLocationParticles(EffectItem.Create(this.Location, this.Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
Effects.PlaySound(this.Location, this.Map, 0x201);
}
if(m_Timer != null)
m_Timer.Stop();
Delete();
}
public override void LockPick( Mobile from )
{
base.LockPick( from );
Timer.DelayCall(TimeSpan.FromSeconds(3), new TimerCallback(Delete));
if(m_Key != null)
m_Key.Decay();
ExperimentalGem gem = new ExperimentalGem();
gem.Owner = from;
from.AddToBackpack(gem);
from.SendLocalizedMessage(1113382); // You've solved the puzzle!! An item has been placed in your bag.
}
protected override void GenerateTreasure()
{
Solution = new PuzzleChestSolution();
}
public MastermindPuzzleItem( Serial serial ) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // ver
writer.Write(m_Key);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
m_Key = reader.ReadItem() as MagicKey;
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), new TimerCallback(Slice));
m_Timer.Start();
}
}
}

View File

@@ -0,0 +1,215 @@
using Server;
using System;
using Server.Mobiles;
using System.Collections.Generic;
using Server.Gumps;
namespace Server.Items
{
public class MazePuzzleItem : BaseDecayingItem, ICircuitTrap
{
private MagicKey m_Key;
public List<int> Path { get; set; }
public List<int> Progress { get; set; }
public CircuitCount Count { get { return CircuitCount.ThirtySix; } }
public int GumpTitle { get { return 1153747; } } // <center>GENERATOR CONTROL PANEL</center>
public int GumpDescription { get { return 1153749; } } // // <center>Close the Grid Circuit</center>
public bool CanDecipher { get { return true; } }
[CommandProperty(AccessLevel.GameMaster)]
public MagicKey Key { get { return m_Key; } set { m_Key = value; } }
public override int LabelNumber { get { return 1113379; } } // Puzzle Board
public override int Lifespan { get { return 600; } }
[Constructable]
public MazePuzzleItem(MagicKey key) : base(0x2AAA)
{
Hue = 914;
m_Key = key;
}
public override void OnDoubleClick(Mobile from)
{
if(!IsChildOf(from.Backpack))
from.SendLocalizedMessage(500325); // I am too far away to do that.
else if(from is PlayerMobile && IsInPuzzleRoom(from))
{
from.CloseGump(typeof(PuzzleChest.PuzzleGump));
from.CloseGump(typeof(PuzzleChest.StatusGump));
BaseGump.SendGump(new CircuitTrapGump((PlayerMobile)from, this));
}
}
private static Rectangle2D m_Bounds = new Rectangle2D(1089, 1162, 16, 12);
public static bool IsInPuzzleRoom(Mobile from)
{
return from.Map == Map.TerMur && m_Bounds.Contains(new Point2D(from.X, from.Y));
}
public override void OnDelete()
{
Mobile m = RootParent as Mobile;
if (m != null)
{
if (m.HasGump(typeof(CircuitTrapGump)))
{
m.CloseGump(typeof(CircuitTrapGump));
}
}
}
public void OnSelfClose(Mobile m)
{
}
public void OnProgress(Mobile m, int pick)
{
m.PlaySound(0x1F5);
}
public void OnFailed(Mobile m)
{
DoDamage(m);
}
public void OnComplete(Mobile m)
{
m.PlaySound(0x3D);
OnPuzzleCompleted(m);
}
private Timer m_DamageTimer;
public void DoDamage(Mobile m)
{
if(m_DamageTimer != null && m_DamageTimer.Running)
m_DamageTimer.Stop();
m_DamageTimer = new InternalTimer(this, m);
m_DamageTimer.Start();
}
public void ApplyShock(Mobile m, int tick)
{
if (m == null || !m.Alive || this.Deleted)
{
if (m_DamageTimer != null)
m_DamageTimer.Stop();
}
else
{
int damage = (int)(75 / Math.Max(1, tick - 1)) + Utility.RandomMinMax(1, 9);
AOS.Damage(m, damage, 0, 0, 0, 0, 100);
m.BoltEffect(0);
m.FixedParticles(0x3818, 1, 11, 0x13A8, 0, 0, EffectLayer.CenterFeet);
m.FixedParticles(0x3818, 1, 11, 0x13A8, 0, 0, EffectLayer.Waist);
m.FixedParticles(0x3818, 1, 11, 0x13A8, 0, 0, EffectLayer.Head);
m.PlaySound(0x1DC);
m.LocalOverheadMessage(Server.Network.MessageType.Regular, 0x21, 1114443); // * Your body convulses from electric shock *
m.NonlocalOverheadMessage(Server.Network.MessageType.Regular, 0x21, 1114443, m.Name); // * ~1_NAME~ spasms from electric shock *
}
}
private class InternalTimer : Timer
{
private MazePuzzleItem m_Item;
private Mobile m_From;
private DateTime m_NextDamage;
private int m_Tick;
public InternalTimer(MazePuzzleItem item, Mobile from) : base(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1))
{
m_Item = item;
m_From = from;
m_NextDamage = DateTime.UtcNow;
m_Tick = 0;
if(item != null)
item.ApplyShock(from, 0);
}
protected override void OnTick()
{
m_Tick++;
if(m_From == null || m_Item == null || !m_From.Alive || m_Item.Deleted)
{
this.Stop();
return;
}
if(DateTime.UtcNow > m_NextDamage)
{
m_Item.ApplyShock(m_From, m_Tick);
int delay;
if(m_Tick < 3)
delay = 2;
else if (m_Tick < 5)
delay = 4;
else
delay = 6;
if(m_Tick >= 10)
this.Stop();
else
m_NextDamage = DateTime.UtcNow + TimeSpan.FromSeconds(delay);
}
}
}
public void OnPuzzleCompleted(Mobile m)
{
if(m != null)
{
Container pack = m.Backpack;
if(pack != null)
{
Item copperKey = pack.FindItemByType(typeof(CopperPuzzleKey));
Item goldKey = pack.FindItemByType(typeof(GoldPuzzleKey));
if(copperKey == null)
pack.DropItem(new CopperPuzzleKey());
else if (goldKey == null)
pack.DropItem(new GoldPuzzleKey());
else
return;
m.SendLocalizedMessage(1113382); // You've solved the puzzle!! An item has been placed in your bag.
}
//TODO: Message/Effects?
}
Timer.DelayCall(TimeSpan.FromSeconds(3), new TimerCallback(Delete));
}
public MazePuzzleItem( Serial serial ) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // ver
writer.Write(m_Key);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
m_Key = reader.ReadItem() as MagicKey;
}
}
}

View File

@@ -0,0 +1,63 @@
using System;
namespace Server.Items
{
public class PuzzleBook : BrownBook
{
public static readonly BookContent Content = new BookContent(
"Instructions", "Sir Wilber",
new BookPageInfo(
"Greetings Traveler!",
"I would like to invite",
"you to a little game.",
"See the magic key? It "),
new BookPageInfo(
"will grant you access to",
"the Puzzle Room. Be advised",
"that once you take the key,",
"you will have no more than",
"30 minutes to enter the room."),
new BookPageInfo(
"and solve the puzzles. If",
"you fail, you will be",
"expelled and all your",
"progress will be lost! ",
"There are 3 puzzle chests.",
"Two of them must be completed",
"first to unlock the third."),
new BookPageInfo(
"If successful, you will get a",
"special item required to enter",
"my other playground should you",
"discover its location within",
"the underworld!!"));
[Constructable]
public PuzzleBook() : base(false)
{
Movable = false;
ItemID = 4030;
}
public PuzzleBook(Serial serial)
: base(serial)
{
}
public override BookContent DefaultContent { get { return Content; } }
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadEncodedInt();
}
}
}

View File

@@ -0,0 +1,113 @@
using Server;
using System;
using Server.Mobiles;
namespace Server.Items
{
public enum PuzzleType
{
WestBox, // Maze #1
EastBox, // Maze #2
NorthBox // Mastermind
}
public class PuzzleBox : Item
{
private PuzzleType m_PuzzleType;
[CommandProperty(AccessLevel.GameMaster)]
public PuzzleType PuzzleType { get { return m_PuzzleType; } set { m_PuzzleType = value; } }
public override int LabelNumber { get { return 1113486; } } // a puzzle box
[Constructable]
public PuzzleBox(PuzzleType type) : base(2472)
{
m_PuzzleType = type;
Movable = false;
}
public override void OnDoubleClick(Mobile from)
{
if(!from.InRange(this.Location, 3))
from.SendLocalizedMessage(3000268); // that is too far away.
else if (from.Backpack != null)
{
Type needed;
Item puzzle = null;
Item key = from.Backpack.FindItemByType(typeof(MagicKey));
Item puzzleItem1 = from.Backpack.FindItemByType(typeof(MazePuzzleItem));
Item puzzleItem2 = from.Backpack.FindItemByType(typeof(MastermindPuzzleItem));
if (key == null)
{
int x = Utility.RandomMinMax(1095, 1099);
int y = Utility.RandomMinMax(1178, 1179);
int z = -1;
Point3D loc = from.Location;
Point3D p = new Point3D(x, y, z);
BaseCreature.TeleportPets(from, p, Map.TerMur);
from.MoveToWorld(p, Map.TerMur);
from.PlaySound(0x1FE);
Effects.SendLocationParticles(EffectItem.Create(loc, from.Map, EffectItem.DefaultDuration), 0x3728, 10, 10, 2023);
Effects.SendLocationParticles(EffectItem.Create(p, from.Map, EffectItem.DefaultDuration), 0x3728, 10, 10, 5023);
}
if (puzzleItem1 != null || puzzleItem2 != null)
{
from.SendMessage("You already have a puzzle board.");
return;
}
switch(m_PuzzleType)
{
default:
case PuzzleType.WestBox:
case PuzzleType.EastBox: needed = typeof(MagicKey); break;
case PuzzleType.NorthBox: needed = typeof(GoldPuzzleKey); break;
}
Item item = from.Backpack.FindItemByType(needed);
if(item != null && key is MagicKey)
{
if(m_PuzzleType == PuzzleType.NorthBox)
puzzle = new MastermindPuzzleItem((MagicKey)key);
else
puzzle = new MazePuzzleItem((MagicKey)key);
}
if (puzzle != null)
{
if (!from.Backpack.TryDropItem(from, puzzle, true))
puzzle.Delete();
else
from.SendMessage("You recieve a puzzle board.");
}
else
from.SendMessage("You do not have the required key to get that puzzle board.");
}
}
public PuzzleBox( Serial serial ) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // ver
writer.Write((int)m_PuzzleType);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
m_PuzzleType = (PuzzleType)reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,46 @@
using Server;
using System;
using Server.Mobiles;
namespace Server.Items
{
public class PuzzleRoomTeleporter : Teleporter
{
[Constructable]
public PuzzleRoomTeleporter()
{
}
public override bool CanTeleport(Mobile m)
{
if (m.Backpack == null)
return false;
Item item = m.Backpack.FindItemByType(typeof(MagicKey));
if (item == null)
{
m.SendLocalizedMessage(1113393); // You must carry a magic key to enter this room.
return false;
}
return base.CanTeleport(m);
}
public PuzzleRoomTeleporter( Serial serial ) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // ver
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}