Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
@@ -0,0 +1,913 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
using Server.ContextMenus;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Multis;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class RuneCodex : Item, ISecurable
|
||||
{
|
||||
public sealed class UICache : IEquatable<UICache>, IEquatable<PlayerMobile>
|
||||
{
|
||||
public enum ViewMode
|
||||
{
|
||||
Categories,
|
||||
Entries
|
||||
}
|
||||
|
||||
public PlayerMobile User { get; private set; }
|
||||
|
||||
public RuneCodexCategory Category { get; set; }
|
||||
public Point2D CategoryScroll { get; set; }
|
||||
public Point2D CategoryPoint { get; set; }
|
||||
|
||||
public RuneCodexEntry Entry { get; set; }
|
||||
public Point2D EntryScroll { get; set; }
|
||||
public Point2D EntryPoint { get; set; }
|
||||
|
||||
public ViewMode Mode { get; set; }
|
||||
public bool EditMode { get; set; }
|
||||
|
||||
public UICache(PlayerMobile user)
|
||||
{
|
||||
User = user;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return User == null ? 0 : User.Serial.Value;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is UICache)
|
||||
{
|
||||
return Equals((UICache)obj);
|
||||
}
|
||||
|
||||
if (obj is PlayerMobile)
|
||||
{
|
||||
return Equals((PlayerMobile)obj);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Equals(UICache other)
|
||||
{
|
||||
return other != null && Equals(other.User);
|
||||
}
|
||||
|
||||
public bool Equals(PlayerMobile other)
|
||||
{
|
||||
return User == other;
|
||||
}
|
||||
}
|
||||
|
||||
public static string DefaultDescription = "World Locations";
|
||||
|
||||
private string _Descripton = DefaultDescription;
|
||||
private int _Charges;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string Descripton { get => _Descripton; set => SetDescription(value); }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public RuneCodexCategoryGrid Categories { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public SecureLevel Level { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Charges
|
||||
{
|
||||
get => _Charges;
|
||||
set
|
||||
{
|
||||
_Charges = Math.Max(0, value);
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int RecallChargeCost { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int GateChargeCost { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int CloneEntryChargeCost { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool EditLocked { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool AddLocked { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool RemoveLocked { get; set; }
|
||||
|
||||
public Dictionary<Type, int> ChargeTypes { get; private set; }
|
||||
|
||||
public List<UICache> Users { get; private set; }
|
||||
|
||||
[Constructable]
|
||||
public RuneCodex()
|
||||
: this(1000)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public RuneCodex(int charges)
|
||||
: base(0x22C5)
|
||||
{
|
||||
Users = new List<UICache>();
|
||||
|
||||
ChargeTypes = new Dictionary<Type, int>
|
||||
{
|
||||
{typeof(Gold), 100}
|
||||
};
|
||||
|
||||
Categories = new RuneCodexCategoryGrid();
|
||||
Charges = Math.Max(0, charges);
|
||||
|
||||
CloneEntryChargeCost = 5;
|
||||
RecallChargeCost = 1;
|
||||
GateChargeCost = 2;
|
||||
|
||||
Name = "Rune Codex";
|
||||
Weight = 1.0;
|
||||
Hue = 74;
|
||||
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public RuneCodex(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
Users = new List<UICache>();
|
||||
}
|
||||
|
||||
public virtual bool CanAddCategories(Mobile m)
|
||||
{
|
||||
return m.AccessLevel > AccessLevel.Counselor || BlessedFor == m || (!AddLocked && IsAccessibleTo(m));
|
||||
}
|
||||
|
||||
public virtual bool CanEditCategories(Mobile m)
|
||||
{
|
||||
return m.AccessLevel > AccessLevel.Counselor || BlessedFor == m || (!EditLocked && IsAccessibleTo(m));
|
||||
}
|
||||
|
||||
public virtual bool CanRemoveCategories(Mobile m)
|
||||
{
|
||||
return m.AccessLevel > AccessLevel.Counselor || BlessedFor == m || (!RemoveLocked && IsAccessibleTo(m));
|
||||
}
|
||||
|
||||
public virtual bool CanAddEntries(Mobile m)
|
||||
{
|
||||
return m.AccessLevel > AccessLevel.Counselor || BlessedFor == m || (!AddLocked && IsAccessibleTo(m));
|
||||
}
|
||||
|
||||
public virtual bool CanEditEntries(Mobile m)
|
||||
{
|
||||
return m.AccessLevel > AccessLevel.Counselor || BlessedFor == m || (!EditLocked && IsAccessibleTo(m));
|
||||
}
|
||||
|
||||
public virtual bool CanRemoveEntries(Mobile m)
|
||||
{
|
||||
return m.AccessLevel > AccessLevel.Counselor || BlessedFor == m || (!RemoveLocked && IsAccessibleTo(m));
|
||||
}
|
||||
|
||||
public override bool IsAccessibleTo(Mobile check)
|
||||
{
|
||||
return check.AccessLevel > AccessLevel.Counselor || BlessedFor == check || base.IsAccessibleTo(check);
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
|
||||
{
|
||||
base.GetContextMenuEntries(from, list);
|
||||
|
||||
SetSecureLevelEntry.AddTo(from, this, list);
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile m)
|
||||
{
|
||||
if (!this.CheckDoubleClick(m, true, false, 3) || !(m is PlayerMobile))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var pm = (PlayerMobile)m;
|
||||
|
||||
var ui = Users.FirstOrDefault(uic => uic.User == pm) ?? new UICache(pm);
|
||||
|
||||
Users.Update(ui);
|
||||
|
||||
new RuneCodexGump(pm, this).Send();
|
||||
}
|
||||
|
||||
public void SetDescription(string desc)
|
||||
{
|
||||
_Descripton = String.IsNullOrWhiteSpace(desc) ? DefaultDescription : desc;
|
||||
InvalidateProperties();
|
||||
}
|
||||
|
||||
public virtual bool CanChargeWith(Mobile m, Item item, out int cost, bool message)
|
||||
{
|
||||
cost = 0;
|
||||
|
||||
if (m == null || m.Deleted || item == null || item.Deleted || !item.IsAccessibleTo(m))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var t = item.GetType();
|
||||
|
||||
if (ChargeTypes.ContainsKey(t))
|
||||
{
|
||||
cost = ChargeTypes[t];
|
||||
return true;
|
||||
}
|
||||
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage("That item is not accepted for charging this codex.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual bool AddCharges(Mobile m, Item item, bool message)
|
||||
{
|
||||
if (m == null || m.Deleted || item == null || item.Deleted || !item.IsAccessibleTo(m))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CanChargeWith(m, item, out var cost, message))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (item.Amount < cost)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage("One charge costs {0:#,0} {1}.", cost, item.ResolveName(m));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
var c = (int)Math.Min((long)(Charges + (int)Math.Floor(item.Amount / (double)cost)), Int32.MaxValue) - Charges;
|
||||
|
||||
if (c <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var con = c * cost;
|
||||
|
||||
item.Consume(con);
|
||||
|
||||
Charges += c;
|
||||
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage(
|
||||
"You added {0:#,0} charge{1} to the codex and consumed {2:#,0} {3}.",
|
||||
c,
|
||||
c != 1 ? "s" : String.Empty,
|
||||
con,
|
||||
item.ResolveName());
|
||||
}
|
||||
|
||||
InvalidateProperties();
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool AddRunebook(Mobile m, Runebook book, RuneCodexCategory cat, bool message)
|
||||
{
|
||||
if (m == null || m.Deleted || book == null || book.Deleted || !book.IsAccessibleTo(m))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cat == null)
|
||||
{
|
||||
var pm = m as PlayerMobile;
|
||||
|
||||
if (pm != null)
|
||||
{
|
||||
var ui = Users.FirstOrDefault(uic => uic.User == pm);
|
||||
|
||||
if (ui != null)
|
||||
{
|
||||
cat = ui.Category ?? Categories[ui.CategoryPoint.X, ui.CategoryPoint.Y];
|
||||
}
|
||||
else
|
||||
{
|
||||
cat = Categories[0, 0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cat = Categories[0, 0];
|
||||
}
|
||||
}
|
||||
|
||||
if (book.Entries == null || book.Entries.Count == 0)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage("That rune book is empty.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Categories.Count >= Categories.Capacity)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage("This rune codex can't hold more categories.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cat != null && cat.AddRunebook(m, book, message))
|
||||
{
|
||||
InvalidateProperties();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual bool AddRune(Mobile m, RecallRune rune, RuneCodexCategory cat, bool message)
|
||||
{
|
||||
if (m == null || m.Deleted || rune == null || rune.Deleted || !rune.IsAccessibleTo(m))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var pm = m as PlayerMobile;
|
||||
|
||||
var loc = Point2D.Zero;
|
||||
|
||||
if (cat == null)
|
||||
{
|
||||
if (pm != null)
|
||||
{
|
||||
var ui = Users.FirstOrDefault(uic => uic.User == pm);
|
||||
|
||||
if (ui != null)
|
||||
{
|
||||
cat = ui.Category ?? Categories[ui.CategoryPoint.X, ui.CategoryPoint.Y];
|
||||
loc = ui.EntryPoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
cat = Categories[0, 0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cat = Categories[0, 0];
|
||||
}
|
||||
}
|
||||
|
||||
if (!rune.Marked || rune.Target == Point3D.Zero || rune.TargetMap == Map.Internal)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage("That rune is blank.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cat != null)
|
||||
{
|
||||
if (cat.Entries.Count >= cat.Entries.Capacity)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage("The rune codex category \"{0}\" can't hold more runes.", cat.Description);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cat.SetRune(m, rune, loc, message))
|
||||
{
|
||||
InvalidateProperties();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Add(Mobile m, Item item, RuneCodexCategory cat, bool message)
|
||||
{
|
||||
if (m == null || m.Deleted || item == null || item.Deleted || !item.IsAccessibleTo(m))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (item is RecallRune)
|
||||
{
|
||||
return AddRune(m, (RecallRune)item, cat, message);
|
||||
}
|
||||
|
||||
if (item is Runebook)
|
||||
{
|
||||
return AddRunebook(m, (Runebook)item, cat, message);
|
||||
}
|
||||
|
||||
#region Master Runebook Support
|
||||
//Using Reflection for shards that don't have it installed.
|
||||
var t = item.GetType();
|
||||
|
||||
if (Insensitive.Equals(t.Name, "MasterRunebook"))
|
||||
{
|
||||
var pi = t.GetProperty("Books");
|
||||
|
||||
if (pi != null && pi.CanRead)
|
||||
{
|
||||
var obj = pi.GetValue(item, null);
|
||||
|
||||
if (obj is ICollection)
|
||||
{
|
||||
var ex = new Queue<Runebook>(((ICollection)obj).OfType<Runebook>().Where(r => r.Entries.Count > 0));
|
||||
|
||||
if (ex.Count == 0)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage("That master rune book is empty.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Categories.Count + ex.Count > Categories.Capacity)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage("That master rune book won't fit in this rune codex.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
var extracted = 0;
|
||||
|
||||
while (ex.Count > 0)
|
||||
{
|
||||
var b = ex.Dequeue();
|
||||
|
||||
if (AddRunebook(m, b, cat, message))
|
||||
{
|
||||
++extracted;
|
||||
}
|
||||
}
|
||||
|
||||
if (extracted > 0)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage(
|
||||
"You extract {0:#,0} book{1} from the master rune book and add them to the codex.",
|
||||
extracted,
|
||||
extracted != 1 ? "s" : String.Empty);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage("There was nothing in the master rune book to extract.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endregion Master Runebook Support
|
||||
|
||||
if (AddCharges(m, item, message))
|
||||
{
|
||||
return item.Deleted;
|
||||
}
|
||||
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage("Drop a rune book or recall rune on the codex to add them.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Remove(RuneCodexCategory cat)
|
||||
{
|
||||
for (var x = 0; x < Categories.Width; x++)
|
||||
{
|
||||
for (var y = 0; y < Categories.Height; y++)
|
||||
{
|
||||
if (Categories[x, y] != cat)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Categories[x, y] = null;
|
||||
InvalidateProperties();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Drop(Mobile m, RuneCodexCategory cat, bool message)
|
||||
{
|
||||
if (m == null || m.Deleted || cat == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cat.Entries == null || cat.Entries.Count == 0)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage("The category \"{0}\" is empty.", cat.Name);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
var cost = CloneEntryChargeCost * cat.Entries.Count;
|
||||
|
||||
if (!ConsumeCharges(cost))
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage("This action requires {0:#,0} charge{1}.", cost, cost != 1 ? "s" : String.Empty);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
var entries = new Queue<RuneCodexEntry>(cat.Entries.Not(e => e == null));
|
||||
var book = new Runebook();
|
||||
var count = 1;
|
||||
|
||||
while (entries.Count > 0)
|
||||
{
|
||||
var entry = entries.Dequeue();
|
||||
|
||||
if (entry == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
book.Entries.Add(
|
||||
new RunebookEntry(
|
||||
entry.Location,
|
||||
entry.Location,
|
||||
entry.Name,
|
||||
BaseHouse.FindHouseAt(entry.Location, entry.Location, 16)));
|
||||
|
||||
if (book.Entries.Count < 16 && entries.Count > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
m.AddToBackpack(book);
|
||||
|
||||
if (entries.Count == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
book = new Runebook();
|
||||
++count;
|
||||
}
|
||||
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage(
|
||||
"You created {0:#,0} rune book{1} and consumed {2:#,0} charge{3} from the codex.",
|
||||
count,
|
||||
count != 1 ? "s" : String.Empty,
|
||||
cost,
|
||||
cost != 1 ? "s" : String.Empty);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Drop(Mobile m, RuneCodexEntry entry, bool message)
|
||||
{
|
||||
if (m == null || m.Deleted || entry == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ConsumeCharges(CloneEntryChargeCost))
|
||||
{
|
||||
m.SendMessage(
|
||||
"This action requires {0:#,0} charge{1}.",
|
||||
CloneEntryChargeCost,
|
||||
CloneEntryChargeCost != 1 ? "s" : String.Empty);
|
||||
return false;
|
||||
}
|
||||
|
||||
m.AddToBackpack(
|
||||
new RecallRune
|
||||
{
|
||||
Marked = true,
|
||||
Target = entry.Location,
|
||||
TargetMap = entry.Location,
|
||||
Description = entry.Name,
|
||||
House = BaseHouse.FindHouseAt(entry.Location, entry.Location, 16)
|
||||
});
|
||||
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage(
|
||||
"You create a recall rune and consume {0:#,0} charge{1} from the codex.",
|
||||
CloneEntryChargeCost,
|
||||
CloneEntryChargeCost != 1 ? "s" : String.Empty);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Recall(Mobile m, RuneCodexEntry entry, bool message)
|
||||
{
|
||||
if (m == null || m.Deleted || entry == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ConsumeCharges(RecallChargeCost))
|
||||
{
|
||||
m.SendMessage(
|
||||
"This action requires {0:#,0} charge{1}.",
|
||||
RecallChargeCost,
|
||||
RecallChargeCost != 1 ? "s" : String.Empty);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!entry.Recall(m))
|
||||
{
|
||||
Charges += RecallChargeCost;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Gate(Mobile m, RuneCodexEntry entry, bool message)
|
||||
{
|
||||
if (m == null || m.Deleted || entry == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ConsumeCharges(GateChargeCost))
|
||||
{
|
||||
m.SendMessage("This action requires {0:#,0} charge{1}.", GateChargeCost, GateChargeCost != 1 ? "s" : String.Empty);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!entry.Gate(m))
|
||||
{
|
||||
Charges += GateChargeCost;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnDragDrop(Mobile m, Item dropped)
|
||||
{
|
||||
return Add(m, dropped, null, true);
|
||||
}
|
||||
|
||||
public override void OnAfterDuped(Item newItem)
|
||||
{
|
||||
base.OnAfterDuped(newItem);
|
||||
|
||||
var c = newItem as RuneCodex;
|
||||
|
||||
if (c == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
c.AddLocked = AddLocked;
|
||||
c.EditLocked = EditLocked;
|
||||
c.RemoveLocked = RemoveLocked;
|
||||
|
||||
c.CloneEntryChargeCost = CloneEntryChargeCost;
|
||||
c.RecallChargeCost = RecallChargeCost;
|
||||
c.GateChargeCost = GateChargeCost;
|
||||
|
||||
c.Charges = Charges;
|
||||
c.Descripton = Descripton;
|
||||
|
||||
c.Categories = new RuneCodexCategoryGrid();
|
||||
c.ChargeTypes = new Dictionary<Type, int>(ChargeTypes);
|
||||
c.Users = new List<UICache>();
|
||||
|
||||
RuneCodexCategory cata, catb;
|
||||
RuneCodexEntry entrya, entryb;
|
||||
|
||||
for (var cx = 0; cx < Categories.Width; cx++)
|
||||
{
|
||||
for (var cy = 0; cy < Categories.Height; cy++)
|
||||
{
|
||||
cata = Categories[cx, cy];
|
||||
|
||||
if (cata == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
catb = new RuneCodexCategory(cata.Name, cata.Description, cata.Hue);
|
||||
|
||||
c.Categories.SetContent(cx, cy, catb);
|
||||
|
||||
for (var ex = 0; ex < cata.Entries.Width; ex++)
|
||||
{
|
||||
for (var ey = 0; ey < cata.Entries.Width; ey++)
|
||||
{
|
||||
entrya = cata.Entries[ex, ey];
|
||||
|
||||
if (entrya == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
entryb = new RuneCodexEntry(entrya.Name, entrya.Description, entrya.Location);
|
||||
|
||||
catb.Entries.SetContent(ex, ey, entryb);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool ConsumeCharges(int amount)
|
||||
{
|
||||
amount = Math.Max(0, amount);
|
||||
|
||||
if (Charges < amount)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Charges -= amount;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
// charges: ~1_val~
|
||||
list.Add(1060741, Charges.ToString("#,0"));
|
||||
|
||||
var eTotal = 0;
|
||||
var eCap = 0;
|
||||
|
||||
foreach (var c in Categories.Not(c => c == null))
|
||||
{
|
||||
eTotal += c.Entries.Count;
|
||||
eCap += c.Entries.Capacity;
|
||||
}
|
||||
|
||||
list.Add("Categories: {0} / {1}\nEntries: {2} / {3}", Categories.Count, Categories.Capacity, eTotal, eCap);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(3);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 3:
|
||||
writer.WriteFlag(Level);
|
||||
goto case 2;
|
||||
case 2:
|
||||
writer.Write(RemoveLocked);
|
||||
goto case 1;
|
||||
case 1:
|
||||
{
|
||||
writer.Write(EditLocked);
|
||||
writer.Write(AddLocked);
|
||||
writer.Write(CloneEntryChargeCost);
|
||||
|
||||
writer.WriteDictionary(
|
||||
ChargeTypes,
|
||||
(k, v) =>
|
||||
{
|
||||
writer.WriteType(k);
|
||||
writer.Write(v);
|
||||
});
|
||||
}
|
||||
goto case 0;
|
||||
case 0:
|
||||
{
|
||||
writer.Write(Charges);
|
||||
writer.Write(RecallChargeCost);
|
||||
writer.Write(GateChargeCost);
|
||||
writer.Write(_Descripton);
|
||||
Categories.Serialize(writer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 3:
|
||||
Level = reader.ReadFlag<SecureLevel>();
|
||||
goto case 2;
|
||||
case 2:
|
||||
RemoveLocked = reader.ReadBool();
|
||||
goto case 1;
|
||||
case 1:
|
||||
{
|
||||
EditLocked = reader.ReadBool();
|
||||
AddLocked = reader.ReadBool();
|
||||
CloneEntryChargeCost = reader.ReadInt();
|
||||
|
||||
ChargeTypes = reader.ReadDictionary(
|
||||
() =>
|
||||
{
|
||||
var k = reader.ReadType();
|
||||
var v = reader.ReadInt();
|
||||
return new KeyValuePair<Type, int>(k, v);
|
||||
});
|
||||
}
|
||||
goto case 0;
|
||||
case 0:
|
||||
{
|
||||
Charges = reader.ReadInt();
|
||||
RecallChargeCost = reader.ReadInt();
|
||||
GateChargeCost = reader.ReadInt();
|
||||
_Descripton = reader.ReadString();
|
||||
Categories = new RuneCodexCategoryGrid(reader);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (version > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Charges = 1000;
|
||||
CloneEntryChargeCost = 5;
|
||||
RecallChargeCost = 1;
|
||||
GateChargeCost = 2;
|
||||
ChargeTypes = new Dictionary<Type, int>
|
||||
{
|
||||
{typeof(Gold), 100}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,349 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
|
||||
using VitaNex.SuperGumps;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class RuneCodexCategory : PropertyObject
|
||||
{
|
||||
public static string DefaultName = "Misc Places";
|
||||
public static string DefaultDescription = "A collection of places.";
|
||||
public static int DefaultHue = 85;
|
||||
|
||||
private string _Name = DefaultName;
|
||||
private string _Description = DefaultDescription;
|
||||
private int _Hue = DefaultHue;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string Name { get => _Name; set => SetName(value); }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string Description { get => _Description; set => SetDescription(value); }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Hue { get => _Hue; set => SetHue(value); }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public RuneCodexEntryGrid Entries { get; set; }
|
||||
|
||||
public RuneCodexCategory()
|
||||
: this(DefaultName, DefaultDescription, DefaultHue)
|
||||
{ }
|
||||
|
||||
public RuneCodexCategory(string name, string desc, int hue)
|
||||
{
|
||||
Name = name;
|
||||
Description = desc;
|
||||
Hue = hue;
|
||||
Entries = new RuneCodexEntryGrid();
|
||||
}
|
||||
|
||||
public RuneCodexCategory(GenericReader reader)
|
||||
: base(reader)
|
||||
{ }
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
UseDefaults();
|
||||
Empty();
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
UseDefaults();
|
||||
Empty();
|
||||
}
|
||||
|
||||
public virtual void UseDefaults()
|
||||
{
|
||||
Name = DefaultName;
|
||||
Description = DefaultDescription;
|
||||
Hue = DefaultHue;
|
||||
}
|
||||
|
||||
public virtual void Empty()
|
||||
{
|
||||
Entries.SetAllContent(null, e => e != null);
|
||||
}
|
||||
|
||||
public void SetName(string name)
|
||||
{
|
||||
_Name = String.IsNullOrWhiteSpace(name) ? DefaultName : name;
|
||||
}
|
||||
|
||||
public void SetDescription(string desc)
|
||||
{
|
||||
_Description = String.IsNullOrWhiteSpace(desc) ? DefaultDescription : desc;
|
||||
}
|
||||
|
||||
public void SetHue(int hue)
|
||||
{
|
||||
_Hue = hue <= 0 ? DefaultHue : hue;
|
||||
}
|
||||
|
||||
public bool AddRunebook(Mobile m, Runebook book, bool message)
|
||||
{
|
||||
if (m == null || m.Deleted || book == null || book.Deleted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var mrb = Insensitive.Equals(book.GetType().Name, "InternalRunebook");
|
||||
|
||||
if (book.Entries.Count == 0)
|
||||
{
|
||||
if (!mrb && message)
|
||||
{
|
||||
m.SendMessage("That rune book is empty.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Entries.Count >= Entries.Capacity)
|
||||
{
|
||||
if (!mrb && message)
|
||||
{
|
||||
m.SendMessage("The category \"{0}\" can't hold more runes.", _Name);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Entries.Count + book.Entries.Count > Entries.Capacity)
|
||||
{
|
||||
if (!mrb && message)
|
||||
{
|
||||
m.SendMessage("That rune book won't fit in the category \"{0}\".", _Name);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
var bEntries = new Queue<RunebookEntry>(book.Entries);
|
||||
|
||||
Entries.ForEach(
|
||||
(x, y, e) =>
|
||||
{
|
||||
if (e != null || bEntries.Count <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var be = bEntries.Dequeue();
|
||||
|
||||
Entries.SetContent(x, y, new RuneCodexEntry(book.Name, be.Description, be.Location.ToMapPoint(be.Map)));
|
||||
});
|
||||
|
||||
if (mrb)
|
||||
{
|
||||
book.Entries.Clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
book.Delete();
|
||||
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage("You add the rune book to the category \"{0}\".", _Name);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool SetRune(Mobile m, RecallRune rune, Point2D loc, bool message)
|
||||
{
|
||||
if (m == null || m.Deleted || rune == null || rune.Deleted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!rune.Marked || rune.Target == Point3D.Zero || rune.TargetMap == Map.Internal)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage("That rune is blank.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Entries.Count >= Entries.Capacity)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage("The category \"{0}\" can't hold more runes.", _Name);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Entries[loc.X, loc.Y] != null)
|
||||
{
|
||||
return AddRune(m, rune, message);
|
||||
}
|
||||
|
||||
Entries.SetContent(
|
||||
loc.X,
|
||||
loc.Y,
|
||||
new RuneCodexEntry(rune.Description, rune.Name, rune.Target.ToMapPoint(rune.TargetMap)));
|
||||
rune.Delete();
|
||||
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage("You add the rune to the category \"{0}\".", _Name);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool AddRune(Mobile m, RecallRune rune, bool message)
|
||||
{
|
||||
if (m == null || m.Deleted || rune == null || rune.Deleted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!rune.Marked || rune.Target == Point3D.Zero || rune.TargetMap == Map.Internal)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage("That rune is blank.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Entries.Count >= Entries.Capacity)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage("The category \"{0}\" can't hold more runes.", _Name);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Entries.ForEach(
|
||||
(x, y, e) =>
|
||||
{
|
||||
if (e != null || rune.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Entries.SetContent(x, y, new RuneCodexEntry(rune.Description, rune.Name, rune.Target.ToMapPoint(rune.TargetMap)));
|
||||
rune.Delete();
|
||||
});
|
||||
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage("You add the rune to the rune codex category \"{0}\".", _Name);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Remove(RuneCodexEntry entry)
|
||||
{
|
||||
for (var x = 0; x < Entries.Width; x++)
|
||||
{
|
||||
for (var y = 0; y < Entries.Height; y++)
|
||||
{
|
||||
if (Entries[x, y] != entry)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Entries[x, y] = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual string ToHtmlString(Mobile viewer = null)
|
||||
{
|
||||
var html = new StringBuilder();
|
||||
|
||||
GetHtmlString(html, viewer);
|
||||
|
||||
return html.ToString();
|
||||
}
|
||||
|
||||
public virtual void GetHtmlString(StringBuilder html, Mobile viewer = null)
|
||||
{
|
||||
html.Append("".WrapUOHtmlColor(SuperGump.DefaultHtmlColor, false));
|
||||
|
||||
html.AppendLine("Entries: {0:#,0} / {1:#,0}", Entries.Count, Entries.Capacity);
|
||||
html.AppendLine();
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(Description))
|
||||
{
|
||||
html.AppendLine(Description.WrapUOHtmlColor(Color.LawnGreen, SuperGump.DefaultHtmlColor));
|
||||
}
|
||||
|
||||
html.Append("".WrapUOHtmlColor(SuperGump.DefaultHtmlColor, false));
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
writer.Write(_Name);
|
||||
writer.Write(_Description);
|
||||
writer.Write(_Hue);
|
||||
|
||||
Entries.Serialize(writer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Name = reader.ReadString();
|
||||
Description = reader.ReadString();
|
||||
Hue = reader.ReadInt();
|
||||
|
||||
Entries = new RuneCodexEntryGrid(reader);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class RuneCodexCategoryGrid : Grid<RuneCodexCategory>
|
||||
{
|
||||
public RuneCodexCategoryGrid()
|
||||
: base(10, 10)
|
||||
{
|
||||
SetContent(0, 0, new RuneCodexCategory());
|
||||
}
|
||||
|
||||
public RuneCodexCategoryGrid(GenericReader reader)
|
||||
: base(reader)
|
||||
{ }
|
||||
|
||||
public override RuneCodexCategory this[int x, int y]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (x == 0 && y == 0 && base[x, y] == null)
|
||||
{
|
||||
return (base[x, y] = new RuneCodexCategory());
|
||||
}
|
||||
|
||||
return base[x, y];
|
||||
}
|
||||
set
|
||||
{
|
||||
if (x == 0 && y == 0 && value == null)
|
||||
{
|
||||
value = new RuneCodexCategory();
|
||||
}
|
||||
|
||||
base[x, y] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
|
||||
public override void SerializeContent(GenericWriter writer, RuneCodexCategory content, int x, int y)
|
||||
{
|
||||
base.SerializeContent(writer, content, x, y);
|
||||
|
||||
if (OnSerializeContent == null)
|
||||
{
|
||||
content.Serialize(writer);
|
||||
}
|
||||
}
|
||||
|
||||
public override RuneCodexCategory DeserializeContent(GenericReader reader, Type type, int x, int y)
|
||||
{
|
||||
if (OnDeserializeContent == null)
|
||||
{
|
||||
return new RuneCodexCategory(reader);
|
||||
}
|
||||
|
||||
return base.DeserializeContent(reader, type, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Spells.Fourth;
|
||||
using Server.Spells.Seventh;
|
||||
|
||||
using VitaNex.SuperGumps;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class RuneCodexEntry : PropertyObject
|
||||
{
|
||||
public static string DefaultName = "Unknown Place";
|
||||
public static string DefaultDescription = String.Empty;
|
||||
|
||||
private string _Name = DefaultName;
|
||||
private string _Description = DefaultDescription;
|
||||
private MapPoint _Location = MapPoint.Empty;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string Name { get => _Name; set => SetName(value); }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string Description { get => _Description; set => SetDescription(value); }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public MapPoint Location { get => _Location; set => SetLocation(value); }
|
||||
|
||||
public RuneCodexEntry()
|
||||
: this(DefaultName, DefaultDescription, MapPoint.Empty)
|
||||
{ }
|
||||
|
||||
public RuneCodexEntry(string name, string desc, MapPoint dest)
|
||||
{
|
||||
Name = name ?? DefaultName;
|
||||
Description = desc ?? DefaultDescription;
|
||||
Location = dest;
|
||||
}
|
||||
|
||||
public RuneCodexEntry(GenericReader reader)
|
||||
: base(reader)
|
||||
{ }
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
UseDefaults();
|
||||
Location = MapPoint.Empty;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
UseDefaults();
|
||||
Location = MapPoint.Empty;
|
||||
}
|
||||
|
||||
public virtual void UseDefaults()
|
||||
{
|
||||
Name = DefaultName;
|
||||
Description = DefaultDescription;
|
||||
}
|
||||
|
||||
public void SetName(string name)
|
||||
{
|
||||
_Name = String.IsNullOrWhiteSpace(name) ? DefaultName : name;
|
||||
}
|
||||
|
||||
public void SetDescription(string desc)
|
||||
{
|
||||
_Description = String.IsNullOrWhiteSpace(desc) ? DefaultDescription : desc;
|
||||
}
|
||||
|
||||
public void SetLocation(MapPoint dest)
|
||||
{
|
||||
_Location = dest;
|
||||
}
|
||||
|
||||
public bool Recall(Mobile m)
|
||||
{
|
||||
if (m == null || m.Deleted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_Location.Internal || _Location.Zero)
|
||||
{
|
||||
m.SendMessage("That rune is blank.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m.Player)
|
||||
{
|
||||
var t = GetType();
|
||||
|
||||
if (m.AccessLevel < AccessLevel.Counselor && !m.CanBeginAction(t))
|
||||
{
|
||||
m.SendMessage("You must wait before using the rune codex again.");
|
||||
return false;
|
||||
}
|
||||
|
||||
var spell = new RecallSpell(
|
||||
m,
|
||||
null,
|
||||
new RunebookEntry(_Location.Location, _Location.Map, _Description, null),
|
||||
null);
|
||||
|
||||
if (!spell.Cast())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m.BeginAction(t, TimeSpan.FromSeconds(3));
|
||||
}
|
||||
else
|
||||
{
|
||||
_Location.MoveToWorld(m);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Gate(Mobile m)
|
||||
{
|
||||
if (m == null || m.Deleted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_Location.Internal || _Location.Zero)
|
||||
{
|
||||
m.SendMessage("That rune is blank.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m.Player)
|
||||
{
|
||||
var t = GetType();
|
||||
|
||||
if (m.AccessLevel < AccessLevel.Counselor && !m.CanBeginAction(t))
|
||||
{
|
||||
m.SendMessage("You must wait before using the rune codex again.");
|
||||
return false;
|
||||
}
|
||||
|
||||
var spell = new GateTravelSpell(m, null, new RunebookEntry(_Location.Location, _Location.Map, _Description, null));
|
||||
|
||||
if (!spell.Cast())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m.BeginAction(t, TimeSpan.FromSeconds(3));
|
||||
}
|
||||
else
|
||||
{
|
||||
_Location.MoveToWorld(m);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual string ToHtmlString(Mobile viewer = null)
|
||||
{
|
||||
var html = new StringBuilder();
|
||||
|
||||
GetHtmlString(html);
|
||||
|
||||
return html.ToString();
|
||||
}
|
||||
|
||||
public virtual void GetHtmlString(StringBuilder html, Mobile viewer = null)
|
||||
{
|
||||
html.Append("".WrapUOHtmlColor(SuperGump.DefaultHtmlColor, false));
|
||||
|
||||
html.AppendLine("Facet: {0}", Location.Map);
|
||||
html.AppendLine("Location: {0}, {1}, {2}", Location.X, Location.Y, Location.Z);
|
||||
|
||||
int xLong = 0, yLat = 0;
|
||||
int xMins = 0, yMins = 0;
|
||||
bool xEast = false, ySouth = false;
|
||||
|
||||
if (Sextant.Format(Location, Location.Map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast, ref ySouth))
|
||||
{
|
||||
html.AppendLine(
|
||||
"Coords: {0}<7D> {1}'{2}, {3}<7D> {4}'{5}",
|
||||
yLat,
|
||||
yMins,
|
||||
ySouth ? "S" : "N",
|
||||
xLong,
|
||||
xMins,
|
||||
xEast ? "E" : "W");
|
||||
}
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(Description))
|
||||
{
|
||||
html.AppendLine();
|
||||
html.AppendLine(Description.WrapUOHtmlColor(Color.LawnGreen, SuperGump.DefaultHtmlColor));
|
||||
html.AppendLine();
|
||||
}
|
||||
|
||||
html.Append("".WrapUOHtmlColor(SuperGump.DefaultHtmlColor, false));
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(1);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
writer.Write(_Name);
|
||||
goto case 0;
|
||||
case 0:
|
||||
{
|
||||
writer.Write(_Description);
|
||||
_Location.Serialize(writer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
_Name = reader.ReadString();
|
||||
goto case 0;
|
||||
case 0:
|
||||
{
|
||||
_Description = reader.ReadString();
|
||||
_Location = new MapPoint(reader);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class RuneCodexEntryGrid : Grid<RuneCodexEntry>
|
||||
{
|
||||
public RuneCodexEntryGrid()
|
||||
: base(10, 10)
|
||||
{ }
|
||||
|
||||
public RuneCodexEntryGrid(GenericReader reader)
|
||||
: base(reader)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
|
||||
public override void SerializeContent(GenericWriter writer, RuneCodexEntry content, int x, int y)
|
||||
{
|
||||
base.SerializeContent(writer, content, x, y);
|
||||
|
||||
if (OnSerializeContent == null)
|
||||
{
|
||||
content.Serialize(writer);
|
||||
}
|
||||
}
|
||||
|
||||
public override RuneCodexEntry DeserializeContent(GenericReader reader, Type type, int x, int y)
|
||||
{
|
||||
if (OnDeserializeContent == null)
|
||||
{
|
||||
return new RuneCodexEntry(reader);
|
||||
}
|
||||
|
||||
return base.DeserializeContent(reader, type, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,119 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
using Server.Items;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public abstract class CustomContainer : BaseContainer
|
||||
{
|
||||
private int _ContainerItemID;
|
||||
|
||||
[CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)]
|
||||
public virtual int ContainerItemID
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_ContainerItemID <= 0)
|
||||
{
|
||||
_ContainerItemID = DefaultContainerItemID;
|
||||
}
|
||||
|
||||
return _ContainerItemID;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value <= 0)
|
||||
{
|
||||
value = DefaultContainerItemID;
|
||||
}
|
||||
|
||||
if (_ContainerItemID == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_ContainerItemID = value;
|
||||
Update();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual int DefaultContainerItemID => 0xE77;
|
||||
|
||||
public CustomContainer(int itemID)
|
||||
: this(itemID, 0xE76)
|
||||
{ }
|
||||
|
||||
public CustomContainer(int itemID, int containerID)
|
||||
: base(itemID)
|
||||
{
|
||||
ItemID = ContainerItemID = containerID;
|
||||
}
|
||||
|
||||
public CustomContainer(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public virtual void Update()
|
||||
{
|
||||
UpdateContainerData();
|
||||
}
|
||||
|
||||
public override void UpdateContainerData()
|
||||
{
|
||||
if (ContainerItemID > 0)
|
||||
{
|
||||
ContainerData = ContainerData.GetData(ContainerItemID);
|
||||
}
|
||||
else
|
||||
{
|
||||
base.UpdateContainerData();
|
||||
}
|
||||
|
||||
GumpID = -1;
|
||||
DropSound = -1;
|
||||
Delta(ItemDelta.Update);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
writer.Write(_ContainerItemID);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
_ContainerItemID = reader.ReadInt();
|
||||
break;
|
||||
}
|
||||
|
||||
Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
using Server.Items;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
[Flipable(0x4910, 0x4911)]
|
||||
public class HugeWoodenChest : CustomContainer
|
||||
{
|
||||
public override int DefaultContainerItemID => 0x4910;
|
||||
|
||||
[Constructable]
|
||||
public HugeWoodenChest()
|
||||
: base(0x4910, 0x4910)
|
||||
{ }
|
||||
|
||||
public HugeWoodenChest(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void UpdateContainerData()
|
||||
{
|
||||
if (ItemID == 0x4910 || ItemID == 0x4911)
|
||||
{
|
||||
ContainerData = new ContainerData(0x3E8, new Rectangle2D(90, 90, 460, 280), 0x42);
|
||||
return;
|
||||
}
|
||||
|
||||
base.UpdateContainerData();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
93
Scripts/SubSystem/VitaNex/Core/Items/Currency/VendorToken.cs
Normal file
93
Scripts/SubSystem/VitaNex/Core/Items/Currency/VendorToken.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public interface IVendorToken
|
||||
{
|
||||
string Name { get; set; }
|
||||
int Amount { get; set; }
|
||||
bool Stackable { get; set; }
|
||||
|
||||
void Deserialize(GenericReader reader);
|
||||
void Serialize(GenericWriter writer);
|
||||
}
|
||||
|
||||
public abstract class VendorToken : Item, IVendorToken
|
||||
{
|
||||
public override bool DisplayWeight => false;
|
||||
|
||||
public VendorToken()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
public VendorToken(int amount)
|
||||
: base(0xEED)
|
||||
{
|
||||
Name = "Vendor Token";
|
||||
Hue = 85;
|
||||
Weight = 0;
|
||||
Stackable = true;
|
||||
Amount = Math.Max(1, Math.Min(60000, amount));
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public VendorToken(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override DeathMoveResult OnInventoryDeath(Mobile parent)
|
||||
{
|
||||
if (parent is BaseCreature)
|
||||
{
|
||||
return DeathMoveResult.MoveToCorpse;
|
||||
}
|
||||
|
||||
return base.OnInventoryDeath(parent);
|
||||
}
|
||||
|
||||
public override int GetDropSound()
|
||||
{
|
||||
if (Amount <= 1)
|
||||
{
|
||||
return 0x2E4;
|
||||
}
|
||||
|
||||
if (Amount <= 5)
|
||||
{
|
||||
return 0x2E5;
|
||||
}
|
||||
|
||||
return 0x2E6;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
726
Scripts/SubSystem/VitaNex/Core/Items/Deeds/HueDeeds.cs
Normal file
726
Scripts/SubSystem/VitaNex/Core/Items/Deeds/HueDeeds.cs
Normal file
@@ -0,0 +1,726 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
|
||||
using VitaNex.Network;
|
||||
using VitaNex.SuperGumps.UI;
|
||||
using VitaNex.Targets;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public static class HueDeeds
|
||||
{
|
||||
public static event Action<IHueDeed> OnCreated;
|
||||
|
||||
public static void Register<T>(Action<T> onCreated)
|
||||
where T : IHueDeed
|
||||
{
|
||||
OnCreated += o =>
|
||||
{
|
||||
if (o is T d)
|
||||
{
|
||||
onCreated(d);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static void InvokeCreated(IHueDeed d)
|
||||
{
|
||||
if (OnCreated != null)
|
||||
{
|
||||
OnCreated(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface IHueDeed
|
||||
{
|
||||
List<int> Hues { get; }
|
||||
|
||||
void AddHue(int hue);
|
||||
void AddHues(params int[] hues);
|
||||
void AddHueRange(int hue, int count);
|
||||
}
|
||||
|
||||
public abstract class BaseHueDeed<TEntity> : Item, IHueDeed
|
||||
where TEntity : IEntity
|
||||
{
|
||||
private HueSelector _Gump;
|
||||
private GenericSelectTarget<TEntity> _Target;
|
||||
|
||||
public List<int> Hues { get; private set; }
|
||||
|
||||
public virtual string TargetUsage => "an object";
|
||||
|
||||
public BaseHueDeed()
|
||||
: base(0x14F0)
|
||||
{
|
||||
Hues = new List<int>();
|
||||
|
||||
Name = "Color Change Deed";
|
||||
Weight = 1.0;
|
||||
LootType = LootType.Blessed;
|
||||
|
||||
Timer.DelayCall(HueDeeds.InvokeCreated, this);
|
||||
}
|
||||
|
||||
public BaseHueDeed(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public void AddHue(int hue)
|
||||
{
|
||||
Hues.Update(hue);
|
||||
}
|
||||
|
||||
public void AddHues(params int[] hues)
|
||||
{
|
||||
if (hues == null || hues.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var h in hues)
|
||||
{
|
||||
AddHue(h);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddHueRange(int hue, int count)
|
||||
{
|
||||
count = Math.Max(0, count);
|
||||
|
||||
while (--count >= 0)
|
||||
{
|
||||
AddHue(hue++);
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
ExtendedOPL.AddTo(list, "Use: Change the color of {0}".WrapUOHtmlColor(Color.LawnGreen), TargetUsage);
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile m)
|
||||
{
|
||||
if (this.CheckDoubleClick(m, true, false, 2, true))
|
||||
{
|
||||
BeginTarget(m);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void BeginTarget(Mobile m)
|
||||
{
|
||||
if (_Target != null)
|
||||
{
|
||||
if (_Target.User != null && _Target.User.Target == _Target)
|
||||
{
|
||||
_Target.Cancel(_Target.User, TargetCancelType.Overriden);
|
||||
}
|
||||
|
||||
_Target = null;
|
||||
}
|
||||
|
||||
m.SendMessage("Target an object to recolor...");
|
||||
|
||||
_Target = new GenericSelectTarget<TEntity>(
|
||||
(u, t) =>
|
||||
{
|
||||
_Target = null;
|
||||
OpenGump(u, t);
|
||||
},
|
||||
u =>
|
||||
{
|
||||
OnTargetFail(u);
|
||||
_Target = null;
|
||||
});
|
||||
|
||||
m.Target = _Target;
|
||||
}
|
||||
|
||||
protected virtual void OnTargetFail(Mobile m)
|
||||
{
|
||||
if (_Target.User == m && _Target.Result == TargetResult.Invalid)
|
||||
{
|
||||
m.SendMessage("That is not a valid target.");
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OpenGump(Mobile m, TEntity t)
|
||||
{
|
||||
if (_Gump != null)
|
||||
{
|
||||
_Gump.Close();
|
||||
_Gump = null;
|
||||
}
|
||||
|
||||
m.SendMessage("Select a color from the chart...");
|
||||
|
||||
_Gump = new HueSelector(m)
|
||||
{
|
||||
PreviewIcon = GetPreviewIcon(t),
|
||||
Hues = Hues.ToArray(),
|
||||
AcceptCallback = hue =>
|
||||
{
|
||||
_Gump = null;
|
||||
ApplyHue(m, t, hue);
|
||||
},
|
||||
CancelCallback = hue => _Gump = null
|
||||
};
|
||||
|
||||
_Gump.Send();
|
||||
}
|
||||
|
||||
public virtual int GetPreviewIcon(TEntity t)
|
||||
{
|
||||
return HueSelector.DefaultIcon;
|
||||
}
|
||||
|
||||
protected virtual void ApplyHue(Mobile m, TEntity t, int hue)
|
||||
{
|
||||
if (m == null || t == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (hue < 0 || hue >= 3000)
|
||||
{
|
||||
m.SendMessage(0x22, "You cannot use an invalid hue.");
|
||||
OpenGump(m, t);
|
||||
return;
|
||||
}
|
||||
|
||||
var item = t as Item;
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
if (item.Hue == hue)
|
||||
{
|
||||
m.SendMessage(0x22, "The item is already that color.");
|
||||
OpenGump(m, t);
|
||||
return;
|
||||
}
|
||||
|
||||
item.Hue = hue;
|
||||
m.SendMessage(0x55, "The item has been recolored.");
|
||||
Delete();
|
||||
return;
|
||||
}
|
||||
|
||||
var mob = t as Mobile;
|
||||
|
||||
if (mob != null)
|
||||
{
|
||||
if (mob.Hue == hue)
|
||||
{
|
||||
m.SendMessage(0x22, "{0} skin is already that color.", mob == m ? "Your" : "Their");
|
||||
OpenGump(m, t);
|
||||
return;
|
||||
}
|
||||
|
||||
mob.Hue = hue;
|
||||
m.SendMessage(0x55, "{0} skin has been recolored.", mob == m ? "Your" : "Their");
|
||||
Delete();
|
||||
return;
|
||||
}
|
||||
|
||||
m.SendMessage(0x22, "Could not recolor that object.");
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
base.OnDelete();
|
||||
|
||||
_Gump = null;
|
||||
_Target = null;
|
||||
|
||||
Hues.Free(true);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
|
||||
writer.WriteList(Hues, writer.Write);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
|
||||
Hues = reader.ReadList(reader.ReadInt);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class ItemHueDeed<TItem> : BaseHueDeed<TItem>
|
||||
where TItem : Item
|
||||
{
|
||||
public override string TargetUsage => "an item";
|
||||
|
||||
public ItemHueDeed()
|
||||
{ }
|
||||
|
||||
public ItemHueDeed(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
protected override void OpenGump(Mobile m, TItem t)
|
||||
{
|
||||
if (m == null || t == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m.AccessLevel < AccessLevel.GameMaster)
|
||||
{
|
||||
if (!t.Movable && !t.IsAccessibleTo(m))
|
||||
{
|
||||
m.SendMessage("That item is not accessible.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!t.IsChildOf(m.Backpack) && t.RootParent != m)
|
||||
{
|
||||
m.SendMessage("That item must be equipped or in your pack to recolor it.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
base.OpenGump(m, t);
|
||||
}
|
||||
|
||||
public override int GetPreviewIcon(TItem t)
|
||||
{
|
||||
return t == null ? HueSelector.DefaultIcon : t.ItemID;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class MobileHueDeed<TMobile> : BaseHueDeed<TMobile>
|
||||
where TMobile : Mobile
|
||||
{
|
||||
public override string TargetUsage => "a mobile";
|
||||
|
||||
public MobileHueDeed()
|
||||
{ }
|
||||
|
||||
public MobileHueDeed(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
protected override void OpenGump(Mobile m, TMobile t)
|
||||
{
|
||||
if (m == null || t == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m.AccessLevel < t.AccessLevel)
|
||||
{
|
||||
m.SendMessage("They are not accessible.");
|
||||
return;
|
||||
}
|
||||
|
||||
base.OpenGump(m, t);
|
||||
}
|
||||
|
||||
public override int GetPreviewIcon(TMobile t)
|
||||
{
|
||||
return t == null ? HueSelector.DefaultIcon : ShrinkTable.Lookup(t);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public class SkinHueDeed : MobileHueDeed<PlayerMobile>
|
||||
{
|
||||
public override string TargetUsage => "your character";
|
||||
|
||||
[Constructable]
|
||||
public SkinHueDeed()
|
||||
{
|
||||
Name = "Skin Recolor Deed";
|
||||
AddHueRange(1002, 57);
|
||||
}
|
||||
|
||||
public SkinHueDeed(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
protected override void BeginTarget(Mobile m)
|
||||
{
|
||||
OpenGump(m, m as PlayerMobile);
|
||||
}
|
||||
|
||||
protected override void OpenGump(Mobile m, PlayerMobile t)
|
||||
{
|
||||
if (m == null || t == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m.AccessLevel < AccessLevel.GameMaster)
|
||||
{
|
||||
if (m != t)
|
||||
{
|
||||
m.SendMessage("You can only recolor your own skin.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
base.OpenGump(m, t);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public class PetHueDeed : MobileHueDeed<BaseCreature>
|
||||
{
|
||||
public override string TargetUsage => "your pet";
|
||||
|
||||
[Constructable]
|
||||
public PetHueDeed()
|
||||
{
|
||||
Name = "Pet Recolor Deed";
|
||||
AddHueRange(2301, 18);
|
||||
}
|
||||
|
||||
public PetHueDeed(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
protected override void OpenGump(Mobile m, BaseCreature t)
|
||||
{
|
||||
if (m == null || t == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m.AccessLevel < AccessLevel.GameMaster)
|
||||
{
|
||||
if (t.GetMaster() != m)
|
||||
{
|
||||
m.SendMessage("You can only recolor the skin of pets that you own.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
base.OpenGump(m, t);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public class WeaponHueDeed : ItemHueDeed<BaseWeapon>
|
||||
{
|
||||
public override string TargetUsage => "a weapon";
|
||||
|
||||
[Constructable]
|
||||
public WeaponHueDeed()
|
||||
{
|
||||
Name = "Weapon Recolor Deed";
|
||||
AddHueRange(2401, 30);
|
||||
}
|
||||
|
||||
public WeaponHueDeed(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public class ArmorHueDeed : ItemHueDeed<BaseArmor>
|
||||
{
|
||||
public override string TargetUsage => "armor";
|
||||
|
||||
[Constructable]
|
||||
public ArmorHueDeed()
|
||||
{
|
||||
Name = "Armor Recolor Deed";
|
||||
AddHueRange(2401, 30);
|
||||
}
|
||||
|
||||
public ArmorHueDeed(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public class ClothingHueDeed : ItemHueDeed<BaseClothing>
|
||||
{
|
||||
public override string TargetUsage => "clothing";
|
||||
|
||||
[Constructable]
|
||||
public ClothingHueDeed()
|
||||
{
|
||||
Name = "Clothing Recolor Deed";
|
||||
AddHueRange(2, 1000);
|
||||
}
|
||||
|
||||
public ClothingHueDeed(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public class JewelHueDeed : ItemHueDeed<BaseJewel>
|
||||
{
|
||||
public override string TargetUsage => "your jewelry";
|
||||
|
||||
[Constructable]
|
||||
public JewelHueDeed()
|
||||
{
|
||||
Name = "Jewelry Recolor Deed";
|
||||
AddHueRange(2401, 30);
|
||||
}
|
||||
|
||||
public JewelHueDeed(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public class QuiverHueDeed : ItemHueDeed<BaseQuiver>
|
||||
{
|
||||
public override string TargetUsage => "your quiver";
|
||||
|
||||
[Constructable]
|
||||
public QuiverHueDeed()
|
||||
{
|
||||
Name = "Quiver Recolor Deed";
|
||||
AddHueRange(2, 1000);
|
||||
}
|
||||
|
||||
public QuiverHueDeed(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public class LightHueDeed : ItemHueDeed<BaseEquipableLight>
|
||||
{
|
||||
public override string TargetUsage => "your light source";
|
||||
|
||||
[Constructable]
|
||||
public LightHueDeed()
|
||||
{
|
||||
Name = "Light Source Recolor Deed";
|
||||
AddHueRange(2401, 30);
|
||||
}
|
||||
|
||||
public LightHueDeed(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public class SpellbookHueDeed : ItemHueDeed<Spellbook>
|
||||
{
|
||||
public override string TargetUsage => "your spellbook";
|
||||
|
||||
[Constructable]
|
||||
public SpellbookHueDeed()
|
||||
{
|
||||
Name = "Spellbook Recolor Deed";
|
||||
AddHueRange(2, 1000);
|
||||
}
|
||||
|
||||
public SpellbookHueDeed(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public class ContainerHueDeed : ItemHueDeed<Container>
|
||||
{
|
||||
public override string TargetUsage => "a container";
|
||||
|
||||
[Constructable]
|
||||
public ContainerHueDeed()
|
||||
{
|
||||
Name = "Container Recolor Deed";
|
||||
AddHueRange(2, 1000);
|
||||
}
|
||||
|
||||
public ContainerHueDeed(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
723
Scripts/SubSystem/VitaNex/Core/Items/Deeds/NameDeeds.cs
Normal file
723
Scripts/SubSystem/VitaNex/Core/Items/Deeds/NameDeeds.cs
Normal file
@@ -0,0 +1,723 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Misc;
|
||||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
|
||||
using VitaNex.Network;
|
||||
using VitaNex.SuperGumps;
|
||||
using VitaNex.SuperGumps.UI;
|
||||
using VitaNex.Targets;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public static class NameDeeds
|
||||
{
|
||||
public static event Action<INameDeed> OnCreated;
|
||||
|
||||
public static void Register<T>(Action<T> onCreated)
|
||||
where T : INameDeed
|
||||
{
|
||||
OnCreated += o =>
|
||||
{
|
||||
if (o is T d)
|
||||
{
|
||||
onCreated(d);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static void InvokeCreated(INameDeed d)
|
||||
{
|
||||
if (OnCreated != null)
|
||||
{
|
||||
OnCreated(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface INameDeed
|
||||
{
|
||||
List<string> Names { get; }
|
||||
|
||||
void AddName(string name);
|
||||
void AddNames(params string[] names);
|
||||
}
|
||||
|
||||
public abstract class BaseNameDeed<TEntity> : Item, INameDeed
|
||||
where TEntity : IEntity
|
||||
{
|
||||
private SuperGump _Gump;
|
||||
private GenericSelectTarget<TEntity> _Target;
|
||||
|
||||
public List<string> Names { get; private set; }
|
||||
|
||||
public virtual string TargetUsage => "an object";
|
||||
|
||||
public BaseNameDeed()
|
||||
: base(0x14F0)
|
||||
{
|
||||
Names = new List<string>();
|
||||
|
||||
Name = "Rename Deed";
|
||||
Weight = 1.0;
|
||||
LootType = LootType.Blessed;
|
||||
|
||||
Timer.DelayCall(NameDeeds.InvokeCreated, this);
|
||||
}
|
||||
|
||||
public BaseNameDeed(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public void AddName(string name)
|
||||
{
|
||||
Names.Update(name);
|
||||
}
|
||||
|
||||
public void AddNames(params string[] names)
|
||||
{
|
||||
if (names == null || names.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var n in names)
|
||||
{
|
||||
AddName(n);
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
new ExtendedOPL(list)
|
||||
{
|
||||
{"Use: Change the name of {0}".WrapUOHtmlColor(Color.LawnGreen), TargetUsage}
|
||||
}.Apply();
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile m)
|
||||
{
|
||||
if (this.CheckDoubleClick(m, true, false, 2, true))
|
||||
{
|
||||
BeginTarget(m);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void BeginTarget(Mobile m)
|
||||
{
|
||||
if (_Target != null)
|
||||
{
|
||||
if (_Target.User != null && _Target.User.Target == _Target)
|
||||
{
|
||||
_Target.Cancel(_Target.User, TargetCancelType.Overriden);
|
||||
}
|
||||
|
||||
_Target = null;
|
||||
}
|
||||
|
||||
m.SendMessage("Target an object to rename...");
|
||||
|
||||
_Target = new GenericSelectTarget<TEntity>(
|
||||
(u, t) =>
|
||||
{
|
||||
_Target = null;
|
||||
OpenGump(u, t);
|
||||
},
|
||||
u =>
|
||||
{
|
||||
OnTargetFail(u);
|
||||
_Target = null;
|
||||
});
|
||||
|
||||
m.Target = _Target;
|
||||
}
|
||||
|
||||
protected virtual void OnTargetFail(Mobile m)
|
||||
{
|
||||
if (_Target.User == m && _Target.Result == TargetResult.Invalid)
|
||||
{
|
||||
m.SendMessage("That is not a valid target.");
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OpenGump(Mobile m, TEntity t)
|
||||
{
|
||||
if (_Gump != null)
|
||||
{
|
||||
_Gump.Close();
|
||||
_Gump = null;
|
||||
}
|
||||
|
||||
if (Names != null && Names.Count > 0)
|
||||
{
|
||||
m.SendMessage("Select a name from the registry...");
|
||||
|
||||
var opts = new MenuGumpOptions();
|
||||
|
||||
foreach (var name in Names.OrderByNatural())
|
||||
{
|
||||
var n = name;
|
||||
|
||||
opts.AppendEntry(
|
||||
new ListGumpEntry(
|
||||
n,
|
||||
() =>
|
||||
{
|
||||
_Gump = null;
|
||||
ApplyName(m, t, n);
|
||||
}));
|
||||
}
|
||||
|
||||
var menu = new MenuGump(m, null, opts);
|
||||
|
||||
menu.OnActionClose += HandleGumpClose;
|
||||
_Gump = menu.Send();
|
||||
}
|
||||
else
|
||||
{
|
||||
string name;
|
||||
int limit;
|
||||
|
||||
if (t is Item)
|
||||
{
|
||||
name = (t as Item).Name;
|
||||
limit = 20;
|
||||
}
|
||||
else if (t is Mobile)
|
||||
{
|
||||
name = (t as Mobile).RawName;
|
||||
limit = 20;
|
||||
}
|
||||
else
|
||||
{
|
||||
name = String.Empty;
|
||||
limit = 0;
|
||||
}
|
||||
|
||||
var dialog = new InputDialogGump(m)
|
||||
{
|
||||
Title = "Name Selection",
|
||||
Html = "Type the name you wish to use and click OK to accept.",
|
||||
InputText = name ?? String.Empty,
|
||||
Limit = limit,
|
||||
Callback = (b, n) =>
|
||||
{
|
||||
_Gump = null;
|
||||
ApplyName(m, t, n);
|
||||
}
|
||||
};
|
||||
|
||||
dialog.OnActionClose += HandleGumpClose;
|
||||
_Gump = dialog.Send();
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleGumpClose(SuperGump g, bool all)
|
||||
{
|
||||
if (_Gump == g && all)
|
||||
{
|
||||
_Gump.OnActionClose -= HandleGumpClose;
|
||||
_Gump = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void ApplyName(Mobile m, TEntity t, string name)
|
||||
{
|
||||
if (m == null || t == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (String.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
m.SendMessage(0x22, "You cannot use a blank name.");
|
||||
OpenGump(m, t);
|
||||
return;
|
||||
}
|
||||
|
||||
name = Utility.FixHtml(name.Trim());
|
||||
|
||||
if (!NameVerification.Validate(name, 2, 20, true, t is Item, true, 1, NameVerification.SpaceDashPeriodQuote))
|
||||
{
|
||||
m.SendMessage(0x22, "That name is unacceptable.");
|
||||
OpenGump(m, t);
|
||||
return;
|
||||
}
|
||||
|
||||
var item = t as Item;
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
if (item.Name == name)
|
||||
{
|
||||
m.SendMessage(0x22, "The item is already named {0}.", name);
|
||||
OpenGump(m, t);
|
||||
return;
|
||||
}
|
||||
|
||||
item.Name = name;
|
||||
|
||||
m.SendMessage(0x55, "The item has been renamed.");
|
||||
Delete();
|
||||
return;
|
||||
}
|
||||
|
||||
var mob = t as Mobile;
|
||||
|
||||
if (mob != null)
|
||||
{
|
||||
if (mob.RawName == name)
|
||||
{
|
||||
m.SendMessage(0x22, "{0} are already named {1}.", mob == m ? "You" : "They", name);
|
||||
OpenGump(m, t);
|
||||
return;
|
||||
}
|
||||
|
||||
mob.RawName = name;
|
||||
|
||||
m.SendMessage(0x55, "{0} name has been changed.", mob == m ? "Your" : "Their");
|
||||
Delete();
|
||||
|
||||
if (mob is PlayerMobile)
|
||||
{
|
||||
var pm = (PlayerMobile)mob;
|
||||
|
||||
PlayerNames.Register(pm);
|
||||
PlayerNames.ValidateSharedName(pm);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m.SendMessage(0x22, "Could not rename that object.");
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
base.OnDelete();
|
||||
|
||||
_Gump = null;
|
||||
_Target = null;
|
||||
|
||||
Names.Free(true);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
|
||||
writer.WriteList(Names, writer.Write);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
|
||||
Names = reader.ReadList(reader.ReadString);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class ItemNameDeed<TItem> : BaseNameDeed<TItem>
|
||||
where TItem : Item
|
||||
{
|
||||
public override string TargetUsage => "an item";
|
||||
|
||||
public ItemNameDeed()
|
||||
{ }
|
||||
|
||||
public ItemNameDeed(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
protected override void OpenGump(Mobile m, TItem t)
|
||||
{
|
||||
if (m == null || t == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m.AccessLevel < AccessLevel.GameMaster)
|
||||
{
|
||||
if (!t.Movable && !t.IsAccessibleTo(m))
|
||||
{
|
||||
m.SendMessage("That item is not accessible.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!t.IsChildOf(m.Backpack) && t.RootParent != m)
|
||||
{
|
||||
m.SendMessage("That item must be equipped or in your pack to rename it.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
base.OpenGump(m, t);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class MobileNameDeed<TMobile> : BaseNameDeed<TMobile>
|
||||
where TMobile : Mobile
|
||||
{
|
||||
public override string TargetUsage => "a mobile";
|
||||
|
||||
public MobileNameDeed()
|
||||
{ }
|
||||
|
||||
public MobileNameDeed(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
protected override void OpenGump(Mobile m, TMobile t)
|
||||
{
|
||||
if (m == null || t == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m.AccessLevel < t.AccessLevel)
|
||||
{
|
||||
m.SendMessage("They are not accessible.");
|
||||
return;
|
||||
}
|
||||
|
||||
base.OpenGump(m, t);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public class PlayerNameDeed : MobileNameDeed<PlayerMobile>
|
||||
{
|
||||
public override string TargetUsage => "your character";
|
||||
|
||||
[Constructable]
|
||||
public PlayerNameDeed()
|
||||
{
|
||||
Name = "Player Rename Deed";
|
||||
}
|
||||
|
||||
public PlayerNameDeed(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
protected override void BeginTarget(Mobile m)
|
||||
{
|
||||
OpenGump(m, m as PlayerMobile);
|
||||
}
|
||||
|
||||
protected override void OpenGump(Mobile m, PlayerMobile t)
|
||||
{
|
||||
if (m == null || t == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m.AccessLevel < AccessLevel.GameMaster)
|
||||
{
|
||||
if (m != t)
|
||||
{
|
||||
m.SendMessage("You can only change your own name.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
base.OpenGump(m, t);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public class WeaponNameDeed : ItemNameDeed<BaseWeapon>
|
||||
{
|
||||
public override string TargetUsage => "your weapon";
|
||||
|
||||
[Constructable]
|
||||
public WeaponNameDeed()
|
||||
{
|
||||
Name = "Weapon Rename Deed";
|
||||
}
|
||||
|
||||
public WeaponNameDeed(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public class ArmorNameDeed : ItemNameDeed<BaseArmor>
|
||||
{
|
||||
public override string TargetUsage => "your armor";
|
||||
|
||||
[Constructable]
|
||||
public ArmorNameDeed()
|
||||
{
|
||||
Name = "Armor Rename Deed";
|
||||
}
|
||||
|
||||
public ArmorNameDeed(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public class ClothingNameDeed : ItemNameDeed<BaseClothing>
|
||||
{
|
||||
public override string TargetUsage => "your clothing";
|
||||
|
||||
[Constructable]
|
||||
public ClothingNameDeed()
|
||||
{
|
||||
Name = "Clothing Rename Deed";
|
||||
}
|
||||
|
||||
public ClothingNameDeed(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public class JewelNameDeed : ItemNameDeed<BaseJewel>
|
||||
{
|
||||
public override string TargetUsage => "your jewelry";
|
||||
|
||||
[Constructable]
|
||||
public JewelNameDeed()
|
||||
{
|
||||
Name = "Jewelry Rename Deed";
|
||||
}
|
||||
|
||||
public JewelNameDeed(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public class QuiverNameDeed : ItemNameDeed<BaseQuiver>
|
||||
{
|
||||
public override string TargetUsage => "your quiver";
|
||||
|
||||
[Constructable]
|
||||
public QuiverNameDeed()
|
||||
{
|
||||
Name = "Quiver Rename Deed";
|
||||
}
|
||||
|
||||
public QuiverNameDeed(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public class LightNameDeed : ItemNameDeed<BaseEquipableLight>
|
||||
{
|
||||
public override string TargetUsage => "your light source";
|
||||
|
||||
[Constructable]
|
||||
public LightNameDeed()
|
||||
{
|
||||
Name = "Light Source Rename Deed";
|
||||
}
|
||||
|
||||
public LightNameDeed(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public class SpellbookNameDeed : ItemNameDeed<Spellbook>
|
||||
{
|
||||
public override string TargetUsage => "your spellbook";
|
||||
|
||||
[Constructable]
|
||||
public SpellbookNameDeed()
|
||||
{
|
||||
Name = "Spellbook Rename Deed";
|
||||
}
|
||||
|
||||
public SpellbookNameDeed(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public class ContainerNameDeed : ItemNameDeed<Container>
|
||||
{
|
||||
public override string TargetUsage => "a container";
|
||||
|
||||
[Constructable]
|
||||
public ContainerNameDeed()
|
||||
{
|
||||
Name = "Container Rename Deed";
|
||||
}
|
||||
|
||||
public ContainerNameDeed(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
449
Scripts/SubSystem/VitaNex/Core/Items/Fireworks/BaseFirework.cs
Normal file
449
Scripts/SubSystem/VitaNex/Core/Items/Fireworks/BaseFirework.cs
Normal file
@@ -0,0 +1,449 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Server;
|
||||
using Server.Engines.Craft;
|
||||
using Server.Items;
|
||||
|
||||
using VitaNex.FX;
|
||||
using VitaNex.Network;
|
||||
using VitaNex.SuperCrafts;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public abstract class BaseFirework : Item, ICraftable
|
||||
{
|
||||
protected virtual object UseLock => GetType();
|
||||
|
||||
public virtual string DefToken => String.Empty;
|
||||
public virtual TimeSpan DefUseDelay => TimeSpan.FromSeconds(3.0);
|
||||
|
||||
private string _Token;
|
||||
private Mobile _Crafter;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string Token
|
||||
{
|
||||
get => _Token;
|
||||
set
|
||||
{
|
||||
_Token = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Mobile Crafter
|
||||
{
|
||||
get => _Crafter;
|
||||
set
|
||||
{
|
||||
_Crafter = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TimeSpan UseDelay { get; set; }
|
||||
|
||||
#region Fuse
|
||||
public virtual TimeSpan DefFuseDelay => TimeSpan.FromSeconds(1.0);
|
||||
|
||||
private Timer _FuseTimer;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TimeSpan FuseDelay { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool FuseLit => _FuseTimer != null && _FuseTimer.Running;
|
||||
#endregion
|
||||
|
||||
#region Ignite Effect
|
||||
public virtual int DefIgniteEffectID => 14276;
|
||||
public virtual int DefIgniteEffectHue => 0;
|
||||
public virtual int DefIgniteEffectSpeed => 5;
|
||||
public virtual EffectRender DefIgniteEffectRender => EffectRender.LightenMore;
|
||||
public virtual int DefIgniteEffectSound => 1232;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int IgniteEffectID { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int IgniteEffectHue { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int IgniteEffectSpeed { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public EffectRender IgniteEffectRender { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int IgniteEffectSound { get; set; }
|
||||
#endregion
|
||||
|
||||
#region Fail Effect
|
||||
public virtual int DefFailEffectID => 14133;
|
||||
public virtual int DefFailEffectHue => 0;
|
||||
public virtual int DefFailEffectSpeed => 10;
|
||||
public virtual int DefFailEffectDuration => 30;
|
||||
public virtual EffectRender DefFailEffectRender => EffectRender.Normal;
|
||||
public virtual int DefFailEffectSound => 1488;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int FailEffectID { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int FailEffectHue { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int FailEffectSpeed { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int FailEffectDuration { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public EffectRender FailEffectRender { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int FailEffectSound { get; set; }
|
||||
#endregion
|
||||
|
||||
public BaseFirework(int itemID, int hue)
|
||||
: base(itemID)
|
||||
{
|
||||
Name = "Firework Rocket";
|
||||
Weight = 1.0;
|
||||
Light = LightType.Circle300;
|
||||
|
||||
Hue = hue;
|
||||
|
||||
UseDelay = DefUseDelay;
|
||||
Token = DefToken;
|
||||
|
||||
FuseDelay = DefFuseDelay;
|
||||
|
||||
IgniteEffectID = DefIgniteEffectID;
|
||||
IgniteEffectHue = DefIgniteEffectHue;
|
||||
IgniteEffectSpeed = DefIgniteEffectSpeed;
|
||||
IgniteEffectRender = DefIgniteEffectRender;
|
||||
IgniteEffectSound = DefIgniteEffectSound;
|
||||
|
||||
FailEffectID = DefFailEffectID;
|
||||
FailEffectHue = DefFailEffectHue;
|
||||
FailEffectSpeed = DefFailEffectSpeed;
|
||||
FailEffectDuration = DefFailEffectDuration;
|
||||
FailEffectRender = DefFailEffectRender;
|
||||
FailEffectSound = DefFailEffectSound;
|
||||
}
|
||||
|
||||
public BaseFirework(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override bool IsAccessibleTo(Mobile check)
|
||||
{
|
||||
return base.IsAccessibleTo(check) && !FuseLit;
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
if (Crafter != null && !String.IsNullOrWhiteSpace(Crafter.RawName))
|
||||
{
|
||||
list.Add(1050043, Crafter.RawName);
|
||||
}
|
||||
|
||||
var props = new StringBuilder();
|
||||
|
||||
GetProperties(props);
|
||||
|
||||
if (props.Length > 0)
|
||||
{
|
||||
list.Add(props.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void GetProperties(StringBuilder props)
|
||||
{
|
||||
if (!Visible)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (FuseLit)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
if (_FuseTimer.Next < now)
|
||||
{
|
||||
var ts = now - _FuseTimer.Next;
|
||||
|
||||
if (ts > TimeSpan.Zero)
|
||||
{
|
||||
props.AppendLine("Fuse: {0}", ts.ToSimpleString("h:m:s"));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
props.AppendLine("Use: Light the fuse!".WrapUOHtmlColor(Color.LawnGreen));
|
||||
}
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(Token))
|
||||
{
|
||||
props.AppendLine("\"{0}\"".WrapUOHtmlColor(Color.Gold), Token);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual int OnCraft(
|
||||
int quality,
|
||||
bool makersMark,
|
||||
Mobile m,
|
||||
CraftSystem craftSystem,
|
||||
Type typeRes,
|
||||
#if ServUO
|
||||
ITool tool,
|
||||
#else
|
||||
BaseTool tool,
|
||||
#endif
|
||||
CraftItem craftItem,
|
||||
int resHue)
|
||||
{
|
||||
if (makersMark)
|
||||
{
|
||||
Crafter = m;
|
||||
}
|
||||
|
||||
var context = craftSystem.GetContext(m);
|
||||
|
||||
if (context != null && context.DoNotColor)
|
||||
{
|
||||
Hue = 0;
|
||||
}
|
||||
else if (resHue > 0)
|
||||
{
|
||||
Hue = resHue;
|
||||
}
|
||||
|
||||
if (craftSystem is Pyrotechnics && craftItem != null)
|
||||
{
|
||||
var fuses = new List<CraftRes>(craftItem.Resources.Count);
|
||||
|
||||
fuses.SetAll(craftItem.Resources.GetAt);
|
||||
fuses.RemoveAll(res => !res.ItemType.TypeEquals<FireworkFuse>());
|
||||
|
||||
var fuseDelay = FuseDelay.TotalSeconds * fuses.Sum(r => r.Amount);
|
||||
|
||||
fuses.Free(true);
|
||||
|
||||
if (fuseDelay > 0)
|
||||
{
|
||||
FuseDelay = TimeSpan.FromSeconds(fuseDelay);
|
||||
}
|
||||
}
|
||||
|
||||
return quality;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile m)
|
||||
{
|
||||
if (m == null || m.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (FuseLit)
|
||||
{
|
||||
m.SendMessage("The fuse is already burning.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.CheckDoubleClick(m, true, false, 10))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m.BeginAction(UseLock, UseDelay))
|
||||
{
|
||||
m.SendMessage("You must wait before you can light another {0}.", this.ResolveName(m));
|
||||
return;
|
||||
}
|
||||
|
||||
MoveToWorld(m.Location, m.Map);
|
||||
|
||||
IgniteFuse(m);
|
||||
|
||||
InvalidateProperties();
|
||||
}
|
||||
|
||||
protected void IgniteFuse(Mobile m)
|
||||
{
|
||||
if (m == null || m.Deleted || FuseLit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!OnIgnite(m))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (IgniteEffectID > 0)
|
||||
{
|
||||
var fx = new EffectInfo(
|
||||
GetWorldLocation(),
|
||||
Map,
|
||||
IgniteEffectID,
|
||||
IgniteEffectHue,
|
||||
IgniteEffectSpeed,
|
||||
(int)Math.Ceiling(FuseDelay.TotalMilliseconds / 100.0),
|
||||
IgniteEffectRender);
|
||||
|
||||
fx.Send();
|
||||
}
|
||||
|
||||
if (IgniteEffectSound > 0)
|
||||
{
|
||||
Effects.PlaySound(GetWorldLocation(), Map, IgniteEffectSound);
|
||||
}
|
||||
|
||||
_FuseTimer = Timer.DelayCall(
|
||||
FuseDelay,
|
||||
() =>
|
||||
{
|
||||
_FuseTimer = null;
|
||||
|
||||
InvalidateProperties();
|
||||
|
||||
if (!OnFuseBurned(m))
|
||||
{
|
||||
Fail(m);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected virtual bool OnIgnite(Mobile m)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected abstract bool OnFuseBurned(Mobile m);
|
||||
|
||||
protected void Fail(Mobile m)
|
||||
{
|
||||
if (FailEffectID > 0)
|
||||
{
|
||||
var fx = new EffectInfo(
|
||||
GetWorldLocation(),
|
||||
Map,
|
||||
FailEffectID,
|
||||
FailEffectHue,
|
||||
FailEffectSpeed,
|
||||
FailEffectDuration,
|
||||
FailEffectRender);
|
||||
|
||||
fx.Send();
|
||||
}
|
||||
|
||||
if (FailEffectSound > 0)
|
||||
{
|
||||
Effects.PlaySound(GetWorldLocation(), Map, 1488);
|
||||
}
|
||||
|
||||
Movable = Visible = true;
|
||||
|
||||
OnFail(m);
|
||||
}
|
||||
|
||||
protected virtual void OnFail(Mobile m)
|
||||
{
|
||||
if (m != null)
|
||||
{
|
||||
m.SendMessage("The fuse has failed to ignite on {0}!", this.ResolveName(m));
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
writer.Write(_Token);
|
||||
writer.Write(_Crafter);
|
||||
|
||||
writer.Write(UseDelay);
|
||||
writer.Write(FuseDelay);
|
||||
|
||||
writer.Write(IgniteEffectID);
|
||||
writer.Write(IgniteEffectHue);
|
||||
writer.Write(IgniteEffectSpeed);
|
||||
writer.WriteFlag(IgniteEffectRender);
|
||||
writer.Write(IgniteEffectSound);
|
||||
|
||||
writer.Write(FailEffectID);
|
||||
writer.Write(FailEffectHue);
|
||||
writer.Write(FailEffectSpeed);
|
||||
writer.Write(FailEffectDuration);
|
||||
writer.WriteFlag(FailEffectRender);
|
||||
writer.Write(FailEffectSound);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
_Token = reader.ReadString();
|
||||
_Crafter = reader.ReadMobile();
|
||||
|
||||
UseDelay = reader.ReadTimeSpan();
|
||||
FuseDelay = reader.ReadTimeSpan();
|
||||
|
||||
IgniteEffectID = reader.ReadInt();
|
||||
IgniteEffectHue = reader.ReadInt();
|
||||
IgniteEffectSpeed = reader.ReadInt();
|
||||
IgniteEffectRender = reader.ReadFlag<EffectRender>();
|
||||
IgniteEffectSound = reader.ReadInt();
|
||||
|
||||
FailEffectID = reader.ReadInt();
|
||||
FailEffectHue = reader.ReadInt();
|
||||
FailEffectSpeed = reader.ReadInt();
|
||||
FailEffectDuration = reader.ReadInt();
|
||||
FailEffectRender = reader.ReadFlag<EffectRender>();
|
||||
FailEffectSound = reader.ReadInt();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
using Server;
|
||||
using Server.Engines.Craft;
|
||||
using Server.Items;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public abstract class FireworkComponent : Item, ICraftable
|
||||
{
|
||||
private Mobile _Crafter;
|
||||
|
||||
[CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)]
|
||||
public Mobile Crafter
|
||||
{
|
||||
get => _Crafter;
|
||||
set
|
||||
{
|
||||
_Crafter = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public FireworkComponent(int itemID)
|
||||
: base(itemID)
|
||||
{ }
|
||||
|
||||
public FireworkComponent(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override bool StackWith(Mobile m, Item dropped, bool playSound)
|
||||
{
|
||||
if (m == null || !(dropped is FireworkComponent) || ((FireworkComponent)dropped)._Crafter != _Crafter)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.StackWith(m, dropped, playSound);
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
if (Crafter != null)
|
||||
{
|
||||
list.Add(1050043, Crafter.RawName);
|
||||
}
|
||||
|
||||
var props = new StringBuilder();
|
||||
|
||||
GetProperties(props);
|
||||
|
||||
if (props.Length > 0)
|
||||
{
|
||||
list.Add(props.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void GetProperties(StringBuilder props)
|
||||
{ }
|
||||
|
||||
public virtual int OnCraft(
|
||||
int quality,
|
||||
bool makersMark,
|
||||
Mobile m,
|
||||
CraftSystem craft,
|
||||
Type typeRes,
|
||||
#if ServUO
|
||||
ITool tool,
|
||||
#else
|
||||
BaseTool tool,
|
||||
#endif
|
||||
CraftItem item,
|
||||
int resHue)
|
||||
{
|
||||
if (makersMark)
|
||||
{
|
||||
Crafter = m;
|
||||
}
|
||||
|
||||
var context = craft.GetContext(m);
|
||||
|
||||
if (context != null && context.DoNotColor)
|
||||
{
|
||||
Hue = 0;
|
||||
}
|
||||
else if (resHue > 0)
|
||||
{
|
||||
Hue = resHue;
|
||||
}
|
||||
|
||||
return quality;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
|
||||
writer.Write(_Crafter);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
|
||||
_Crafter = reader.ReadMobile();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class FireworkFuse : FireworkComponent
|
||||
{
|
||||
[Constructable]
|
||||
public FireworkFuse()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public FireworkFuse(int amount)
|
||||
: base(3613)
|
||||
{
|
||||
Name = "Firework Fuse";
|
||||
Hue = 85;
|
||||
Stackable = true;
|
||||
Amount = Math.Max(1, Math.Min(60000, amount));
|
||||
}
|
||||
|
||||
public FireworkFuse(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,419 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
using Server.Engines.Craft;
|
||||
using Server.Items;
|
||||
|
||||
using VitaNex.SuperCrafts;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public abstract class BaseFireworkStar : FireworkComponent
|
||||
{
|
||||
public static CraftResource GetMetal(Type star)
|
||||
{
|
||||
if (!star.IsEqualOrChildOf<BaseFireworkStar>() || star.IsEqualOrChildOf<FireworkStarCustom>())
|
||||
{
|
||||
return CraftResource.None;
|
||||
}
|
||||
|
||||
if (star.IsEqualOrChildOf<FireworkStarIron>())
|
||||
{
|
||||
return CraftResource.Iron;
|
||||
}
|
||||
|
||||
if (star.IsEqualOrChildOf<FireworkStarDullCopper>())
|
||||
{
|
||||
return CraftResource.DullCopper;
|
||||
}
|
||||
|
||||
if (star.IsEqualOrChildOf<FireworkStarShadowIron>())
|
||||
{
|
||||
return CraftResource.ShadowIron;
|
||||
}
|
||||
|
||||
if (star.IsEqualOrChildOf<FireworkStarCopper>())
|
||||
{
|
||||
return CraftResource.Copper;
|
||||
}
|
||||
|
||||
if (star.IsEqualOrChildOf<FireworkStarBronze>())
|
||||
{
|
||||
return CraftResource.Bronze;
|
||||
}
|
||||
|
||||
if (star.IsEqualOrChildOf<FireworkStarGold>())
|
||||
{
|
||||
return CraftResource.Gold;
|
||||
}
|
||||
|
||||
if (star.IsEqualOrChildOf<FireworkStarAgapite>())
|
||||
{
|
||||
return CraftResource.Agapite;
|
||||
}
|
||||
|
||||
if (star.IsEqualOrChildOf<FireworkStarVerite>())
|
||||
{
|
||||
return CraftResource.Verite;
|
||||
}
|
||||
|
||||
if (star.IsEqualOrChildOf<FireworkStarValorite>())
|
||||
{
|
||||
return CraftResource.Valorite;
|
||||
}
|
||||
|
||||
return CraftResource.None;
|
||||
}
|
||||
|
||||
public static int[] GetEffectHues(Type star)
|
||||
{
|
||||
var res = GetMetal(star);
|
||||
|
||||
return res != CraftResource.None ? GetEffectHues(ref res) : new int[0];
|
||||
}
|
||||
|
||||
public static int[] GetEffectHues(ref CraftResource res)
|
||||
{
|
||||
LimitResource(ref res);
|
||||
|
||||
int hue;
|
||||
|
||||
switch (res)
|
||||
{
|
||||
case CraftResource.Iron:
|
||||
hue = 48; // Gold
|
||||
break;
|
||||
case CraftResource.DullCopper:
|
||||
hue = 98; // Dark Blue
|
||||
break;
|
||||
case CraftResource.ShadowIron:
|
||||
hue = 43; // Orange
|
||||
break;
|
||||
case CraftResource.Copper:
|
||||
hue = 88; // Blue
|
||||
break;
|
||||
case CraftResource.Bronze:
|
||||
hue = 38; // Red
|
||||
break;
|
||||
case CraftResource.Gold:
|
||||
hue = 63; // Green
|
||||
break;
|
||||
case CraftResource.Agapite:
|
||||
hue = 53; // Yellow
|
||||
break;
|
||||
case CraftResource.Verite:
|
||||
hue = 13; // Purple
|
||||
break;
|
||||
case CraftResource.Valorite:
|
||||
hue = 183; // Aqua
|
||||
break;
|
||||
default:
|
||||
hue = 48;
|
||||
break;
|
||||
}
|
||||
|
||||
var hues = new int[9];
|
||||
|
||||
hues.SetAll(
|
||||
i =>
|
||||
{
|
||||
if (i > 0 && i % 3 == 0)
|
||||
{
|
||||
hue += 100;
|
||||
}
|
||||
|
||||
return hue++;
|
||||
});
|
||||
|
||||
return hues;
|
||||
}
|
||||
|
||||
public static void LimitResource(ref CraftResource res)
|
||||
{
|
||||
var r = (int)res;
|
||||
|
||||
if (r <= 0 || r > 9)
|
||||
{
|
||||
res = CraftResource.Iron;
|
||||
}
|
||||
}
|
||||
|
||||
private CraftResource _Resource;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public CraftResource Resource
|
||||
{
|
||||
get
|
||||
{
|
||||
LimitResource(ref _Resource);
|
||||
|
||||
return _Resource;
|
||||
}
|
||||
set
|
||||
{
|
||||
LimitResource(ref value);
|
||||
|
||||
if (_Resource == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var old = _Resource;
|
||||
_Resource = value;
|
||||
|
||||
if (Hue == 0 || Hue == CraftResources.GetHue(old))
|
||||
{
|
||||
Hue = CraftResources.GetHue(_Resource);
|
||||
}
|
||||
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public override double DefaultWeight => 0.1;
|
||||
|
||||
public BaseFireworkStar(CraftResource res, int amount)
|
||||
: base(16932)
|
||||
{
|
||||
Name = "Firework Star";
|
||||
Resource = res;
|
||||
Stackable = true;
|
||||
Amount = Math.Max(1, Math.Min(60000, amount));
|
||||
}
|
||||
|
||||
public BaseFireworkStar(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void AddNameProperty(ObjectPropertyList list)
|
||||
{
|
||||
var res = CraftResources.GetName(Resource);
|
||||
|
||||
if (CraftResources.IsStandard(Resource))
|
||||
{
|
||||
res = String.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Insensitive.Contains(res, "Normal") || Insensitive.Contains(res, "Plain"))
|
||||
{
|
||||
var typ = CraftResources.GetType(Resource).ToString();
|
||||
|
||||
res = res.Replace("Normal", typ);
|
||||
res = res.Replace("Plain", typ);
|
||||
}
|
||||
|
||||
res = res.Replace("Scales", "Scale");
|
||||
res = res.Replace("Crystals", "Crystal");
|
||||
}
|
||||
|
||||
if (Amount <= 1)
|
||||
{
|
||||
list.Add(1050039, "{0}\t{1}", res, this.ResolveName());
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Add(1050039, "{0}\t{1} {2}", Amount, res, this.ResolveName());
|
||||
}
|
||||
}
|
||||
|
||||
public override bool StackWith(Mobile m, Item dropped, bool playSound)
|
||||
{
|
||||
if (m == null || !(dropped is BaseFireworkStar) || ((BaseFireworkStar)dropped)._Resource != _Resource)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.StackWith(m, dropped, playSound);
|
||||
}
|
||||
|
||||
public override int OnCraft(
|
||||
int quality,
|
||||
bool makersMark,
|
||||
Mobile m,
|
||||
CraftSystem craftSystem,
|
||||
Type typeRes,
|
||||
#if ServUO
|
||||
ITool tool,
|
||||
#else
|
||||
BaseTool tool,
|
||||
#endif
|
||||
CraftItem craftItem,
|
||||
int resHue)
|
||||
{
|
||||
if (craftSystem is Pyrotechnics && craftItem != null)
|
||||
{
|
||||
var resourceType = typeRes ?? craftItem.Resources.GetAt(0).ItemType;
|
||||
|
||||
Resource = CraftResources.GetFromType(resourceType);
|
||||
}
|
||||
|
||||
return base.OnCraft(quality, makersMark, m, craftSystem, typeRes, tool, craftItem, resHue);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
|
||||
writer.WriteFlag(_Resource);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
|
||||
_Resource = reader.ReadFlag<CraftResource>();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class FireworkStarCustom : BaseFireworkStar
|
||||
{
|
||||
private bool _Converted;
|
||||
|
||||
[Constructable]
|
||||
public FireworkStarCustom()
|
||||
: this(CraftResource.Iron, 1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public FireworkStarCustom(CraftResource res, int amount)
|
||||
: base(res, amount)
|
||||
{ }
|
||||
|
||||
public FireworkStarCustom(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void ReplaceWith(Item newItem)
|
||||
{
|
||||
if (Parent is Container)
|
||||
{
|
||||
var cont = (Container)Parent;
|
||||
|
||||
if (newItem is BaseFireworkStar)
|
||||
{
|
||||
var star = (BaseFireworkStar)newItem;
|
||||
var starType = star.GetType();
|
||||
var stackWith = cont.FindItemsByType<BaseFireworkStar>()
|
||||
.FirstOrDefault(
|
||||
s => s.Stackable && s.Resource == star.Resource && s.Amount + star.Amount <= 60000 &&
|
||||
s.GetType().IsEqual(starType));
|
||||
|
||||
if (stackWith != null)
|
||||
{
|
||||
stackWith.Amount += newItem.Amount;
|
||||
newItem.Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
cont.AddItem(newItem);
|
||||
|
||||
newItem.Location = Location;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cont.AddItem(newItem);
|
||||
|
||||
newItem.Location = Location;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
newItem.MoveToWorld(GetWorldLocation(), Map);
|
||||
}
|
||||
|
||||
Delete();
|
||||
}
|
||||
|
||||
public void Convert()
|
||||
{
|
||||
if (_Converted || Deleted || Map == null || Map == Map.Internal)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_Converted = true;
|
||||
|
||||
switch (Resource)
|
||||
{
|
||||
case CraftResource.Iron:
|
||||
ReplaceWith(new FireworkStarIron(Amount));
|
||||
break;
|
||||
case CraftResource.DullCopper:
|
||||
ReplaceWith(new FireworkStarDullCopper(Amount));
|
||||
break;
|
||||
case CraftResource.ShadowIron:
|
||||
ReplaceWith(new FireworkStarShadowIron(Amount));
|
||||
break;
|
||||
case CraftResource.Copper:
|
||||
ReplaceWith(new FireworkStarCopper(Amount));
|
||||
break;
|
||||
case CraftResource.Bronze:
|
||||
ReplaceWith(new FireworkStarBronze(Amount));
|
||||
break;
|
||||
case CraftResource.Gold:
|
||||
ReplaceWith(new FireworkStarGold(Amount));
|
||||
break;
|
||||
case CraftResource.Agapite:
|
||||
ReplaceWith(new FireworkStarAgapite(Amount));
|
||||
break;
|
||||
case CraftResource.Verite:
|
||||
ReplaceWith(new FireworkStarVerite(Amount));
|
||||
break;
|
||||
case CraftResource.Valorite:
|
||||
ReplaceWith(new FireworkStarValorite(Amount));
|
||||
break;
|
||||
default:
|
||||
ReplaceWith(new FireworkStarIron(Amount));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if NEWPARENT
|
||||
public override void OnAdded(IEntity parent)
|
||||
#else
|
||||
public override void OnAdded(object parent)
|
||||
#endif
|
||||
{
|
||||
base.OnAdded(parent);
|
||||
|
||||
if (Map != null && Map != Map.Internal)
|
||||
{
|
||||
Convert();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
using Server.Items;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class FireworkStarAgapite : BaseFireworkStar
|
||||
{
|
||||
[Constructable]
|
||||
public FireworkStarAgapite()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public FireworkStarAgapite(int amount)
|
||||
: base(CraftResource.Agapite, amount)
|
||||
{ }
|
||||
|
||||
public FireworkStarAgapite(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
using Server.Items;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class FireworkStarBronze : BaseFireworkStar
|
||||
{
|
||||
[Constructable]
|
||||
public FireworkStarBronze()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public FireworkStarBronze(int amount)
|
||||
: base(CraftResource.Bronze, amount)
|
||||
{ }
|
||||
|
||||
public FireworkStarBronze(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
using Server.Items;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class FireworkStarCopper : BaseFireworkStar
|
||||
{
|
||||
[Constructable]
|
||||
public FireworkStarCopper()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public FireworkStarCopper(int amount)
|
||||
: base(CraftResource.Copper, amount)
|
||||
{ }
|
||||
|
||||
public FireworkStarCopper(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
using Server.Items;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class FireworkStarDullCopper : BaseFireworkStar
|
||||
{
|
||||
[Constructable]
|
||||
public FireworkStarDullCopper()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public FireworkStarDullCopper(int amount)
|
||||
: base(CraftResource.DullCopper, amount)
|
||||
{ }
|
||||
|
||||
public FireworkStarDullCopper(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
using Server.Items;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class FireworkStarGold : BaseFireworkStar
|
||||
{
|
||||
[Constructable]
|
||||
public FireworkStarGold()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public FireworkStarGold(int amount)
|
||||
: base(CraftResource.Gold, amount)
|
||||
{ }
|
||||
|
||||
public FireworkStarGold(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
using Server.Items;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class FireworkStarIron : BaseFireworkStar
|
||||
{
|
||||
[Constructable]
|
||||
public FireworkStarIron()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public FireworkStarIron(int amount)
|
||||
: base(CraftResource.Iron, amount)
|
||||
{ }
|
||||
|
||||
public FireworkStarIron(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
using Server.Items;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class FireworkStarShadowIron : BaseFireworkStar
|
||||
{
|
||||
[Constructable]
|
||||
public FireworkStarShadowIron()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public FireworkStarShadowIron(int amount)
|
||||
: base(CraftResource.ShadowIron, amount)
|
||||
{ }
|
||||
|
||||
public FireworkStarShadowIron(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
using Server.Items;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class FireworkStarValorite : BaseFireworkStar
|
||||
{
|
||||
[Constructable]
|
||||
public FireworkStarValorite()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public FireworkStarValorite(int amount)
|
||||
: base(CraftResource.Valorite, amount)
|
||||
{ }
|
||||
|
||||
public FireworkStarValorite(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
using Server.Items;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class FireworkStarVerite : BaseFireworkStar
|
||||
{
|
||||
[Constructable]
|
||||
public FireworkStarVerite()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public FireworkStarVerite(int amount)
|
||||
: base(CraftResource.Verite, amount)
|
||||
{ }
|
||||
|
||||
public FireworkStarVerite(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public enum FireworkStars
|
||||
{
|
||||
None,
|
||||
Peony,
|
||||
Chrysanthemum,
|
||||
Dahlia,
|
||||
Willow,
|
||||
BloomFlower,
|
||||
Ring,
|
||||
Crossette
|
||||
}
|
||||
}
|
||||
297
Scripts/SubSystem/VitaNex/Core/Items/Fireworks/Fireworks.cs
Normal file
297
Scripts/SubSystem/VitaNex/Core/Items/Fireworks/Fireworks.cs
Normal file
@@ -0,0 +1,297 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
|
||||
using VitaNex.FX;
|
||||
using VitaNex.Geometry;
|
||||
using VitaNex.Network;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public static class Fireworks
|
||||
{
|
||||
public static void DoStarsEffect(
|
||||
this FireworkStars fx,
|
||||
IPoint3D p,
|
||||
Map map,
|
||||
int radius,
|
||||
int sound,
|
||||
int[] stars,
|
||||
int[] hues)
|
||||
{
|
||||
if (fx == FireworkStars.None || stars == null || stars.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
radius = Math.Max(0, Math.Min(10, radius));
|
||||
|
||||
if (hues == null || hues.Length == 0)
|
||||
{
|
||||
hues = new int[9];
|
||||
|
||||
hues.SetAll(i => Utility.RandomBrightHue());
|
||||
}
|
||||
|
||||
switch (fx)
|
||||
{
|
||||
case FireworkStars.Peony:
|
||||
{
|
||||
var shape = new Sphere3D(p, radius, true);
|
||||
|
||||
foreach (var b in shape)
|
||||
{
|
||||
new MovingEffectInfo(
|
||||
p,
|
||||
b,
|
||||
map,
|
||||
stars.GetRandom(),
|
||||
hues.GetRandom(),
|
||||
Utility.RandomMinMax(4, 6),
|
||||
EffectRender.LightenMore).MovingImpact(
|
||||
e =>
|
||||
{
|
||||
if (sound > 0 && Utility.RandomDouble() <= 0.25)
|
||||
{
|
||||
Effects.PlaySound(b, map, sound);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
shape.Clear();
|
||||
}
|
||||
break;
|
||||
case FireworkStars.Chrysanthemum:
|
||||
{
|
||||
var shape = new Disc3D(p, radius, false);
|
||||
|
||||
foreach (var b in shape)
|
||||
{
|
||||
new MovingEffectInfo(
|
||||
p,
|
||||
b,
|
||||
map,
|
||||
stars.GetRandom(),
|
||||
hues.GetRandom(),
|
||||
Utility.RandomMinMax(4, 6),
|
||||
EffectRender.LightenMore).MovingImpact(
|
||||
e =>
|
||||
{
|
||||
if (sound > 0 && Utility.RandomDouble() <= 0.25)
|
||||
{
|
||||
Effects.PlaySound(b, map, sound);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
shape.Clear();
|
||||
}
|
||||
break;
|
||||
case FireworkStars.Dahlia:
|
||||
{
|
||||
var shape = new Cylinder3D(p, radius, true, false);
|
||||
|
||||
foreach (var b in shape)
|
||||
{
|
||||
new MovingEffectInfo(
|
||||
p,
|
||||
b,
|
||||
map,
|
||||
stars.GetRandom(),
|
||||
hues.GetRandom(),
|
||||
Utility.RandomMinMax(6, 8),
|
||||
EffectRender.LightenMore).MovingImpact(
|
||||
e =>
|
||||
{
|
||||
if (sound > 0 && Utility.RandomDouble() <= 0.25)
|
||||
{
|
||||
Effects.PlaySound(b, map, sound);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
shape.Clear();
|
||||
}
|
||||
break;
|
||||
case FireworkStars.Willow:
|
||||
{
|
||||
var shape = new Disc3D(p, radius, true);
|
||||
|
||||
foreach (var b in shape)
|
||||
{
|
||||
new MovingEffectInfo(
|
||||
p,
|
||||
b,
|
||||
map,
|
||||
stars.GetRandom(),
|
||||
hues.GetRandom(),
|
||||
Utility.RandomMinMax(6, 8),
|
||||
EffectRender.LightenMore).MovingImpact(
|
||||
e =>
|
||||
{
|
||||
if (Utility.RandomDouble() < 0.66)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var zL = b.Z;
|
||||
var zR = b.GetWorldTop(map).Z;
|
||||
|
||||
if (zL <= zR || zL < p.Z)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var zDiff = zL - zR;
|
||||
|
||||
if (zDiff < 30)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var t = b.Clone3D(0, 0, -(zDiff / 2));
|
||||
|
||||
new MovingEffectInfo(b, t, map, e.EffectID, e.Hue, Math.Max(1, e.Speed / 2), e.Render).Send();
|
||||
|
||||
if (sound > 0 && Utility.RandomDouble() <= 0.25)
|
||||
{
|
||||
Effects.PlaySound(b, map, sound);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
shape.Clear();
|
||||
}
|
||||
break;
|
||||
case FireworkStars.BloomFlower:
|
||||
{
|
||||
var shape = new Ring3D(p, radius);
|
||||
|
||||
foreach (var b in shape)
|
||||
{
|
||||
new MovingEffectInfo(
|
||||
p,
|
||||
b,
|
||||
map,
|
||||
stars.GetRandom(),
|
||||
hues.GetRandom(),
|
||||
Utility.RandomMinMax(6, 8),
|
||||
EffectRender.LightenMore).MovingImpact(
|
||||
e =>
|
||||
{
|
||||
if (Utility.RandomDouble() < 0.66)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var t = b.Clone3D(Utility.RandomMinMax(-3, 3), Utility.RandomMinMax(-3, 3), Utility.RandomMinMax(-10, 10));
|
||||
|
||||
new MovingEffectInfo(b, t, map, e.EffectID, e.Hue, e.Speed, e.Render).Send();
|
||||
|
||||
if (sound > 0 && Utility.RandomDouble() <= 0.25)
|
||||
{
|
||||
Effects.PlaySound(b, map, sound);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
shape.Clear();
|
||||
}
|
||||
break;
|
||||
case FireworkStars.Ring:
|
||||
{
|
||||
var shape = new Ring3D(p, radius);
|
||||
|
||||
foreach (var b in shape)
|
||||
{
|
||||
new MovingEffectInfo(
|
||||
p,
|
||||
b,
|
||||
map,
|
||||
stars.GetRandom(),
|
||||
hues.GetRandom(),
|
||||
Utility.RandomMinMax(6, 8),
|
||||
EffectRender.LightenMore).MovingImpact(
|
||||
e =>
|
||||
{
|
||||
var zL = b.Z;
|
||||
var zR = b.GetWorldTop(map).Z;
|
||||
|
||||
if (zL <= zR || zL < p.Z)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var zDiff = zL - zR;
|
||||
|
||||
if (zDiff < 30)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var t = b.Clone3D(0, 0, -(zDiff / 2));
|
||||
|
||||
new MovingEffectInfo(b, t, map, e.EffectID, e.Hue, 2, e.Render).Send();
|
||||
|
||||
if (sound > 0 && Utility.RandomDouble() <= 0.25)
|
||||
{
|
||||
Effects.PlaySound(b, map, sound);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
shape.Clear();
|
||||
}
|
||||
break;
|
||||
case FireworkStars.Crossette:
|
||||
{
|
||||
var shape = new Plane3D(p, radius, true);
|
||||
|
||||
foreach (var b in shape)
|
||||
{
|
||||
new MovingEffectInfo(
|
||||
p,
|
||||
b,
|
||||
map,
|
||||
stars.GetRandom(),
|
||||
hues.GetRandom(),
|
||||
Utility.RandomMinMax(6, 8),
|
||||
EffectRender.LightenMore).MovingImpact(
|
||||
e =>
|
||||
{
|
||||
if (Utility.RandomDouble() < 0.33)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var t = b.Clone3D(Utility.RandomMinMax(-5, 5), Utility.RandomMinMax(-5, 5));
|
||||
|
||||
new MovingEffectInfo(b, t, map, e.EffectID, e.Hue, e.Speed, e.Render).Send();
|
||||
|
||||
if (sound > 0 && Utility.RandomDouble() <= 0.25)
|
||||
{
|
||||
Effects.PlaySound(b, map, sound);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
shape.Clear();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,493 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
using Server.Engines.Craft;
|
||||
using Server.Items;
|
||||
|
||||
using VitaNex.FX;
|
||||
using VitaNex.Network;
|
||||
using VitaNex.SuperCrafts;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public abstract class BaseFireworkRocket : BaseFirework
|
||||
{
|
||||
#region Launch Effect
|
||||
public virtual int DefLaunchID => ItemID;
|
||||
public virtual int DefLaunchHue => Hue;
|
||||
public virtual int DefLaunchSpeed => 8;
|
||||
public virtual EffectRender DefLaunchRender => EffectRender.Normal;
|
||||
public virtual int DefLaunchSound => 551;
|
||||
public virtual int DefLaunchRangeMin => 1;
|
||||
public virtual int DefLaunchRangeMax => 3;
|
||||
public virtual int DefLaunchHeightMin => 60;
|
||||
public virtual int DefLaunchHeightMax => 80;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int LaunchID { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int LaunchHue { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int LaunchSpeed { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public EffectRender LaunchRender { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int LaunchSound { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int LaunchHeightMin { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int LaunchHeightMax { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int LaunchRangeMin { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int LaunchRangeMax { get; set; }
|
||||
#endregion
|
||||
|
||||
#region Trail Effect
|
||||
public virtual int DefTrailID => 14120;
|
||||
public virtual int DefTrailHue => 0;
|
||||
public virtual int DefTrailSpeed => 10;
|
||||
public virtual int DefTrailDuration => 10;
|
||||
public virtual EffectRender DefTrailRender => EffectRender.SemiTransparent;
|
||||
public virtual int DefTrailSound => 856;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int TrailID { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int TrailHue { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int TrailSpeed { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int TrailDuration { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public EffectRender TrailRender { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int TrailSound { get; set; }
|
||||
#endregion
|
||||
|
||||
#region Explode Effect
|
||||
public virtual int DefExplodeID => 14000;
|
||||
public virtual int DefExplodeHue => 0;
|
||||
public virtual int DefExplodeSpeed => 10;
|
||||
public virtual int DefExplodeDuration => 13;
|
||||
public virtual EffectRender DefExplodeRender => EffectRender.LightenMore;
|
||||
public virtual int DefExplodeSound => 776;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ExplodeID { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ExplodeHue { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ExplodeSpeed { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ExplodeDuration { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public EffectRender ExplodeRender { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ExplodeSound { get; set; }
|
||||
#endregion
|
||||
|
||||
#region Stars Effect
|
||||
public virtual FireworkStars DefStarsEffect => FireworkStars.Peony;
|
||||
public virtual int DefStarsHue => 0;
|
||||
public virtual int DefStarsSound => 776;
|
||||
public virtual int DefStarsRangeMin => 5;
|
||||
public virtual int DefStarsRangeMax => 10;
|
||||
|
||||
public virtual int[] DefStars => new[] { 14170, 14155, 14138, 10980, 10296, 10297, 10298, 10299, 10300, 10301 };
|
||||
|
||||
public virtual int[] DefStarHues => new int[0];
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public FireworkStars StarsEffect { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int StarsHue { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int StarsSound { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int StarsRangeMin { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int StarsRangeMax { get; set; }
|
||||
|
||||
public List<int> Stars { get; set; }
|
||||
public List<int> StarHues { get; set; }
|
||||
#endregion
|
||||
|
||||
public BaseFireworkRocket(int itemID, int hue)
|
||||
: base(itemID, hue)
|
||||
{
|
||||
LaunchID = DefLaunchID;
|
||||
LaunchHue = DefLaunchHue;
|
||||
LaunchSpeed = DefLaunchSpeed;
|
||||
LaunchRender = DefLaunchRender;
|
||||
LaunchSound = DefLaunchSound;
|
||||
LaunchHeightMin = DefLaunchHeightMin;
|
||||
LaunchHeightMax = DefLaunchHeightMax;
|
||||
LaunchRangeMin = DefLaunchRangeMin;
|
||||
LaunchRangeMax = DefLaunchRangeMax;
|
||||
|
||||
TrailID = DefTrailID;
|
||||
TrailHue = DefTrailHue;
|
||||
TrailSpeed = DefTrailSpeed;
|
||||
TrailDuration = DefTrailDuration;
|
||||
TrailRender = DefTrailRender;
|
||||
TrailSound = DefTrailSound;
|
||||
|
||||
ExplodeID = DefExplodeID;
|
||||
ExplodeHue = DefExplodeHue;
|
||||
ExplodeSpeed = DefExplodeSpeed;
|
||||
ExplodeDuration = DefExplodeDuration;
|
||||
ExplodeRender = DefExplodeRender;
|
||||
ExplodeSound = DefExplodeSound;
|
||||
|
||||
StarsEffect = DefStarsEffect;
|
||||
StarsHue = DefStarsHue;
|
||||
StarsSound = DefStarsSound;
|
||||
StarsRangeMin = DefStarsRangeMin;
|
||||
StarsRangeMax = DefStarsRangeMax;
|
||||
Stars = new List<int>(DefStars);
|
||||
StarHues = new List<int>(DefStarHues);
|
||||
}
|
||||
|
||||
public BaseFireworkRocket(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
protected virtual Point3D[] GetPath()
|
||||
{
|
||||
var start = GetWorldLocation();
|
||||
var end = start.GetRandomPoint2D(Utility.RandomMinMax(LaunchRangeMin, LaunchRangeMax));
|
||||
|
||||
return start.GetLine3D(end.ToPoint3D(Utility.RandomMinMax(LaunchHeightMin, LaunchHeightMax)), Map, false);
|
||||
}
|
||||
|
||||
protected override bool OnFuseBurned(Mobile m)
|
||||
{
|
||||
return Launch(m);
|
||||
}
|
||||
|
||||
protected bool Launch(Mobile m)
|
||||
{
|
||||
if (m == null || m.Deleted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var path = GetPath();
|
||||
|
||||
if (path == null || path.Length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var start = path.First();
|
||||
var end = path.Last();
|
||||
|
||||
if (!OnLaunch(m, start, end))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var q = new MovingEffectQueue(() => Explode(m, end));
|
||||
|
||||
for (var i = 0; i < path.Length; i++)
|
||||
{
|
||||
var p = path[i];
|
||||
|
||||
if (i + 1 >= path.Length)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var pn = path[i + 1];
|
||||
|
||||
q.Add(
|
||||
new MovingEffectInfo(
|
||||
p,
|
||||
pn,
|
||||
Map,
|
||||
LaunchID,
|
||||
LaunchHue,
|
||||
LaunchSpeed,
|
||||
LaunchRender,
|
||||
TimeSpan.Zero,
|
||||
() => LaunchTrail(pn)));
|
||||
}
|
||||
|
||||
q.Process();
|
||||
|
||||
if (LaunchSound > 0)
|
||||
{
|
||||
Effects.PlaySound(GetWorldLocation(), Map, LaunchSound);
|
||||
}
|
||||
|
||||
Visible = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected virtual bool OnLaunch(Mobile m, Point3D start, Point3D end)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void LaunchTrail(Point3D p)
|
||||
{
|
||||
if (TrailID > 0)
|
||||
{
|
||||
var fx = new EffectInfo(p, Map, TrailID, TrailHue, TrailSpeed, TrailDuration, TrailRender);
|
||||
|
||||
fx.Send();
|
||||
}
|
||||
|
||||
if (TrailSound > 0)
|
||||
{
|
||||
Effects.PlaySound(p, Map, TrailSound);
|
||||
}
|
||||
}
|
||||
|
||||
protected void Explode(Mobile m, Point3D p)
|
||||
{
|
||||
if (m == null || m.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!OnExplode(m, p))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExplodeID > 0)
|
||||
{
|
||||
var fx = new EffectInfo(p, Map, ExplodeID, ExplodeHue, ExplodeSpeed, ExplodeDuration, ExplodeRender);
|
||||
|
||||
fx.Send();
|
||||
}
|
||||
|
||||
if (ExplodeSound >= 0)
|
||||
{
|
||||
Effects.PlaySound(p, Map, ExplodeSound);
|
||||
}
|
||||
|
||||
ExplodeStars(
|
||||
m,
|
||||
StarsEffect,
|
||||
p,
|
||||
Utility.RandomMinMax(StarsRangeMin, StarsRangeMax),
|
||||
StarsSound,
|
||||
Stars.ToArray(),
|
||||
StarsHue > 0 ? new[] { StarsHue } : StarHues.ToArray());
|
||||
|
||||
Movable = false;
|
||||
|
||||
Timer.DelayCall(
|
||||
TimeSpan.FromSeconds(1.0),
|
||||
() =>
|
||||
{
|
||||
Movable = true;
|
||||
Consume();
|
||||
});
|
||||
}
|
||||
|
||||
protected virtual bool OnExplode(Mobile m, Point3D p)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected virtual void ExplodeStars(
|
||||
Mobile m,
|
||||
FireworkStars fx,
|
||||
Point3D p,
|
||||
int radius,
|
||||
int sound,
|
||||
int[] stars,
|
||||
int[] hues)
|
||||
{
|
||||
if (m != null && !m.Deleted && fx != FireworkStars.None && stars != null && stars.Length != 0 && !Deleted)
|
||||
{
|
||||
fx.DoStarsEffect(p, Map, radius, sound, stars, hues);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
base.OnDelete();
|
||||
|
||||
Stars.Clear();
|
||||
Stars.TrimExcess();
|
||||
|
||||
StarHues.Clear();
|
||||
StarHues.TrimExcess();
|
||||
}
|
||||
|
||||
public override int OnCraft(
|
||||
int quality,
|
||||
bool makersMark,
|
||||
Mobile m,
|
||||
CraftSystem craftSystem,
|
||||
Type typeRes,
|
||||
#if ServUO
|
||||
ITool tool,
|
||||
#else
|
||||
BaseTool tool,
|
||||
#endif
|
||||
CraftItem craftItem,
|
||||
int resHue)
|
||||
{
|
||||
if (craftSystem is Pyrotechnics && craftItem != null)
|
||||
{
|
||||
var stars = new CraftRes[craftItem.Resources.Count];
|
||||
|
||||
stars.SetAll(i => craftItem.Resources.GetAt(i));
|
||||
stars = stars.Where(res => res.ItemType.IsEqualOrChildOf<BaseFireworkStar>()).ToArray();
|
||||
|
||||
if (stars.Length > 0)
|
||||
{
|
||||
StarsRangeMin = 1 + stars.Sum(s => s.Amount);
|
||||
StarsRangeMax = StarsRangeMin * 2;
|
||||
|
||||
LaunchHeightMin = Math.Max(50, Math.Min(100, StarsRangeMin * 5));
|
||||
LaunchHeightMax = Math.Max(50, Math.Min(100, StarsRangeMax * 5));
|
||||
|
||||
StarHues.AddRange(BaseFireworkStar.GetEffectHues(typeRes ?? stars[0].ItemType));
|
||||
|
||||
if (stars.Length > 1)
|
||||
{
|
||||
StarHues.AddRange(stars.Skip(1).SelectMany(s => BaseFireworkStar.GetEffectHues(s.ItemType)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return base.OnCraft(quality, makersMark, m, craftSystem, typeRes, tool, craftItem, resHue);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
writer.Write(LaunchID);
|
||||
writer.Write(LaunchHue);
|
||||
writer.Write(LaunchSpeed);
|
||||
writer.WriteFlag(LaunchRender);
|
||||
writer.Write(LaunchSound);
|
||||
writer.Write(LaunchRangeMin);
|
||||
writer.Write(LaunchRangeMax);
|
||||
writer.Write(LaunchHeightMin);
|
||||
writer.Write(LaunchHeightMax);
|
||||
|
||||
writer.Write(TrailID);
|
||||
writer.Write(TrailHue);
|
||||
writer.Write(TrailSpeed);
|
||||
writer.Write(TrailDuration);
|
||||
writer.WriteFlag(TrailRender);
|
||||
writer.Write(TrailSound);
|
||||
|
||||
writer.Write(ExplodeID);
|
||||
writer.Write(ExplodeHue);
|
||||
writer.Write(ExplodeSpeed);
|
||||
writer.Write(ExplodeDuration);
|
||||
writer.WriteFlag(ExplodeRender);
|
||||
writer.Write(ExplodeSound);
|
||||
|
||||
writer.WriteFlag(StarsEffect);
|
||||
writer.Write(StarsHue);
|
||||
writer.Write(StarsSound);
|
||||
writer.Write(StarsRangeMin);
|
||||
writer.Write(StarsRangeMax);
|
||||
writer.WriteList(Stars, writer.Write);
|
||||
writer.WriteList(StarHues, writer.Write);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
LaunchID = reader.ReadInt();
|
||||
LaunchHue = reader.ReadInt();
|
||||
LaunchSpeed = reader.ReadInt();
|
||||
LaunchRender = reader.ReadFlag<EffectRender>();
|
||||
LaunchSound = reader.ReadInt();
|
||||
LaunchRangeMin = reader.ReadInt();
|
||||
LaunchRangeMax = reader.ReadInt();
|
||||
LaunchHeightMin = reader.ReadInt();
|
||||
LaunchHeightMax = reader.ReadInt();
|
||||
|
||||
TrailID = reader.ReadInt();
|
||||
TrailHue = reader.ReadInt();
|
||||
TrailSpeed = reader.ReadInt();
|
||||
TrailDuration = reader.ReadInt();
|
||||
TrailRender = reader.ReadFlag<EffectRender>();
|
||||
TrailSound = reader.ReadInt();
|
||||
|
||||
ExplodeID = reader.ReadInt();
|
||||
ExplodeHue = reader.ReadInt();
|
||||
ExplodeSpeed = reader.ReadInt();
|
||||
ExplodeDuration = reader.ReadInt();
|
||||
ExplodeRender = reader.ReadFlag<EffectRender>();
|
||||
ExplodeSound = reader.ReadInt();
|
||||
|
||||
StarsEffect = reader.ReadFlag<FireworkStars>();
|
||||
StarsHue = reader.ReadInt();
|
||||
StarsSound = reader.ReadInt();
|
||||
StarsRangeMin = reader.ReadInt();
|
||||
StarsRangeMax = reader.ReadInt();
|
||||
Stars = reader.ReadList(reader.ReadInt);
|
||||
StarHues = reader.ReadList(reader.ReadInt);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class BigBettyRocket : BaseFireworkRocket
|
||||
{
|
||||
public override FireworkStars DefStarsEffect => FireworkStars.Willow;
|
||||
|
||||
[Constructable]
|
||||
public BigBettyRocket()
|
||||
: this(Utility.RandomMetalHue())
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public BigBettyRocket(int hue)
|
||||
: base(2887, hue)
|
||||
{
|
||||
Name = "Big Betty";
|
||||
Weight = 6.0;
|
||||
}
|
||||
|
||||
public BigBettyRocket(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class BlockBusterRocket : BaseFireworkRocket
|
||||
{
|
||||
public override FireworkStars DefStarsEffect => FireworkStars.BloomFlower;
|
||||
|
||||
[Constructable]
|
||||
public BlockBusterRocket()
|
||||
: this(Utility.RandomMetalHue())
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public BlockBusterRocket(int hue)
|
||||
: base(9242, hue)
|
||||
{
|
||||
Name = "Block Buster";
|
||||
Weight = 8.0;
|
||||
}
|
||||
|
||||
public BlockBusterRocket(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class BottleRocket : BaseFireworkRocket
|
||||
{
|
||||
public override FireworkStars DefStarsEffect => FireworkStars.Peony;
|
||||
|
||||
[Constructable]
|
||||
public BottleRocket()
|
||||
: this(Utility.RandomMetalHue())
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public BottleRocket(int hue)
|
||||
: base(6189, hue)
|
||||
{
|
||||
Name = "Bottle Rocket";
|
||||
Weight = 2.0;
|
||||
}
|
||||
|
||||
public BottleRocket(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class LittleBoyRocket : BaseFireworkRocket
|
||||
{
|
||||
public override FireworkStars DefStarsEffect => FireworkStars.Dahlia;
|
||||
|
||||
[Constructable]
|
||||
public LittleBoyRocket()
|
||||
: this(Utility.RandomMetalHue())
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public LittleBoyRocket(int hue)
|
||||
: base(2581, hue)
|
||||
{
|
||||
Name = "Little Boy";
|
||||
Weight = 2.0;
|
||||
}
|
||||
|
||||
public LittleBoyRocket(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class MoonShineRocket : BaseFireworkRocket
|
||||
{
|
||||
public override FireworkStars DefStarsEffect => FireworkStars.Ring;
|
||||
|
||||
[Constructable]
|
||||
public MoonShineRocket()
|
||||
: this(Utility.RandomMetalHue())
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public MoonShineRocket(int hue)
|
||||
: base(18881, hue)
|
||||
{
|
||||
Name = "Moon Shine";
|
||||
Weight = 4.0;
|
||||
}
|
||||
|
||||
public MoonShineRocket(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class PenetratorRocket : BaseFireworkRocket
|
||||
{
|
||||
public override FireworkStars DefStarsEffect => FireworkStars.Chrysanthemum;
|
||||
|
||||
[Constructable]
|
||||
public PenetratorRocket()
|
||||
: this(Utility.RandomMetalHue())
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public PenetratorRocket(int hue)
|
||||
: base(6202, hue)
|
||||
{
|
||||
Name = "The Penetrator";
|
||||
Weight = 4.0;
|
||||
}
|
||||
|
||||
public PenetratorRocket(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class SkyShieldRocket : BaseFireworkRocket
|
||||
{
|
||||
public override FireworkStars DefStarsEffect => FireworkStars.Crossette;
|
||||
|
||||
[Constructable]
|
||||
public SkyShieldRocket()
|
||||
: this(Utility.RandomMetalHue())
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public SkyShieldRocket(int hue)
|
||||
: base(576, hue)
|
||||
{
|
||||
Name = "Sky Shield";
|
||||
Weight = 3.0;
|
||||
}
|
||||
|
||||
public SkyShieldRocket(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
199
Scripts/SubSystem/VitaNex/Core/Items/Food/Magical/MagicalFood.cs
Normal file
199
Scripts/SubSystem/VitaNex/Core/Items/Food/Magical/MagicalFood.cs
Normal file
@@ -0,0 +1,199 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public interface IMagicFoodMod
|
||||
{ }
|
||||
|
||||
public interface IMagicFood
|
||||
{
|
||||
TimeSpan BuffDuration { get; set; }
|
||||
int IconID { get; set; }
|
||||
int EffectID { get; set; }
|
||||
int SoundID { get; set; }
|
||||
|
||||
bool Eat(Mobile m);
|
||||
bool ApplyBuff(Mobile m);
|
||||
bool RemoveBuff(Mobile m);
|
||||
}
|
||||
|
||||
public abstract class MagicFood : Food, IMagicFood
|
||||
{
|
||||
private Timer DelayTimer { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual TimeSpan BuffDuration { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual int IconID { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual int EffectID { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual int SoundID { get; set; }
|
||||
|
||||
public MagicFood(int itemID)
|
||||
: this(itemID, 1)
|
||||
{ }
|
||||
|
||||
public MagicFood(int itemID, int amount)
|
||||
: base(amount, itemID)
|
||||
{
|
||||
BuffDuration = TimeSpan.FromSeconds(300.0);
|
||||
}
|
||||
|
||||
public MagicFood(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override sealed bool Eat(Mobile m)
|
||||
{
|
||||
if (m == null || m.Deleted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (CheckHunger(m))
|
||||
{
|
||||
m.PlaySound(Utility.Random(0x3A, 3));
|
||||
|
||||
if (m.Body.IsHuman && !m.Mounted)
|
||||
{
|
||||
m.Animate(34, 5, 1, true, false, 0);
|
||||
}
|
||||
|
||||
if (Poison != null)
|
||||
{
|
||||
m.ApplyPoison(Poisoner, Poison);
|
||||
}
|
||||
|
||||
OnEaten(m);
|
||||
Consume();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public abstract bool ApplyBuff(Mobile m);
|
||||
public abstract bool RemoveBuff(Mobile m);
|
||||
|
||||
public override bool CheckHunger(Mobile m)
|
||||
{
|
||||
return FillFactor <= 0 || FillHunger(m, FillFactor);
|
||||
}
|
||||
|
||||
protected virtual void OnEaten(Mobile m)
|
||||
{
|
||||
if (m != null && !m.Deleted)
|
||||
{
|
||||
DoApplyBuff(m);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void DoApplyBuff(Mobile m)
|
||||
{
|
||||
if (m == null || m.Deleted || !ApplyBuff(m))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (SoundID > 0)
|
||||
{
|
||||
m.PlaySound(SoundID);
|
||||
}
|
||||
|
||||
if (EffectID > 0)
|
||||
{
|
||||
m.FixedParticles(EffectID, 10, 15, 5018, EffectLayer.Waist);
|
||||
}
|
||||
|
||||
if (IconID > 0)
|
||||
{
|
||||
m.Send(new AddBuffPacket(m, new BuffInfo((BuffIcon)IconID, LabelNumber)));
|
||||
}
|
||||
|
||||
if (DelayTimer != null && DelayTimer.Running)
|
||||
{
|
||||
DelayTimer.Stop();
|
||||
}
|
||||
|
||||
DelayTimer = Timer.DelayCall(BuffDuration, DoRemoveBuff, m);
|
||||
}
|
||||
|
||||
protected virtual void DoRemoveBuff(Mobile m)
|
||||
{
|
||||
if (m == null || m.Deleted || !RemoveBuff(m))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (IconID > 0)
|
||||
{
|
||||
m.Send(new RemoveBuffPacket(m, (BuffIcon)IconID));
|
||||
}
|
||||
|
||||
if (DelayTimer != null && DelayTimer.Running)
|
||||
{
|
||||
DelayTimer.Stop();
|
||||
}
|
||||
|
||||
DelayTimer = null;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
writer.Write(BuffDuration);
|
||||
writer.Write(IconID);
|
||||
writer.Write(EffectID);
|
||||
writer.Write(SoundID);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
BuffDuration = reader.ReadTimeSpan();
|
||||
IconID = reader.ReadInt();
|
||||
EffectID = reader.ReadInt();
|
||||
SoundID = reader.ReadInt();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
431
Scripts/SubSystem/VitaNex/Core/Items/Misc/GhostMulti.cs
Normal file
431
Scripts/SubSystem/VitaNex/Core/Items/Misc/GhostMulti.cs
Normal file
@@ -0,0 +1,431 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Server;
|
||||
using Server.Network;
|
||||
|
||||
using VitaNex.FX;
|
||||
using VitaNex.Network;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class GhostMulti : Item
|
||||
{
|
||||
private PollTimer _Timer;
|
||||
private Point3D _Center;
|
||||
private List<EffectInfo> _Effects;
|
||||
|
||||
private int _MultiID;
|
||||
private EffectRender _Render;
|
||||
private TimeSpan _Interval;
|
||||
private int _Duration;
|
||||
private int _Speed;
|
||||
|
||||
[Hue, CommandProperty(AccessLevel.GameMaster)]
|
||||
public override int Hue
|
||||
{
|
||||
get => base.Hue;
|
||||
set
|
||||
{
|
||||
value = Math.Max(0, Math.Min(3000, value));
|
||||
|
||||
base.Hue = value;
|
||||
|
||||
if (_Effects == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var e in _Effects)
|
||||
{
|
||||
e.Hue = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int MultiID
|
||||
{
|
||||
get => _MultiID;
|
||||
set
|
||||
{
|
||||
if (_MultiID == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_MultiID = value;
|
||||
|
||||
Stop();
|
||||
Start();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public EffectRender Render
|
||||
{
|
||||
get => _Render;
|
||||
set
|
||||
{
|
||||
_Render = value;
|
||||
|
||||
if (_Effects == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var e in _Effects)
|
||||
{
|
||||
e.Render = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TimeSpan Interval
|
||||
{
|
||||
get => _Interval;
|
||||
set
|
||||
{
|
||||
_Interval = value;
|
||||
|
||||
if (_Timer != null)
|
||||
{
|
||||
_Timer.Interval = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Duration
|
||||
{
|
||||
get => _Duration;
|
||||
set
|
||||
{
|
||||
_Duration = value;
|
||||
|
||||
if (_Effects == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var e in _Effects)
|
||||
{
|
||||
e.Duration = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Speed
|
||||
{
|
||||
get => _Speed;
|
||||
set
|
||||
{
|
||||
_Speed = value;
|
||||
|
||||
if (_Effects == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var e in _Effects)
|
||||
{
|
||||
e.Speed = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool Active { get; set; }
|
||||
|
||||
public override bool Decays => false;
|
||||
public override bool IsVirtualItem => true;
|
||||
public override bool HandlesOnMovement => true;
|
||||
|
||||
public virtual bool PlayerRangeSensitive => true;
|
||||
public virtual TimeSpan ActivityInterval => TimeSpan.FromSeconds(30.0);
|
||||
|
||||
private PollTimer _ActivityTimer;
|
||||
private DateTime _LastActivity;
|
||||
|
||||
[Constructable]
|
||||
public GhostMulti()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public GhostMulti(int multiID)
|
||||
: this(14284, multiID)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public GhostMulti(int itemID, int multiID)
|
||||
: base(itemID)
|
||||
{
|
||||
_MultiID = multiID;
|
||||
_Interval = TimeSpan.FromSeconds(3.55);
|
||||
_Render = EffectRender.Normal;
|
||||
_Duration = 73;
|
||||
_Speed = 10;
|
||||
|
||||
Name = "Ghostly Structure";
|
||||
Light = LightType.DarkCircle300;
|
||||
Weight = 0;
|
||||
Visible = false;
|
||||
Active = true;
|
||||
}
|
||||
|
||||
public GhostMulti(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
base.OnDelete();
|
||||
|
||||
Stop();
|
||||
}
|
||||
|
||||
public override void OnLocationChange(Point3D oldLocation)
|
||||
{
|
||||
base.OnLocationChange(oldLocation);
|
||||
|
||||
Start();
|
||||
}
|
||||
|
||||
public override void OnMapChange()
|
||||
{
|
||||
base.OnMapChange();
|
||||
|
||||
Start();
|
||||
}
|
||||
|
||||
public override void OnMovement(Mobile m, Point3D oldLocation)
|
||||
{
|
||||
base.OnMovement(m, oldLocation);
|
||||
|
||||
if (m == null || m.Deleted || !m.Player || m.NetState == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_LastActivity = DateTime.UtcNow;
|
||||
|
||||
Start();
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
if (Deleted || !Active || Map == null || Map == Map.Internal || Parent != null)
|
||||
{
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_Effects == null || _Center != GetWorldLocation())
|
||||
{
|
||||
ClearEffects();
|
||||
|
||||
_Effects = new List<EffectInfo>(GetEffects());
|
||||
}
|
||||
|
||||
if (_Timer == null)
|
||||
{
|
||||
_Timer = PollTimer.CreateInstance(
|
||||
Interval,
|
||||
() =>
|
||||
{
|
||||
if (!Active)
|
||||
{
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
SendEffects();
|
||||
},
|
||||
() => !Deleted && Active && Map != null && Map != Map.Internal && Parent == null);
|
||||
}
|
||||
else
|
||||
{
|
||||
_Timer.Running = true;
|
||||
}
|
||||
|
||||
if (!PlayerRangeSensitive)
|
||||
{
|
||||
if (_ActivityTimer != null)
|
||||
{
|
||||
_ActivityTimer.Running = false;
|
||||
_ActivityTimer = null;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (_ActivityTimer != null)
|
||||
{
|
||||
_ActivityTimer.Running = true;
|
||||
return;
|
||||
}
|
||||
|
||||
_ActivityTimer = PollTimer.CreateInstance(
|
||||
ActivityInterval,
|
||||
() =>
|
||||
{
|
||||
if (DateTime.UtcNow - _LastActivity < ActivityInterval)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var clients = GetClientsInRange(Core.GlobalMaxUpdateRange);
|
||||
|
||||
if (clients.Any())
|
||||
{
|
||||
clients.Free();
|
||||
return;
|
||||
}
|
||||
|
||||
clients.Free();
|
||||
|
||||
Stop();
|
||||
},
|
||||
() => !Deleted && Map != null && Map != Map.Internal && Parent == null);
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
if (_ActivityTimer != null)
|
||||
{
|
||||
_ActivityTimer.Running = false;
|
||||
_ActivityTimer = null;
|
||||
}
|
||||
|
||||
ClearEffects();
|
||||
|
||||
if (_Timer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_Timer.Running = false;
|
||||
_Timer = null;
|
||||
}
|
||||
|
||||
protected EffectInfo[] GetEffects()
|
||||
{
|
||||
var l = GetWorldLocation();
|
||||
var c = MultiData.GetComponents(MultiID);
|
||||
|
||||
_Center = l.Clone3D(c.Center.X, c.Center.Y, l.Z);
|
||||
|
||||
var list = new EffectInfo[c.List.Length];
|
||||
|
||||
Parallel.For(
|
||||
0,
|
||||
list.Length,
|
||||
index =>
|
||||
{
|
||||
var t = c.List[index];
|
||||
var p = l.Clone3D(t.m_OffsetX, t.m_OffsetY, t.m_OffsetZ);
|
||||
|
||||
list[index] = new EffectInfo(p, Map, t.m_ItemID, Hue, Speed, Duration, Render);
|
||||
});
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
protected virtual void ClearEffects()
|
||||
{
|
||||
if (_Effects == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var e in _Effects)
|
||||
{
|
||||
e.Dispose();
|
||||
}
|
||||
|
||||
_Effects.Free(true);
|
||||
_Effects = null;
|
||||
}
|
||||
|
||||
protected virtual void SendEffects()
|
||||
{
|
||||
if (_Effects == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var e in _Effects)
|
||||
{
|
||||
e.Send();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(1);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
writer.Write(Active);
|
||||
goto case 0;
|
||||
case 0:
|
||||
{
|
||||
writer.Write(_MultiID);
|
||||
writer.Write(_Center);
|
||||
writer.WriteFlag(_Render);
|
||||
writer.Write(_Duration);
|
||||
writer.Write(_Speed);
|
||||
writer.Write(_Interval);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
Active = reader.ReadBool();
|
||||
goto case 0;
|
||||
case 0:
|
||||
{
|
||||
_MultiID = reader.ReadInt();
|
||||
_Center = reader.ReadPoint3D();
|
||||
_Render = reader.ReadFlag<EffectRender>();
|
||||
_Duration = reader.ReadInt();
|
||||
_Speed = reader.ReadInt();
|
||||
_Interval = reader.ReadTimeSpan();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server.Items;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class LuckyDipBankCheckPrize : LuckyDipPrize
|
||||
{
|
||||
public int Worth => Args[0] as int? ?? 0;
|
||||
|
||||
public LuckyDipBankCheckPrize()
|
||||
: this(0.0, 0)
|
||||
{ }
|
||||
|
||||
public LuckyDipBankCheckPrize(double chance, int worth)
|
||||
: base(chance, typeof(BankCheck), worth)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class LuckyDipPrize : IEquatable<LuckyDipPrize>
|
||||
{
|
||||
public double Chance { get; set; }
|
||||
public Type Type { get; set; }
|
||||
public object[] Args { get; set; }
|
||||
|
||||
public bool Disabled => Type == null || Chance <= 0.0;
|
||||
|
||||
public LuckyDipPrize()
|
||||
: this(0.0, null, null)
|
||||
{ }
|
||||
|
||||
public LuckyDipPrize(double chance, Type type, params object[] args)
|
||||
{
|
||||
Chance = Math.Min(0.0, Math.Max(1.0, chance));
|
||||
Type = type;
|
||||
Args = args ?? new object[0];
|
||||
}
|
||||
|
||||
public bool Equals(LuckyDipPrize other)
|
||||
{
|
||||
return Equals(Args, other.Args) && Chance.Equals(other.Chance) && Type == other.Type;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return !ReferenceEquals(null, obj) && (obj is LuckyDipPrize && Equals((LuckyDipPrize)obj));
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = (Args != null ? Args.GetHashCode() : 0);
|
||||
hashCode = (hashCode * 397) ^ Chance.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ (Type != null ? Type.GetHashCode() : 0);
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
public TItem CreateInstance<TItem>()
|
||||
where TItem : Item
|
||||
{
|
||||
return Type.CreateInstanceSafe<TItem>(Args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,314 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class LuckyDipTicket : Item
|
||||
{
|
||||
private static void Normalize(ref double chance)
|
||||
{
|
||||
chance = Math.Max(0.0, Math.Min(1.0, chance));
|
||||
}
|
||||
|
||||
private int _LuckCap = 3000;
|
||||
private int _PrizeTier;
|
||||
|
||||
public List<LuckyDipPrize> Prizes { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)]
|
||||
public int PrizeTier
|
||||
{
|
||||
get => _PrizeTier;
|
||||
set
|
||||
{
|
||||
value = Math.Max(1, value);
|
||||
|
||||
if (_PrizeTier == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_PrizeTier = value;
|
||||
InitPrizes();
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)]
|
||||
public int LuckCap
|
||||
{
|
||||
get => _LuckCap;
|
||||
set
|
||||
{
|
||||
value = Math.Max(0, value);
|
||||
|
||||
if (_LuckCap == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_LuckCap = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)]
|
||||
public virtual int GoldPrice => (int)Math.Ceiling(GetAveragePrizeWorth());
|
||||
|
||||
[Constructable]
|
||||
public LuckyDipTicket()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public LuckyDipTicket(int tierMin, int tierMax)
|
||||
: this(Utility.RandomMinMax(tierMin, tierMax))
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public LuckyDipTicket(int tier)
|
||||
: base(0x14F0)
|
||||
{
|
||||
PrizeTier = tier;
|
||||
|
||||
Name = "Lucky Dip Ticket";
|
||||
Weight = 1.0;
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public LuckyDipTicket(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public void InitPrizes()
|
||||
{
|
||||
if (Prizes == null)
|
||||
{
|
||||
Prizes = new List<LuckyDipPrize>();
|
||||
}
|
||||
|
||||
Prizes.Clear();
|
||||
InitBankChecks();
|
||||
InitItems();
|
||||
}
|
||||
|
||||
protected virtual void InitItems()
|
||||
{ }
|
||||
|
||||
protected virtual void InitBankChecks()
|
||||
{
|
||||
var f = (int)Math.Max(0, Math.Pow(10, PrizeTier));
|
||||
|
||||
AddPrize(new LuckyDipBankCheckPrize(0.80, 1 * f));
|
||||
AddPrize(new LuckyDipBankCheckPrize(0.40, 10 * f));
|
||||
AddPrize(new LuckyDipBankCheckPrize(0.20, 25 * f));
|
||||
AddPrize(new LuckyDipBankCheckPrize(0.10, 50 * f));
|
||||
AddPrize(new LuckyDipBankCheckPrize(0.05, 75 * f));
|
||||
AddPrize(new LuckyDipBankCheckPrize(0.02, 100 * f));
|
||||
}
|
||||
|
||||
public virtual int GetMinPrizeWorth()
|
||||
{
|
||||
return Prizes.OfType<LuckyDipBankCheckPrize>().Min(e => e.Worth);
|
||||
}
|
||||
|
||||
public virtual int GetMaxPrizeWorth()
|
||||
{
|
||||
return Prizes.OfType<LuckyDipBankCheckPrize>().Max(e => e.Worth);
|
||||
}
|
||||
|
||||
public virtual double GetAveragePrizeWorth()
|
||||
{
|
||||
return Prizes.OfType<LuckyDipBankCheckPrize>().Average(e => e.Worth);
|
||||
}
|
||||
|
||||
public double GetMinChance()
|
||||
{
|
||||
return Prizes.Min(e => e.Chance);
|
||||
}
|
||||
|
||||
public double GetMaxChance()
|
||||
{
|
||||
return Prizes.Max(e => e.Chance);
|
||||
}
|
||||
|
||||
public double GetAverageChance()
|
||||
{
|
||||
return Prizes.Average(e => e.Chance);
|
||||
}
|
||||
|
||||
public void AddPrize(LuckyDipPrize prize)
|
||||
{
|
||||
if (!Prizes.Contains(prize) && OnAddPrize(prize))
|
||||
{
|
||||
Prizes.Add(prize);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual bool OnAddPrize(LuckyDipPrize prize)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual IEnumerable<LuckyDipPrize> GetPrizes(double chance)
|
||||
{
|
||||
if (Prizes == null || Prizes.Count == 0)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
Normalize(ref chance);
|
||||
|
||||
foreach (var p in Prizes.Where(e => !e.Disabled && e.Chance >= chance).OrderByDescending(e => e.Chance))
|
||||
{
|
||||
yield return p;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual LuckyDipPrize GetPrize(double chance)
|
||||
{
|
||||
if (Prizes == null || Prizes.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Normalize(ref chance);
|
||||
|
||||
return GetPrizes(1.0 - chance).GetRandom();
|
||||
}
|
||||
|
||||
protected void BeginGamble(Mobile from)
|
||||
{
|
||||
if (from == null || from.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (from.BeginAction(GetType(), TimeSpan.FromSeconds(2.0), EndGamble))
|
||||
{
|
||||
from.SendMessage(85, "Please wait a moment while we process your ticket...");
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage(34, "You must wait a moment before using another ticket.");
|
||||
}
|
||||
}
|
||||
|
||||
protected void EndGamble(Mobile from, Type t)
|
||||
{
|
||||
if (from == null || from.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var a = Utility.RandomDouble() * 0.5;
|
||||
var b = (Math.Min(LuckCap, from.Luck) / (double)LuckCap) * 0.5;
|
||||
var c = a + b;
|
||||
|
||||
Normalize(ref c);
|
||||
|
||||
//Console.WriteLine("LDT: A = {0} B = {1} C = {2}", a, b, c);
|
||||
|
||||
var prizeEntry = GetPrize(c);
|
||||
|
||||
if (prizeEntry == null || prizeEntry.Disabled)
|
||||
{
|
||||
from.SendMessage(34, "Sorry {0}, you didn't win anything, better luck next time!", from.RawName);
|
||||
Delete();
|
||||
return;
|
||||
}
|
||||
|
||||
var prize = prizeEntry.CreateInstance<Item>();
|
||||
|
||||
if (prize == null)
|
||||
{
|
||||
Prizes.Remove(prizeEntry);
|
||||
|
||||
VitaNexCore.ToConsole(
|
||||
"WARNING: An instance of {0} could not be constructed in {1} at {2}",
|
||||
prizeEntry.Type.FullName,
|
||||
GetType().FullName,
|
||||
prizeEntry.GetType().FullName);
|
||||
|
||||
from.SendMessage(34, "We couldn't process your ticket, please try again.");
|
||||
return;
|
||||
}
|
||||
|
||||
from.SendMessage(85, "Congratulations, you won a prize! ({0})", prize.ResolveName(from));
|
||||
ReplaceWith(prize);
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (this.CheckDoubleClick(from, true, false, 2, true))
|
||||
{
|
||||
BeginGamble(from);
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
var props = String.Format("Use: A chance to win a Tier {0} prize!".WrapUOHtmlColor(Color.SkyBlue), PrizeTier);
|
||||
|
||||
if (LuckCap > 0)
|
||||
{
|
||||
props += "\n" + "Tip: Increase your luck to increase your odds!".WrapUOHtmlColor(Color.Gold);
|
||||
}
|
||||
|
||||
list.Add(props);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
writer.Write(LuckCap);
|
||||
writer.Write(PrizeTier);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
LuckCap = reader.ReadInt();
|
||||
PrizeTier = reader.ReadInt();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
153
Scripts/SubSystem/VitaNex/Core/Items/Misc/SeveredHead.cs
Normal file
153
Scripts/SubSystem/VitaNex/Core/Items/Misc/SeveredHead.cs
Normal file
@@ -0,0 +1,153 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
|
||||
using VitaNex.FX;
|
||||
using VitaNex.Network;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public delegate bool DecapitateHandler(Mobile from, Mobile target, Func<Mobile, Item> createHead = null);
|
||||
|
||||
public class SeveredHead : Item
|
||||
{
|
||||
public static DecapitateHandler Decapitate = HandleDecapitate;
|
||||
|
||||
public static bool HandleDecapitate(Mobile from, Mobile target, Func<Mobile, Item> createHead = null)
|
||||
{
|
||||
if (from == null || target == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var map = target.Map;
|
||||
|
||||
target.Freeze(TimeSpan.FromSeconds(1.0));
|
||||
|
||||
var range = Utility.RandomMinMax(5, 7);
|
||||
var zOffset = target.Mounted ? 20 : 10;
|
||||
|
||||
var src = target.Location.Clone3D(0, 0, zOffset);
|
||||
var points = src.GetAllPointsInRange(map, range, range);
|
||||
|
||||
Effects.PlaySound(target.Location, map, 0x19C);
|
||||
|
||||
target.Send(VNScreenLightFlash.Instance);
|
||||
|
||||
Timer.DelayCall(
|
||||
TimeSpan.FromMilliseconds(100),
|
||||
() =>
|
||||
{
|
||||
foreach (var trg in points)
|
||||
{
|
||||
var bloodID = Utility.RandomMinMax(4650, 4655);
|
||||
|
||||
new MovingEffectInfo(src, trg.Clone3D(0, 0, 2), from.Map, bloodID).MovingImpact(
|
||||
info =>
|
||||
{
|
||||
new Blood(bloodID).MoveToWorld(info.Target.Location, info.Map);
|
||||
Effects.PlaySound(info.Target, info.Map, 0x028);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
target.Damage(target.HitsMax, from);
|
||||
|
||||
Timer.DelayCall(
|
||||
TimeSpan.FromMilliseconds(100),
|
||||
() =>
|
||||
{
|
||||
var corpse = target.Corpse as Corpse;
|
||||
|
||||
if (corpse != null && !corpse.Deleted)
|
||||
{
|
||||
corpse.TurnToBones();
|
||||
}
|
||||
});
|
||||
|
||||
var head = createHead != null ? createHead(target) : null;
|
||||
|
||||
int headID;
|
||||
int headHue;
|
||||
|
||||
if (head != null)
|
||||
{
|
||||
headID = head.ItemID;
|
||||
headHue = head.Hue;
|
||||
}
|
||||
else
|
||||
{
|
||||
headID = 7393;
|
||||
headHue = target.SolidHueOverride >= 0 ? target.SolidHueOverride : target.Hue;
|
||||
}
|
||||
|
||||
new MovingEffectInfo(src, src.Clone3D(0, 0, 40), map, headID, headHue).MovingImpact(
|
||||
info => new MovingEffectInfo(
|
||||
info.Target,
|
||||
info.Source.Clone3D(Utility.RandomMinMax(-1, 1), Utility.RandomMinMax(-1, 1), 2),
|
||||
info.Map,
|
||||
headID,
|
||||
headHue).MovingImpact(
|
||||
hInfo =>
|
||||
{
|
||||
if (head != null && !head.Deleted)
|
||||
{
|
||||
head.MoveToWorld(hInfo.Target.Location, info.Map);
|
||||
}
|
||||
}));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string DefaultName => "a severed head";
|
||||
|
||||
[Constructable]
|
||||
public SeveredHead()
|
||||
: this(String.Empty)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public SeveredHead(Mobile m)
|
||||
: this(m == null || String.IsNullOrWhiteSpace(m.RawName) ? String.Empty : "the severed head of " + m.RawName)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public SeveredHead(string name)
|
||||
: base(7393)
|
||||
{
|
||||
Name = !String.IsNullOrWhiteSpace(name) ? name : DefaultName;
|
||||
}
|
||||
|
||||
public SeveredHead(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
273
Scripts/SubSystem/VitaNex/Core/Items/Misc/StrobeLantern.cs
Normal file
273
Scripts/SubSystem/VitaNex/Core/Items/Misc/StrobeLantern.cs
Normal file
@@ -0,0 +1,273 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class StrobeLantern : Lantern
|
||||
{
|
||||
private static readonly short[] _Hues = { 11, 22, 33, 44, 55, 66, 77, 88, 99 };
|
||||
private static readonly LightType[] _Lights = { LightType.Circle150, LightType.Circle225, LightType.Circle300 };
|
||||
|
||||
public static List<StrobeLantern> Instances { get; private set; }
|
||||
|
||||
private static readonly PollTimer _Timer;
|
||||
|
||||
static StrobeLantern()
|
||||
{
|
||||
Instances = new List<StrobeLantern>();
|
||||
|
||||
_Timer = PollTimer.FromSeconds(1.0, CheckStrobe, Instances.Any);
|
||||
}
|
||||
|
||||
private static void CheckStrobe()
|
||||
{
|
||||
Instances.ForEachReverse(o => o.Strobe());
|
||||
}
|
||||
|
||||
private long _NextUpdate;
|
||||
private int _StrobeIndex;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool StrobeReverse { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TimeSpan StrobeInterval { get; set; }
|
||||
|
||||
[Hue, CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)]
|
||||
public override int Hue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (CanStrobe() && Hues.InBounds(_StrobeIndex))
|
||||
{
|
||||
return Hues[_StrobeIndex];
|
||||
}
|
||||
|
||||
return base.Hue;
|
||||
}
|
||||
set => base.Hue = value;
|
||||
}
|
||||
|
||||
public virtual short[] Hues => _Hues;
|
||||
public virtual LightType[] Lights => _Lights;
|
||||
|
||||
public virtual LightType DefaultLight => LightType.DarkCircle300;
|
||||
public virtual TimeSpan DefaultStrobeInterval => TimeSpan.FromSeconds(0.5);
|
||||
|
||||
[Constructable]
|
||||
public StrobeLantern()
|
||||
{
|
||||
Name = "Strobe Lantern";
|
||||
Weight = 4;
|
||||
Hue = 0;
|
||||
|
||||
Light = DefaultLight;
|
||||
StrobeInterval = DefaultStrobeInterval;
|
||||
|
||||
Instances.Add(this);
|
||||
}
|
||||
|
||||
public StrobeLantern(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
Instances.Add(this);
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
base.OnDelete();
|
||||
|
||||
Instances.Remove(this);
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
base.OnAfterDelete();
|
||||
|
||||
Instances.Remove(this);
|
||||
}
|
||||
|
||||
public virtual bool CanStrobe()
|
||||
{
|
||||
return !Deleted && Burning && Map != null && Map != Map.Internal && !Hues.IsNullOrEmpty();
|
||||
}
|
||||
|
||||
public void Strobe()
|
||||
{
|
||||
if (!CanStrobe() || VitaNexCore.Ticks < _NextUpdate)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_NextUpdate = VitaNexCore.Ticks + (int)StrobeInterval.TotalMilliseconds;
|
||||
|
||||
var index = ++_StrobeIndex % Hues.Length;
|
||||
|
||||
if (StrobeReverse)
|
||||
{
|
||||
index = (Hues.Length - index) - 1;
|
||||
}
|
||||
|
||||
_StrobeIndex = index;
|
||||
|
||||
OnStrobe();
|
||||
}
|
||||
|
||||
public override void Ignite()
|
||||
{
|
||||
var old = Burning;
|
||||
|
||||
base.Ignite();
|
||||
|
||||
if (!old && Burning)
|
||||
{
|
||||
OnStrobeBegin();
|
||||
}
|
||||
else if (old && !Burning)
|
||||
{
|
||||
OnStrobeEnd();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Douse()
|
||||
{
|
||||
var old = Burning;
|
||||
|
||||
base.Douse();
|
||||
|
||||
if (!old && Burning)
|
||||
{
|
||||
OnStrobeBegin();
|
||||
}
|
||||
else if (old && !Burning)
|
||||
{
|
||||
OnStrobeEnd();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnStrobe()
|
||||
{
|
||||
Light = Lights.GetRandom(Light);
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
protected virtual void OnStrobeBegin()
|
||||
{
|
||||
Light = Lights.GetRandom(Light);
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
protected virtual void OnStrobeEnd()
|
||||
{
|
||||
Light = DefaultLight;
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
public virtual void Update()
|
||||
{
|
||||
ReleaseWorldPackets();
|
||||
Delta(ItemDelta.Update);
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile m)
|
||||
{
|
||||
var access = Protected ? AccessLevel.Counselor : AccessLevel.Player;
|
||||
|
||||
if (this.CheckUse(m, true, false, 2, false, false, true, access))
|
||||
{
|
||||
base.OnDoubleClick(m);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var v = writer.SetVersion(2);
|
||||
|
||||
switch (v)
|
||||
{
|
||||
case 2:
|
||||
{
|
||||
writer.Write(StrobeReverse);
|
||||
writer.Write(StrobeInterval);
|
||||
|
||||
writer.Write(Burning);
|
||||
}
|
||||
break;
|
||||
// Old
|
||||
case 1:
|
||||
writer.Write(Burning);
|
||||
goto case 0;
|
||||
case 0:
|
||||
{
|
||||
writer.Write(StrobeInterval);
|
||||
writer.Write(_StrobeIndex);
|
||||
writer.Write(StrobeReverse);
|
||||
|
||||
writer.WriteArray(Hues, (w, o) => w.Write(o));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var v = reader.GetVersion();
|
||||
|
||||
var burning = false;
|
||||
|
||||
switch (v)
|
||||
{
|
||||
case 2:
|
||||
{
|
||||
StrobeReverse = reader.ReadBool();
|
||||
StrobeInterval = reader.ReadTimeSpan();
|
||||
|
||||
burning = reader.ReadBool();
|
||||
}
|
||||
break;
|
||||
// Old
|
||||
case 1:
|
||||
burning = reader.ReadBool();
|
||||
goto case 0;
|
||||
case 0:
|
||||
{
|
||||
StrobeInterval = reader.ReadTimeSpan();
|
||||
_StrobeIndex = reader.ReadInt();
|
||||
StrobeReverse = reader.ReadBool();
|
||||
|
||||
reader.ReadArray(r => r.ReadShort());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (burning)
|
||||
{
|
||||
Timer.DelayCall(Ignite);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class BoundsPreviewTile : Static
|
||||
{
|
||||
public override bool IsVirtualItem => true;
|
||||
public override bool DisplayLootType => false;
|
||||
public override bool DisplayWeight => false;
|
||||
public override double DefaultWeight => 0;
|
||||
public override bool Decays => true;
|
||||
public override TimeSpan DecayTime => TimeSpan.FromMinutes(10.0);
|
||||
|
||||
public BoundsPreviewTile(string name, int hue)
|
||||
: base(9272, 1)
|
||||
{
|
||||
Name = name;
|
||||
Hue = hue;
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public BoundsPreviewTile(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void SendInfoTo(NetState state, bool sendOplPacket)
|
||||
{
|
||||
if (state == null || state.Mobile == null || state.Mobile.AccessLevel >= AccessLevel.Counselor)
|
||||
{
|
||||
base.SendInfoTo(state, sendOplPacket);
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
list.Add(String.Format("({0}, {1}, {2})", X, Y, Z));
|
||||
}
|
||||
|
||||
public override void OnAosSingleClick(Mobile from)
|
||||
{
|
||||
OnSingleClick(from);
|
||||
}
|
||||
|
||||
public override void OnSingleClick(Mobile from)
|
||||
{
|
||||
base.OnSingleClick(from);
|
||||
|
||||
LabelTo(from, String.Format("{0} ({1}, {2}, {3})", this.ResolveName(from.GetLanguage()), X, Y, Z));
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{ }
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
685
Scripts/SubSystem/VitaNex/Core/Items/Skills/SkillCodex.cs
Normal file
685
Scripts/SubSystem/VitaNex/Core/Items/Skills/SkillCodex.cs
Normal file
@@ -0,0 +1,685 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
|
||||
using Server;
|
||||
|
||||
using VitaNex.SuperGumps;
|
||||
using VitaNex.SuperGumps.UI;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public enum SkillCodexFlags : byte
|
||||
{
|
||||
Base = 0x00,
|
||||
Cap = 0x01,
|
||||
Both = 0x02
|
||||
}
|
||||
|
||||
public enum SkillCodexMode : byte
|
||||
{
|
||||
Fixed = 0x00,
|
||||
Increase = 0x01,
|
||||
Decrease = 0x02
|
||||
}
|
||||
|
||||
public abstract class SkillCodex : Item
|
||||
{
|
||||
private SuperGump SelectionGump { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public SkillCodexMode Mode { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public SkillCodexFlags Flags { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Count { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public double Value { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ValueFixed { get => (int)(Value * 10.0); set => Value = value / 10.0; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool DeleteWhenEmpty { get; set; }
|
||||
|
||||
public List<SkillName> IgnoredSkills { get; protected set; }
|
||||
public List<SkillName> SelectedSkills { get; protected set; }
|
||||
|
||||
public SkillCodex()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
public SkillCodex(int count)
|
||||
: this(count, 100.0)
|
||||
{ }
|
||||
|
||||
public SkillCodex(int count, double value)
|
||||
: this(count, value, true)
|
||||
{ }
|
||||
|
||||
public SkillCodex(int count, double value, bool deleteWhenEmpty)
|
||||
: this(count, value, deleteWhenEmpty, SkillCodexMode.Fixed)
|
||||
{ }
|
||||
|
||||
public SkillCodex(int count, double value, bool deleteWhenEmpty, SkillCodexMode mode)
|
||||
: this(count, value, deleteWhenEmpty, mode, SkillCodexFlags.Base)
|
||||
{ }
|
||||
|
||||
public SkillCodex(int count, double value, bool deleteWhenEmpty, SkillCodexMode mode, SkillCodexFlags flags)
|
||||
: base(8793)
|
||||
{
|
||||
SelectedSkills = new List<SkillName>();
|
||||
IgnoredSkills = new List<SkillName>();
|
||||
|
||||
Mode = mode;
|
||||
Flags = flags;
|
||||
Count = count;
|
||||
Value = value;
|
||||
DeleteWhenEmpty = deleteWhenEmpty;
|
||||
|
||||
Name = "Codex of Wisdom";
|
||||
LootType = LootType.Blessed;
|
||||
Stackable = false;
|
||||
}
|
||||
|
||||
public SkillCodex(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
string html = String.Empty, flags = String.Empty;
|
||||
|
||||
html += String.Format("<basefont color=#{0:X6}>Use: ", Color.LawnGreen.ToRgb());
|
||||
|
||||
switch (Flags)
|
||||
{
|
||||
case SkillCodexFlags.Base:
|
||||
flags = "value";
|
||||
break;
|
||||
case SkillCodexFlags.Cap:
|
||||
flags = "cap";
|
||||
break;
|
||||
case SkillCodexFlags.Both:
|
||||
flags = "value and cap";
|
||||
break;
|
||||
}
|
||||
|
||||
switch (Mode)
|
||||
{
|
||||
case SkillCodexMode.Increase:
|
||||
{
|
||||
html += String.Format(
|
||||
"Increase {0} skill{1} {2} by {3:F2}%",
|
||||
Count,
|
||||
Count == 1 ? String.Empty : "s",
|
||||
flags,
|
||||
Value);
|
||||
}
|
||||
break;
|
||||
case SkillCodexMode.Decrease:
|
||||
{
|
||||
html += String.Format(
|
||||
"Decrease {0} skill{1} {2} by {3:F2}%",
|
||||
Count,
|
||||
Count == 1 ? String.Empty : "s",
|
||||
flags,
|
||||
Value);
|
||||
}
|
||||
break;
|
||||
case SkillCodexMode.Fixed:
|
||||
{
|
||||
html += String.Format("Set {0} skill{1} {2} to {3:F2}%", Count, Count == 1 ? String.Empty : "s", flags, Value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
list.Add(html);
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from == null || from.Deleted || !Validate(from, true))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SelectSkills(from);
|
||||
InvalidateProperties();
|
||||
}
|
||||
|
||||
public virtual bool ValidateSkill(Mobile user, Skill skill, bool message)
|
||||
{
|
||||
if (user == null || user.Deleted || skill == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (Mode)
|
||||
{
|
||||
case SkillCodexMode.Increase:
|
||||
{
|
||||
if (Flags == SkillCodexFlags.Base || Flags == SkillCodexFlags.Both)
|
||||
{
|
||||
if (user.SkillsTotal + ValueFixed > user.SkillsCap)
|
||||
{
|
||||
if (!CanReduceSkills(user))
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
user.SendMessage(
|
||||
SuperGump.DefaultErrorHue,
|
||||
"You already know everything this codex can offer, reduce some skills to make room for more knowledge.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (skill.IsCapped() || skill.WillCap(Value, false))
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
user.SendMessage(
|
||||
SuperGump.DefaultErrorHue,
|
||||
"You already know everything this codex can offer about {0}.",
|
||||
skill.Name);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!skill.IsLocked(SkillLock.Up))
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
user.SendMessage(SuperGump.DefaultErrorHue, "The skill {0} is locked.", skill.Name);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SkillCodexMode.Decrease:
|
||||
{
|
||||
if (Flags == SkillCodexFlags.Base || Flags == SkillCodexFlags.Both)
|
||||
{
|
||||
if (user.SkillsTotal - ValueFixed < 0)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
user.SendMessage(SuperGump.DefaultErrorHue, "You already forgot everything this codex can offer.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (skill.IsZero() || skill.WillZero(Value, false))
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
user.SendMessage(
|
||||
SuperGump.DefaultErrorHue,
|
||||
"You already forgot everything this codex can offer about {0}, any further and you'll forget how to breath!",
|
||||
skill.Name);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!skill.IsLocked(SkillLock.Down))
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
user.SendMessage(SuperGump.DefaultErrorHue, "The skill {0} is locked.", skill.Name);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SkillCodexMode.Fixed:
|
||||
{
|
||||
if (Flags == SkillCodexFlags.Cap)
|
||||
{
|
||||
if (skill.CapFixedPoint == ValueFixed)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
user.SendMessage(
|
||||
SuperGump.DefaultErrorHue,
|
||||
"You already know everything this codex can offer about {0}.",
|
||||
skill.Name);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (Flags == SkillCodexFlags.Base || Flags == SkillCodexFlags.Both)
|
||||
{
|
||||
if (skill.IsLocked(SkillLock.Locked))
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
user.SendMessage(SuperGump.DefaultErrorHue, "The skill {0} is locked.", skill.Name);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ValueFixed < skill.BaseFixedPoint)
|
||||
{
|
||||
if (!skill.IsLocked(SkillLock.Down))
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
user.SendMessage(SuperGump.DefaultErrorHue, "You can not decrease this skill because it is not locked down!");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (user.SkillsTotal - (skill.BaseFixedPoint - ValueFixed) < 0)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
user.SendMessage(
|
||||
SuperGump.DefaultErrorHue,
|
||||
"You already forgot everything this codex can offer, any further and you'll forget how to breath!");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (ValueFixed > skill.BaseFixedPoint)
|
||||
{
|
||||
if (!skill.IsLocked(SkillLock.Up))
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
user.SendMessage(SuperGump.DefaultErrorHue, "You can not increase this skill because it is not locked up!");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (user.SkillsTotal + (ValueFixed - skill.BaseFixedPoint) > user.SkillsCap)
|
||||
{
|
||||
if (!CanReduceSkills(user))
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
user.SendMessage(
|
||||
SuperGump.DefaultErrorHue,
|
||||
"You already know everything this codex can offer, reduce some skills to make room for more knowledge.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
user.SendMessage(
|
||||
SuperGump.DefaultErrorHue,
|
||||
"You already know everything this codex can offer about {0}.",
|
||||
skill.Name);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool Validate(Mobile user, bool message)
|
||||
{
|
||||
if (user == null || user.Deleted || !user.CanSee(this))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IsChildOf(user.Backpack))
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
user.SendMessage(SuperGump.DefaultErrorHue, "This codex must be in your backpack to read it.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Count <= 0)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
user.SendMessage(SuperGump.DefaultErrorHue, "This codex does not contain any skills to learn.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void SelectSkills(Mobile user)
|
||||
{
|
||||
if (user == null || user.Deleted || !Validate(user, true))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (SelectionGump != null)
|
||||
{
|
||||
SelectionGump.Close(true);
|
||||
}
|
||||
|
||||
SelectionGump = new SkillSelectionGump(
|
||||
user,
|
||||
null,
|
||||
Count,
|
||||
null,
|
||||
null,
|
||||
skills =>
|
||||
{
|
||||
if (!ApplySkills(user, skills))
|
||||
{
|
||||
SelectSkills(user);
|
||||
}
|
||||
},
|
||||
IgnoredSkills.ToArray()).Send();
|
||||
}
|
||||
|
||||
public virtual bool ApplySkills(Mobile user, SkillName[] skills)
|
||||
{
|
||||
if (user == null || user.Deleted || skills == null || skills.Length == 0 || !Validate(user, true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var sn in skills)
|
||||
{
|
||||
if (user.Deleted || !Validate(user, true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var skill = user.Skills[sn];
|
||||
|
||||
if (!ValidateSkill(user, skill, true))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var charge = false;
|
||||
|
||||
if (Flags == SkillCodexFlags.Cap || Flags == SkillCodexFlags.Both)
|
||||
{
|
||||
switch (Mode)
|
||||
{
|
||||
case SkillCodexMode.Increase:
|
||||
{
|
||||
skill.IncreaseCap(Value);
|
||||
}
|
||||
break;
|
||||
case SkillCodexMode.Decrease:
|
||||
{
|
||||
skill.DecreaseCap(Value);
|
||||
}
|
||||
break;
|
||||
case SkillCodexMode.Fixed:
|
||||
{
|
||||
skill.SetCap(Value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (Flags != SkillCodexFlags.Both)
|
||||
{
|
||||
EndApply(user, skill);
|
||||
return true;
|
||||
}
|
||||
|
||||
charge = true;
|
||||
}
|
||||
|
||||
if (Flags == SkillCodexFlags.Base || Flags == SkillCodexFlags.Both)
|
||||
{
|
||||
charge = false;
|
||||
|
||||
switch (Mode)
|
||||
{
|
||||
case SkillCodexMode.Increase:
|
||||
{
|
||||
if (user.SkillsTotal + ValueFixed > user.SkillsCap)
|
||||
{
|
||||
if (TryReduceSkills(user) && skill.IncreaseBase(Value))
|
||||
{
|
||||
charge = true;
|
||||
}
|
||||
}
|
||||
else if (skill.IncreaseBase(Value))
|
||||
{
|
||||
charge = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SkillCodexMode.Decrease:
|
||||
{
|
||||
if (skill.DecreaseBase(Value))
|
||||
{
|
||||
charge = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SkillCodexMode.Fixed:
|
||||
{
|
||||
if (ValueFixed > skill.BaseFixedPoint)
|
||||
{
|
||||
if (user.SkillsTotal + ValueFixed > user.SkillsCap)
|
||||
{
|
||||
if (TryReduceSkills(user) && skill.SetBase(Value))
|
||||
{
|
||||
charge = true;
|
||||
}
|
||||
}
|
||||
else if (skill.SetBase(Value))
|
||||
{
|
||||
charge = true;
|
||||
}
|
||||
}
|
||||
else if (ValueFixed < skill.BaseFixedPoint && skill.SetBase(Value))
|
||||
{
|
||||
charge = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (charge)
|
||||
{
|
||||
EndApply(user, skill);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected virtual void EndApply(Mobile user, Skill skill)
|
||||
{
|
||||
skill.Normalize();
|
||||
|
||||
UseCharges();
|
||||
|
||||
if (Count <= 0 && DeleteWhenEmpty)
|
||||
{
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual bool CanReduceSkills(Mobile user)
|
||||
{
|
||||
var target = (user.SkillsTotal + ValueFixed) - user.SkillsCap;
|
||||
var canReduceBy = 0;
|
||||
|
||||
foreach (var s in user.Skills)
|
||||
{
|
||||
if (s.IsLocked(SkillLock.Down))
|
||||
{
|
||||
if (canReduceBy + s.BaseFixedPoint > target)
|
||||
{
|
||||
canReduceBy += (target - canReduceBy);
|
||||
}
|
||||
else
|
||||
{
|
||||
canReduceBy += s.BaseFixedPoint;
|
||||
}
|
||||
}
|
||||
|
||||
if (canReduceBy >= target)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual bool TryReduceSkills(Mobile user)
|
||||
{
|
||||
if (!CanReduceSkills(user))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var target = (user.SkillsTotal + ValueFixed) - user.SkillsCap;
|
||||
var reducedBy = 0;
|
||||
|
||||
foreach (var s in user.Skills)
|
||||
{
|
||||
if (s.IsLocked(SkillLock.Down))
|
||||
{
|
||||
if (reducedBy + s.BaseFixedPoint > target)
|
||||
{
|
||||
var diff = (target - reducedBy);
|
||||
|
||||
if (s.DecreaseBase(diff / 10))
|
||||
{
|
||||
reducedBy += diff;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s.SetBase(0))
|
||||
{
|
||||
reducedBy += s.BaseFixedPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (reducedBy >= target)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual void UseCharges(int count = 1)
|
||||
{
|
||||
Count = Math.Max(0, Count - count);
|
||||
InvalidateProperties();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(1);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
writer.WriteFlag(Mode);
|
||||
writer.WriteFlag(Flags);
|
||||
writer.Write(Count);
|
||||
writer.Write(Value);
|
||||
writer.Write(DeleteWhenEmpty);
|
||||
writer.WriteList(IgnoredSkills, skill => writer.WriteFlag(skill));
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
{
|
||||
writer.Write((byte)Mode);
|
||||
writer.Write((byte)Flags);
|
||||
writer.Write(Count);
|
||||
writer.Write(Value);
|
||||
writer.Write(DeleteWhenEmpty);
|
||||
writer.WriteList(IgnoredSkills, (w, skill) => w.Write((short)skill));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
Mode = reader.ReadFlag<SkillCodexMode>();
|
||||
Flags = reader.ReadFlag<SkillCodexFlags>();
|
||||
Count = reader.ReadInt();
|
||||
Value = reader.ReadDouble();
|
||||
DeleteWhenEmpty = reader.ReadBool();
|
||||
IgnoredSkills = reader.ReadList(r => r.ReadFlag<SkillName>());
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
{
|
||||
Mode = (SkillCodexMode)reader.ReadByte();
|
||||
Flags = (SkillCodexFlags)reader.ReadByte();
|
||||
Count = reader.ReadInt();
|
||||
Value = reader.ReadDouble();
|
||||
DeleteWhenEmpty = reader.ReadBool();
|
||||
IgnoredSkills = reader.ReadList(r => (SkillName)r.ReadShort());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class ThrowableCat : BaseThrowableAtMobile<Mobile>
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableCat()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableCat(int amount)
|
||||
: base(8475, amount)
|
||||
{
|
||||
Name = "Snowball";
|
||||
|
||||
Weight = 2.0;
|
||||
Stackable = true;
|
||||
|
||||
Consumable = true;
|
||||
AllowCombat = false;
|
||||
TargetFlags = TargetFlags.None;
|
||||
|
||||
Delivery = ThrowableAtMobileDelivery.None;
|
||||
DismountUser = false;
|
||||
|
||||
ThrowSound = 105;
|
||||
ImpactSound = 676;
|
||||
|
||||
EffectID = ItemID;
|
||||
EffectHue = Hue;
|
||||
|
||||
ThrowRecovery = TimeSpan.Zero;
|
||||
}
|
||||
|
||||
public ThrowableCat(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
protected override void OnThrownAt(Mobile from, Mobile target)
|
||||
{
|
||||
if (from == null || from.Deleted || target == null || target.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var cat = new Cat
|
||||
{
|
||||
Name = "Snowball"
|
||||
};
|
||||
|
||||
var pmTarget = target as PlayerMobile;
|
||||
|
||||
if (pmTarget != null)
|
||||
{
|
||||
if (pmTarget.Followers + cat.ControlSlots <= pmTarget.FollowersMax)
|
||||
{
|
||||
cat.Controlled = true;
|
||||
cat.ControlMaster = pmTarget;
|
||||
cat.ControlTarget = pmTarget;
|
||||
cat.ControlOrder = OrderType.Follow;
|
||||
}
|
||||
}
|
||||
|
||||
cat.MoveToWorld(target.Location, target.Map);
|
||||
|
||||
base.OnThrownAt(from, target);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{ }
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{ }
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
using Server.Items;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public abstract class BaseThrowableBench : ThrowableFurniture
|
||||
{
|
||||
public BaseThrowableBench(int itemID)
|
||||
: base(itemID)
|
||||
{
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
public BaseThrowableBench(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0xB2D, 0xB2C)]
|
||||
public class ThrowableWoodenBench : BaseThrowableBench
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableWoodenBench()
|
||||
: base(Utility.RandomList(0xB2D, 0xB2C))
|
||||
{ }
|
||||
|
||||
public ThrowableWoodenBench(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
using Server.Items;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public abstract class BaseThrowableChair : ThrowableFurniture
|
||||
{
|
||||
public BaseThrowableChair(int itemID)
|
||||
: base(itemID)
|
||||
{
|
||||
Weight = 20.0;
|
||||
}
|
||||
|
||||
public BaseThrowableChair(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0xB4F, 0xB4E, 0xB50, 0xB51)]
|
||||
public abstract class ThrowableFancyWoodenChairCushion : BaseThrowableChair
|
||||
{
|
||||
public ThrowableFancyWoodenChairCushion()
|
||||
: base(Utility.RandomList(0xB4F, 0xB4E, 0xB50, 0xB51))
|
||||
{ }
|
||||
|
||||
public ThrowableFancyWoodenChairCushion(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0xB53, 0xB52, 0xB54, 0xB55)]
|
||||
public abstract class ThrowableWoodenChairCushion : BaseThrowableChair
|
||||
{
|
||||
public ThrowableWoodenChairCushion()
|
||||
: base(Utility.RandomList(0xB53, 0xB52, 0xB54, 0xB55))
|
||||
{ }
|
||||
|
||||
public ThrowableWoodenChairCushion(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0xB57, 0xB56, 0xB59, 0xB58)]
|
||||
public class ThrowableWoodenChair : BaseThrowableChair
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableWoodenChair()
|
||||
: base(Utility.RandomList(0xB57, 0xB56, 0xB59, 0xB58))
|
||||
{ }
|
||||
|
||||
public ThrowableWoodenChair(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0xB5B, 0xB5A, 0xB5C, 0xB5D)]
|
||||
public class ThrowableBambooChair : BaseThrowableChair
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableBambooChair()
|
||||
: base(Utility.RandomList(0xB5B, 0xB5A, 0xB5C, 0xB5D))
|
||||
{ }
|
||||
|
||||
public ThrowableBambooChair(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0x1218, 0x1219, 0x121A, 0x121B)]
|
||||
public class ThrowableStoneChair : BaseThrowableChair
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableStoneChair()
|
||||
: base(Utility.RandomList(0x1218, 0x1219, 0x121A, 0x121B))
|
||||
{ }
|
||||
|
||||
public ThrowableStoneChair(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0x2DE3, 0x2DE4, 0x2DE5, 0x2DE6)]
|
||||
public class ThrowableOrnateElvenChair : BaseThrowableChair
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableOrnateElvenChair()
|
||||
: base(Utility.RandomList(0x2DE3, 0x2DE4, 0x2DE5, 0x2DE6))
|
||||
{ }
|
||||
|
||||
public ThrowableOrnateElvenChair(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0x2DEB, 0x2DEC, 0x2DED, 0x2DEE)]
|
||||
public class ThrowableBigElvenChair : BaseThrowableChair
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableBigElvenChair()
|
||||
: base(Utility.RandomList(0x2DEB, 0x2DEC, 0x2DED, 0x2DEE))
|
||||
{ }
|
||||
|
||||
public ThrowableBigElvenChair(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0x2DF5, 0x2DF6)]
|
||||
public class ThrowableElvenReadingChair : BaseThrowableChair
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableElvenReadingChair()
|
||||
: base(Utility.RandomList(0x2DF5, 0x2DF6))
|
||||
{ }
|
||||
|
||||
public ThrowableElvenReadingChair(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Targeting;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public abstract class ThrowableFurniture : BaseThrowableAtMobile<Mobile>, IDyable
|
||||
{
|
||||
public ThrowableFurniture(int itemID)
|
||||
: base(itemID, 1)
|
||||
{
|
||||
Weight = 10.0;
|
||||
|
||||
AllowCombat = true;
|
||||
AllowDeadUser = false;
|
||||
Consumable = true;
|
||||
ClearHands = true;
|
||||
DismountUser = true;
|
||||
|
||||
Damages = false;
|
||||
Heals = false;
|
||||
|
||||
ThrowRange = 8;
|
||||
|
||||
ThrowSound = 1491;
|
||||
ImpactSound = 1335;
|
||||
|
||||
RequiredSkillValue = 0.0;
|
||||
|
||||
TargetFlags = TargetFlags.None;
|
||||
|
||||
Delivery = ThrowableAtMobileDelivery.None;
|
||||
|
||||
ThrowRecovery = TimeSpan.Zero;
|
||||
}
|
||||
|
||||
public ThrowableFurniture(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public virtual bool Dye(Mobile m, DyeTub sender)
|
||||
{
|
||||
return m != null && sender is FurnitureDyeTub;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
[Furniture]
|
||||
public abstract class BaseThrowableStool : ThrowableFurniture
|
||||
{
|
||||
public BaseThrowableStool(int itemID)
|
||||
: base(itemID)
|
||||
{
|
||||
Weight = 10.0;
|
||||
}
|
||||
|
||||
public BaseThrowableStool(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture]
|
||||
public class ThrowableStool : BaseThrowableStool
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableStool()
|
||||
: base(0xA2A)
|
||||
{ }
|
||||
|
||||
public ThrowableStool(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture]
|
||||
public class ThrowableFootStool : BaseThrowableStool
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableFootStool()
|
||||
: base(0xB5E)
|
||||
{ }
|
||||
|
||||
public ThrowableFootStool(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
using Server.Items;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public abstract class BaseThrowableTable : ThrowableFurniture
|
||||
{
|
||||
public BaseThrowableTable(int itemID)
|
||||
: base(itemID)
|
||||
{
|
||||
Weight = 10.0;
|
||||
}
|
||||
|
||||
public BaseThrowableTable(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture]
|
||||
public class ThrowableElegantLowTable : BaseThrowableTable
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableElegantLowTable()
|
||||
: base(0x2819)
|
||||
{ }
|
||||
|
||||
public ThrowableElegantLowTable(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture]
|
||||
public class ThrowablePlainLowTable : BaseThrowableTable
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowablePlainLowTable()
|
||||
: base(0x281A)
|
||||
{ }
|
||||
|
||||
public ThrowablePlainLowTable(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0xB90, 0xB7D)]
|
||||
public class ThrowableLargeTable : BaseThrowableTable
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableLargeTable()
|
||||
: base(Utility.RandomList(0xB90, 0xB7D))
|
||||
{ }
|
||||
|
||||
public ThrowableLargeTable(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0xB35, 0xB34)]
|
||||
public class ThrowableNightstand : BaseThrowableTable
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableNightstand()
|
||||
: base(Utility.RandomList(0xB35, 0xB34))
|
||||
{ }
|
||||
|
||||
public ThrowableNightstand(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0xB8F, 0xB7C)]
|
||||
public class ThrowableYewWoodTable : BaseThrowableTable
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableYewWoodTable()
|
||||
: base(Utility.RandomList(0xB8F, 0xB7C))
|
||||
{ }
|
||||
|
||||
public ThrowableYewWoodTable(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
using Server.Items;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public abstract class BaseThrowableThrone : ThrowableFurniture
|
||||
{
|
||||
public BaseThrowableThrone(int itemID)
|
||||
: base(itemID)
|
||||
{
|
||||
Weight = 10.0;
|
||||
}
|
||||
|
||||
public BaseThrowableThrone(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0xB32, 0xB33)]
|
||||
public class ThrowableThrone : BaseThrowableThrone
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableThrone()
|
||||
: base(Utility.RandomList(0xB32, 0xB33))
|
||||
{ }
|
||||
|
||||
public ThrowableThrone(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture, Flipable(0xB2E, 0xB2F, 0xB31, 0xB30)]
|
||||
public class ThrowableWoodenThrone : BaseThrowableThrone
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableWoodenThrone()
|
||||
: base(Utility.RandomList(0xB2E, 0xB2F, 0xB31, 0xB30))
|
||||
{ }
|
||||
|
||||
public ThrowableWoodenThrone(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,520 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Movement;
|
||||
using Server.Targeting;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class HauntedMomentoEntity : BaseCreature
|
||||
{
|
||||
private HauntedMomento _Momento;
|
||||
|
||||
[CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)]
|
||||
public HauntedMomento Momento => _Momento;
|
||||
|
||||
public override bool ClickTitle => false;
|
||||
public override bool AlwaysMurderer => true;
|
||||
public override bool BardImmune => true;
|
||||
public override bool BleedImmune => true;
|
||||
public override bool NoHouseRestrictions => true;
|
||||
public override bool ShowFameTitle => false;
|
||||
public override bool Unprovokable => true;
|
||||
public override bool CanMoveOverObstacles => true;
|
||||
public override bool CanOpenDoors => true;
|
||||
public override bool CanTarget => false;
|
||||
//public override bool CanDrop => false;
|
||||
public override bool Commandable => false;
|
||||
public override bool DeleteCorpseOnDeath => true;
|
||||
public override bool IsScaryToPets => true;
|
||||
public override bool IsDispellable => false;
|
||||
public override bool PlayerRangeSensitive => false;
|
||||
public override bool CanFlee => false;
|
||||
|
||||
public HauntedMomentoEntity(HauntedMomento momento)
|
||||
: base(AIType.AI_Use_Default, FightMode.None, 10, 0, 0.2, 0.2)
|
||||
{
|
||||
_Momento = momento;
|
||||
|
||||
Name = "?";
|
||||
|
||||
Hue = 0x4001;
|
||||
BaseSoundID = 0;
|
||||
|
||||
Hidden = true;
|
||||
Blessed = true;
|
||||
Tamable = false;
|
||||
CanSwim = true;
|
||||
|
||||
Fame = 0;
|
||||
Karma = 0;
|
||||
|
||||
VirtualArmor = 1337;
|
||||
|
||||
SetStr(0);
|
||||
SetDex(0);
|
||||
SetInt(0);
|
||||
SetHits(1);
|
||||
SetDamage(0);
|
||||
|
||||
SetDamageType(ResistanceType.Cold, 0);
|
||||
SetDamageType(ResistanceType.Energy, 0);
|
||||
SetDamageType(ResistanceType.Fire, 0);
|
||||
SetDamageType(ResistanceType.Physical, 0);
|
||||
SetDamageType(ResistanceType.Poison, 0);
|
||||
|
||||
SetResistance(ResistanceType.Cold, 100);
|
||||
SetResistance(ResistanceType.Energy, 100);
|
||||
SetResistance(ResistanceType.Fire, 100);
|
||||
SetResistance(ResistanceType.Physical, 100);
|
||||
SetResistance(ResistanceType.Poison, 100);
|
||||
|
||||
this.SetAllSkills(0, 0);
|
||||
|
||||
ChangeBody();
|
||||
OnThink();
|
||||
}
|
||||
|
||||
public HauntedMomentoEntity(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public static bool IsBeingLookedAt(Direction facing, Direction to)
|
||||
{
|
||||
if (facing.HasFlag(Direction.Running))
|
||||
{
|
||||
facing &= ~Direction.Running;
|
||||
}
|
||||
|
||||
switch (facing)
|
||||
{
|
||||
case Direction.Up:
|
||||
return (to == Direction.Left || to == Direction.West || to == Direction.Up || to == Direction.North ||
|
||||
to == Direction.Right);
|
||||
case Direction.North:
|
||||
return (to == Direction.West || to == Direction.Up || to == Direction.North || to == Direction.Right ||
|
||||
to == Direction.East);
|
||||
case Direction.Right:
|
||||
return (to == Direction.Up || to == Direction.North || to == Direction.Right || to == Direction.East ||
|
||||
to == Direction.Down);
|
||||
case Direction.East:
|
||||
return (to == Direction.North || to == Direction.Right || to == Direction.East || to == Direction.Down ||
|
||||
to == Direction.South);
|
||||
case Direction.Down:
|
||||
return (to == Direction.Right || to == Direction.East || to == Direction.Down || to == Direction.South ||
|
||||
to == Direction.Left);
|
||||
case Direction.South:
|
||||
return (to == Direction.East || to == Direction.Down || to == Direction.South || to == Direction.Left ||
|
||||
to == Direction.West);
|
||||
case Direction.Left:
|
||||
return (to == Direction.Down || to == Direction.South || to == Direction.Left || to == Direction.West ||
|
||||
to == Direction.Up);
|
||||
case Direction.West:
|
||||
return (to == Direction.South || to == Direction.Left || to == Direction.West || to == Direction.Up ||
|
||||
to == Direction.North);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void ChangeBody()
|
||||
{
|
||||
Body = Utility.RandomList(26, 50, 146, 148, 196, 747, 748, 970);
|
||||
|
||||
PlaySound(1383);
|
||||
}
|
||||
|
||||
public override void OnThink()
|
||||
{
|
||||
base.OnThink();
|
||||
|
||||
if (Deleted || _Momento == null || _Momento.Deleted || _Momento.Map == null || _Momento.Map == Map.Internal ||
|
||||
!(_Momento.RootParent is Mobile))
|
||||
{
|
||||
Delete();
|
||||
return;
|
||||
}
|
||||
|
||||
var parent = (Mobile)_Momento.RootParent;
|
||||
|
||||
if (parent.Deleted || parent.Map == null || parent.Map == Map.Internal)
|
||||
{
|
||||
Delete();
|
||||
return;
|
||||
}
|
||||
|
||||
Hidden = true;
|
||||
|
||||
Home = parent.Location;
|
||||
RangeHome = RangePerception;
|
||||
|
||||
var map = parent.Map;
|
||||
|
||||
if (Map == null || Map == Map.Internal || Map != map || !InRange(parent, 20))
|
||||
{
|
||||
MoveToWorld(parent.GetRandomPoint3D(RangeHome + (RangeHome / 2)).GetWorldTop(map), map);
|
||||
|
||||
ChangeBody();
|
||||
}
|
||||
|
||||
var to = parent.GetDirectionTo(this);
|
||||
|
||||
var stop = (parent.InRange(this, RangeHome / 2));
|
||||
|
||||
if (parent is PlayerMobile)
|
||||
{
|
||||
var hide = (IsBeingLookedAt(parent.Direction, to) || !parent.InRange(this, RangeHome + (RangeHome / 2)));
|
||||
|
||||
if (hide)
|
||||
{
|
||||
((PlayerMobile)parent).VisibilityList.Update(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
((PlayerMobile)parent).VisibilityList.Remove(this);
|
||||
}
|
||||
}
|
||||
|
||||
if (stop)
|
||||
{
|
||||
Frozen = true;
|
||||
return;
|
||||
}
|
||||
|
||||
Frozen = false;
|
||||
|
||||
int x = X, y = Y, z = Z;
|
||||
|
||||
Movement.Offset(GetDirectionTo(Home), ref x, ref y);
|
||||
|
||||
var p = new Point3D(x, y, z).GetWorldTop(map);
|
||||
|
||||
if (!map.CanFit(p, 16))
|
||||
{
|
||||
SetLocation(p, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Move(GetDirectionTo(p));
|
||||
}
|
||||
|
||||
Direction = GetDirectionTo(parent);
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
if (_Momento != null)
|
||||
{
|
||||
var parent = _Momento.RootParent as Mobile;
|
||||
|
||||
if (parent is PlayerMobile)
|
||||
{
|
||||
((PlayerMobile)parent).VisibilityList.Remove(this);
|
||||
}
|
||||
|
||||
if (_Momento.Entity == this)
|
||||
{
|
||||
_Momento.Entity = null;
|
||||
}
|
||||
}
|
||||
|
||||
base.OnAfterDelete();
|
||||
}
|
||||
|
||||
public override bool CanBeDamaged()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool CanBeRenamedBy(Mobile from)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool CanBeControlledBy(Mobile m)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool CheckFlee()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override bool OnMove(Direction d)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnMoveOver(Mobile m)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnMoveOff(Mobile m)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool CheckShove(Mobile shoved)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile m)
|
||||
{ }
|
||||
|
||||
public override void OnAosSingleClick(Mobile m)
|
||||
{ }
|
||||
|
||||
public override void OnSingleClick(Mobile m)
|
||||
{ }
|
||||
|
||||
public override bool OnDragDrop(Mobile from, Item dropped)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool OnDragLift(Item item)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnStatsQuery(Mobile from)
|
||||
{ }
|
||||
|
||||
public override void AddNameProperties(ObjectPropertyList list)
|
||||
{ }
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{ }
|
||||
|
||||
public override void GenerateLoot()
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(1);
|
||||
|
||||
writer.Write(_Momento);
|
||||
|
||||
if (version < 1)
|
||||
{
|
||||
writer.Write(false);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
_Momento = reader.ReadItem<HauntedMomento>();
|
||||
|
||||
if (version < 1)
|
||||
{
|
||||
reader.ReadBool();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class HauntedMomento : BaseThrowableAtMobile<Mobile>
|
||||
{
|
||||
private static bool _Initialized;
|
||||
|
||||
[CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)]
|
||||
public HauntedMomentoEntity Entity { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public HauntedMomento()
|
||||
: base(0x3679, 1)
|
||||
{
|
||||
Name = "Haunted Momento";
|
||||
Token = "Mysterious Energies Surround This Momento";
|
||||
|
||||
Weight = 1.0;
|
||||
Stackable = false;
|
||||
LootType = LootType.Blessed;
|
||||
|
||||
AllowCombat = false;
|
||||
TargetFlags = TargetFlags.None;
|
||||
|
||||
Delivery = ThrowableAtMobileDelivery.AddToPack;
|
||||
DismountUser = false;
|
||||
|
||||
ThrowSound = 0x180;
|
||||
ImpactSound = 0x181;
|
||||
|
||||
EffectID = ItemID;
|
||||
EffectHue = Hue;
|
||||
|
||||
ThrowRecovery = TimeSpan.Zero;
|
||||
}
|
||||
|
||||
public HauntedMomento(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
if (_Initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EventSink.Login += e =>
|
||||
{
|
||||
if (e.Mobile == null || e.Mobile.Deleted || e.Mobile.Backpack == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
VitaNexCore.TryCatch(
|
||||
() =>
|
||||
{
|
||||
var momentos = e.Mobile.Backpack.FindItemsByType<HauntedMomento>(true);
|
||||
|
||||
momentos.ForEach(
|
||||
m =>
|
||||
{
|
||||
if (m != null && !m.Deleted)
|
||||
{
|
||||
m.InvalidateEntity();
|
||||
}
|
||||
});
|
||||
|
||||
momentos.Clear();
|
||||
});
|
||||
};
|
||||
|
||||
_Initialized = true;
|
||||
}
|
||||
|
||||
public override bool CanThrowAt(Mobile from, Mobile target, bool message)
|
||||
{
|
||||
if (!base.CanThrowAt(from, target, message))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!target.Player)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
from.SendMessage(37, "You can only throw the {0} at other players.", Name);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void OnLocationChange(Point3D oldLocation)
|
||||
{
|
||||
base.OnLocationChange(oldLocation);
|
||||
|
||||
InvalidateEntity();
|
||||
}
|
||||
|
||||
protected virtual HauntedMomentoEntity CreateEntity()
|
||||
{
|
||||
return new HauntedMomentoEntity(this);
|
||||
}
|
||||
|
||||
public override void OnMapChange()
|
||||
{
|
||||
base.OnMapChange();
|
||||
|
||||
InvalidateEntity();
|
||||
|
||||
if (Entity != null)
|
||||
{
|
||||
Entity.ChangeBody();
|
||||
}
|
||||
}
|
||||
|
||||
#if NEWPARENT
|
||||
public override void OnAdded(IEntity parent)
|
||||
#else
|
||||
public override void OnAdded(object parent)
|
||||
#endif
|
||||
{
|
||||
base.OnAdded(parent);
|
||||
|
||||
InvalidateEntity();
|
||||
}
|
||||
|
||||
protected virtual void InvalidateEntity()
|
||||
{
|
||||
if (Map == null || Map == Map.Internal || !(RootParent is Mobile) || Parent is BankBox)
|
||||
{
|
||||
if (Entity != null)
|
||||
{
|
||||
Entity.Delete();
|
||||
Entity = null;
|
||||
}
|
||||
}
|
||||
else if (Entity == null || Entity.Deleted)
|
||||
{
|
||||
Entity = CreateEntity();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
if (Entity != null)
|
||||
{
|
||||
Entity.Delete();
|
||||
}
|
||||
|
||||
base.OnAfterDelete();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
writer.Write(Entity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
Entity = reader.ReadMobile<HauntedMomentoEntity>();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class ThrowableRat : BaseThrowableAtMobile<Mobile>
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableRat()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableRat(int amount)
|
||||
: base(8483, amount)
|
||||
{
|
||||
Name = "Reeking Rat";
|
||||
Weight = 1.0;
|
||||
Token = "Mickey's Ugly Cousin";
|
||||
|
||||
Consumable = true;
|
||||
AllowCombat = false;
|
||||
TargetFlags = TargetFlags.None;
|
||||
|
||||
Delivery = ThrowableAtMobileDelivery.None;
|
||||
DismountUser = false;
|
||||
|
||||
ThrowSound = 206;
|
||||
ImpactSound = 204;
|
||||
|
||||
EffectID = ItemID;
|
||||
EffectHue = Hue;
|
||||
|
||||
ThrowRecovery = TimeSpan.Zero;
|
||||
}
|
||||
|
||||
public ThrowableRat(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
protected override void OnThrownAt(Mobile from, Mobile target)
|
||||
{
|
||||
if (from == null || from.Deleted || target == null || target.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var rat = new Rat
|
||||
{
|
||||
Name = "Reeking Rat"
|
||||
};
|
||||
|
||||
var pmTarget = target as PlayerMobile;
|
||||
|
||||
if (pmTarget != null)
|
||||
{
|
||||
if (pmTarget.Followers + rat.ControlSlots <= pmTarget.FollowersMax)
|
||||
{
|
||||
rat.Controlled = true;
|
||||
rat.ControlMaster = pmTarget;
|
||||
rat.ControlTarget = pmTarget;
|
||||
rat.ControlOrder = OrderType.Follow;
|
||||
}
|
||||
}
|
||||
|
||||
rat.MoveToWorld(target.Location, target.Map);
|
||||
|
||||
base.OnThrownAt(from, target);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Targeting;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class ThrowableRock : BaseThrowableAtMobile<Mobile>
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableRock()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableRock(int amount)
|
||||
: base(0x11B6, amount)
|
||||
{
|
||||
Name = "Gigantic Boulder";
|
||||
Usage = "Pass The Rock!";
|
||||
Token = "Your Strength Has Increased By Over 9000!";
|
||||
|
||||
Weight = 1.0;
|
||||
Stackable = true;
|
||||
|
||||
AllowCombat = false;
|
||||
TargetFlags = TargetFlags.None;
|
||||
|
||||
Delivery = ThrowableAtMobileDelivery.AddToPack;
|
||||
DismountUser = false;
|
||||
|
||||
ThrowSound = 543;
|
||||
ImpactSound = 1613;
|
||||
|
||||
EffectID = ItemID;
|
||||
EffectHue = Hue;
|
||||
|
||||
ThrowRecovery = TimeSpan.Zero;
|
||||
}
|
||||
|
||||
public ThrowableRock(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{ }
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{ }
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Targeting;
|
||||
|
||||
using VitaNex.FX;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
[Flipable(10248, 10249)]
|
||||
public class ThrowableStinkBomb : BaseThrowableAtMobile<Mobile>
|
||||
{
|
||||
private static readonly PollTimer _InternalTimer;
|
||||
|
||||
public static Dictionary<Mobile, DateTime> Stinky { get; private set; }
|
||||
|
||||
static ThrowableStinkBomb()
|
||||
{
|
||||
Stinky = new Dictionary<Mobile, DateTime>();
|
||||
|
||||
_InternalTimer = PollTimer.FromSeconds(5.0, InternalCallback, () => Stinky.Count > 0);
|
||||
}
|
||||
|
||||
private static void InternalCallback()
|
||||
{
|
||||
Stinky.RemoveKeyRange(m => !CheckStinky(m));
|
||||
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
var e = Enumerable.Empty<Tuple<Mobile, TimeSpan>>();
|
||||
e = Stinky.Aggregate(e, (c, kv) => c.With(DoStinkEffect(kv.Key).Select(t => Tuple.Create(t, kv.Value - now))));
|
||||
|
||||
foreach (var t in e.Where(t => t.Item2.TotalSeconds > 0))
|
||||
{
|
||||
MakeStinky(t.Item1, t.Item2);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool CheckStinky(Mobile m)
|
||||
{
|
||||
return Stinky.ContainsKey(m) && Stinky[m] >= DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public static void MakeStinky(Mobile m, TimeSpan duration)
|
||||
{
|
||||
Stinky[m] = DateTime.UtcNow + duration;
|
||||
}
|
||||
|
||||
public static IEnumerable<Mobile> DoStinkEffect(Mobile m)
|
||||
{
|
||||
if (!CheckStinky(m) || m.Hidden || !m.Alive)
|
||||
{
|
||||
return Enumerable.Empty<Mobile>();
|
||||
}
|
||||
|
||||
Effects.PlaySound(m.Location, m.Map, 1064);
|
||||
|
||||
new PoisonExplodeEffect(m, m.Map, 1)
|
||||
{
|
||||
EffectMutator = e =>
|
||||
{
|
||||
if (e.ProcessIndex == 0)
|
||||
{
|
||||
e.SoundID = 1064;
|
||||
}
|
||||
},
|
||||
EffectHandler = e =>
|
||||
{
|
||||
if (e.ProcessIndex != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var t in e.Source.FindMobilesInRange(e.Map, 0)
|
||||
.Where(t => t != null && !t.Deleted && t != m && !t.Hidden && t.Alive && t.Body.IsHuman))
|
||||
{
|
||||
Effects.PlaySound(t.Location, t.Map, Utility.RandomList(1065, 1066, 1067));
|
||||
}
|
||||
}
|
||||
}.Send();
|
||||
|
||||
return m.FindMobilesInRange(m.Map, 1)
|
||||
.Where(t => t != null && !t.Deleted && t != m && !t.Hidden && t.Alive && t.Body.IsHuman);
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ExplosionRange { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TimeSpan StinkyDuration { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableStinkBomb()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableStinkBomb(int amount)
|
||||
: base(Utility.RandomList(10248, 10249), amount)
|
||||
{
|
||||
Name = "Stink Bomb";
|
||||
Usage = "Throw To Unleash A Terrible Smell!";
|
||||
Hue = 1270;
|
||||
Weight = 1.0;
|
||||
Stackable = true;
|
||||
|
||||
StinkyDuration = TimeSpan.FromSeconds(30.0);
|
||||
|
||||
TargetFlags = TargetFlags.None;
|
||||
Delivery = ThrowableAtMobileDelivery.None;
|
||||
|
||||
ThrowSound = 1491;
|
||||
ImpactSound = 1064;
|
||||
|
||||
EffectID = ItemID;
|
||||
EffectHue = Hue;
|
||||
|
||||
ThrowRecovery = TimeSpan.FromSeconds(60.0);
|
||||
|
||||
ExplosionRange = 5;
|
||||
|
||||
RequiredSkill = SkillName.Alchemy;
|
||||
RequiredSkillValue = 25.0;
|
||||
}
|
||||
|
||||
public ThrowableStinkBomb(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
protected override void OnThrownAt(Mobile from, Mobile target)
|
||||
{
|
||||
if (from == null || from.Deleted || target == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int layer = 0, range = ExplosionRange; layer < ExplosionRange && range >= 0; layer++, range--)
|
||||
{
|
||||
new PoisonExplodeEffect(target.Clone3D(0, 0, layer * 10), target.Map, range, 0, null, ExplosionStink).Send();
|
||||
}
|
||||
|
||||
base.OnThrownAt(from, target);
|
||||
}
|
||||
|
||||
public virtual void ExplosionStink(EffectInfo info)
|
||||
{
|
||||
Effects.PlaySound(info.Source.Location, info.Map, ImpactSound);
|
||||
|
||||
foreach (var m in info.Source.FindMobilesInRange(info.Map, 0)
|
||||
.Not(t => t == null || t.Deleted || t.Hidden || (!t.Alive && !AllowDeadTarget)))
|
||||
{
|
||||
Effects.PlaySound(m.Location, m.Map, Utility.RandomList(1065, 1066, 1067));
|
||||
|
||||
if (StinkyDuration > TimeSpan.Zero)
|
||||
{
|
||||
MakeStinky(m, StinkyDuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
writer.Write(ExplosionRange);
|
||||
writer.Write(StinkyDuration);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
ExplosionRange = reader.ReadInt();
|
||||
StinkyDuration = reader.ReadTimeSpan();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (StinkyDuration <= TimeSpan.Zero)
|
||||
{
|
||||
StinkyDuration = TimeSpan.FromSeconds(30);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
|
||||
using VitaNex.FX;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
[Flipable(8790, 8791)]
|
||||
public class ThrowableCureBomb : BaseThrowableAtMobile<Mobile>
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ExplosionRange { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public override string Usage
|
||||
{
|
||||
get => !String.IsNullOrWhiteSpace(base.Usage)
|
||||
? base.Usage
|
||||
: String.Format(
|
||||
"Cause an explosion at the target which will attempt to cure all allies within {0:#,0} paces.",
|
||||
ExplosionRange);
|
||||
set => base.Usage = value;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public ThrowableCureBomb()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableCureBomb(int amount)
|
||||
: base(Utility.RandomList(8790, 8791), amount)
|
||||
{
|
||||
Name = "Curing Bobomb";
|
||||
Usage = String.Empty;
|
||||
Hue = 74;
|
||||
Weight = 10.0;
|
||||
Stackable = true;
|
||||
|
||||
Delivery = ThrowableAtMobileDelivery.None;
|
||||
|
||||
ThrowSound = 1491;
|
||||
ImpactSound = Utility.RandomList(776, 777);
|
||||
|
||||
EffectID = ItemID;
|
||||
EffectHue = Hue;
|
||||
|
||||
ThrowRecovery = TimeSpan.FromSeconds(60.0);
|
||||
|
||||
ExplosionRange = 5;
|
||||
|
||||
RequiredSkillValue = 100.0;
|
||||
}
|
||||
|
||||
public ThrowableCureBomb(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
protected override void OnThrownAt(Mobile from, Mobile target)
|
||||
{
|
||||
if (from == null || from.Deleted || target == null || target.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var fx = new PoisonExplodeEffect(target, target.Map, ExplosionRange)
|
||||
{
|
||||
EffectHandler = e =>
|
||||
{
|
||||
if (e.ProcessIndex != 0)
|
||||
{
|
||||
ExplosionCure(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
fx.Send();
|
||||
|
||||
base.OnThrownAt(from, target);
|
||||
}
|
||||
|
||||
public virtual void ExplosionCure(EffectInfo info)
|
||||
{
|
||||
Effects.PlaySound(info.Source.Location, info.Map, ImpactSound);
|
||||
|
||||
var targets = info.Source.Location.GetMobilesInRange(info.Map, 0);
|
||||
|
||||
foreach (var m in targets.Where(m => m != null && !m.Deleted && User.CanBeBeneficial(m, false, false)))
|
||||
{
|
||||
m.PlaySound(ImpactSound);
|
||||
m.CurePoison(User);
|
||||
}
|
||||
|
||||
targets.Free(true);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
writer.Write(ExplosionRange);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
ExplosionRange = reader.ReadInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
|
||||
using VitaNex.FX;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
[Flipable(8790, 8791)]
|
||||
public class ThrowableHealBomb : BaseThrowableAtMobile<Mobile>
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ExplosionRange { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public override string Usage
|
||||
{
|
||||
get => !String.IsNullOrWhiteSpace(base.Usage)
|
||||
? base.Usage
|
||||
: String.Format(
|
||||
"Cause an explosion at the target which will replenish {0:#,0} to {1:#,0} health for all allies within {2:#,0} paces.",
|
||||
HealMin,
|
||||
HealMax,
|
||||
ExplosionRange);
|
||||
set => base.Usage = value;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public ThrowableHealBomb()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableHealBomb(int amount)
|
||||
: base(Utility.RandomList(8790, 8791), amount)
|
||||
{
|
||||
Name = "Healing Bobomb";
|
||||
Usage = String.Empty;
|
||||
Hue = 55;
|
||||
Weight = 10.0;
|
||||
Stackable = true;
|
||||
|
||||
Delivery = ThrowableAtMobileDelivery.None;
|
||||
|
||||
Heals = true;
|
||||
HealMin = 25;
|
||||
HealMax = 100;
|
||||
|
||||
ThrowSound = 1491;
|
||||
ImpactSound = Utility.RandomList(776, 777);
|
||||
|
||||
EffectID = ItemID;
|
||||
EffectHue = Hue;
|
||||
|
||||
ThrowRecovery = TimeSpan.FromSeconds(60.0);
|
||||
|
||||
ExplosionRange = 5;
|
||||
|
||||
RequiredSkillValue = 100.0;
|
||||
}
|
||||
|
||||
public ThrowableHealBomb(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
protected override void OnThrownAt(Mobile from, Mobile target)
|
||||
{
|
||||
if (from == null || from.Deleted || target == null || target.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var fx = new EnergyExplodeEffect(target, target.Map, ExplosionRange)
|
||||
{
|
||||
EffectHandler = e =>
|
||||
{
|
||||
if (e.ProcessIndex != 0)
|
||||
{
|
||||
ExplosionHeal(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
fx.Send();
|
||||
|
||||
base.OnThrownAt(from, target);
|
||||
}
|
||||
|
||||
public virtual void ExplosionHeal(EffectInfo info)
|
||||
{
|
||||
Effects.PlaySound(info.Source.Location, info.Map, ImpactSound);
|
||||
|
||||
var targets = info.Source.Location.GetMobilesInRange(info.Map, 0);
|
||||
|
||||
foreach (var m in targets.Where(m => m != null && !m.Deleted && User.CanBeBeneficial(m, false, false)))
|
||||
{
|
||||
m.PlaySound(ImpactSound);
|
||||
m.Heal(Utility.RandomMinMax(HealMin, HealMax), User, true);
|
||||
}
|
||||
|
||||
targets.Free(true);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
writer.Write(ExplosionRange);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
ExplosionRange = reader.ReadInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
|
||||
using VitaNex.FX;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
[Flipable(8790, 8791)]
|
||||
public class ThrowableManaBomb : BaseThrowableAtMobile<Mobile>
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ExplosionRange { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public override string Usage
|
||||
{
|
||||
get => !String.IsNullOrWhiteSpace(base.Usage)
|
||||
? base.Usage
|
||||
: String.Format(
|
||||
"Cause an explosion at the target which will replenish {0:#,0} to {1:#,0} mana for all allies within {2:#,0} paces.",
|
||||
HealMin,
|
||||
HealMax,
|
||||
ExplosionRange);
|
||||
set => base.Usage = value;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public ThrowableManaBomb()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableManaBomb(int amount)
|
||||
: base(Utility.RandomList(8790, 8791), amount)
|
||||
{
|
||||
Name = "Mana Bobomb";
|
||||
Usage = String.Empty;
|
||||
Hue = 2;
|
||||
Weight = 10.0;
|
||||
Stackable = true;
|
||||
|
||||
Delivery = ThrowableAtMobileDelivery.None;
|
||||
|
||||
HealMin = 25;
|
||||
HealMax = 100;
|
||||
|
||||
ThrowSound = 1491;
|
||||
ImpactSound = Utility.RandomList(776, 777);
|
||||
|
||||
EffectID = ItemID;
|
||||
EffectHue = Hue;
|
||||
|
||||
ThrowRecovery = TimeSpan.FromSeconds(60.0);
|
||||
|
||||
ExplosionRange = 5;
|
||||
|
||||
RequiredSkillValue = 100.0;
|
||||
}
|
||||
|
||||
public ThrowableManaBomb(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
protected override void OnThrownAt(Mobile from, Mobile target)
|
||||
{
|
||||
if (from == null || from.Deleted || target == null || target.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var fx = new EnergyExplodeEffect(target, target.Map, ExplosionRange)
|
||||
{
|
||||
EffectHandler = e =>
|
||||
{
|
||||
if (e.ProcessIndex != 0)
|
||||
{
|
||||
ExplosionMana(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
fx.Send();
|
||||
|
||||
base.OnThrownAt(from, target);
|
||||
}
|
||||
|
||||
public virtual void ExplosionMana(EffectInfo info)
|
||||
{
|
||||
Effects.PlaySound(info.Source.Location, info.Map, ImpactSound);
|
||||
|
||||
var targets = info.Source.Location.GetMobilesInRange(info.Map, 0);
|
||||
|
||||
foreach (var m in targets.Where(m => m != null && !m.Deleted && User.CanBeBeneficial(m, false, false)))
|
||||
{
|
||||
m.PlaySound(ImpactSound);
|
||||
m.Mana += Utility.RandomMinMax(HealMin, HealMax);
|
||||
}
|
||||
|
||||
targets.Free(true);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
writer.Write(ExplosionRange);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
ExplosionRange = reader.ReadInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Network;
|
||||
using Server.Targeting;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class ThrowableAxe : BaseThrowableAtMobile<Mobile>
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool InstantKillForced { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int InstantKillChance { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool InstantKillHead { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableAxe()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableAxe(int amount)
|
||||
: base(0x255D, amount)
|
||||
{
|
||||
InstantKillForced = false;
|
||||
InstantKillChance = 1;
|
||||
|
||||
Name = "Throwing Axe";
|
||||
Usage = "When thrown, has a slight chance to decapitate the target.";
|
||||
Token = "BOOM! Head Shot!";
|
||||
|
||||
Weight = 10.0;
|
||||
Stackable = true;
|
||||
Consumable = true;
|
||||
AllowCombat = true;
|
||||
|
||||
TargetFlags = TargetFlags.Harmful;
|
||||
|
||||
Delivery = ThrowableAtMobileDelivery.MoveToWorld;
|
||||
DismountUser = true;
|
||||
|
||||
Damages = true;
|
||||
DamageMin = 30;
|
||||
DamageMax = 50;
|
||||
|
||||
ThrowSound = 513;
|
||||
ImpactSound = 1310;
|
||||
|
||||
EffectID = ItemID;
|
||||
EffectHue = Hue;
|
||||
|
||||
ThrowRecovery = TimeSpan.FromMinutes(2.0);
|
||||
|
||||
RequiredSkill = SkillName.Tactics;
|
||||
RequiredSkillValue = 50.0;
|
||||
}
|
||||
|
||||
public ThrowableAxe(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
protected virtual SeveredHead CreateHead(Mobile target)
|
||||
{
|
||||
return !InstantKillHead || target == null || !target.Body.IsHuman || target.Blessed ? null : new SeveredHead(target);
|
||||
}
|
||||
|
||||
protected override void OnThrownAt(Mobile m, Mobile target)
|
||||
{
|
||||
if (m != null && target != null && (InstantKillForced || Utility.RandomDouble() < InstantKillChance / 100.0))
|
||||
{
|
||||
SeveredHead.Decapitate(m, target, CreateHead);
|
||||
m.PublicOverheadMessage(MessageType.Yell, 37, true, "BOOM! Head Shot!");
|
||||
}
|
||||
|
||||
base.OnThrownAt(m, target);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(2);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 2:
|
||||
case 1:
|
||||
writer.Write(InstantKillHead);
|
||||
goto case 0;
|
||||
case 0:
|
||||
{
|
||||
writer.Write(InstantKillForced);
|
||||
writer.Write(InstantKillChance);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 2:
|
||||
case 1:
|
||||
InstantKillHead = reader.ReadBool();
|
||||
goto case 0;
|
||||
case 0:
|
||||
{
|
||||
InstantKillForced = reader.ReadBool();
|
||||
InstantKillChance = version < 2 ? (int)reader.ReadDouble() : reader.ReadInt();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
|
||||
using VitaNex.FX;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
[Flipable(8790, 8791)]
|
||||
public class ThrowableBomb : BaseThrowableAtMobile<Mobile>
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ExplosionRange { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public override string Usage
|
||||
{
|
||||
get => !String.IsNullOrWhiteSpace(base.Usage)
|
||||
? base.Usage
|
||||
: String.Format(
|
||||
"Cause an explosion at the target which will deal {0:#,0} to {1:#,0} damage to all enemies within {2:#,0} paces.",
|
||||
DamageMin,
|
||||
DamageMax,
|
||||
ExplosionRange);
|
||||
set => base.Usage = value;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public ThrowableBomb()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableBomb(int amount)
|
||||
: base(Utility.RandomList(8790, 8791), amount)
|
||||
{
|
||||
Name = "Bobomb";
|
||||
Token = "A.C.M.E";
|
||||
Hue = 2104;
|
||||
Weight = 10.0;
|
||||
Stackable = true;
|
||||
|
||||
Delivery = ThrowableAtMobileDelivery.None;
|
||||
|
||||
Damages = true;
|
||||
DamageMin = 25;
|
||||
DamageMax = 50;
|
||||
|
||||
ThrowSound = 1491;
|
||||
ImpactSound = Utility.RandomList(776, 777);
|
||||
|
||||
EffectID = ItemID;
|
||||
EffectHue = Hue;
|
||||
|
||||
ThrowRecovery = TimeSpan.FromSeconds(60.0);
|
||||
|
||||
ExplosionRange = 5;
|
||||
|
||||
RequiredSkillValue = 100.0;
|
||||
}
|
||||
|
||||
public ThrowableBomb(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
protected override void OnThrownAt(Mobile from, Mobile target)
|
||||
{
|
||||
if (from == null || from.Deleted || target == null || target.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var fx = new FireExplodeEffect(target, target.Map, ExplosionRange)
|
||||
{
|
||||
EffectHandler = e =>
|
||||
{
|
||||
if (e.ProcessIndex != 0)
|
||||
{
|
||||
ExplosionDamage(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
fx.Send();
|
||||
|
||||
base.OnThrownAt(from, target);
|
||||
}
|
||||
|
||||
public virtual void ExplosionDamage(EffectInfo info)
|
||||
{
|
||||
Effects.PlaySound(info.Source.Location, info.Map, ImpactSound);
|
||||
|
||||
foreach (var m in info.Source.Location.GetMobilesInRange(info.Map, 0)
|
||||
.Where(m => m != null && !m.Deleted && User.CanBeHarmful(m, false, true)))
|
||||
{
|
||||
m.PlaySound(ImpactSound);
|
||||
m.Damage(Utility.RandomMinMax(DamageMin, DamageMax), User, true);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(1);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
case 0:
|
||||
writer.Write(ExplosionRange);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
case 0:
|
||||
{
|
||||
ExplosionRange = reader.ReadInt();
|
||||
|
||||
if (version < 1)
|
||||
{
|
||||
reader.ReadInt();
|
||||
reader.ReadInt();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Targeting;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class ThrowableTrainingDagger : ThrowableDagger
|
||||
{
|
||||
private PollTimer TrainingTimer { get; set; }
|
||||
private Point3D TrainingLocation { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public double SkillGainChance { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableTrainingDagger()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableTrainingDagger(int amount)
|
||||
: base(amount)
|
||||
{
|
||||
SkillGainChance = 25.0;
|
||||
|
||||
Name = "Throwing Training Dagger";
|
||||
Usage = "Throw at a target to train your Throwing skill.";
|
||||
|
||||
Hue = 2020;
|
||||
Layer = Layer.OneHanded;
|
||||
Weight = 1.0;
|
||||
Stackable = true;
|
||||
|
||||
TargetFlags = TargetFlags.None;
|
||||
|
||||
Consumable = false;
|
||||
Delivery = ThrowableAtMobileDelivery.None;
|
||||
DismountUser = false;
|
||||
|
||||
Damages = false;
|
||||
DamageMin = 0;
|
||||
DamageMax = 0;
|
||||
|
||||
ThrowRecovery = TimeSpan.Zero;
|
||||
|
||||
RequiredSkillValue = 0;
|
||||
}
|
||||
|
||||
public ThrowableTrainingDagger(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
protected override void OnThrownAt(Mobile from, Mobile target)
|
||||
{
|
||||
base.OnThrownAt(from, target);
|
||||
|
||||
if (Utility.RandomDouble() * 100 <= SkillGainChance)
|
||||
{
|
||||
from.Skills[RequiredSkill].IncreaseBase(Utility.RandomDouble());
|
||||
}
|
||||
|
||||
CheckTraining(from, target);
|
||||
}
|
||||
|
||||
public virtual void CheckTraining(Mobile from, Mobile target)
|
||||
{
|
||||
if (from == null || from.Deleted || target == null || target.Deleted)
|
||||
{
|
||||
if (TrainingTimer != null)
|
||||
{
|
||||
TrainingTimer.Stop();
|
||||
TrainingTimer = null;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (TrainingTimer == null)
|
||||
{
|
||||
TrainingLocation = from.Location;
|
||||
|
||||
TrainingTimer = PollTimer.CreateInstance(
|
||||
TimeSpan.FromSeconds(1.0),
|
||||
() =>
|
||||
{
|
||||
if (from.Location != TrainingLocation)
|
||||
{
|
||||
TrainingTimer.Stop();
|
||||
TrainingTimer = null;
|
||||
return;
|
||||
}
|
||||
|
||||
BeginThrow(from, target);
|
||||
});
|
||||
}
|
||||
else if (from.Location != TrainingLocation)
|
||||
{
|
||||
TrainingTimer.Stop();
|
||||
TrainingTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
writer.Write(SkillGainChance);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
SkillGainChance = reader.ReadDouble();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Flipable(3921, 3922)]
|
||||
public class ThrowableDagger : BaseThrowableAtMobile<Mobile>
|
||||
{
|
||||
[Constructable]
|
||||
public ThrowableDagger()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public ThrowableDagger(int amount)
|
||||
: base(Utility.RandomList(3921, 3922), amount)
|
||||
{
|
||||
Name = "Throwing Dagger";
|
||||
|
||||
Layer = Layer.OneHanded;
|
||||
Weight = 1.0;
|
||||
Stackable = true;
|
||||
|
||||
TargetFlags = TargetFlags.Harmful;
|
||||
|
||||
Delivery = ThrowableAtMobileDelivery.AddToPack;
|
||||
DismountUser = false;
|
||||
|
||||
Damages = true;
|
||||
DamageMin = 20;
|
||||
DamageMax = 40;
|
||||
|
||||
ThrowSound = 1492;
|
||||
ImpactSound = 903;
|
||||
|
||||
EffectID = ItemID;
|
||||
EffectHue = Hue;
|
||||
|
||||
ThrowRecovery = TimeSpan.FromSeconds(60.0);
|
||||
RequiredSkillValue = 60.0;
|
||||
}
|
||||
|
||||
public ThrowableDagger(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{ }
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{ }
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public abstract class BaseDazingThrowable<TMobile> : BaseThrowableAtMobile<TMobile>
|
||||
where TMobile : Mobile
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual TimeSpan MountRecovery { get; set; }
|
||||
|
||||
public BaseDazingThrowable(int itemID, int amount = 1)
|
||||
: base(itemID, amount)
|
||||
{
|
||||
MountRecovery = TimeSpan.FromSeconds(3.0);
|
||||
}
|
||||
|
||||
public BaseDazingThrowable(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override bool CanThrowAt(Mobile from, TMobile target, bool message)
|
||||
{
|
||||
if (!base.CanThrowAt(from, target, message))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!target.Mounted)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
from.SendMessage(37, "Your target is not mounted.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void OnThrownAt(Mobile from, TMobile target)
|
||||
{
|
||||
base.OnThrownAt(from, target);
|
||||
|
||||
var mounted = target.Mounted;
|
||||
|
||||
if (target is PlayerMobile)
|
||||
{
|
||||
var pm = target as PlayerMobile;
|
||||
|
||||
pm.SetMountBlock(BlockMountType.Dazed, MountRecovery, mounted);
|
||||
}
|
||||
|
||||
if (!mounted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BaseMount.Dismount(target);
|
||||
OnTargetDismounted(from, target, true);
|
||||
}
|
||||
|
||||
protected virtual void OnTargetDismounted(Mobile from, TMobile target, bool message)
|
||||
{
|
||||
if (from == null || from.Deleted || target == null || target.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (message)
|
||||
{
|
||||
target.SendMessage(37, "{0} has brought you down with the {1}!", from.RawName, Name);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
writer.Write(MountRecovery);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
MountRecovery = reader.ReadTimeSpan();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,633 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
using Server.Spells;
|
||||
using Server.Targeting;
|
||||
|
||||
using VitaNex.FX;
|
||||
using VitaNex.Network;
|
||||
using VitaNex.Targets;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public abstract class BaseThrowable<TEntity> : Item, IBaseThrowable
|
||||
where TEntity : IEntity
|
||||
{
|
||||
public PollTimer UpdateTimer { get; protected set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual bool Silent { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual string Usage { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual string Token { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual bool AllowNoOwner { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual bool AllowCombat { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual bool AllowDeadUser { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual bool Consumable { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual bool ClearHands { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual bool DismountUser { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual int EffectID { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual int EffectHue { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual int EffectSpeed { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual EffectRender EffectRender { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual TargetFlags TargetFlags { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual int ThrowSound { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual int ImpactSound { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual int ThrowRange { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual TimeSpan ThrowRecovery { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual DateTime ThrownLast { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual SkillName RequiredSkill { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual double RequiredSkillValue { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual Mobile User { get; set; }
|
||||
|
||||
public BaseThrowable(int itemID)
|
||||
: this(itemID, 1)
|
||||
{ }
|
||||
|
||||
public BaseThrowable(int itemID, int amount)
|
||||
: base(itemID)
|
||||
{
|
||||
Stackable = true;
|
||||
Amount = amount;
|
||||
Weight = 1.0;
|
||||
|
||||
Usage = "Throw Me!";
|
||||
AllowNoOwner = false;
|
||||
AllowCombat = true;
|
||||
AllowDeadUser = false;
|
||||
Consumable = true;
|
||||
ClearHands = true;
|
||||
DismountUser = true;
|
||||
EffectID = 0;
|
||||
EffectHue = 0;
|
||||
EffectRender = EffectRender.Normal;
|
||||
EffectSpeed = 10;
|
||||
ThrowSound = -1;
|
||||
ImpactSound = -1;
|
||||
ThrowRecovery = TimeSpan.FromSeconds(60.0);
|
||||
ThrowRange = 12;
|
||||
RequiredSkill = SkillName.Throwing;
|
||||
RequiredSkillValue = 0;
|
||||
}
|
||||
|
||||
public BaseThrowable(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void OnAfterDuped(Item newItem)
|
||||
{
|
||||
base.OnAfterDuped(newItem);
|
||||
|
||||
var t = newItem as BaseThrowable<TEntity>;
|
||||
|
||||
if (t != null)
|
||||
{
|
||||
t.UpdateTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
base.OnAfterDelete();
|
||||
|
||||
if (UpdateTimer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateTimer.Running = false;
|
||||
UpdateTimer = null;
|
||||
}
|
||||
|
||||
public virtual bool CanThrow(Mobile m, bool message)
|
||||
{
|
||||
if (m == null || m.Deleted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m.AccessLevel >= AccessLevel.GameMaster)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!AllowNoOwner && RootParent != m)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage(37, "You must own the {0} before you can throw it!", this.ResolveName(m));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m.Alive && !AllowDeadUser)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage(37, "You can't throw the {0} while dead.", this.ResolveName(m));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (RequiredSkillValue > 0 && m.Skills[RequiredSkill].Value < RequiredSkillValue)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage(37, "You do not have the skill required to throw the {0}.", this.ResolveName(m));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m.CanBeginAction(GetType()))
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage(37, "Your arms are tired, you must wait to throw another {0}!", this.ResolveName(m));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!AllowCombat && SpellHelper.CheckCombat(m))
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage(37, "You can't throw the {0} while in combat!", this.ResolveName(m));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m.BodyMod > 0 && !m.BodyMod.IsHuman)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage(37, "How are you supposed to throw the {0} with no hands, beast?", this.ResolveName(m));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool CanThrowAt(Mobile m, TEntity target, bool message)
|
||||
{
|
||||
if (m == null || m.Deleted || target == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m == target as Mobile)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage(37, "You can't throw the {0} at yourself!", this.ResolveName(m));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m.AccessLevel >= AccessLevel.GameMaster)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!m.CanSee(target) || !m.InLOS(target))
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
m.SendMessage(37, "You can't aim at something you can't see!");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void BeginThrow(Mobile m, TEntity target)
|
||||
{
|
||||
if (m == null || m.Deleted || target == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CanThrow(m, true) || !CanThrowAt(m, target, true) ||
|
||||
(m.AccessLevel < AccessLevel.GameMaster && !m.BeginAction(GetType())))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
User = m;
|
||||
|
||||
OnBeforeThrownAt(m, target);
|
||||
|
||||
var effect = EffectID > 0 ? EffectID : ItemID;
|
||||
var hue = EffectHue > 0 ? EffectHue : Hue;
|
||||
|
||||
new MovingEffectInfo(m, target, target.Map, effect, hue, EffectSpeed, EffectRender).MovingImpact(
|
||||
() => FinishThrow(m, target));
|
||||
}
|
||||
|
||||
public virtual void FinishThrow(Mobile m, TEntity target)
|
||||
{
|
||||
if (m != null && !m.Deleted && target != null)
|
||||
{
|
||||
OnThrownAt(m, target);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual Target BeginTarget(Mobile m)
|
||||
{
|
||||
return new GenericSelectTarget<TEntity>(BeginThrow, t => { }, ThrowRange, false, TargetFlags);
|
||||
}
|
||||
|
||||
protected virtual void OnBeginTarget(Mobile m, bool message)
|
||||
{
|
||||
if (m == null || m.Deleted || !message || Silent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m.LocalOverheadMessage(
|
||||
MessageType.Emote,
|
||||
0x55,
|
||||
true,
|
||||
String.Format("You begin to swing the {0}...", this.ResolveName(m)));
|
||||
m.NonlocalOverheadMessage(
|
||||
MessageType.Emote,
|
||||
0x55,
|
||||
true,
|
||||
String.Format("{0} begins to swing the {1}...", m.RawName, this.ResolveName(m)));
|
||||
}
|
||||
|
||||
protected virtual void OnBeforeThrownAt(Mobile m, TEntity target)
|
||||
{
|
||||
if (m == null || m.Deleted || target == null || !CanThrowAt(m, target, false))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m.Spell != null)
|
||||
{
|
||||
m.Spell.OnCasterUsingObject(this);
|
||||
}
|
||||
|
||||
if (DismountUser)
|
||||
{
|
||||
EtherealMount.StopMounting(m);
|
||||
}
|
||||
|
||||
if (ClearHands)
|
||||
{
|
||||
m.ClearHands();
|
||||
}
|
||||
|
||||
if (DismountUser && m.Mounted)
|
||||
{
|
||||
BaseMount.Dismount(m);
|
||||
}
|
||||
|
||||
if ((m.Direction & Direction.Running) != Direction.Running)
|
||||
{
|
||||
m.Direction = m.GetDirectionTo(target.Location);
|
||||
}
|
||||
|
||||
m.Animate(11, 5, 1, true, false, 0);
|
||||
|
||||
if (ThrowSound >= 0)
|
||||
{
|
||||
m.PlaySound(ThrowSound);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnThrownAt(Mobile m, TEntity target)
|
||||
{
|
||||
if (m == null || m.Deleted || target == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ImpactSound >= 0)
|
||||
{
|
||||
Effects.PlaySound(target.Location, target.Map, ImpactSound);
|
||||
}
|
||||
|
||||
ThrownLast = DateTime.UtcNow;
|
||||
|
||||
if (Consumable)
|
||||
{
|
||||
Consume();
|
||||
}
|
||||
|
||||
if (ThrowRecovery > TimeSpan.Zero)
|
||||
{
|
||||
if (UpdateTimer == null)
|
||||
{
|
||||
UpdateTimer = PollTimer.FromSeconds(
|
||||
1.0,
|
||||
() =>
|
||||
{
|
||||
ClearProperties();
|
||||
Delta(ItemDelta.Properties);
|
||||
|
||||
var readyWhen = ThrownLast + ThrowRecovery;
|
||||
|
||||
if (DateTime.UtcNow < readyWhen)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m.EndAction(GetType());
|
||||
|
||||
if (UpdateTimer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateTimer.Running = false;
|
||||
UpdateTimer = null;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateTimer.Running = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (UpdateTimer != null)
|
||||
{
|
||||
UpdateTimer.Running = false;
|
||||
UpdateTimer = null;
|
||||
}
|
||||
|
||||
ClearProperties();
|
||||
Delta(ItemDelta.Properties);
|
||||
m.EndAction(GetType());
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
base.OnDelete();
|
||||
|
||||
if (UpdateTimer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateTimer.Running = false;
|
||||
UpdateTimer = null;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile m)
|
||||
{
|
||||
if (m == null || m.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CanThrow(m, true))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m.Spell != null)
|
||||
{
|
||||
m.Spell.OnCasterUsingObject(this);
|
||||
}
|
||||
|
||||
if (ClearHands)
|
||||
{
|
||||
m.ClearHands();
|
||||
}
|
||||
|
||||
if (DismountUser)
|
||||
{
|
||||
EtherealMount.StopMounting(m);
|
||||
}
|
||||
|
||||
if (DismountUser && m.Mounted)
|
||||
{
|
||||
BaseMount.Dismount(m);
|
||||
}
|
||||
|
||||
m.Target = BeginTarget(m);
|
||||
OnBeginTarget(m, true);
|
||||
}
|
||||
|
||||
public override void OnAosSingleClick(Mobile from)
|
||||
{
|
||||
OnSingleClick(from);
|
||||
}
|
||||
|
||||
public override void OnSingleClick(Mobile from)
|
||||
{
|
||||
base.OnSingleClick(from);
|
||||
|
||||
DateTime now = DateTime.UtcNow, readyWhen = ThrownLast + ThrowRecovery;
|
||||
var diff = TimeSpan.Zero;
|
||||
|
||||
if (readyWhen > now)
|
||||
{
|
||||
diff = readyWhen - now;
|
||||
}
|
||||
|
||||
if (diff > TimeSpan.Zero)
|
||||
{
|
||||
var time = String.Format("{0:D2}:{1:D2}:{2:D2}", diff.Hours, diff.Minutes, diff.Seconds);
|
||||
LabelTo(from, "Use: {0}", time);
|
||||
}
|
||||
else if (!String.IsNullOrWhiteSpace(Usage))
|
||||
{
|
||||
LabelTo(from, "Use: {0}", Usage);
|
||||
}
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(Token))
|
||||
{
|
||||
LabelTo(from, "\"{0}\"", Token);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(2);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 3:
|
||||
writer.Write(AllowNoOwner);
|
||||
goto case 2;
|
||||
case 2:
|
||||
case 1:
|
||||
writer.Write(Silent);
|
||||
goto case 0;
|
||||
case 0:
|
||||
{
|
||||
writer.Write(Usage);
|
||||
writer.Write(Token);
|
||||
writer.Write(AllowCombat);
|
||||
writer.Write(AllowDeadUser);
|
||||
writer.Write(Consumable);
|
||||
writer.Write(ClearHands);
|
||||
writer.Write(DismountUser);
|
||||
writer.Write(EffectID);
|
||||
writer.Write(EffectHue);
|
||||
writer.Write(EffectSpeed);
|
||||
|
||||
if (version < 2)
|
||||
{
|
||||
writer.Write((short)EffectRender);
|
||||
writer.Write((byte)TargetFlags);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteFlag(EffectRender);
|
||||
writer.WriteFlag(TargetFlags);
|
||||
}
|
||||
|
||||
writer.Write(ThrowSound);
|
||||
writer.Write(ImpactSound);
|
||||
writer.Write(ThrowRange);
|
||||
writer.Write(ThrowRecovery);
|
||||
writer.Write(ThrownLast);
|
||||
|
||||
if (version < 2)
|
||||
{
|
||||
writer.Write((short)RequiredSkill);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteFlag(RequiredSkill);
|
||||
}
|
||||
|
||||
writer.Write(RequiredSkillValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 3:
|
||||
AllowNoOwner = reader.ReadBool();
|
||||
goto case 2;
|
||||
case 2:
|
||||
case 1:
|
||||
Silent = reader.ReadBool();
|
||||
goto case 0;
|
||||
case 0:
|
||||
{
|
||||
Usage = reader.ReadString();
|
||||
Token = reader.ReadString();
|
||||
AllowCombat = reader.ReadBool();
|
||||
AllowDeadUser = reader.ReadBool();
|
||||
Consumable = reader.ReadBool();
|
||||
ClearHands = reader.ReadBool();
|
||||
DismountUser = reader.ReadBool();
|
||||
EffectID = reader.ReadInt();
|
||||
EffectHue = reader.ReadInt();
|
||||
EffectSpeed = reader.ReadInt();
|
||||
|
||||
if (version < 2)
|
||||
{
|
||||
EffectRender = (EffectRender)reader.ReadShort();
|
||||
TargetFlags = (TargetFlags)reader.ReadByte();
|
||||
}
|
||||
else
|
||||
{
|
||||
EffectRender = reader.ReadFlag<EffectRender>();
|
||||
TargetFlags = reader.ReadFlag<TargetFlags>();
|
||||
}
|
||||
|
||||
ThrowSound = reader.ReadInt();
|
||||
ImpactSound = reader.ReadInt();
|
||||
ThrowRange = reader.ReadInt();
|
||||
ThrowRecovery = reader.ReadTimeSpan();
|
||||
ThrownLast = reader.ReadDateTime();
|
||||
|
||||
if (version < 2)
|
||||
{
|
||||
RequiredSkill = (SkillName)reader.ReadShort();
|
||||
}
|
||||
else
|
||||
{
|
||||
RequiredSkill = reader.ReadFlag<SkillName>();
|
||||
}
|
||||
|
||||
RequiredSkillValue = reader.ReadDouble();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Targeting;
|
||||
|
||||
using VitaNex.Targets;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public enum ThrowableAtMobileDelivery : byte
|
||||
{
|
||||
None = 0x00,
|
||||
MoveToWorld = 0x01,
|
||||
AddToPack = 0x02
|
||||
}
|
||||
|
||||
public abstract class BaseThrowableAtMobile<TMobile> : BaseThrowable<TMobile>
|
||||
where TMobile : Mobile
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual bool AllowDeadTarget { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual ThrowableAtMobileDelivery Delivery { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual bool Damages { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual int DamageMin { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual int DamageMax { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual bool Heals { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual int HealMin { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual int HealMax { get; set; }
|
||||
|
||||
public BaseThrowableAtMobile(int itemID)
|
||||
: this(itemID, 1)
|
||||
{ }
|
||||
|
||||
public BaseThrowableAtMobile(int itemID, int amount)
|
||||
: base(itemID, amount)
|
||||
{
|
||||
AllowDeadTarget = false;
|
||||
Delivery = ThrowableAtMobileDelivery.MoveToWorld;
|
||||
Damages = false;
|
||||
DamageMin = 0;
|
||||
DamageMax = 0;
|
||||
Heals = false;
|
||||
HealMin = 0;
|
||||
HealMax = 0;
|
||||
}
|
||||
|
||||
public BaseThrowableAtMobile(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override bool CanThrowAt(Mobile from, TMobile target, bool message)
|
||||
{
|
||||
if (from == null || from.Deleted || target == null || target.Deleted || !base.CanThrowAt(from, target, message))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!target.Alive && !AllowDeadTarget)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
from.SendMessage(37, "You can't throw the {0} at the dead.", Name);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (target.Alive && Damages && !from.CanBeHarmful(target, false, true))
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
from.SendMessage(37, "You can't harm them.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (target.Alive && Heals && !from.CanBeBeneficial(target, false, true))
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
from.SendMessage(37, "You can't heal them.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void OnBeforeThrownAt(Mobile from, TMobile target)
|
||||
{
|
||||
if (from == null || from.Deleted || target == null || target.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (target.Alive && Heals)
|
||||
{
|
||||
from.DoBeneficial(target);
|
||||
}
|
||||
|
||||
if (target.Alive && Damages)
|
||||
{
|
||||
from.DoHarmful(target);
|
||||
}
|
||||
|
||||
base.OnBeforeThrownAt(from, target);
|
||||
}
|
||||
|
||||
protected override void OnThrownAt(Mobile from, TMobile target)
|
||||
{
|
||||
if (from == null || from.Deleted || target == null || target.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (target.Alive && Damages)
|
||||
{
|
||||
target.Damage(Utility.RandomMinMax(DamageMin, DamageMax), from);
|
||||
}
|
||||
|
||||
if (target.Alive && Heals)
|
||||
{
|
||||
target.Heal(Utility.RandomMinMax(HealMin, HealMax), from);
|
||||
}
|
||||
|
||||
if (Delivery != ThrowableAtMobileDelivery.None)
|
||||
{
|
||||
var instance = VitaNexCore.TryCatchGet(() => GetType().CreateInstance<BaseThrowableAtMobile<TMobile>>());
|
||||
|
||||
if (instance != null)
|
||||
{
|
||||
switch (Delivery)
|
||||
{
|
||||
case ThrowableAtMobileDelivery.MoveToWorld:
|
||||
instance.MoveToWorld(target.Location, target.Map);
|
||||
break;
|
||||
case ThrowableAtMobileDelivery.AddToPack:
|
||||
{
|
||||
if (!target.AddToBackpack(instance))
|
||||
{
|
||||
instance.MoveToWorld(target.Location, target.Map);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
instance.Delete();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base.OnThrownAt(from, target);
|
||||
}
|
||||
|
||||
public override Target BeginTarget(Mobile from)
|
||||
{
|
||||
return new MobileSelectTarget<TMobile>(BeginThrow, src => { }, ThrowRange, false, TargetFlags);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(1);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
case 0:
|
||||
{
|
||||
writer.Write(AllowDeadTarget);
|
||||
|
||||
if (version < 1)
|
||||
{
|
||||
writer.Write((byte)Delivery);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteFlag(Delivery);
|
||||
}
|
||||
|
||||
writer.Write(Damages);
|
||||
writer.Write(DamageMin);
|
||||
writer.Write(DamageMax);
|
||||
writer.Write(Heals);
|
||||
writer.Write(HealMin);
|
||||
writer.Write(HealMax);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
case 0:
|
||||
{
|
||||
AllowDeadTarget = reader.ReadBool();
|
||||
|
||||
if (version < 1)
|
||||
{
|
||||
Delivery = (ThrowableAtMobileDelivery)reader.ReadByte();
|
||||
}
|
||||
else
|
||||
{
|
||||
Delivery = reader.ReadFlag<ThrowableAtMobileDelivery>();
|
||||
}
|
||||
|
||||
Damages = reader.ReadBool();
|
||||
DamageMin = reader.ReadInt();
|
||||
DamageMax = reader.ReadInt();
|
||||
Heals = reader.ReadBool();
|
||||
HealMin = reader.ReadInt();
|
||||
HealMax = reader.ReadInt();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
|
||||
using Server;
|
||||
|
||||
using VitaNex.Network;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public static class BaseThrowableOPL
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
ExtendedOPL.OnItemOPLRequest += OnItemOPLRequest;
|
||||
}
|
||||
|
||||
private static void OnItemOPLRequest(Item item, Mobile viewer, ExtendedOPL list)
|
||||
{
|
||||
if (item == null || list == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (viewer == null && item.Parent is Mobile)
|
||||
{
|
||||
viewer = (Mobile)item.Parent;
|
||||
}
|
||||
|
||||
if (viewer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var throwable = item as IBaseThrowable;
|
||||
|
||||
if (throwable == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GetProperties(throwable, viewer, list);
|
||||
}
|
||||
|
||||
public static void GetProperties(IBaseThrowable throwable, Mobile viewer, ExtendedOPL list)
|
||||
{
|
||||
if (throwable == null || list == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var lines = new List<string>();
|
||||
|
||||
if (throwable.Consumable)
|
||||
{
|
||||
lines.Add("Consumable");
|
||||
}
|
||||
|
||||
if (throwable.ClearHands)
|
||||
{
|
||||
lines.Add("Clears Hands");
|
||||
}
|
||||
|
||||
if (!throwable.AllowCombat)
|
||||
{
|
||||
lines.Add("Non-Combat");
|
||||
}
|
||||
|
||||
if (lines.Count > 0)
|
||||
{
|
||||
list.Add(String.Join(", ", lines).WrapUOHtmlColor(Color.Orange));
|
||||
lines.Clear();
|
||||
}
|
||||
|
||||
if (throwable.RequiredSkillValue > 0)
|
||||
{
|
||||
list.Add("Required Skill: {0} - {1:F2}%", throwable.RequiredSkill, throwable.RequiredSkillValue);
|
||||
}
|
||||
|
||||
DateTime now = DateTime.UtcNow, readyWhen = (throwable.ThrownLast + throwable.ThrowRecovery);
|
||||
var diff = TimeSpan.Zero;
|
||||
|
||||
if (readyWhen > now)
|
||||
{
|
||||
diff = readyWhen - now;
|
||||
}
|
||||
|
||||
if (diff > TimeSpan.Zero)
|
||||
{
|
||||
list.Add("Use: {0:D2}:{1:D2}:{2:D2}".WrapUOHtmlColor(Color.LimeGreen), diff.Hours, diff.Minutes, diff.Seconds);
|
||||
}
|
||||
else if (!String.IsNullOrWhiteSpace(throwable.Usage))
|
||||
{
|
||||
list.Add("Use: {0}".WrapUOHtmlColor(Color.Cyan), throwable.Usage);
|
||||
}
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(throwable.Token))
|
||||
{
|
||||
list.Add("\"{0}\"".WrapUOHtmlColor(Color.Gold), throwable.Token);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Targeting;
|
||||
|
||||
using VitaNex.Network;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public interface IBaseThrowable
|
||||
{
|
||||
string Token { get; set; }
|
||||
string Usage { get; set; }
|
||||
|
||||
bool AllowCombat { get; set; }
|
||||
bool AllowDeadUser { get; set; }
|
||||
bool ClearHands { get; set; }
|
||||
bool Consumable { get; set; }
|
||||
bool DismountUser { get; set; }
|
||||
|
||||
int EffectHue { get; set; }
|
||||
int EffectID { get; set; }
|
||||
int EffectSpeed { get; set; }
|
||||
EffectRender EffectRender { get; set; }
|
||||
|
||||
int ThrowSound { get; set; }
|
||||
int ImpactSound { get; set; }
|
||||
|
||||
SkillName RequiredSkill { get; set; }
|
||||
double RequiredSkillValue { get; set; }
|
||||
|
||||
TargetFlags TargetFlags { get; set; }
|
||||
DateTime ThrownLast { get; set; }
|
||||
TimeSpan ThrowRecovery { get; set; }
|
||||
int ThrowRange { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using Server;
|
||||
using Server.Engines.Craft;
|
||||
using Server.Items;
|
||||
|
||||
using VitaNex.SuperCrafts;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class PyrotechnicsKit : BaseTool
|
||||
{
|
||||
public override CraftSystem CraftSystem => SuperCraftSystem.Resolve<Pyrotechnics>();
|
||||
|
||||
[Constructable]
|
||||
public PyrotechnicsKit()
|
||||
: this(50)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public PyrotechnicsKit(int uses)
|
||||
: base(uses, Utility.RandomList(39213, 39214))
|
||||
{
|
||||
Name = "Pyrotechnics Kit";
|
||||
Weight = 2.0;
|
||||
}
|
||||
|
||||
public PyrotechnicsKit(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
194
Scripts/SubSystem/VitaNex/Core/Items/Utility/AccessCloak.cs
Normal file
194
Scripts/SubSystem/VitaNex/Core/Items/Utility/AccessCloak.cs
Normal file
@@ -0,0 +1,194 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class AccessCloak : BaseCloak
|
||||
{
|
||||
private AccessLevel _AccessTemp;
|
||||
private AccessLevel _AccessMask;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public AccessLevel AccessMask
|
||||
{
|
||||
get => _AccessMask;
|
||||
set
|
||||
{
|
||||
if (value <= _AccessTemp)
|
||||
{
|
||||
_AccessMask = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool DisplayLootType => false;
|
||||
public override bool DisplayWeight => false;
|
||||
|
||||
[Constructable]
|
||||
public AccessCloak()
|
||||
: this(AccessLevel.Player)
|
||||
{ }
|
||||
|
||||
public AccessCloak(Mobile owner)
|
||||
: this(owner, AccessLevel.Player)
|
||||
{ }
|
||||
|
||||
public AccessCloak(Mobile owner, AccessLevel mask)
|
||||
: this(mask)
|
||||
{
|
||||
_AccessTemp = owner != null ? owner.AccessLevel : AccessLevel.Player;
|
||||
}
|
||||
|
||||
public AccessCloak(AccessLevel mask)
|
||||
: base(0x1515)
|
||||
{
|
||||
_AccessMask = mask;
|
||||
|
||||
Name = "Access Cloak";
|
||||
Hue = Utility.RandomDyedHue();
|
||||
LootType = LootType.Blessed;
|
||||
StrRequirement = 0;
|
||||
Weight = 0;
|
||||
}
|
||||
|
||||
public AccessCloak(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override DeathMoveResult OnParentDeath(Mobile parent)
|
||||
{
|
||||
return DeathMoveResult.MoveToBackpack;
|
||||
}
|
||||
|
||||
public override bool OnEquip(Mobile from)
|
||||
{
|
||||
if (BlessedFor == null)
|
||||
{
|
||||
BlessedFor = from;
|
||||
_AccessTemp = BlessedFor.AccessLevel;
|
||||
}
|
||||
|
||||
if (BlessedFor != from)
|
||||
{
|
||||
from.SendMessage("That does not belong to you.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.OnEquip(from);
|
||||
}
|
||||
|
||||
#if NEWPARENT
|
||||
public override void OnAdded(IEntity parent)
|
||||
#else
|
||||
public override void OnAdded(object parent)
|
||||
#endif
|
||||
{
|
||||
if (BlessedFor != null)
|
||||
{
|
||||
BlessedFor.AccessLevel = _AccessMask;
|
||||
|
||||
BlessedFor.Hits = BlessedFor.HitsMax;
|
||||
BlessedFor.Stam = BlessedFor.StamMax;
|
||||
BlessedFor.Mana = BlessedFor.ManaMax;
|
||||
}
|
||||
|
||||
base.OnAdded(parent);
|
||||
}
|
||||
|
||||
#if NEWPARENT
|
||||
public override void OnRemoved(IEntity parent)
|
||||
#else
|
||||
public override void OnRemoved(object parent)
|
||||
#endif
|
||||
{
|
||||
if (BlessedFor != null)
|
||||
{
|
||||
BlessedFor.AccessLevel = _AccessTemp;
|
||||
|
||||
BlessedFor.Hits = BlessedFor.HitsMax;
|
||||
BlessedFor.Stam = BlessedFor.StamMax;
|
||||
BlessedFor.Mana = BlessedFor.ManaMax;
|
||||
}
|
||||
|
||||
base.OnRemoved(parent);
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
if (BlessedFor != null)
|
||||
{
|
||||
BlessedFor.AccessLevel = _AccessTemp;
|
||||
|
||||
BlessedFor.Hits = BlessedFor.HitsMax;
|
||||
BlessedFor.Stam = BlessedFor.StamMax;
|
||||
BlessedFor.Mana = BlessedFor.ManaMax;
|
||||
}
|
||||
|
||||
base.OnDelete();
|
||||
}
|
||||
|
||||
public override void AddNameProperty(ObjectPropertyList list)
|
||||
{
|
||||
base.AddNameProperty(list);
|
||||
|
||||
list.Add(
|
||||
"<basefont color=#{0:X6}>Cloak: {1} => {2}<basefont color=#FFFFFF>",
|
||||
Color.Gold.ToRgb(),
|
||||
_AccessTemp,
|
||||
_AccessMask);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
writer.Write(BlessedFor);
|
||||
writer.WriteFlag(_AccessMask);
|
||||
writer.WriteFlag(_AccessTemp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
BlessedFor = reader.ReadMobile();
|
||||
|
||||
_AccessMask = reader.ReadFlag<AccessLevel>();
|
||||
_AccessTemp = reader.ReadFlag<AccessLevel>();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
501
Scripts/SubSystem/VitaNex/Core/Items/Utility/BroadcastScroll.cs
Normal file
501
Scripts/SubSystem/VitaNex/Core/Items/Utility/BroadcastScroll.cs
Normal file
@@ -0,0 +1,501 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
using VitaNex.SuperGumps.UI;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public class BroadcastScrollGump : TextInputPanelGump<BroadcastScroll>
|
||||
{
|
||||
public bool UseConfirmDialog { get; set; }
|
||||
|
||||
public BroadcastScrollGump(
|
||||
PlayerMobile user,
|
||||
Gump parent = null,
|
||||
BroadcastScroll scroll = null,
|
||||
bool useConfirm = true)
|
||||
: base(
|
||||
user,
|
||||
parent,
|
||||
null,
|
||||
null,
|
||||
400,
|
||||
150,
|
||||
"No scroll selected.",
|
||||
"Broadcast Scroll Message (200 Chars)",
|
||||
null,
|
||||
scroll,
|
||||
null,
|
||||
200)
|
||||
{
|
||||
UseConfirmDialog = useConfirm;
|
||||
}
|
||||
|
||||
protected override void Compile()
|
||||
{
|
||||
if (Selected != null && Selected.Message != Input)
|
||||
{
|
||||
Input = Selected.Message;
|
||||
}
|
||||
|
||||
base.Compile();
|
||||
}
|
||||
|
||||
protected override void ParseInput(string text)
|
||||
{
|
||||
base.ParseInput(text);
|
||||
|
||||
if (Selected != null)
|
||||
{
|
||||
Selected.Message = Input ?? String.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void CompileMenuOptions(MenuGumpOptions list)
|
||||
{
|
||||
if (Selected != null && !String.IsNullOrWhiteSpace(Selected.Message))
|
||||
{
|
||||
list.AppendEntry(
|
||||
new ListGumpEntry(
|
||||
"Broadcast",
|
||||
b =>
|
||||
{
|
||||
if (Selected != null)
|
||||
{
|
||||
Selected.Message = Input ?? String.Empty;
|
||||
Selected.Broadcast(User);
|
||||
}
|
||||
|
||||
Refresh(true);
|
||||
},
|
||||
HighlightHue));
|
||||
|
||||
list.AppendEntry(
|
||||
new ListGumpEntry(
|
||||
"Clear",
|
||||
b =>
|
||||
{
|
||||
if (Selected != null)
|
||||
{
|
||||
Selected.Message = Input = String.Empty;
|
||||
}
|
||||
|
||||
Refresh(true);
|
||||
},
|
||||
ErrorHue));
|
||||
}
|
||||
|
||||
base.CompileMenuOptions(list);
|
||||
}
|
||||
}
|
||||
|
||||
[Flipable(0xE34, 0xEF3)]
|
||||
public class BroadcastScroll : Item, IUsesRemaining
|
||||
{
|
||||
public static bool Feedback = false;
|
||||
|
||||
private bool _ShowUsesRemaining = true;
|
||||
private int _UsesRemaining = 10;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual string Message { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual int MessageHue { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual int UsesRemaining
|
||||
{
|
||||
get => _UsesRemaining;
|
||||
set
|
||||
{
|
||||
_UsesRemaining = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual bool ShowUsesRemaining
|
||||
{
|
||||
get => _ShowUsesRemaining;
|
||||
set
|
||||
{
|
||||
_ShowUsesRemaining = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool DisplayLootType => false;
|
||||
public override bool DisplayWeight => false;
|
||||
|
||||
[Constructable]
|
||||
public BroadcastScroll()
|
||||
: this(1)
|
||||
{ }
|
||||
|
||||
[Constructable]
|
||||
public BroadcastScroll(int uses)
|
||||
: base(0xE34)
|
||||
{
|
||||
UsesRemaining = Math.Max(1, uses);
|
||||
|
||||
Name = "Broadcast Scroll";
|
||||
LootType = LootType.Blessed;
|
||||
Stackable = false;
|
||||
Weight = 0;
|
||||
}
|
||||
|
||||
public BroadcastScroll(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public void Broadcast(Mobile from)
|
||||
{
|
||||
if (from == null || from.Deleted || !from.Player)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsChildOf(from.Backpack) || !IsAccessibleTo(from) || !from.CanSee(this) || InSecureTrade)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (String.IsNullOrWhiteSpace(Message))
|
||||
{
|
||||
new NoticeDialogGump(from)
|
||||
{
|
||||
Title = "Empty Message",
|
||||
Html = "Your broadcast message can't be blank and can't consist only of white-space."
|
||||
}.Send();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (Deleted || UsesRemaining <= 0)
|
||||
{
|
||||
if (from is PlayerMobile)
|
||||
{
|
||||
new NoticeDialogGump((PlayerMobile)from)
|
||||
{
|
||||
Title = "Scroll Exhausted",
|
||||
Html = "Your broadcast scroll has been exhausted, you can't send another message."
|
||||
}.Send();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//Send the message to all online players, including staff.
|
||||
int reach = 0, staff = 0;
|
||||
|
||||
foreach (var state in NetState.Instances.Where(ns => ns != null && ns.Running && ns.Mobile != null))
|
||||
{
|
||||
state.Mobile.SendMessage(MessageHue > 0 ? MessageHue : from.SpeechHue, "Message from {0}:", from.RawName);
|
||||
state.Mobile.SendMessage(MessageHue > 0 ? MessageHue : from.SpeechHue, Message);
|
||||
|
||||
if (state.Mobile == from || (DateTime.UtcNow - state.ConnectedOn) < TimeSpan.FromMinutes(1))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//If receiver is not sender and receiver has been logged in for over 1 minute, include them in total reached.
|
||||
reach++;
|
||||
|
||||
if (state.Mobile.AccessLevel >= AccessLevel.Counselor)
|
||||
{
|
||||
staff++;
|
||||
}
|
||||
}
|
||||
|
||||
//If we reached people and they weren't just staff, charge for the message.
|
||||
if (reach - staff > 0)
|
||||
{
|
||||
if (Feedback)
|
||||
{
|
||||
from.SendMessage(0x55, "Your broadcast was seen by {0:#,0} people!", reach);
|
||||
}
|
||||
|
||||
if (--UsesRemaining <= 0)
|
||||
{
|
||||
from.SendMessage(0x22, "Your broadcast scroll has been exhausted, you throw away the scrap paper.");
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage(0x22, "Your broadcast was not seen by anyone, your scroll was not consumed this time.");
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
base.OnDoubleClick(from);
|
||||
|
||||
if (!this.CheckDoubleClick(from, true, true, 2, true))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (from is PlayerMobile && UsesRemaining > 0)
|
||||
{
|
||||
new BroadcastScrollGump((PlayerMobile)from, scroll: this).Send();
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
if (ShowUsesRemaining)
|
||||
{
|
||||
// uses remaining: ~1_val~
|
||||
list.Add(1060584, UsesRemaining == Int32.MaxValue ? "unlimited" : String.Format("{0:#,0}", UsesRemaining));
|
||||
}
|
||||
|
||||
list.Add("Use: Broadcast A Global Message".WrapUOHtmlColor(Color.SkyBlue));
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
writer.Write(Message);
|
||||
writer.Write(_UsesRemaining);
|
||||
writer.Write(_ShowUsesRemaining);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Message = reader.ReadString();
|
||||
_UsesRemaining = reader.ReadInt();
|
||||
_ShowUsesRemaining = reader.ReadBool();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class BroadcastScroll_Unlimited : BroadcastScroll
|
||||
{
|
||||
public override int UsesRemaining { get => Int32.MaxValue; set { } }
|
||||
|
||||
[Constructable]
|
||||
public BroadcastScroll_Unlimited()
|
||||
: base(Int32.MaxValue)
|
||||
{
|
||||
ShowUsesRemaining = false;
|
||||
}
|
||||
|
||||
public BroadcastScroll_Unlimited(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public class BroadcastScroll_3Uses : BroadcastScroll
|
||||
{
|
||||
[Constructable]
|
||||
public BroadcastScroll_3Uses()
|
||||
: base(3)
|
||||
{ }
|
||||
|
||||
public BroadcastScroll_3Uses(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public class BroadcastScroll_5Uses : BroadcastScroll
|
||||
{
|
||||
[Constructable]
|
||||
public BroadcastScroll_5Uses()
|
||||
: base(5)
|
||||
{ }
|
||||
|
||||
public BroadcastScroll_5Uses(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public class BroadcastScroll_10Uses : BroadcastScroll
|
||||
{
|
||||
[Constructable]
|
||||
public BroadcastScroll_10Uses()
|
||||
: base(10)
|
||||
{ }
|
||||
|
||||
public BroadcastScroll_10Uses(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public class BroadcastScroll_30Uses : BroadcastScroll
|
||||
{
|
||||
[Constructable]
|
||||
public BroadcastScroll_30Uses()
|
||||
: base(30)
|
||||
{ }
|
||||
|
||||
public BroadcastScroll_30Uses(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public class BroadcastScroll_50Uses : BroadcastScroll
|
||||
{
|
||||
[Constructable]
|
||||
public BroadcastScroll_50Uses()
|
||||
: base(50)
|
||||
{ }
|
||||
|
||||
public BroadcastScroll_50Uses(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public class BroadcastScroll_100Uses : BroadcastScroll
|
||||
{
|
||||
[Constructable]
|
||||
public BroadcastScroll_100Uses()
|
||||
: base(100)
|
||||
{ }
|
||||
|
||||
public BroadcastScroll_100Uses(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
407
Scripts/SubSystem/VitaNex/Core/Items/Utility/FloorTiles.cs
Normal file
407
Scripts/SubSystem/VitaNex/Core/Items/Utility/FloorTiles.cs
Normal file
@@ -0,0 +1,407 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Items
|
||||
{
|
||||
public abstract class FloorTile<TMob> : Item
|
||||
where TMob : Mobile
|
||||
{
|
||||
public override double DefaultWeight => 0;
|
||||
public override bool DisplayWeight => false;
|
||||
public override bool DisplayLootType => false;
|
||||
public override bool Decays => false;
|
||||
|
||||
public Func<TMob, bool> MoveOverHandler { get; set; }
|
||||
public Func<TMob, bool> MoveOffHandler { get; set; }
|
||||
|
||||
public FloorTile()
|
||||
: this(null, null)
|
||||
{ }
|
||||
|
||||
public FloorTile(Func<TMob, bool> moveOver, Func<TMob, bool> moveOff)
|
||||
: base(9272)
|
||||
{
|
||||
MoveOverHandler = moveOver;
|
||||
MoveOffHandler = moveOff;
|
||||
|
||||
Name = "Floor Tile";
|
||||
Movable = false;
|
||||
Visible = false;
|
||||
}
|
||||
|
||||
public FloorTile(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override sealed bool OnMoveOver(Mobile m)
|
||||
{
|
||||
if (m == null || m.Deleted || !(m is TMob))
|
||||
{
|
||||
return base.OnMoveOver(m);
|
||||
}
|
||||
|
||||
return OnMoveOver(m as TMob);
|
||||
}
|
||||
|
||||
public virtual bool OnMoveOver(TMob mob)
|
||||
{
|
||||
if (base.OnMoveOver(mob))
|
||||
{
|
||||
if (MoveOverHandler != null)
|
||||
{
|
||||
return MoveOverHandler(mob);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override sealed bool OnMoveOff(Mobile m)
|
||||
{
|
||||
if (m == null || m.Deleted || !(m is TMob))
|
||||
{
|
||||
return base.OnMoveOff(m);
|
||||
}
|
||||
|
||||
return OnMoveOff(m as TMob);
|
||||
}
|
||||
|
||||
public virtual bool OnMoveOff(TMob mob)
|
||||
{
|
||||
if (base.OnMoveOff(mob))
|
||||
{
|
||||
if (MoveOffHandler != null)
|
||||
{
|
||||
return MoveOffHandler(mob);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class RestrictMobileTile<TMob> : FloorTile<TMob>
|
||||
where TMob : Mobile
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool Restricted { get; set; }
|
||||
|
||||
public RestrictMobileTile()
|
||||
: this(null, null)
|
||||
{ }
|
||||
|
||||
public RestrictMobileTile(Func<TMob, bool> moveOver, Func<TMob, bool> moveOff)
|
||||
: base(moveOver, moveOff)
|
||||
{
|
||||
Restricted = true;
|
||||
Name = "Restrict Mobiles";
|
||||
}
|
||||
|
||||
public RestrictMobileTile(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override bool OnMoveOver(TMob m)
|
||||
{
|
||||
if (base.OnMoveOver(m))
|
||||
{
|
||||
return !Restricted;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool OnMoveOff(TMob m)
|
||||
{
|
||||
if (base.OnMoveOff(m))
|
||||
{
|
||||
return !Restricted;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
writer.Write(Restricted);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
Restricted = reader.ReadBool();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class RestrictMobileTile : RestrictMobileTile<Mobile>
|
||||
{
|
||||
[Constructable]
|
||||
public RestrictMobileTile()
|
||||
: this(null, null)
|
||||
{ }
|
||||
|
||||
public RestrictMobileTile(Func<Mobile, bool> moveOver, Func<Mobile, bool> moveOff)
|
||||
: base(moveOver, moveOff)
|
||||
{
|
||||
Name = "Restrict Mobiles";
|
||||
}
|
||||
|
||||
public RestrictMobileTile(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.SetVersion(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.GetVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public class RestrictCreatureTile : RestrictMobileTile<BaseCreature>
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool AllowControlled { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public RestrictCreatureTile()
|
||||
: this(null, null)
|
||||
{ }
|
||||
|
||||
public RestrictCreatureTile(Func<BaseCreature, bool> moveOver, Func<BaseCreature, bool> moveOff)
|
||||
: base(moveOver, moveOff)
|
||||
{
|
||||
AllowControlled = true;
|
||||
Name = "Restrict Creatures";
|
||||
}
|
||||
|
||||
public RestrictCreatureTile(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override bool OnMoveOver(BaseCreature m)
|
||||
{
|
||||
if (!base.OnMoveOver(m))
|
||||
{
|
||||
if (m.Controlled && AllowControlled)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnMoveOff(BaseCreature m)
|
||||
{
|
||||
if (!base.OnMoveOff(m))
|
||||
{
|
||||
if (m.Controlled && AllowControlled)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
writer.Write(AllowControlled);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
AllowControlled = reader.ReadBool();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class RestrictPlayerTile : RestrictMobileTile<PlayerMobile>
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool AllowDead { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool AllowYoung { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public RestrictPlayerTile()
|
||||
: this(null, null)
|
||||
{ }
|
||||
|
||||
public RestrictPlayerTile(Func<PlayerMobile, bool> moveOver, Func<PlayerMobile, bool> moveOff)
|
||||
: base(moveOver, moveOff)
|
||||
{
|
||||
AllowYoung = true;
|
||||
AllowDead = true;
|
||||
Name = "Restrict Players";
|
||||
}
|
||||
|
||||
public RestrictPlayerTile(Serial serial)
|
||||
: base(serial)
|
||||
{ }
|
||||
|
||||
public override bool OnMoveOver(PlayerMobile m)
|
||||
{
|
||||
if (m.Player && m.AccessLevel > AccessLevel.Counselor)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!base.OnMoveOver(m))
|
||||
{
|
||||
if (!m.Alive && AllowDead)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m.Young && AllowYoung)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnMoveOff(PlayerMobile m)
|
||||
{
|
||||
if (m.Player && m.AccessLevel > AccessLevel.Counselor)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!base.OnMoveOff(m))
|
||||
{
|
||||
if (!m.Alive && AllowDead)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m.Young && AllowYoung)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(0);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
writer.Write(AllowDead);
|
||||
writer.Write(AllowYoung);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
AllowDead = reader.ReadBool();
|
||||
AllowYoung = reader.ReadBool();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user