Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
@@ -0,0 +1,281 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user