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

218 lines
6.8 KiB
C#

using System;
using Server;
using Server.Multis;
using Server.Mobiles;
using System.Collections.Generic;
using Server.ContextMenus;
namespace Server.Items
{
public class MooringLine : Item
{
[CommandProperty(AccessLevel.GameMaster)]
public BaseBoat Boat { get; private set; }
public override int LabelNumber => Boat == null || Boat.IsRowBoat ? 1020935 : 1149697; // rope || mooring line
public MooringLine(BaseBoat boat)
: base(5368)
{
Boat = boat;
Movable = false;
Weight = 0;
}
public override void OnDoubleClickDead(Mobile m)
{
OnDoubleClick(m);
}
public override void OnDoubleClick(Mobile from)
{
if (Boat == null || from == null)
return;
BaseBoat boat = BaseBoat.FindBoatAt(from, from.Map);
int range = boat != null && boat == Boat ? 3 : 8;
bool canMove = false;
if (!Boat.IsRowBoat)
Boat.Refresh(from);
if (!from.InRange(Location, range))
from.SendLocalizedMessage(500295); //You are too far away to do that.
else if (!from.InLOS(Location))
from.SendLocalizedMessage(500950); //You cannot see that.
else if (Boat.IsMoving || Boat.IsTurning)
from.SendLocalizedMessage(1116611); //You can't use that while the ship is moving!
else if (BaseBoat.IsDriving(from))
from.SendLocalizedMessage(1116610); //You can't do that while piloting a ship!
else if (BaseHouse.FindHouseAt(from) != null)
from.SendLocalizedMessage(1149795); //You may not dock a ship while on another ship or inside a house.
else if (Boat == boat && !MoveToNearestDockOrLand(from))
from.SendLocalizedMessage(1149796); //You can not dock a ship this far out to sea. You must be near land or shallow water.
else if (boat == null || boat != null && Boat != boat)
{
if (Boat.HasAccess(from))
canMove = true;
else
from.SendLocalizedMessage(1116617); //You do not have permission to board this ship.
}
if (canMove)
{
BaseCreature.TeleportPets(from, Location, Map);
from.MoveToWorld(Location, Map);
Boat.SendContainerPacket();
}
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
if (Boat != null && Boat.IsRowBoat && from.Alive && !Boat.Contains(from))
{
list.Add(new DryDockEntry(Boat, from));
}
}
public bool MoveToNearestDockOrLand(Mobile from)
{
if ((Boat != null && !Boat.Contains(from)) || !ValidateDockOrLand())
return false;
Map map = Map;
if (map == null)
return false;
Rectangle2D rec;
Point3D nearest = Point3D.Zero;
Point3D p = Point3D.Zero;
if (Boat.IsRowBoat)
rec = new Rectangle2D(Boat.X - 8, Boat.Y - 8, 16, 16);
else
{
switch (Boat.Facing)
{
default:
case Direction.North:
case Direction.South:
if (X < Boat.X)
{
rec = new Rectangle2D(X - 8, Y - 8, 8, 16);
}
else
{
rec = new Rectangle2D(X, Y - 8, 8, 16);
}
break;
case Direction.West:
case Direction.East:
if (Y < Boat.Y)
{
rec = new Rectangle2D(X - 8, Y - 8, 16, 8);
}
else
{
rec = new Rectangle2D(X - 8, Y, 16, 8);
}
break;
}
}
for (int x = rec.X; x <= rec.X + rec.Width; x++)
{
for (int y = rec.Y; y <= rec.Y + rec.Height; y++)
{
p = new Point3D(x, y, map.GetAverageZ(x, y));
if (ValidateTile(from, ref p))
{
if (nearest == Point3D.Zero || from.GetDistanceToSqrt(p) < from.GetDistanceToSqrt(nearest))
nearest = p;
}
}
}
if (nearest != Point3D.Zero)
{
BaseCreature.TeleportPets(from, nearest, Map);
from.MoveToWorld(nearest, Map);
return true;
}
return false;
}
public bool ValidateTile(Mobile from, ref Point3D p)
{
int x = p.X;
int y = p.Y;
int z = p.Z;
Map map = from.Map;
if (Spells.SpellHelper.CheckMulti(p, map) || Region.Find(p, map).IsPartOf<Factions.StrongholdRegion>())
return false;
StaticTile[] staticTiles = map.Tiles.GetStaticTiles(x, y, true);
object highest = null;
//Gets highest tile, which will be used to determine if we can walk on it.
foreach (StaticTile tile in staticTiles)
{
if (highest == null || (highest is StaticTile && tile.Z + tile.Height > ((StaticTile)highest).Z + ((StaticTile)highest).Height))
highest = tile;
}
if (highest != null && highest is StaticTile)
{
StaticTile st = (StaticTile)highest;
ItemData id = TileData.ItemTable[st.ID & TileData.MaxItemValue];
if (id.Surface && !id.Impassable)
{
p.Z = st.Z + st.Height;
return from.InLOS(p);
}
}
return map.CanFit(x, y, z, 16, false, false);
}
public bool ValidateDockOrLand()
{
return BaseGalleon.IsNearLandOrDocks(Boat);
}
public MooringLine(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
writer.Write(Boat);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
Boat = reader.ReadItem() as BaseBoat;
}
}
}