Files
abysmal-isle/Scripts/Services/Revamped Dungeons/Covetous Void Spawn/Items/MagicFishFinder.cs
Unstable Kitsune b918192e4e Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
2023-11-28 23:20:26 -05:00

281 lines
8.3 KiB
C#

using Server;
using System;
using Server.Mobiles;
using System.Collections.Generic;
using System.Linq;
using Server.Commands;
namespace Server.Items
{
public class MagicalFishFinder : Item
{
public const int DecayPeriod = 4;
[CommandProperty(AccessLevel.GameMaster)]
public DateTime Expires { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public DateTime LastUpdate { get; set; }
private Timer m_Timer;
public override int LabelNumber { get { return 1152602; } } // Magical Fish Finder
[Constructable]
public MagicalFishFinder() : base(5366)
{
Hue = 2500;
Expires = DateTime.UtcNow + TimeSpan.FromHours(DecayPeriod);
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), CheckDecay);
}
public void CheckDecay()
{
if (Expires < DateTime.UtcNow)
Decay();
else
InvalidateProperties();
}
public void Decay()
{
if (RootParent is Mobile)
{
Mobile parent = (Mobile)RootParent;
if (Name == null)
parent.SendLocalizedMessage(1072515, "#" + LabelNumber); // The ~1_name~ expired...
else
parent.SendLocalizedMessage(1072515, Name); // The ~1_name~ expired...
Effects.SendLocationParticles(EffectItem.Create(parent.Location, parent.Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
Effects.PlaySound(parent.Location, parent.Map, 0x201);
}
else
{
Effects.SendLocationParticles(EffectItem.Create(this.Location, this.Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
Effects.PlaySound(this.Location, this.Map, 0x201);
}
Delete();
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
int left = 0;
if (DateTime.UtcNow < Expires)
left = (int)(Expires - DateTime.UtcNow).TotalSeconds;
list.Add(1072517, left.ToString()); // Lifespan: ~1_val~ seconds
}
public override void Delete()
{
base.Delete();
if (m_Timer != null)
{
m_Timer.Stop();
m_Timer = null;
}
}
public override void OnDoubleClick(Mobile m)
{
if (IsChildOf(m.Backpack))
CheckUpdate(m);
}
public void CheckUpdate(Mobile m)
{
if (Schools.ContainsKey(m.Map))
{
SchoolEntry entry = Schools[m.Map].FirstOrDefault(e => m.InRange(e.Location, SchoolRange));
if (entry != null)
{
m.SendLocalizedMessage(1152647); // Fish are schooling right here!
return;
}
entry = Schools[m.Map].FirstOrDefault(e => m.InRange(e.Location, MessageRange));
if (entry != null)
{
m.SendLocalizedMessage(1152638, GetDirectionString(Utility.GetDirection(m, entry.Location))); // The fish finder pulls you to the ~1_DIRECTION~.
}
else
{
m.SendLocalizedMessage(1152637); // The fish finder shows you nothing.
}
}
else
{
m.SendLocalizedMessage(1152637); // The fish finder shows you nothing.
}
}
public string GetDirectionString(Direction d)
{
return String.Format("#{0}", 1152639 + (int)d);
}
public static bool HasSchool(Mobile m)
{
if (m == null || !m.Alive || m.Backpack == null)
return false;
MagicalFishFinder finder = m.Backpack.FindItemByType<MagicalFishFinder>();
if (finder != null && Schools.ContainsKey(m.Map))
{
SchoolEntry entry = Schools[m.Map].FirstOrDefault(e => m.InRange(e.Location, SchoolRange));
if (entry != null)
{
entry.OnFish();
return true;
}
}
return false;
}
public MagicalFishFinder(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
writer.Write(Expires);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
Expires = reader.ReadDateTime();
if (Expires < DateTime.UtcNow)
Decay();
else
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), CheckDecay);
}
public static int MessageRange = 100;
public static int SchoolRange = 20;
public static Dictionary<Map, List<SchoolEntry>> Schools { get; set; }
public static void Initialize()
{
Schools = new Dictionary<Map, List<SchoolEntry>>();
Schools[Map.Trammel] = new List<SchoolEntry>();
Schools[Map.Felucca] = new List<SchoolEntry>();
Schools[Map.Ilshenar] = new List<SchoolEntry>();
Schools[Map.Tokuno] = new List<SchoolEntry>();
foreach (var kvp in Schools)
{
int amount = 150;
if (kvp.Key == Map.Ilshenar || kvp.Key == Map.Tokuno)
amount = 50;
for (int i = 0; i < amount; i++)
{
Point3D p;
int failsafe = 0;
do
{
p = SOS.FindLocation(kvp.Key);
failsafe++;
}
while (p == Point3D.Zero && failsafe < 10);
kvp.Value.Add(new SchoolEntry(kvp.Key, new Point2D(p.X, p.Y)));
}
if(kvp.Value.Count == 0)
Console.WriteLine("Warning: {0} has 0 School entries!", kvp.Key);
}
CommandSystem.Register("MoveToSchool", AccessLevel.GameMaster, e =>
{
Mobile m = e.Mobile;
if (Schools.ContainsKey(m.Map))
{
SchoolEntry entry = Schools[m.Map][Utility.Random(Schools[m.Map].Count)];
if (entry != null)
{
m.MoveToWorld(new Point3D(entry.Location.X, entry.Location.Y, m.Map.GetAverageZ(entry.Location.X, entry.Location.Y)), m.Map);
}
else
m.SendMessage("Bad entry");
}
else
m.SendMessage("Bad map");
});
}
public static void ExpireSchool(Map map, SchoolEntry entry)
{
if (Schools.ContainsKey(map) && Schools[map].Contains(entry))
{
Schools[map].Remove(entry);
Point3D p;
int failsafe = 0;
do
{
p = SOS.FindLocation(map);
failsafe++;
}
while (p == Point3D.Zero && failsafe < 10);
Schools[map].Add(new SchoolEntry(map, new Point2D(p.X, p.Y)));
}
}
public class SchoolEntry
{
public Point2D Location { get; set; }
public bool HasFished { get; set; }
public Map Map { get; set; }
public SchoolEntry(Map map, Point2D location)
{
Map = map;
Location = location;
}
public void OnFish()
{
if (!HasFished)
{
HasFished = true;
Timer.DelayCall(TimeSpan.FromMinutes(Utility.RandomMinMax(5, 8)), Expire);
}
}
public void Expire()
{
MagicalFishFinder.ExpireSchool(Map, this);
}
}
}
}