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

344 lines
11 KiB
C#

using Server;
using System;
using Server.Mobiles;
using System.Collections.Generic;
using Server.Multis;
using Server.Regions;
using Server.Targeting;
using Server.Items;
namespace Server.Mobiles
{
[PropertyObject]
public class CharydbisSpawner
{
public static void GenerateCharydbisSpawner()
{
if (m_SpawnInstance == null)
{
m_SpawnInstance = new CharydbisSpawner();
}
}
public static readonly TimeSpan KillDelay = TimeSpan.FromHours(7);
public static readonly TimeSpan NoSpawnDelay = TimeSpan.FromHours(24);
private Charydbis m_Charydbis;
private Timer m_Timer;
private DateTime m_NextSpawn;
private DateTime m_LastAttempt;
private bool m_IsSummoned;
private bool m_HasSpawned;
private Map m_Map;
private Rectangle2D m_CurrentLocation;
private Rectangle2D m_LastLocation;
private bool m_Active;
[CommandProperty(AccessLevel.GameMaster)]
public Charydbis Charydbis { get { return m_Charydbis; } }
[CommandProperty(AccessLevel.GameMaster)]
public DateTime NextSpawn { get { return m_NextSpawn; } set { m_NextSpawn = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public DateTime LastAttempt { get { return m_LastAttempt; } set { m_LastAttempt = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public bool IsSummoned { get { return m_IsSummoned; } set { m_IsSummoned = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public bool HasSpawned { get { return m_HasSpawned; } set { m_HasSpawned = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public Map Map { get { return m_Map; } set { m_Map = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public Rectangle2D CurrentLocation { get { return m_CurrentLocation; } set { m_CurrentLocation = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public Rectangle2D LastLocation { get { return m_LastLocation; } set { m_LastLocation = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public bool Active
{
get
{
return m_Active;
}
set
{
Reset();
m_NextSpawn = DateTime.UtcNow;
m_Active = value;
}
}
private static CharydbisSpawner m_SpawnInstance;
public static CharydbisSpawner SpawnInstance
{
get
{
return m_SpawnInstance;
}
set
{
m_SpawnInstance = value;
}
}
public CharydbisSpawner()
{
m_Charydbis = null;
m_NextSpawn = DateTime.UtcNow;
m_IsSummoned = false;
m_HasSpawned = false;
Active = true;
}
public bool TrySpawnCharybdis(Mobile from)
{
if (!m_Active)
{
from.SendLocalizedMessage(1150198); //The spyglass goes dark, it has failed to find what you seek.
return false;
}
else if (m_IsSummoned)
{
if (m_Charydbis != null && m_Charydbis.Alive)
{
Point3D pnt = new Point3D(m_CurrentLocation.X + 5, m_CurrentLocation.Y + 5, -5);
from.SendMessage(String.Format("The location you seek is: {0} in {1}", GetSextantLocation(pnt), m_Map));
}
else if (m_HasSpawned && (m_Charydbis == null || !m_Charydbis.Alive))
{
from.SendMessage("The creature you seek has already been slain.");
}
else
from.SendLocalizedMessage(1150198); //The spyglass goes dark, it has failed to find what you seek.
return false;
}
else if (DateTime.UtcNow < m_NextSpawn)
{
from.SendLocalizedMessage(1150198); //The spyglass goes dark, it has failed to find what you seek.
return false;
}
Map map = from.Map;
if (map != Map.Felucca && map != Map.Trammel)
{
from.SendMessage("You can only summon Charydbis in Felucca or Trammel.");
return false;
}
m_Map = map;
from.SendLocalizedMessage(1150190); //You peer into the spyglass, images swirl in your mind as the magic device searches.
m_NextSpawn = DateTime.UtcNow + NoSpawnDelay;
m_IsSummoned = true;
Point3D p = SOS.FindLocation(map);
from.SendMessage(String.Format("The location you seek is: {0} in {1}", GetSextantLocation(p), m_Map));
m_CurrentLocation = new Rectangle2D(p.X - 5, p.Y - 5, 10, 10);
m_LastLocation = m_CurrentLocation;
m_Timer = new InternalTimer(this, NoSpawnDelay);
m_Timer.Start();
m_LastAttempt = DateTime.UtcNow;
return true;
}
public string GetSextantLocation(Point3D pnt)
{
int xLong = 0, yLat = 0;
int xMins = 0, yMins = 0;
bool xEast = false, ySouth = false;
if (Sextant.Format(pnt, m_Map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast, ref ySouth))
return String.Format("{0}° {1}'{2}, {3}° {4}'{5}", yLat, yMins, ySouth ? "S" : "N", xLong, xMins, xEast ? "E" : "W");
return pnt.ToString();
}
public void SpawnCharydbis(Mobile from, Point3D pnt, Map map, BaseBoat boat)
{
Effects.PlaySound(pnt, map, 0x668);
m_Charydbis = new Charydbis(from);
from.SendMessage("It seems as though you've snagged your hook.");
Timer.DelayCall(TimeSpan.FromSeconds(11), new TimerStateCallback(DoTeleportEffect), new object[] { pnt, map });
Timer.DelayCall(TimeSpan.FromSeconds(12), new TimerStateCallback(DoDelayedSpawn), new object[] { from, pnt, map, boat });
}
public void DoTeleportEffect(object o)
{
object[] ojs = (object[])o;
Point3D pnt = (Point3D)ojs[0];
Map map = (Map)ojs[1];
m_Charydbis.DoTeleportEffects(new Point3D(pnt.X, pnt.Y, map.GetAverageZ(pnt.X, pnt.Y)), map);
}
public void DoDelayedSpawn(object o)
{
object[] ojs = (object[])o;
Mobile from = (Mobile)ojs[0];
Point3D pnt = (Point3D)ojs[1];
Map map = (Map)ojs[2];
BaseBoat boat = (BaseBoat)ojs[3];
int x = pnt.X, y = pnt.Y;
m_Charydbis.MoveToWorld(new Point3D(x, y, map.GetAverageZ(pnt.X, pnt.Y)), map);
m_Charydbis.Combatant = from;
from.SendMessage("THATS NO FISH!");
if (boat != null)
{
pnt = boat.Location;
}
for (int i = 0; i < 8; i++)
{
x = pnt.X; y = pnt.Y;
if (TrySpawnMobile(ref x, ref y, map))
{
GiantTentacle tent = new GiantTentacle(m_Charydbis);
m_Charydbis.AddTentacle(tent);
tent.MoveToWorld(new Point3D(x, y, -5), map);
}
}
}
public bool TrySpawnMobile(ref int x, ref int y, Map map)
{
for (int i = 0; map != null && i < 25; ++i)
{
int tx = x - 10 + Utility.Random(21);
int ty = y - 10 + Utility.Random(21);
LandTile t = map.Tiles.GetLandTile(tx, ty);
if (t.Z == -5 && ((t.ID >= 0xA8 && t.ID <= 0xAB) || (t.ID >= 0x136 && t.ID <= 0x137)) && !Spells.SpellHelper.CheckMulti(new Point3D(tx, ty, -5), map))
{
x = tx;
y = ty;
return true;
}
}
return false;
}
public void OnCharybdisKilled()
{
DateTime timeout = m_LastAttempt + KillDelay;
if (m_LastAttempt + KillDelay < DateTime.UtcNow)
{
m_Charydbis = null;
Reset();
}
else
{
TimeSpan ts = timeout - DateTime.UtcNow;
m_NextSpawn = DateTime.UtcNow + ts;
m_Timer = new InternalTimer(this, ts);
m_Timer.Start();
}
}
public void Reset()
{
if (m_Charydbis != null && m_Charydbis.Alive)
{
IPooledEnumerable eable = m_Charydbis.GetMobilesInRange(12);
foreach (Mobile mob in eable)
{
if (mob is PlayerMobile)
mob.SendMessage("Charydbis sinks to the depths of the ocean from which it came from...You have taken too long!");
}
eable.Free();
for (int x = m_Charydbis.X - 1; x <= m_Charydbis.X + 1; x++)
{
for (int y = m_Charydbis.Y - 1; y <= m_Charydbis.Y + 1; y++)
{
int splash = Utility.RandomList(0x352D, 0x5675);
Effects.SendLocationEffect(new Point3D(x, y, m_Charydbis.Z), m_Charydbis.Map, splash, 16, 4);
Effects.PlaySound(new Point3D(x, y, m_Charydbis.Z), m_Charydbis.Map, 0x364);
}
}
m_Charydbis.Delete();
}
m_Charydbis = null;
m_IsSummoned = false;
m_HasSpawned = false;
m_CurrentLocation = new Rectangle2D(0, 0, 0, 0);
m_NextSpawn = DateTime.UtcNow;
if (m_Timer != null)
m_Timer.Stop();
}
private class InternalTimer : Timer
{
private CharydbisSpawner m_Info;
public InternalTimer(CharydbisSpawner info, TimeSpan ts)
: base(ts)
{
m_Info = info;
}
protected override void OnTick()
{
m_Info.Reset();
}
}
public void Serialize(GenericWriter writer)
{
writer.Write((int)0);
writer.Write(m_HasSpawned);
writer.Write(m_LastAttempt);
writer.Write(m_Active);
writer.Write(m_Charydbis);
writer.Write(m_NextSpawn);
writer.Write(m_IsSummoned);
writer.Write(m_Map);
writer.Write(m_CurrentLocation);
writer.Write(m_LastLocation);
}
public void Deserialize(GenericReader reader)
{
int version = reader.ReadInt();
m_HasSpawned = reader.ReadBool();
m_LastAttempt = reader.ReadDateTime();
m_Active = reader.ReadBool();
m_Charydbis = reader.ReadMobile() as Charydbis;
m_NextSpawn = reader.ReadDateTime();
m_IsSummoned = reader.ReadBool();
m_Map = reader.ReadMap();
m_CurrentLocation = reader.ReadRect2D();
m_LastLocation = reader.ReadRect2D();
if (m_NextSpawn > DateTime.UtcNow)
m_Timer = new InternalTimer(this, m_NextSpawn - DateTime.UtcNow);
else
Reset();
}
}
}