Files
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

473 lines
14 KiB
C#

using Server;
using System;
using System.Collections.Generic;
using Server.Mobiles;
using Server.Targeting;
using Server.Network;
using Server.Engines.PartySystem;
namespace Server.Items
{
[Flipable(17615, 17616)]
public class LobsterTrap : Container, ITelekinesisable
{
public static readonly int TrapID = Utility.RandomMinMax(17615, 17616);
public static readonly int BuoyID = 17611;
public static readonly int MaxCatch = 5;
private Type m_BaitType;
private bool m_EnhancedBait;
private int m_BaitUses;
private bool m_InUse;
private Timer m_Timer;
private Mobile m_Owner;
private int m_Bobs;
[CommandProperty(AccessLevel.GameMaster)]
public Type BaitType
{
get { return m_BaitType; }
set
{
m_BaitType = value;
if (m_BaitType == null)
{
m_EnhancedBait = false;
m_BaitUses = 0;
}
InvalidateProperties();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public bool EnhancedBait { get { return m_EnhancedBait; } set { m_EnhancedBait = value; InvalidateProperties(); } }
[CommandProperty(AccessLevel.GameMaster)]
public int BaitUses { get { return m_BaitUses; } set { m_BaitUses = value; InvalidateProperties(); } }
[CommandProperty(AccessLevel.GameMaster)]
public bool InUse { get { return m_InUse; } set { m_InUse = value; InvalidateProperties(); } }
[CommandProperty(AccessLevel.GameMaster)]
public Mobile Owner { get { return m_Owner; } set { m_Owner = value; InvalidateProperties(); } }
public override int LabelNumber { get { if (m_Owner == null) return 1096487; else return 0; } }
public override bool DisplaysContent { get { return false; } }
[Constructable]
public LobsterTrap() : base(17615)
{
}
public void OnTelekinesis(Mobile from)
{
if (m_InUse && ItemID == BuoyID && CanUseTrap(from))
EndTimer(from);
}
public override bool OnDragDropInto(Mobile from, Item item, Point3D p)
{
return false;
}
public override bool OnDragDrop(Mobile from, Item dropped)
{
return false;
}
public override bool TryDropItem(Mobile from, Item dropped, bool sendFullMessage)
{
return false;
}
public override void AddNameProperty(ObjectPropertyList list)
{
if (ItemID == TrapID)
{
if (Items.Count == 0)
list.Add(1116389); //empty lobster trap
else if (Items.Count >= MaxCatch)
list.Add(1149599); //full lobster trap
else
list.Add(1096487); //lobster trap
}
else
{
if (m_Owner == null)
list.Add(1096487); //lobster trap
else
list.Add(1116390, m_Owner.Name);
}
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
if (m_BaitType != null)
{
object label = FishInfo.GetFishLabel(m_BaitType);
if (label is int)
list.Add(1116468, String.Format("#{0}", (int)label)); //baited to attract: ~1_val~
else if (label is string)
list.Add(1116468, (string)label);
list.Add(1116466, m_BaitUses.ToString());
}
}
public override void OnDoubleClick(Mobile from)
{
if (IsChildOf(from.Backpack))
{
if (ItemID == BuoyID)
ItemID = TrapID;
if (Items.Count > 0)
{
DumpContents(from);
from.SendMessage("You dump the contents of the lobster trap into your pack.");
}
else
{
from.SendLocalizedMessage(500974); //What water do you want to fish in?
from.BeginTarget(-1, true, TargetFlags.None, new TargetCallback(OnTarget));
}
}
else if (ItemID == BuoyID)
{
if (RootParent != null)
ItemID = TrapID;
InvalidateProperties();
if (CanUseTrap(from))
EndTimer(from);
InvalidateProperties();
}
else
{
from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
}
}
private void DumpContents(Mobile from)
{
Container pack = from.Backpack;
foreach (Item item in new List<Item>(this.Items))
{
if (item == null)
continue;
if (!pack.TryDropItem(from, item, false))
item.MoveToWorld(from.Location, from.Map);
from.SendLocalizedMessage(1116386, String.Format("#{0}", item.LabelNumber));
}
}
public void OnTarget(Mobile from, object targeted)
{
if (Deleted || m_InUse)
return;
IPoint3D pnt = (IPoint3D)targeted;
Map map = from.Map;
if (map == null || map == Map.Internal)
return;
int x = pnt.X; int y = pnt.Y; int z = pnt.Z;
if (!from.InRange(pnt, 6))
{
from.SendLocalizedMessage(1116388); // The trap is too cumbersome to deploy that far away.
}
else if (!IsValidTile(targeted, map))
from.SendMessage("You cannot deploy a trap there!"); //TODO: Get Cliloc
else if (!IsValidLocation(x, y, z, map))
from.SendLocalizedMessage(1116393); //The location is too close to another trap.
else
{
m_Owner = from;
ItemID = BuoyID;
InvalidateProperties();
Movable = false;
MoveToWorld(new Point3D(x, y, z), map);
m_Bobs = 0;
m_InUse = true;
StartTimer();
Effects.PlaySound(this, map, Utility.Random(0x025, 3));
Effects.SendMovingEffect(from, this, TrapID, 7, 0, false, false);
}
}
public void StartTimer()
{
if (m_Timer != null)
m_Timer.Stop();
m_Timer = Timer.DelayCall(TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1), new TimerCallback(OnTick));
}
public void EndTimer(Mobile from)
{
if (m_Timer != null)
{
m_Timer.Stop();
m_Timer = null;
}
if (from == null) from = m_Owner;
if (from == null)
return;
Movable = true;
ItemID = TrapID;
InvalidateProperties();
m_InUse = false;
if (RootParent == null)
{
if (from.Backpack == null || !from.Backpack.TryDropItem(from, this, false))
this.MoveToWorld(from.Location, from.Map);
}
}
public void OnTick()
{
m_Bobs++;
PublicOverheadMessage(MessageType.Regular, 0, 1116364); //**bob**
if (m_Owner != null && (!SpecialFishingNet.ValidateDeepWater(Map, X, Y) || m_Owner.Skills[SkillName.Fishing].Base >= 75.0))
{
m_Owner.CheckSkill(SkillName.Fishing, 0, m_Owner.Skills[SkillName.Fishing].Cap);
}
if (!m_InUse)
{
EndTimer(null);
return;
}
if (m_Bobs * 5 > Utility.Random(100))
{
OnTrapLost();
return;
}
bool rare = true;
double bump = (double)m_Bobs / 100.0;
Type type = FishInfo.GetSpecialItem(m_Owner, this, this.Location, bump, this is LavaLobsterTrap);
if (type != null)
{
Item item = Loot.Construct(type);
DropItem(item);
if (item is RareCrabAndLobster && rare)
{
RareCrabAndLobster fish = (RareCrabAndLobster)item;
fish.Fisher = m_Owner;
fish.DateCaught = DateTime.UtcNow;
fish.Weight = Utility.RandomMinMax(10, 200);
fish.Stackable = false;
}
if (m_Owner != null)
m_Owner.SendMessage("It looks like you caught something!");
CheckBait();
}
else if (Utility.RandomBool())
{
Item item;
if (Utility.RandomBool())
item = new Crab();
else
item = new Lobster();
if (m_Owner != null)
m_Owner.SendMessage("It looks like you caught something!");
DropItem(item);
CheckBait();
}
}
private void CheckBait()
{
if (m_BaitType != null)
{
BaitUses--;
if (m_BaitUses == 0)
{
BaitType = null;
EnhancedBait = false;
if (m_Owner != null)
m_Owner.SendMessage("You have used up the bait on your lobster trap.");
}
}
}
public void OnTrapLost()
{
if (m_Timer != null)
m_Timer.Stop();
Effects.PlaySound(this, this.Map, Utility.Random(0x025, 3));
IPooledEnumerable eable = this.GetMobilesInRange(12);
foreach (Mobile mob in eable)
{
if (mob is PlayerMobile && m_Owner != null)
mob.SendLocalizedMessage(1116385, m_Owner.Name); //~1_NAME~'s trap bouy is pulled beneath the waves.
}
eable.Free();
Delete();
}
private bool CanUseTrap(Mobile from)
{
if (m_Owner == null || RootParent != null)
return false;
if (!from.InRange(this.Location, 6))
{
from.SendLocalizedMessage(500295); //You are too far away to do that.
return false;
}
//is owner, or in same guild
if (m_Owner == from || (from.Guild != null && from.Guild == m_Owner.Guild))
return true;
//partied
if (Party.Get(from) == Party.Get(m_Owner))
return true;
//fel rules
if (from.Map != null && from.Map.Rules == MapRules.FeluccaRules)
{
from.CriminalAction(true);
from.SendLocalizedMessage(1149823); //The owner of the lobster trap notices you committing a criminal act!
if (m_Owner != null)
m_Owner.SendMessage("You notice {0} taking your lobster trap out of the water!", from.Name);
return true;
}
from.SendLocalizedMessage(1116391); //You realize that the trap isn't yours so you leave it alone.
return false;
}
public virtual bool IsValidTile(object targeted, Map map)
{
int tileID = 0;
if (targeted is LandTarget)
{
LandTarget obj = (LandTarget)targeted;
tileID = obj.TileID;
}
else if (targeted is StaticTarget)
{
StaticTarget obj = (StaticTarget)targeted;
tileID = obj.ItemID;
}
for (int i = 0; i < UseableTiles.Length; i++)
{
if (UseableTiles[i] == tileID)
return true;
}
return false;
}
public bool IsValidLocation(int x, int y, int z, Map map)
{
IPooledEnumerable eable = map.GetItemsInRange(new Point3D(x, y, z), 1);
foreach (Item item in eable)
{
if (item is LobsterTrap)
{
eable.Free();
return false;
}
}
eable.Free();
return true;
}
public virtual int[] UseableTiles { get { return m_WaterTiles; } }
private int[] m_WaterTiles = new int[]
{
//Deep Water
0x00AA, 0x00A9,
0x00A8, 0x00AB,
0x0136, 0x0137,
//Shallow Water
0x5797, 0x579C,
0x746E, 0x7485,
0x7490, 0x74AB,
0x74B5, 0x75D5,
//Static tiles
0x1797, 0x1798,
0x1799, 0x179A,
0x179B, 0x179C,
};
public LobsterTrap(Serial serial) : base(serial) { }
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
int index = FishInfo.GetIndexFromType(m_BaitType);
writer.Write(index);
writer.Write(m_Bobs);
writer.Write(m_InUse);
writer.Write(m_Owner);
writer.Write(m_BaitUses);
writer.Write(m_EnhancedBait);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
int index = reader.ReadInt();
m_BaitType = FishInfo.GetTypeFromIndex(index);
m_Bobs = reader.ReadInt();
m_InUse = reader.ReadBool();
m_Owner = reader.ReadMobile();
m_BaitUses = reader.ReadInt();
m_EnhancedBait = reader.ReadBool();
if (m_BaitType != null && m_BaitUses <= 0)
BaitType = null;
if (m_InUse)
StartTimer();
}
}
}