Files
abysmal-isle/Scripts/Services/Expansions/High Seas/Multis/ShipTracking.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

250 lines
5.9 KiB
C#

using System;
using System.Collections.Generic;
using Server;
using Server.Items;
namespace Server.Multis
{
public class ShipTrackingContext
{
private static Dictionary<Mobile, ShipTrackingContext> m_Table = new Dictionary<Mobile, ShipTrackingContext>();
private Mobile m_Mobile;
public List<BoatTrackingArrow> Arrows { get { return m_Arrows; } }
private List<BoatTrackingArrow> m_Arrows = new List<BoatTrackingArrow>();
public ShipTrackingContext(Mobile mobile, List<BoatTrackingArrow> arrows)
{
m_Mobile = mobile;
m_Arrows = arrows;
m_Table.Add(mobile, this);
}
public static bool RemoveContext(Mobile from)
{
if(!m_Table.ContainsKey(from))
return false;
m_Table.Remove(from);
return true;
}
public static bool CanAddContext(Mobile from)
{
if(!m_Table.ContainsKey(from))
return true;
if(m_Table[from] != null && m_Table[from].Arrows.Count > 5)
return false;
return true;
}
public static ShipTrackingContext GetContext(Mobile from)
{
if(!m_Table.ContainsKey(from))
return null;
return m_Table[from];
}
public bool IsTrackingBoat(Item item)
{
if (item is BaseBoat || item is PlunderBeaconAddon)
{
foreach (BoatTrackingArrow arrow in m_Arrows)
{
if (arrow.Boat == item)
return true;
}
}
return false;
}
public void AddArrow(BoatTrackingArrow arrow)
{
m_Arrows.Add(arrow);
}
public void RemoveArrow(BoatTrackingArrow arrow)
{
if (m_Arrows.Contains(arrow))
m_Arrows.Remove(arrow);
if(m_Mobile == null)
return;
if (m_Arrows.Count == 0)
{
m_Mobile.QuestArrow = null;
RemoveContext(m_Mobile);
}
else
{
if (m_Mobile.QuestArrow == arrow)
m_Mobile.QuestArrow = null;
if (m_Arrows.Count > 0)
m_Mobile.QuestArrow = m_Arrows[0];
}
}
}
public class BoatTrackingArrow : QuestArrow
{
public static readonly int MaxRange = 200;
public static readonly int MaxBoats = 5;
private Mobile m_From;
private Timer m_Timer;
private Item m_Boat;
public Mobile From { get { return m_From; } }
public Timer Timer { get { return m_Timer; } }
public Item Boat { get { return m_Boat; } }
public BoatTrackingArrow(Mobile from, Item boat, int range) : base(from, boat)
{
m_Boat = boat;
m_From = from;
m_Timer = new BoatTrackingTimer(from, boat, range, this);
m_Timer.Start();
}
public override void OnClick(bool rightClick)
{
if (rightClick && m_From != null)
{
ShipTrackingContext st = ShipTrackingContext.GetContext(m_From);
if (st != null)
st.RemoveArrow(this);
m_From = null;
Stop();
}
}
public override void OnStop()
{
if(m_Timer != null)
m_Timer.Stop();
if(m_From != null)
m_From.SendLocalizedMessage(503177); // You have lost your quarry.
}
public static void StopTracking(Mobile from)
{
ShipTrackingContext st = ShipTrackingContext.GetContext(from);
if (st != null)
{
for (int i = 0; i < st.Arrows.Count; i++)
st.Arrows[i].Stop();
ShipTrackingContext.RemoveContext(from);
}
from.QuestArrow = null;
}
public static void StartTracking(Mobile from)
{
if(!ShipTrackingContext.CanAddContext(from))
{
return;
}
var targets = new List<Item>();
Map map = from.Map;
if(map == null || map == Map.Internal)
return;
BaseBoat fromBoat = BaseBoat.FindBoatAt(from, map);
ShipTrackingContext context = ShipTrackingContext.GetContext(from);
if(fromBoat == null)
{
from.SendMessage("You must be on your boat to use this command.");
}
IPooledEnumerable eable = map.GetItemsInRange(from.Location, MaxRange);
foreach(Item item in eable)
{
if(context != null && context.IsTrackingBoat(item))
continue;
if(!targets.Contains(item) && ((item is BaseBoat && (BaseBoat)item != fromBoat) || item is PlunderBeaconAddon))
targets.Add(item);
}
eable.Free();
List<BoatTrackingArrow> arrows = new List<BoatTrackingArrow>();
for(int i = 0; i < targets.Count; i++)
{
if(i >= MaxBoats)
break;
BoatTrackingArrow arrow = new BoatTrackingArrow(from, targets[i], MaxRange);
if(context == null)
arrows.Add(arrow);
else
context.AddArrow(arrow);
}
if (from.QuestArrow == null && arrows.Count > 0)
from.QuestArrow = arrows[0];
if(context == null)
new ShipTrackingContext(from, arrows);
}
}
public class BoatTrackingTimer : Timer
{
private Mobile m_From;
private Item m_Target;
private int m_Range;
private int m_LastX, m_LastY;
private QuestArrow m_Arrow;
public BoatTrackingTimer(Mobile from, Item target, int range, QuestArrow arrow) : base( TimeSpan.FromSeconds( 0.25 ), TimeSpan.FromSeconds( 2.5 ) )
{
m_From = from;
m_Target = target;
m_Range = range;
m_Arrow = arrow;
}
protected override void OnTick()
{
if(!m_Arrow.Running)
{
this.Stop();
return;
}
else if (m_From.NetState == null || m_From.Deleted || m_Target.Deleted || m_From.Map != m_Target.Map || !m_From.InRange(m_Target, m_Range))
{
m_Arrow.Stop();
this.Stop();
return;
}
if(m_LastX != m_Target.X || m_LastY != m_Target.Y)
{
m_LastX = m_Target.X;
m_LastY = m_Target.Y;
m_Arrow.Update();
}
}
}
}