Files
abysmal-isle/Scripts/Items/Quest/WispOrb.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

608 lines
17 KiB
C#

using Server;
using System;
using Server.Mobiles;
using Server.Items;
using System.Collections.Generic;
using Server.ContextMenus;
using Server.Targeting;
using Server.Network;
using System.Linq;
namespace Server.Engines.Despise
{
public enum LeashLength
{
//Tight,
Short,
Long
}
public enum Aggression
{
//Following,
Defensive,
Aggressive
}
public class WispOrb : Item
{
public override int LabelNumber { get { return 1153273; } } // A Wisp Orb
private static readonly int MinPowerToConscript = 4;
private Mobile m_Owner;
private DespiseCreature m_Pet;
private LeashLength m_LeashLength;
private Aggression m_Aggression;
private Alignment m_Alignment;
private IEntity m_Anchor;
private bool m_Conscripted;
[CommandProperty(AccessLevel.GameMaster)]
public Mobile Owner
{
get { return m_Owner; }
}
[CommandProperty(AccessLevel.GameMaster)]
public DespiseCreature Pet
{
get { return m_Pet; }
set
{
if(m_Pet != null && value == null)
{
m_Pet.Unlink();
}
else
{
m_Pet = value;
if (m_Pet != null)
m_Pet.Link(this);
}
InvalidateHue();
InvalidateProperties();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public LeashLength LeashLength
{
get { return m_LeashLength; }
set
{
m_LeashLength = value;
//if (m_Pet != null)
// m_Pet.RangeHome = m_Pet.GetLeashLength();
InvalidateHue();
InvalidateProperties();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public Aggression Aggression
{
get { return m_Aggression; }
set
{
if(value != m_Aggression)
{
m_Aggression = value;
}
InvalidateHue();
InvalidateProperties();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public Alignment Alignment
{
get { return m_Alignment; }
set { m_Alignment = value; InvalidateProperties(); }
}
[CommandProperty(AccessLevel.GameMaster)]
public IEntity Anchor
{
get { return m_Anchor; }
set
{
m_Anchor = value;
if (m_Pet != null && m_Anchor == null)
{
m_Anchor = m_Owner;
m_Pet.Home = GetAnchorLocation();
}
InvalidateProperties();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public bool Conscripted
{
get { return m_Conscripted; }
set
{
m_Conscripted = value;
if (m_Conscripted && DespiseController.Instance != null && DespiseController.Instance.Sequencing)
DespiseController.Instance.TryAddToArmy(this);
}
}
public WispOrb(Mobile owner, Alignment alignment) : base(8448)
{
m_Owner = owner;
LootType = LootType.Blessed;
m_Alignment = alignment;
m_Orbs.Add(this);
InvalidateHue();
}
public void OnUnlinkPet()
{
m_Pet = null;
m_Anchor = null;
m_Aggression = Aggression.Aggressive;
InvalidateProperties();
}
public bool CheckOwnerAlignment()
{
if(m_Owner == null || (m_Owner.Karma > 0 && m_Alignment != Alignment.Good) || (m_Owner.Karma < 0 && m_Alignment != Alignment.Evil))
{
if(m_Owner != null)
m_Owner.SendLocalizedMessage(1153313); // You are no longer aligned with your Wisp Orb. It dissolves into aether!
Delete();
return false;
}
return true;
}
public override void OnDoubleClick(Mobile from)
{
if(CheckOwnerAlignment() && IsChildOf(from.Backpack) && from == m_Owner)
{
int cliloc = m_Pet == null ? 1153274 : 1153277;
from.SendLocalizedMessage(cliloc); // Target a creature to possess. / Target an object or creature to set the anchor. Target the Wisp Orb to change the leash setting. Target the possessed creature to change its aggression.
from.Target = new InternalTarget(this);
}
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
list.Add(new ReleaseEntry(from, this));
list.Add(new ConscriptEntry(from, this));
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
list.Add(1153329, String.Format("#{0}", GetAlignment())); // Alignment: ~1_VAL~
list.Add(1153306, String.Format("{0}", GetArmyPower())); // Army Power: ~1_VAL~
list.Add(1153272, m_Pet != null ? m_Pet.Name : "None"); // Controlling: ~1_VAL~
object name = GetAnchorName();
if(name != null) //Anchor: ~1_NAME~
{
if(name is int)
list.Add(1153265, String.Format("#{0}", (int)name));
else if(name is string)
list.Add(1153265, (string)name);
}
int leash = 1153262 + (int)m_LeashLength;
int aggr = 1153269 + (int)m_Aggression;
list.Add(1153260, String.Format("#{0}", leash.ToString())); // Leash: ~1_VAL~
list.Add(1153267, String.Format("#{0}", aggr.ToString())); // Aggression: ~1_VAL~
}
public override bool DropToWorld(Mobile m, Point3D p)
{
m.SendLocalizedMessage(1153233); // The Wisp Orb vanishes to whence it came...
Delete();
return false;
}
public static void CheckDrop(Container c, Mobile m)
{
List<WispOrb> list = new List<WispOrb>(c.Items.OfType<WispOrb>());
foreach (var orb in list)
{
m.SendLocalizedMessage(1153233); // The Wisp Orb vanishes to whence it came...
orb.Delete();
}
}
public override bool OnDroppedInto(Mobile from, Container target, Point3D p)
{
if (target.RootParentEntity == from)
{
return base.OnDroppedInto(from, target, p);
}
from.SendLocalizedMessage(1153233); // The Wisp Orb vanishes to whence it came...
Delete();
return false;
}
public override bool OnDroppedOnto(Mobile from, Item target)
{
if (target is Container && target.RootParentEntity != from)
{
from.SendLocalizedMessage(1153233); // The Wisp Orb vanishes to whence it came...
Delete();
return false;
}
return base.OnDroppedOnto(from, target);
}
public Point3D GetAnchorLocation()
{
if (m_Pet == null)
return Point3D.Zero;
if (m_Anchor == null)
m_Anchor = m_Pet.ControlMaster;
if (m_Anchor is Item)
{
if (((Item)m_Anchor).HeldBy != null)
return ((Item)m_Anchor).HeldBy.Location;
return ((Item)m_Anchor).GetWorldLocation();
}
return m_Anchor.Location;
}
public IPoint3D GetAnchorActual()
{
if (m_Pet == null)
return null;
if (m_Anchor == null)
m_Anchor = m_Pet.ControlMaster;
if (m_Anchor is Item && ((Item)m_Anchor).RootParentEntity != null)
{
return ((Item)m_Anchor).RootParentEntity;
}
return m_Anchor;
}
private class ConscriptEntry : ContextMenuEntry
{
private Mobile m_From;
private WispOrb m_Orb;
public ConscriptEntry(Mobile from, WispOrb orb) : base(1153285, -1) // Conscript
{
m_From = from;
m_Orb = orb;
if (m_Orb.Pet == null || m_Orb.Conscripted || m_Orb.Pet.Alignment != m_Orb.Alignment)
Flags |= Server.Network.CMEFlags.Disabled;
}
public override void OnClick()
{
if (m_Orb.Pet != null && m_Orb.IsChildOf(m_From.Backpack) && !m_Orb.Conscripted && m_Orb.Pet.Alignment == m_Orb.Alignment)
{
if(m_Orb.Pet.Power < WispOrb.MinPowerToConscript)
m_From.SendLocalizedMessage(1153311); // The creature under control of your Wisp Orb cannot be conscripted at this time.
else
{
m_From.SendLocalizedMessage(1153310); // The creature you are controlling will now fight with you when the Call to Arms sounds. If you do not wish this, then release control of it.
m_Orb.Conscripted = true;
}
}
}
}
private class ReleaseEntry : ContextMenuEntry
{
private Mobile m_From;
private WispOrb m_Orb;
public ReleaseEntry(Mobile from, WispOrb orb) : base(1153284, -1) // Release
{
m_From = from;
m_Orb = orb;
if(m_Orb.Pet == null/* || !m_Orb.Conscripted*/)
Flags |= Server.Network.CMEFlags.Disabled;
}
public override void OnClick()
{
if (m_Orb.Pet != null)
{
m_Orb.Pet.Unlink();
}
}
}
private class InternalTarget : Target
{
private WispOrb m_Orb;
public InternalTarget(WispOrb orb) : base(8, true, TargetFlags.None)
{
m_Orb = orb;
}
protected override void OnTarget(Mobile from, object targeted)
{
if(targeted is BaseCreature)
{
DespiseCreature creature = targeted as DespiseCreature;
if (creature == null)
from.SendLocalizedMessage(1153286); // That cannot be possessed by a Wisp Orb.
else if (m_Orb.Pet == null)
{
if (((BaseCreature)targeted).Controlled)
from.SendLocalizedMessage(1153287); // That creature is already under the control of a Wisp Orb.
else if (creature.Power > 5)
from.SendLocalizedMessage(1153336); // That creature is too powerful for you to coerce.
else
{
m_Orb.Anchor = from;
m_Orb.Pet = creature;
creature.Link(m_Orb);
m_Orb.Pet.SetControlMaster(from);
m_Orb.Pet.ControlTarget = from;
m_Orb.Pet.ControlOrder = OrderType.Follow;
from.SendLocalizedMessage(1153276); // Your Wisp Orb takes control of the creature!
m_Orb.Pet.PublicOverheadMessage(MessageType.Regular, 0x3B2, 1153295, from.Name); // * This creature is now under the control of ~1_NAME~ *
}
}
else if (targeted == m_Orb.Pet)
{
int aggr = (int)m_Orb.Aggression + 1;
if (aggr >= 2) aggr = 0;
m_Orb.Aggression = (Aggression)aggr;
from.SendLocalizedMessage(1153279, m_Orb.Aggression.ToString()); // Your possessed creature's aggression level is now: ~1_VAL~
}
else
{
m_Orb.TrySetAnchor(from, (BaseCreature)targeted);
}
}
else if (targeted == m_Orb)
{
int length = (int)m_Orb.LeashLength + 1;
if(length >= 2) length = 0;
m_Orb.LeashLength = (LeashLength)length;
from.SendLocalizedMessage(1153278, m_Orb.LeashLength.ToString()); // Your possessed creature's leash is now: ~1_VAL~
}
else if (targeted is IPoint3D && m_Orb.Pet != null)
{
m_Orb.TrySetAnchor(from, (IPoint3D)targeted);
}
}
}
private object GetAnchorName()
{
if(m_Anchor == null)
return "None";
if(m_Anchor is Mobile)
return ((Mobile)m_Anchor).Name;
if(m_Anchor is Item)
{
if(((Item)m_Anchor).Name != null)
return ((Item)m_Anchor).Name;
return ((Item)m_Anchor).LabelNumber;
}
if(m_Anchor is StaticTarget)
return String.Format("{0} {1}", ((StaticTarget)m_Anchor).Name, ((StaticTarget)m_Anchor).Location.ToString());
if(m_Anchor is LandTarget)
return String.Format("{0} {1}", ((LandTarget)m_Anchor).Name, ((LandTarget)m_Anchor).Location.ToString());
Point3D p = new Point3D(m_Anchor);
return p.ToString();
}
public void TrySetAnchor(Mobile from, IPoint3D p)
{
if (!CheckOwnerAlignment() || from != m_Owner)
return;
if (p is Mobile)
{
Mobile m = p as Mobile;
Anchor = m;
from.SendLocalizedMessage(1153280, m == m_Owner ? "You!" : m.Name + ".");
m_Pet.ControlTarget = m;
m_Pet.ControlOrder = OrderType.Follow;
}
if (p is Item)
{
Item item = p as Item;
Anchor = item;
object name = GetAnchorName(); // Your possessed creature is now anchored to ~1_NAME~
if (name is int)
from.SendLocalizedMessage(1153280, String.Format("#{0}", (int)name));
else if (name is string)
from.SendLocalizedMessage(1153280, (string)name);
m_Pet.ControlTarget = m_Pet.ControlMaster;
m_Pet.ControlOrder = OrderType.Follow;
}
}
private int GetAlignment()
{
switch (m_Alignment)
{
case Alignment.Neutral: break;
case Alignment.Good: return 1153330;
case Alignment.Evil: return 1153331;
}
return -1;
}
public void InvalidateHue()
{
if (m_Pet == null)
Hue = 1910; // shadow wisp color
else if (m_Pet.Combatant != null)
Hue = 1931; // Orange
else if (IsFollowing())
Hue = 1912;
else
{
switch (m_Aggression)
{
//case Aggression.Following: Hue = 1912; break; // Yellow
case Aggression.Defensive: Hue = 1917; break; // blue
case Aggression.Aggressive: Hue = 1914; break; // green
}
}
}
public bool IsFollowing()
{
return (int)m_Pet.GetDistanceToSqrt(GetAnchorLocation()) > m_Pet.GetLeashLength() + 1 && m_Pet.ControlOrder == OrderType.Follow;
}
public override void Delete()
{
if(m_Orbs.Contains(this))
m_Orbs.Remove(this);
if (m_Pet != null && m_Pet.Alive)
m_Pet.Unlink(false);
base.Delete();
}
public int GetArmyPower()
{
if (m_Pet == null)
return 0;
int power = ((DespiseCreature)m_Pet).Power;
return power * power;
}
public static void TeleportPet(Mobile owner)
{
if(owner == null || owner.Backpack == null)
return;
Item item = owner.Backpack.FindItemByType(typeof(WispOrb));
if(item != null && item is WispOrb)
{
Mobile pet = ((WispOrb)item).Pet;
if(pet != null)
pet.MoveToWorld(owner.Location, owner.Map);
}
}
public WispOrb(Serial serial) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
writer.Write(m_Owner);
writer.Write(m_Pet);
writer.Write((int)m_LeashLength);
writer.Write((int)m_Aggression);
writer.Write((int)m_Alignment);
writer.Write(m_Conscripted);
if (m_Anchor is Mobile)
{
writer.Write((int)1);
writer.Write((Mobile)m_Anchor);
}
else if(m_Anchor is Item)
{
writer.Write((int)2);
writer.Write((Item)m_Anchor);
}
else
{
writer.Write(0);
}
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int v = reader.ReadInt();
m_Owner = reader.ReadMobile();
m_Pet = reader.ReadMobile() as DespiseCreature;
m_LeashLength = (LeashLength)reader.ReadInt();
m_Aggression = (Aggression)reader.ReadInt();
m_Alignment = (Alignment)reader.ReadInt();
m_Conscripted = reader.ReadBool();
switch (reader.ReadInt())
{
case 0: break;
case 1: m_Anchor = (IEntity)reader.ReadMobile(); break;
case 2: m_Anchor = (IEntity)reader.ReadItem(); break;
}
if (m_Anchor == null && m_Pet != null)
{
Anchor = m_Owner;
}
m_Orbs.Add(this);
}
private static List<WispOrb> m_Orbs = new List<WispOrb>();
public static List<WispOrb> Orbs { get { return m_Orbs; } }
}
}