v0.0.1-Alpha (#42)
This commit is contained in:
parent
d30f93c454
commit
a36796c2c1
3552 changed files with 2476 additions and 15223 deletions
96
Projects/Scripts/Items/Misc/AcidSlime.cs
Normal file
96
Projects/Scripts/Items/Misc/AcidSlime.cs
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class AcidSlime : Item
|
||||
{
|
||||
private DateTime m_Created;
|
||||
private bool m_Drying;
|
||||
private TimeSpan m_Duration;
|
||||
private int m_MaxDamage;
|
||||
private int m_MinDamage;
|
||||
private Timer m_Timer;
|
||||
|
||||
[Constructible]
|
||||
public AcidSlime() : this(TimeSpan.FromSeconds(10.0), 5, 10)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructible]
|
||||
public AcidSlime(TimeSpan duration, int minDamage, int maxDamage)
|
||||
: base(0x122A)
|
||||
{
|
||||
Hue = 0x3F;
|
||||
Movable = false;
|
||||
m_MinDamage = minDamage;
|
||||
m_MaxDamage = maxDamage;
|
||||
m_Created = DateTime.UtcNow;
|
||||
m_Duration = duration;
|
||||
m_Timer = Timer.DelayCall(TimeSpan.Zero, TimeSpan.FromSeconds(1), OnTick);
|
||||
}
|
||||
|
||||
public AcidSlime(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "slime";
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
m_Timer?.Stop();
|
||||
}
|
||||
|
||||
private void OnTick()
|
||||
{
|
||||
DateTime now = DateTime.UtcNow;
|
||||
TimeSpan age = now - m_Created;
|
||||
|
||||
if (age > m_Duration)
|
||||
{
|
||||
Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_Drying && age > m_Duration - age)
|
||||
{
|
||||
m_Drying = true;
|
||||
ItemID = 0x122B;
|
||||
}
|
||||
|
||||
List<Mobile> toDamage = new List<Mobile>();
|
||||
|
||||
foreach (Mobile m in GetMobilesInRange(0))
|
||||
if (m.Alive && !m.IsDeadBondedPet && (!(m is BaseCreature bc) || bc.Controlled || bc.Summoned))
|
||||
toDamage.Add(m);
|
||||
|
||||
for (int i = 0; i < toDamage.Count; i++)
|
||||
Damage(toDamage[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnMoveOver(Mobile m)
|
||||
{
|
||||
Damage(m);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Damage(Mobile m)
|
||||
{
|
||||
int damage = Utility.RandomMinMax(m_MinDamage, m_MaxDamage);
|
||||
if (Core.AOS)
|
||||
AOS.Damage(m, damage, 0, 0, 0, 100, 0);
|
||||
else
|
||||
m.Damage(damage);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
211
Projects/Scripts/Items/Misc/ArcaneGem.cs
Normal file
211
Projects/Scripts/Items/Misc/ArcaneGem.cs
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
using System.Collections.Generic;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class ArcaneGem : Item
|
||||
{
|
||||
public const int DefaultArcaneHue = 2117;
|
||||
|
||||
[Constructible]
|
||||
public ArcaneGem() : base(0x1EA7)
|
||||
{
|
||||
Stackable = Core.ML;
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
public ArcaneGem(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "arcane gem";
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
|
||||
}
|
||||
else
|
||||
{
|
||||
from.BeginTarget(2, false, TargetFlags.None, OnTarget);
|
||||
from.SendMessage("What do you wish to use the gem on?");
|
||||
}
|
||||
}
|
||||
|
||||
public int GetChargesFor(Mobile m)
|
||||
{
|
||||
int v = (int)(m.Skills.Tailoring.Value / 5);
|
||||
|
||||
if (v < 16)
|
||||
return 16;
|
||||
if (v > 24)
|
||||
return 24;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
public void OnTarget(Mobile from, object obj)
|
||||
{
|
||||
if (!IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
|
||||
return;
|
||||
}
|
||||
|
||||
if (obj is IArcaneEquip eq && eq is Item item)
|
||||
{
|
||||
BaseClothing clothing = item as BaseClothing;
|
||||
BaseArmor armor = item as BaseArmor;
|
||||
BaseWeapon weapon = item as BaseWeapon;
|
||||
|
||||
CraftResource resource = clothing?.Resource ?? armor?.Resource ?? weapon?.Resource ?? CraftResource.None;
|
||||
|
||||
if (!item.IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
|
||||
return;
|
||||
}
|
||||
|
||||
if (item.LootType == LootType.Blessed)
|
||||
{
|
||||
from.SendMessage(
|
||||
"You can only use this on exceptionally crafted robes, thigh boots, cloaks, or leather gloves.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (resource != CraftResource.None && resource != CraftResource.RegularLeather)
|
||||
{
|
||||
from.SendLocalizedMessage(1049690); // Arcane gems can not be used on that type of leather.
|
||||
return;
|
||||
}
|
||||
|
||||
int charges = GetChargesFor(from);
|
||||
|
||||
if (eq.IsArcane)
|
||||
{
|
||||
if (eq.CurArcaneCharges >= eq.MaxArcaneCharges)
|
||||
{
|
||||
from.SendMessage("That item is already fully charged.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (eq.CurArcaneCharges <= 0)
|
||||
item.Hue = DefaultArcaneHue;
|
||||
|
||||
if (eq.CurArcaneCharges + charges > eq.MaxArcaneCharges)
|
||||
eq.CurArcaneCharges = eq.MaxArcaneCharges;
|
||||
else
|
||||
eq.CurArcaneCharges += charges;
|
||||
|
||||
from.SendMessage("You recharge the item.");
|
||||
if (Amount <= 1)
|
||||
Delete();
|
||||
else Amount--;
|
||||
}
|
||||
}
|
||||
else if (from.Skills.Tailoring.Value >= 80.0)
|
||||
{
|
||||
bool isExceptional = clothing?.Quality == ClothingQuality.Exceptional ||
|
||||
armor?.Quality == ArmorQuality.Exceptional ||
|
||||
weapon?.Quality == WeaponQuality.Exceptional;
|
||||
|
||||
if (isExceptional)
|
||||
{
|
||||
if (clothing != null)
|
||||
{
|
||||
clothing.Quality = ClothingQuality.Regular;
|
||||
clothing.Crafter = from;
|
||||
}
|
||||
else if (armor != null)
|
||||
{
|
||||
armor.Quality = ArmorQuality.Regular;
|
||||
armor.Crafter = from;
|
||||
armor.PhysicalBonus =
|
||||
armor.FireBonus =
|
||||
armor.ColdBonus =
|
||||
armor.PoisonBonus = armor.EnergyBonus = 0; // Is there a method to remove bonuses?
|
||||
}
|
||||
else
|
||||
{
|
||||
weapon.Quality = WeaponQuality.Regular;
|
||||
weapon.Crafter = from;
|
||||
}
|
||||
|
||||
eq.CurArcaneCharges = eq.MaxArcaneCharges = charges;
|
||||
|
||||
item.Hue = DefaultArcaneHue;
|
||||
|
||||
from.SendMessage("You enhance the item with your gem.");
|
||||
if (Amount <= 1)
|
||||
Delete();
|
||||
else Amount--;
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage("Only exceptional items can be enhanced with the gem.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage("You do not have enough skill in tailoring to enhance the item.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage(
|
||||
"You can only use this on exceptionally crafted robes, thigh boots, cloaks, or leather gloves.");
|
||||
}
|
||||
}
|
||||
|
||||
public static bool ConsumeCharges(Mobile from, int amount)
|
||||
{
|
||||
List<Item> items = from.Items;
|
||||
int avail = 0;
|
||||
|
||||
for (int i = 0; i < items.Count; ++i)
|
||||
{
|
||||
Item obj = items[i];
|
||||
|
||||
if (obj is IArcaneEquip eq && eq.IsArcane)
|
||||
avail += eq.CurArcaneCharges;
|
||||
}
|
||||
|
||||
if (avail < amount)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < items.Count; ++i)
|
||||
{
|
||||
Item obj = items[i];
|
||||
|
||||
if (obj is IArcaneEquip eq && eq.IsArcane)
|
||||
{
|
||||
if (eq.CurArcaneCharges > amount)
|
||||
{
|
||||
eq.CurArcaneCharges -= amount;
|
||||
break;
|
||||
}
|
||||
|
||||
amount -= eq.CurArcaneCharges;
|
||||
eq.CurArcaneCharges = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
247
Projects/Scripts/Items/Misc/BankCheck.cs
Normal file
247
Projects/Scripts/Items/Misc/BankCheck.cs
Normal file
|
|
@ -0,0 +1,247 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using Server.Accounting;
|
||||
using Server.Engines.Quests;
|
||||
using Server.Engines.Quests.Haven;
|
||||
using Server.Engines.Quests.Necro;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
using CashBankCheckObjective = Server.Engines.Quests.Necro.CashBankCheckObjective;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class BankCheck : Item
|
||||
{
|
||||
private int m_Worth;
|
||||
|
||||
public BankCheck(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructible]
|
||||
public BankCheck(int worth) : base(0x14F0)
|
||||
{
|
||||
Weight = 1.0;
|
||||
Hue = 0x34;
|
||||
LootType = LootType.Blessed;
|
||||
|
||||
m_Worth = worth;
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Worth
|
||||
{
|
||||
get => m_Worth;
|
||||
set
|
||||
{
|
||||
m_Worth = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool DisplayLootType => Core.AOS;
|
||||
|
||||
public override int LabelNumber => 1041361; // A bank check
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write(m_Worth);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
LootType = LootType.Blessed;
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_Worth = reader.ReadInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
string worth;
|
||||
|
||||
if (Core.ML)
|
||||
worth = m_Worth.ToString("N0", CultureInfo.GetCultureInfo("en-US"));
|
||||
else
|
||||
worth = m_Worth.ToString();
|
||||
|
||||
list.Add(1060738, worth); // value: ~1_val~
|
||||
}
|
||||
|
||||
public override void OnAdded(IEntity parent)
|
||||
{
|
||||
base.OnAdded(parent);
|
||||
|
||||
if (!AccountGold.Enabled) return;
|
||||
|
||||
Mobile owner = null;
|
||||
SecureTradeInfo tradeInfo = null;
|
||||
|
||||
Container root = parent as Container;
|
||||
|
||||
while (root?.Parent is Container container)
|
||||
root = container;
|
||||
|
||||
parent = root ?? parent;
|
||||
|
||||
if (parent is SecureTradeContainer trade && AccountGold.ConvertOnTrade)
|
||||
{
|
||||
if (trade.Trade.From.Container == trade)
|
||||
{
|
||||
tradeInfo = trade.Trade.From;
|
||||
owner = tradeInfo.Mobile;
|
||||
}
|
||||
else if (trade.Trade.To.Container == trade)
|
||||
{
|
||||
tradeInfo = trade.Trade.To;
|
||||
owner = tradeInfo.Mobile;
|
||||
}
|
||||
}
|
||||
else if (parent is BankBox box && AccountGold.ConvertOnBank)
|
||||
{
|
||||
owner = box.Owner;
|
||||
}
|
||||
|
||||
if (owner?.Account == null || !owner.Account.DepositGold(Worth)) return;
|
||||
|
||||
if (tradeInfo != null)
|
||||
{
|
||||
if (owner.NetState?.NewSecureTrading == false)
|
||||
{
|
||||
int plat = Math.DivRem(Worth, AccountGold.CurrencyThreshold, out int gold);
|
||||
|
||||
tradeInfo.Plat += plat;
|
||||
tradeInfo.Gold += gold;
|
||||
}
|
||||
|
||||
tradeInfo.VirtualCheck?.UpdateTrade(tradeInfo.Mobile);
|
||||
}
|
||||
|
||||
owner.SendLocalizedMessage(1042763, Worth.ToString("#,0"));
|
||||
|
||||
Delete();
|
||||
|
||||
((Container)parent).UpdateTotals();
|
||||
}
|
||||
|
||||
public override void OnSingleClick(Mobile from)
|
||||
{
|
||||
from.Send(
|
||||
new MessageLocalizedAffix(
|
||||
Serial,
|
||||
ItemID,
|
||||
MessageType.Label,
|
||||
0x3B2,
|
||||
3,
|
||||
1041361,
|
||||
"",
|
||||
AffixType.Append,
|
||||
string.Concat(" ", m_Worth.ToString()),
|
||||
"")); // A bank check:
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
// This probably isn't OSI accurate, but we can't just make the quests redundant.
|
||||
// Double-clicking the BankCheck in your pack will now credit your account.
|
||||
|
||||
Container box = AccountGold.Enabled ? from.Backpack : from.FindBankNoCreate();
|
||||
|
||||
if (box == null || !IsChildOf(box))
|
||||
{
|
||||
from.SendLocalizedMessage(AccountGold.Enabled ? 1080058 : 1047026);
|
||||
// This must be in your backpack to use it. : That must be in your bank box to use it.
|
||||
return;
|
||||
}
|
||||
|
||||
Delete();
|
||||
|
||||
int deposited = 0;
|
||||
int toAdd = m_Worth;
|
||||
|
||||
if (AccountGold.Enabled && from.Account != null && from.Account.DepositGold(toAdd))
|
||||
{
|
||||
deposited = toAdd;
|
||||
toAdd = 0;
|
||||
}
|
||||
|
||||
if (toAdd > 0)
|
||||
{
|
||||
Gold gold;
|
||||
|
||||
while (toAdd > 60000)
|
||||
{
|
||||
gold = new Gold(60000);
|
||||
|
||||
if (box.TryDropItem(from, gold, false))
|
||||
{
|
||||
toAdd -= 60000;
|
||||
deposited += 60000;
|
||||
}
|
||||
else
|
||||
{
|
||||
gold.Delete();
|
||||
|
||||
from.AddToBackpack(new BankCheck(toAdd));
|
||||
toAdd = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (toAdd > 0)
|
||||
{
|
||||
gold = new Gold(toAdd);
|
||||
|
||||
if (box.TryDropItem(from, gold, false))
|
||||
{
|
||||
deposited += toAdd;
|
||||
}
|
||||
else
|
||||
{
|
||||
gold.Delete();
|
||||
|
||||
from.AddToBackpack(new BankCheck(toAdd));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Gold was deposited in your account:
|
||||
from.SendLocalizedMessage(1042672, true, deposited.ToString("#,0"));
|
||||
|
||||
if (from is PlayerMobile pm)
|
||||
{
|
||||
QuestSystem qs = pm.Quest;
|
||||
|
||||
if (qs is DarkTidesQuest)
|
||||
{
|
||||
QuestObjective obj = qs.FindObjective<CashBankCheckObjective>();
|
||||
|
||||
if (obj?.Completed == false) obj.Complete();
|
||||
}
|
||||
|
||||
if (qs is UzeraanTurmoilQuest)
|
||||
{
|
||||
QuestObjective obj = qs.FindObjective(typeof(Engines.Quests.Haven.CashBankCheckObjective));
|
||||
|
||||
if (obj?.Completed == false) obj.Complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class GlobOfMonstreousInterredGrizzle : Item
|
||||
{
|
||||
[Constructible]
|
||||
public GlobOfMonstreousInterredGrizzle() : base(0x2F3)
|
||||
{
|
||||
}
|
||||
|
||||
public GlobOfMonstreousInterredGrizzle(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1072117; // Glob of Monsterous Interred Grizzle
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class GrizzledSkullCollection : Item
|
||||
{
|
||||
[Constructible]
|
||||
public GrizzledSkullCollection() : base(0x21FC)
|
||||
{
|
||||
}
|
||||
|
||||
public GrizzledSkullCollection(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1072116; // Grizzled Skull collection
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class MonsterousInterredGrizzleMaggots : Item
|
||||
{
|
||||
[Constructible]
|
||||
public MonsterousInterredGrizzleMaggots() : base(0x2633)
|
||||
{
|
||||
}
|
||||
|
||||
public MonsterousInterredGrizzleMaggots(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1075090; // Monsterous Interred Grizzle Maggots
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
30
Projects/Scripts/Items/Misc/Bedlam/ResolvesBridle.cs
Normal file
30
Projects/Scripts/Items/Misc/Bedlam/ResolvesBridle.cs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class ResolvesBridle : Item
|
||||
{
|
||||
[Constructible]
|
||||
public ResolvesBridle() : base(0x1374)
|
||||
{
|
||||
}
|
||||
|
||||
public ResolvesBridle(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1074761; // Resolve's Bridle
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
30
Projects/Scripts/Items/Misc/Bedlam/TombstoneOfTheDamned.cs
Normal file
30
Projects/Scripts/Items/Misc/Bedlam/TombstoneOfTheDamned.cs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class TombstoneOfTheDamned : Item
|
||||
{
|
||||
[Constructible]
|
||||
public TombstoneOfTheDamned() : base(Utility.RandomMinMax(0xED7, 0xEDE))
|
||||
{
|
||||
}
|
||||
|
||||
public TombstoneOfTheDamned(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1072123; // Tombstone of the Damned
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
32
Projects/Scripts/Items/Misc/Beeswax.cs
Normal file
32
Projects/Scripts/Items/Misc/Beeswax.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class Beeswax : Item
|
||||
{
|
||||
[Constructible]
|
||||
public Beeswax(int amount = 1) : base(0x1422)
|
||||
{
|
||||
Weight = 1.0;
|
||||
Stackable = true;
|
||||
Amount = amount;
|
||||
}
|
||||
|
||||
public Beeswax(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
32
Projects/Scripts/Items/Misc/Blighted Grove/AbscessTail.cs
Normal file
32
Projects/Scripts/Items/Misc/Blighted Grove/AbscessTail.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class AbscessTail : Item
|
||||
{
|
||||
[Constructible]
|
||||
public AbscessTail() : base(0x1A9D)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
Hue = 0x51D; // TODO check
|
||||
}
|
||||
|
||||
public AbscessTail(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1074231; // Abscess' Tail
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
32
Projects/Scripts/Items/Misc/Blighted Grove/CoilsFang.cs
Normal file
32
Projects/Scripts/Items/Misc/Blighted Grove/CoilsFang.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class CoilsFang : Item
|
||||
{
|
||||
[Constructible]
|
||||
public CoilsFang() : base(0x10E8)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
Hue = 0x487;
|
||||
}
|
||||
|
||||
public CoilsFang(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1074229; // Coil's Fang
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class EternallyCorruptTree : Item
|
||||
{
|
||||
[Constructible]
|
||||
public EternallyCorruptTree() : base(0x20FA)
|
||||
{
|
||||
Hue = Utility.RandomMinMax(0x899, 0x8B0);
|
||||
}
|
||||
|
||||
public EternallyCorruptTree(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1072093; // Eternally Corrupt Tree
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
32
Projects/Scripts/Items/Misc/Blighted Grove/HydraScale.cs
Normal file
32
Projects/Scripts/Items/Misc/Blighted Grove/HydraScale.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class HydraScale : Item
|
||||
{
|
||||
[Constructible]
|
||||
public HydraScale() : base(0x26B4)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
Hue = 0xC2; // TODO check
|
||||
}
|
||||
|
||||
public HydraScale(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1074760; // A hydra scale.
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class MelisandesFermentedWine : GreaterExplosionPotion
|
||||
{
|
||||
[Constructible]
|
||||
public MelisandesFermentedWine()
|
||||
{
|
||||
Stackable = false;
|
||||
ItemID = 0x99B;
|
||||
Hue = Utility.RandomList(0xB, 0xF, 0x48D); // TODO update
|
||||
}
|
||||
|
||||
public MelisandesFermentedWine(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1072114; // Melisande's Fermented Wine
|
||||
|
||||
public override void Drink(Mobile from)
|
||||
{
|
||||
if (MondainsLegacy.CheckML(from))
|
||||
base.Drink(from);
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
list.Add(1074502); // It looks explosive.
|
||||
list.Add(1075085); // Requirement: Mondain's Legacy
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
using Server.Gumps;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class MelisandesHairDye : Item
|
||||
{
|
||||
[Constructible]
|
||||
public MelisandesHairDye() : base(0xEFF)
|
||||
{
|
||||
Hue = Utility.RandomMinMax(0x47E, 0x499);
|
||||
}
|
||||
|
||||
public MelisandesHairDye(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1041088; // Hair Dye
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (IsChildOf(from.Backpack))
|
||||
{
|
||||
if (MondainsLegacy.CheckML(from))
|
||||
from.SendGump(new ConfirmGump(this));
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
list.Add(1075085); // Requirement: Mondain's Legacy
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
|
||||
private class ConfirmGump : BaseConfirmGump
|
||||
{
|
||||
private Item m_Item;
|
||||
|
||||
public ConfirmGump(Item item)
|
||||
{
|
||||
m_Item = item;
|
||||
}
|
||||
|
||||
public override int TitleNumber => 1074395; // <div align=right>Use Permanent Hair Dye</div>
|
||||
|
||||
public override int LabelNumber =>
|
||||
1074396; // This special hair dye is made of a unique mixture of leaves, permanently changing one's hair color until another dye is used.
|
||||
|
||||
public override void Confirm(Mobile from)
|
||||
{
|
||||
if (m_Item?.Deleted == false && m_Item.IsChildOf(from.Backpack))
|
||||
{
|
||||
if (from.HairItemID != 0)
|
||||
{
|
||||
from.HairHue = m_Item.Hue;
|
||||
from.PlaySound(0x240);
|
||||
from.SendLocalizedMessage(502622); // You dye your hair.
|
||||
m_Item.Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(502623); // You have no hair to dye and you cannot use this.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1073461); // You don't have enough dye.
|
||||
}
|
||||
}
|
||||
|
||||
public override void Refuse(Mobile from)
|
||||
{
|
||||
from.SendLocalizedMessage(502620); // You decide not to dye your hair.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
32
Projects/Scripts/Items/Misc/Blighted Grove/SalivasFeather.cs
Normal file
32
Projects/Scripts/Items/Misc/Blighted Grove/SalivasFeather.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class SalivasFeather : Item
|
||||
{
|
||||
[Constructible]
|
||||
public SalivasFeather() : base(0x1020)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
Hue = 0x5C;
|
||||
}
|
||||
|
||||
public SalivasFeather(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1074234; // Saliva's Feather
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class SamplesOfCorruptedWater : Item
|
||||
{
|
||||
[Constructible]
|
||||
public SamplesOfCorruptedWater() : base(0xEFE)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public SamplesOfCorruptedWater(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1074999; // samples of corrupted water
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
32
Projects/Scripts/Items/Misc/Blighted Grove/TaintedSeeds.cs
Normal file
32
Projects/Scripts/Items/Misc/Blighted Grove/TaintedSeeds.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class TaintedSeeds : Item
|
||||
{
|
||||
[Constructible]
|
||||
public TaintedSeeds() : base(0xDFA)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
Hue = 0x48; // TODO check
|
||||
}
|
||||
|
||||
public TaintedSeeds(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1074233; // Tainted Seeds
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class ThorvaldsMedallion : Item
|
||||
{
|
||||
[Constructible]
|
||||
public ThorvaldsMedallion() : base(0x2AAA)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
Hue = 0x47F; // TODO check
|
||||
}
|
||||
|
||||
public ThorvaldsMedallion(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1074232; // Thorvald's Medallion
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
32
Projects/Scripts/Items/Misc/Blighted Grove/ThrashersTail.cs
Normal file
32
Projects/Scripts/Items/Misc/Blighted Grove/ThrashersTail.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class ThrashersTail : Item
|
||||
{
|
||||
[Constructible]
|
||||
public ThrashersTail() : base(0x1A9D)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
Hue = 0x455;
|
||||
}
|
||||
|
||||
public ThrashersTail(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1074230; // Thrasher's Tail
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
105
Projects/Scripts/Items/Misc/Blocker.cs
Normal file
105
Projects/Scripts/Items/Misc/Blocker.cs
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class Blocker : Item
|
||||
{
|
||||
[Constructible]
|
||||
public Blocker() : base(0x21A4)
|
||||
{
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public Blocker(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 503057; // Impassable!
|
||||
|
||||
protected override Packet GetWorldPacketFor(NetState state)
|
||||
{
|
||||
Mobile mob = state.Mobile;
|
||||
|
||||
if (mob?.AccessLevel >= AccessLevel.GameMaster)
|
||||
return new GMItemPacket(this);
|
||||
|
||||
return base.GetWorldPacketFor(state);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
|
||||
public sealed class GMItemPacket : Packet
|
||||
{
|
||||
public GMItemPacket(Item item) : base(0x1A)
|
||||
{
|
||||
EnsureCapacity(20);
|
||||
|
||||
// 14 base length
|
||||
// +2 - Amount
|
||||
// +2 - Hue
|
||||
// +1 - Flags
|
||||
|
||||
uint serial = item.Serial.Value;
|
||||
int itemID = 0x1183;
|
||||
int amount = item.Amount;
|
||||
Point3D loc = item.Location;
|
||||
int x = loc.X;
|
||||
int y = loc.Y;
|
||||
int hue = item.Hue;
|
||||
int flags = item.GetPacketFlags();
|
||||
int direction = (int)item.Direction;
|
||||
|
||||
if (amount != 0)
|
||||
serial |= 0x80000000;
|
||||
else
|
||||
serial &= 0x7FFFFFFF;
|
||||
|
||||
m_Stream.Write(serial);
|
||||
m_Stream.Write((short)(itemID & 0x7FFF));
|
||||
|
||||
if (amount != 0)
|
||||
m_Stream.Write((short)amount);
|
||||
|
||||
x &= 0x7FFF;
|
||||
|
||||
if (direction != 0)
|
||||
x |= 0x8000;
|
||||
|
||||
m_Stream.Write((short)x);
|
||||
|
||||
y &= 0x3FFF;
|
||||
|
||||
if (hue != 0)
|
||||
y |= 0x8000;
|
||||
|
||||
if (flags != 0)
|
||||
y |= 0x4000;
|
||||
|
||||
m_Stream.Write((short)y);
|
||||
|
||||
if (direction != 0)
|
||||
m_Stream.Write((byte)direction);
|
||||
|
||||
m_Stream.Write((sbyte)loc.Z);
|
||||
|
||||
if (hue != 0)
|
||||
m_Stream.Write((ushort)hue);
|
||||
|
||||
if (flags != 0)
|
||||
m_Stream.Write((byte)flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
56
Projects/Scripts/Items/Misc/Blood.cs
Normal file
56
Projects/Scripts/Items/Misc/Blood.cs
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class Blood : Item
|
||||
{
|
||||
[Constructible]
|
||||
public Blood() : this(Utility.RandomList(0x1645, 0x122A, 0x122B, 0x122C, 0x122D, 0x122E, 0x122F))
|
||||
{
|
||||
}
|
||||
|
||||
[Constructible]
|
||||
public Blood(int itemID) : base(itemID)
|
||||
{
|
||||
Movable = false;
|
||||
|
||||
new InternalTimer(this).Start();
|
||||
}
|
||||
|
||||
public Blood(Serial serial) : base(serial)
|
||||
{
|
||||
new InternalTimer(this).Start();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
|
||||
private class InternalTimer : Timer
|
||||
{
|
||||
private Item m_Blood;
|
||||
|
||||
public InternalTimer(Item blood) : base(TimeSpan.FromSeconds(5.0))
|
||||
{
|
||||
Priority = TimerPriority.OneSecond;
|
||||
|
||||
m_Blood = blood;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Blood.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
212
Projects/Scripts/Items/Misc/Bola.cs
Normal file
212
Projects/Scripts/Items/Misc/Bola.cs
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
using System;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
using Server.Spells.Ninjitsu;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class Bola : Item
|
||||
{
|
||||
[Constructible]
|
||||
public Bola(int amount = 1) : base(0x26AC)
|
||||
{
|
||||
Weight = 4.0;
|
||||
Stackable = true;
|
||||
Amount = amount;
|
||||
}
|
||||
|
||||
public Bola(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1040019); // The bola must be in your pack to use it.
|
||||
}
|
||||
else if (!from.CanBeginAction<Bola>())
|
||||
{
|
||||
from.SendLocalizedMessage(1049624); // You have to wait a few moments before you can use another bola!
|
||||
}
|
||||
else if (from.Target is BolaTarget)
|
||||
{
|
||||
from.SendLocalizedMessage(1049631); // This bola is already being used.
|
||||
}
|
||||
else if (!HasFreeHands(from))
|
||||
{
|
||||
from.SendLocalizedMessage(1040015); // Your hands must be free to use this
|
||||
}
|
||||
else if (from.Mounted)
|
||||
{
|
||||
from.SendLocalizedMessage(1040016); // You cannot use this while riding a mount
|
||||
}
|
||||
else if (AnimalForm.UnderTransformation(from))
|
||||
{
|
||||
from.SendLocalizedMessage(1070902); // You can't use this while in an animal form!
|
||||
}
|
||||
else
|
||||
{
|
||||
EtherealMount.StopMounting(from);
|
||||
|
||||
from.Target = new BolaTarget(this);
|
||||
from.LocalOverheadMessage(MessageType.Emote, 0x3B2, 1049632); // * You begin to swing the bola...*
|
||||
from.NonlocalOverheadMessage(MessageType.Emote, 0x3B2, 1049633,
|
||||
from.Name); // ~1_NAME~ begins to menacingly swing a bola...
|
||||
}
|
||||
}
|
||||
|
||||
private static void FinishThrow(Mobile from, Mobile to)
|
||||
{
|
||||
if (Core.AOS)
|
||||
new Bola().MoveToWorld(to.Location, to.Map);
|
||||
|
||||
if (to is ChaosDragoon || to is ChaosDragoonElite)
|
||||
from.SendLocalizedMessage(1042047); // You fail to knock the rider from its mount.
|
||||
|
||||
IMount mt = to.Mount;
|
||||
if (mt != null && !(to is ChaosDragoon || to is ChaosDragoonElite))
|
||||
mt.Rider = null;
|
||||
|
||||
if (to is PlayerMobile mobile)
|
||||
{
|
||||
if (AnimalForm.UnderTransformation(mobile))
|
||||
mobile.SendLocalizedMessage(1114066, from.Name); // ~1_NAME~ knocked you out of animal form!
|
||||
else if (mobile.Mounted) mobile.SendLocalizedMessage(1040023); // You have been knocked off of your mount!
|
||||
|
||||
mobile.SetMountBlock(BlockMountType.Dazed, TimeSpan.FromSeconds(Core.ML ? 10 : 3), true);
|
||||
}
|
||||
|
||||
if (Core.AOS) /* only failsafe, attacker should already be dismounted */
|
||||
(from as PlayerMobile)?.SetMountBlock(BlockMountType.BolaRecovery, TimeSpan.FromSeconds(Core.ML ? 10 : 3),
|
||||
true);
|
||||
|
||||
to.Damage(1);
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(2.0), () => from.EndAction<Bola>());
|
||||
}
|
||||
|
||||
private static bool HasFreeHands(Mobile from)
|
||||
{
|
||||
Item one = from.FindItemOnLayer(Layer.OneHanded);
|
||||
Item two = from.FindItemOnLayer(Layer.TwoHanded);
|
||||
|
||||
if (Core.SE)
|
||||
{
|
||||
Container pack = from.Backpack;
|
||||
|
||||
if (pack != null)
|
||||
{
|
||||
if (one?.Movable == true)
|
||||
{
|
||||
pack.DropItem(one);
|
||||
one = null;
|
||||
}
|
||||
|
||||
if (two?.Movable == true)
|
||||
{
|
||||
pack.DropItem(two);
|
||||
two = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Core.AOS)
|
||||
{
|
||||
if (one?.Movable == true)
|
||||
{
|
||||
from.AddToBackpack(one);
|
||||
one = null;
|
||||
}
|
||||
|
||||
if (two?.Movable == true)
|
||||
{
|
||||
from.AddToBackpack(two);
|
||||
two = null;
|
||||
}
|
||||
}
|
||||
|
||||
return one == null && two == null;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
|
||||
public class BolaTarget : Target
|
||||
{
|
||||
private Bola m_Bola;
|
||||
|
||||
public BolaTarget(Bola bola) : base(8, false, TargetFlags.Harmful)
|
||||
{
|
||||
m_Bola = bola;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object obj)
|
||||
{
|
||||
if (m_Bola.Deleted)
|
||||
return;
|
||||
|
||||
if (obj is Mobile to)
|
||||
{
|
||||
if (!m_Bola.IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1040019); // The bola must be in your pack to use it.
|
||||
}
|
||||
else if (!HasFreeHands(from))
|
||||
{
|
||||
from.SendLocalizedMessage(1040015); // Your hands must be free to use this
|
||||
}
|
||||
else if (from.Mounted)
|
||||
{
|
||||
from.SendLocalizedMessage(1040016); // You cannot use this while riding a mount
|
||||
}
|
||||
else if (AnimalForm.UnderTransformation(from))
|
||||
{
|
||||
from.SendLocalizedMessage(1070902); // You can't use this while in an animal form!
|
||||
}
|
||||
else if (!to.Mounted && !AnimalForm.UnderTransformation(to))
|
||||
{
|
||||
from.SendLocalizedMessage(1049628); // You have no reason to throw a bola at that.
|
||||
}
|
||||
else if (!from.CanBeHarmful(to))
|
||||
{
|
||||
}
|
||||
else if (from.BeginAction<Bola>())
|
||||
{
|
||||
EtherealMount.StopMounting(from);
|
||||
|
||||
from.DoHarmful(to);
|
||||
|
||||
m_Bola.Consume();
|
||||
|
||||
from.Direction = from.GetDirectionTo(to);
|
||||
from.Animate(11, 5, 1, true, false, 0);
|
||||
from.MovingEffect(to, 0x26AC, 10, 0, false, false);
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(0.5), () => FinishThrow(from, to));
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(
|
||||
1049624); // You have to wait a few moments before you can use another bola!
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1049629); // You cannot throw a bola at that.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
32
Projects/Scripts/Items/Misc/BolaBall.cs
Normal file
32
Projects/Scripts/Items/Misc/BolaBall.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class BolaBall : Item
|
||||
{
|
||||
[Constructible]
|
||||
public BolaBall(int amount = 1) : base(0xE73)
|
||||
{
|
||||
Weight = 4.0;
|
||||
Stackable = true;
|
||||
Amount = amount;
|
||||
Hue = 0x8AC;
|
||||
}
|
||||
|
||||
public BolaBall(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
615
Projects/Scripts/Items/Misc/BulletinBoards.cs
Normal file
615
Projects/Scripts/Items/Misc/BulletinBoards.cs
Normal file
|
|
@ -0,0 +1,615 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Network;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
[Flippable(0x1E5E, 0x1E5F)]
|
||||
public class BulletinBoard : BaseBulletinBoard
|
||||
{
|
||||
[Constructible]
|
||||
public BulletinBoard() : base(0x1E5E)
|
||||
{
|
||||
}
|
||||
|
||||
public BulletinBoard(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class BaseBulletinBoard : Item
|
||||
{
|
||||
// Threads will be removed six hours after the last post was made
|
||||
private static TimeSpan ThreadDeletionTime = TimeSpan.FromHours(6.0);
|
||||
|
||||
// A player may only create a thread once every two minutes
|
||||
private static TimeSpan ThreadCreateTime = TimeSpan.FromMinutes(2.0);
|
||||
|
||||
// A player may only reply once every thirty seconds
|
||||
private static TimeSpan ThreadReplyTime = TimeSpan.FromSeconds(30.0);
|
||||
|
||||
public BaseBulletinBoard(int itemID) : base(itemID)
|
||||
{
|
||||
BoardName = "bulletin board";
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public BaseBulletinBoard(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string BoardName{ get; set; }
|
||||
|
||||
public static bool CheckTime(DateTime time, TimeSpan range)
|
||||
{
|
||||
return time + range < DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public static string FormatTS(TimeSpan ts)
|
||||
{
|
||||
int totalSeconds = (int)ts.TotalSeconds;
|
||||
int seconds = totalSeconds % 60;
|
||||
int minutes = totalSeconds / 60;
|
||||
|
||||
if (minutes != 0 && seconds != 0)
|
||||
return $"{minutes} minute{(minutes == 1 ? "" : "s")} and {seconds} second{(seconds == 1 ? "" : "s")}";
|
||||
if (minutes != 0)
|
||||
return $"{minutes} minute{(minutes == 1 ? "" : "s")}";
|
||||
return $"{seconds} second{(seconds == 1 ? "" : "s")}";
|
||||
}
|
||||
|
||||
public virtual void Cleanup()
|
||||
{
|
||||
List<Item> items = Items;
|
||||
|
||||
for (int i = items.Count - 1; i >= 0; --i)
|
||||
{
|
||||
if (i >= items.Count)
|
||||
continue;
|
||||
|
||||
if (!(items[i] is BulletinMessage msg))
|
||||
continue;
|
||||
|
||||
if (msg.Thread == null && CheckTime(msg.LastPostTime, ThreadDeletionTime))
|
||||
{
|
||||
msg.Delete();
|
||||
RecurseDelete(msg); // A root-level thread has expired
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RecurseDelete(BulletinMessage msg)
|
||||
{
|
||||
List<Item> found = new List<Item>();
|
||||
List<Item> items = Items;
|
||||
|
||||
for (int i = items.Count - 1; i >= 0; --i)
|
||||
{
|
||||
if (i >= items.Count)
|
||||
continue;
|
||||
|
||||
if (!(items[i] is BulletinMessage check))
|
||||
continue;
|
||||
|
||||
if (check.Thread == msg)
|
||||
{
|
||||
check.Delete();
|
||||
found.Add(check);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < found.Count; ++i)
|
||||
RecurseDelete((BulletinMessage)found[i]);
|
||||
}
|
||||
|
||||
public virtual bool GetLastPostTime(Mobile poster, bool onlyCheckRoot, ref DateTime lastPostTime)
|
||||
{
|
||||
List<Item> items = Items;
|
||||
bool wasSet = false;
|
||||
|
||||
for (int i = 0; i < items.Count; ++i)
|
||||
{
|
||||
if (!(items[i] is BulletinMessage msg) || msg.Poster != poster)
|
||||
continue;
|
||||
|
||||
if (onlyCheckRoot && msg.Thread != null)
|
||||
continue;
|
||||
|
||||
if (msg.Time > lastPostTime)
|
||||
{
|
||||
wasSet = true;
|
||||
lastPostTime = msg.Time;
|
||||
}
|
||||
}
|
||||
|
||||
return wasSet;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (CheckRange(from))
|
||||
{
|
||||
Cleanup();
|
||||
|
||||
NetState state = from.NetState;
|
||||
|
||||
state.Send(new BBDisplayBoard(this));
|
||||
if (state.ContainerGridLines)
|
||||
state.Send(new ContainerContent6017(from, this));
|
||||
else
|
||||
state.Send(new ContainerContent(from, this));
|
||||
}
|
||||
else
|
||||
{
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool CheckRange(Mobile from)
|
||||
{
|
||||
if (from.AccessLevel >= AccessLevel.GameMaster)
|
||||
return true;
|
||||
|
||||
return from.Map == Map && from.InRange(GetWorldLocation(), 2);
|
||||
}
|
||||
|
||||
public void PostMessage(Mobile from, BulletinMessage thread, string subject, string[] lines)
|
||||
{
|
||||
if (thread != null)
|
||||
thread.LastPostTime = DateTime.UtcNow;
|
||||
|
||||
AddItem(new BulletinMessage(from, thread, subject, lines));
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write(BoardName);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
BoardName = reader.ReadString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
PacketHandlers.Register(0x71, 0, true, BBClientRequest);
|
||||
}
|
||||
|
||||
public static void BBClientRequest(NetState state, PacketReader pvSrc)
|
||||
{
|
||||
Mobile from = state.Mobile;
|
||||
|
||||
int packetID = pvSrc.ReadByte();
|
||||
|
||||
if (!(World.FindItem(pvSrc.ReadUInt32()) is BaseBulletinBoard board) || !board.CheckRange(from))
|
||||
return;
|
||||
|
||||
switch (packetID)
|
||||
{
|
||||
case 3:
|
||||
BBRequestContent(from, board, pvSrc);
|
||||
break;
|
||||
case 4:
|
||||
BBRequestHeader(from, board, pvSrc);
|
||||
break;
|
||||
case 5:
|
||||
BBPostMessage(from, board, pvSrc);
|
||||
break;
|
||||
case 6:
|
||||
BBRemoveMessage(from, board, pvSrc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static void BBRequestContent(Mobile from, BaseBulletinBoard board, PacketReader pvSrc)
|
||||
{
|
||||
if (!(World.FindItem(pvSrc.ReadUInt32()) is BulletinMessage msg) || msg.Parent != board)
|
||||
return;
|
||||
|
||||
from.Send(new BBMessageContent(board, msg));
|
||||
}
|
||||
|
||||
public static void BBRequestHeader(Mobile from, BaseBulletinBoard board, PacketReader pvSrc)
|
||||
{
|
||||
if (!(World.FindItem(pvSrc.ReadUInt32()) is BulletinMessage msg) || msg.Parent != board)
|
||||
return;
|
||||
|
||||
from.Send(new BBMessageHeader(board, msg));
|
||||
}
|
||||
|
||||
public static void BBPostMessage(Mobile from, BaseBulletinBoard board, PacketReader pvSrc)
|
||||
{
|
||||
BulletinMessage thread = World.FindItem(pvSrc.ReadUInt32()) as BulletinMessage;
|
||||
|
||||
if (thread != null && thread.Parent != board)
|
||||
thread = null;
|
||||
|
||||
int breakout = 0;
|
||||
|
||||
while (thread?.Thread != null && breakout++ < 10)
|
||||
thread = thread.Thread;
|
||||
|
||||
DateTime lastPostTime = DateTime.MinValue;
|
||||
|
||||
if (board.GetLastPostTime(from, thread == null, ref lastPostTime))
|
||||
if (!CheckTime(lastPostTime, thread == null ? ThreadCreateTime : ThreadReplyTime))
|
||||
{
|
||||
if (thread == null)
|
||||
from.SendMessage("You must wait {0} before creating a new thread.", FormatTS(ThreadCreateTime));
|
||||
else
|
||||
from.SendMessage("You must wait {0} before replying to another thread.", FormatTS(ThreadReplyTime));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
string subject = pvSrc.ReadUTF8StringSafe(pvSrc.ReadByte());
|
||||
|
||||
if (subject.Length == 0)
|
||||
return;
|
||||
|
||||
string[] lines = new string[pvSrc.ReadByte()];
|
||||
|
||||
if (lines.Length == 0)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < lines.Length; ++i)
|
||||
lines[i] = pvSrc.ReadUTF8StringSafe(pvSrc.ReadByte());
|
||||
|
||||
board.PostMessage(from, thread, subject, lines);
|
||||
}
|
||||
|
||||
public static void BBRemoveMessage(Mobile from, BaseBulletinBoard board, PacketReader pvSrc)
|
||||
{
|
||||
if (!(World.FindItem(pvSrc.ReadUInt32()) is BulletinMessage msg) || msg.Parent != board)
|
||||
return;
|
||||
|
||||
if (from.AccessLevel < AccessLevel.GameMaster && msg.Poster != from)
|
||||
return;
|
||||
|
||||
msg.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
public struct BulletinEquip
|
||||
{
|
||||
public int itemID;
|
||||
public int hue;
|
||||
|
||||
public BulletinEquip(int itemID, int hue)
|
||||
{
|
||||
this.itemID = itemID;
|
||||
this.hue = hue;
|
||||
}
|
||||
}
|
||||
|
||||
public class BulletinMessage : Item
|
||||
{
|
||||
public BulletinMessage(Mobile poster, BulletinMessage thread, string subject, string[] lines) : base(0xEB0)
|
||||
{
|
||||
Movable = false;
|
||||
|
||||
Poster = poster;
|
||||
Subject = subject;
|
||||
Time = DateTime.UtcNow;
|
||||
LastPostTime = Time;
|
||||
Thread = thread;
|
||||
PostedName = Poster.Name;
|
||||
PostedBody = Poster.Body;
|
||||
PostedHue = Poster.Hue;
|
||||
Lines = lines;
|
||||
|
||||
List<BulletinEquip> list = new List<BulletinEquip>();
|
||||
|
||||
for (int i = 0; i < poster.Items.Count; ++i)
|
||||
{
|
||||
Item item = poster.Items[i];
|
||||
|
||||
if (item.Layer >= Layer.OneHanded && item.Layer <= Layer.Mount)
|
||||
list.Add(new BulletinEquip(item.ItemID, item.Hue));
|
||||
}
|
||||
|
||||
PostedEquip = list.ToArray();
|
||||
}
|
||||
|
||||
public BulletinMessage(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public Mobile Poster{ get; private set; }
|
||||
|
||||
public BulletinMessage Thread{ get; private set; }
|
||||
|
||||
public string Subject{ get; private set; }
|
||||
|
||||
public DateTime Time{ get; private set; }
|
||||
|
||||
public DateTime LastPostTime{ get; set; }
|
||||
|
||||
public string PostedName{ get; private set; }
|
||||
|
||||
public int PostedBody{ get; private set; }
|
||||
|
||||
public int PostedHue{ get; private set; }
|
||||
|
||||
public BulletinEquip[] PostedEquip{ get; private set; }
|
||||
|
||||
public string[] Lines{ get; private set; }
|
||||
|
||||
public string GetTimeAsString()
|
||||
{
|
||||
return Time.ToString("MMM dd, yyyy");
|
||||
}
|
||||
|
||||
public override bool CheckTarget(Mobile from, Target targ, object targeted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool IsAccessibleTo(Mobile check)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1); // version
|
||||
|
||||
writer.Write(Poster);
|
||||
writer.Write(Subject);
|
||||
writer.Write(Time);
|
||||
writer.Write(LastPostTime);
|
||||
writer.Write(Thread != null);
|
||||
writer.Write(Thread);
|
||||
writer.Write(PostedName);
|
||||
writer.Write(PostedBody);
|
||||
writer.Write(PostedHue);
|
||||
|
||||
writer.Write(PostedEquip.Length);
|
||||
|
||||
for (int i = 0; i < PostedEquip.Length; ++i)
|
||||
{
|
||||
writer.Write(PostedEquip[i].itemID);
|
||||
writer.Write(PostedEquip[i].hue);
|
||||
}
|
||||
|
||||
writer.Write(Lines.Length);
|
||||
|
||||
for (int i = 0; i < Lines.Length; ++i)
|
||||
writer.Write(Lines[i]);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
case 0:
|
||||
{
|
||||
Poster = reader.ReadMobile();
|
||||
Subject = reader.ReadString();
|
||||
Time = reader.ReadDateTime();
|
||||
LastPostTime = reader.ReadDateTime();
|
||||
bool hasThread = reader.ReadBool();
|
||||
Thread = reader.ReadItem() as BulletinMessage;
|
||||
PostedName = reader.ReadString();
|
||||
PostedBody = reader.ReadInt();
|
||||
PostedHue = reader.ReadInt();
|
||||
|
||||
PostedEquip = new BulletinEquip[reader.ReadInt()];
|
||||
|
||||
for (int i = 0; i < PostedEquip.Length; ++i)
|
||||
{
|
||||
PostedEquip[i].itemID = reader.ReadInt();
|
||||
PostedEquip[i].hue = reader.ReadInt();
|
||||
}
|
||||
|
||||
Lines = new string[reader.ReadInt()];
|
||||
|
||||
for (int i = 0; i < Lines.Length; ++i)
|
||||
Lines[i] = reader.ReadString();
|
||||
|
||||
if (hasThread && Thread == null)
|
||||
Delete();
|
||||
|
||||
if (version == 0)
|
||||
ValidationQueue<BulletinMessage>.Add(this);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Validate()
|
||||
{
|
||||
if ((Parent as BulletinBoard)?.Items.Contains(this) == false)
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
|
||||
public class BBDisplayBoard : Packet
|
||||
{
|
||||
public BBDisplayBoard(BaseBulletinBoard board) : base(0x71)
|
||||
{
|
||||
EnsureCapacity(38);
|
||||
|
||||
byte[] buffer = Utility.UTF8.GetBytes(board.BoardName ?? "");
|
||||
|
||||
m_Stream.Write((byte)0x00); // PacketID
|
||||
m_Stream.Write(board.Serial); // Bulletin board serial
|
||||
|
||||
// Bulletin board name
|
||||
if (buffer.Length >= 29)
|
||||
{
|
||||
m_Stream.Write(buffer, 0, 29);
|
||||
m_Stream.Write((byte)0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Stream.Write(buffer, 0, buffer.Length);
|
||||
m_Stream.Fill(30 - buffer.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class BBMessageHeader : Packet
|
||||
{
|
||||
public BBMessageHeader(BaseBulletinBoard board, BulletinMessage msg) : base(0x71)
|
||||
{
|
||||
string poster = SafeString(msg.PostedName);
|
||||
string subject = SafeString(msg.Subject);
|
||||
string time = SafeString(msg.GetTimeAsString());
|
||||
|
||||
EnsureCapacity(22 + poster.Length + subject.Length + time.Length);
|
||||
|
||||
m_Stream.Write((byte)0x01); // PacketID
|
||||
m_Stream.Write(board.Serial); // Bulletin board serial
|
||||
m_Stream.Write(msg.Serial); // Message serial
|
||||
|
||||
BulletinMessage thread = msg.Thread;
|
||||
|
||||
if (thread == null)
|
||||
m_Stream.Write(0); // Thread serial--root
|
||||
else
|
||||
m_Stream.Write(thread.Serial); // Thread serial--parent
|
||||
|
||||
WriteString(poster);
|
||||
WriteString(subject);
|
||||
WriteString(time);
|
||||
}
|
||||
|
||||
public void WriteString(string v)
|
||||
{
|
||||
byte[] buffer = Utility.UTF8.GetBytes(v);
|
||||
int len = buffer.Length + 1;
|
||||
|
||||
if (len > 255)
|
||||
len = 255;
|
||||
|
||||
m_Stream.Write((byte)len);
|
||||
m_Stream.Write(buffer, 0, len - 1);
|
||||
m_Stream.Write((byte)0);
|
||||
}
|
||||
|
||||
public string SafeString(string v)
|
||||
{
|
||||
return v ?? string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public class BBMessageContent : Packet
|
||||
{
|
||||
public BBMessageContent(BaseBulletinBoard board, BulletinMessage msg) : base(0x71)
|
||||
{
|
||||
string poster = SafeString(msg.PostedName);
|
||||
string subject = SafeString(msg.Subject);
|
||||
string time = SafeString(msg.GetTimeAsString());
|
||||
|
||||
EnsureCapacity(22 + poster.Length + subject.Length + time.Length);
|
||||
|
||||
m_Stream.Write((byte)0x02); // PacketID
|
||||
m_Stream.Write(board.Serial); // Bulletin board serial
|
||||
m_Stream.Write(msg.Serial); // Message serial
|
||||
|
||||
WriteString(poster);
|
||||
WriteString(subject);
|
||||
WriteString(time);
|
||||
|
||||
m_Stream.Write((short)msg.PostedBody);
|
||||
m_Stream.Write((short)msg.PostedHue);
|
||||
|
||||
int len = msg.PostedEquip.Length;
|
||||
|
||||
if (len > 255)
|
||||
len = 255;
|
||||
|
||||
m_Stream.Write((byte)len);
|
||||
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
BulletinEquip eq = msg.PostedEquip[i];
|
||||
|
||||
m_Stream.Write((short)eq.itemID);
|
||||
m_Stream.Write((short)eq.hue);
|
||||
}
|
||||
|
||||
len = msg.Lines.Length;
|
||||
|
||||
if (len > 255)
|
||||
len = 255;
|
||||
|
||||
m_Stream.Write((byte)len);
|
||||
|
||||
for (int i = 0; i < len; ++i)
|
||||
WriteString(msg.Lines[i], true);
|
||||
}
|
||||
|
||||
public void WriteString(string v)
|
||||
{
|
||||
WriteString(v, false);
|
||||
}
|
||||
|
||||
public void WriteString(string v, bool padding)
|
||||
{
|
||||
byte[] buffer = Utility.UTF8.GetBytes(v);
|
||||
int tail = padding ? 2 : 1;
|
||||
int len = buffer.Length + tail;
|
||||
|
||||
if (len > 255)
|
||||
len = 255;
|
||||
|
||||
m_Stream.Write((byte)len);
|
||||
m_Stream.Write(buffer, 0, len - tail);
|
||||
|
||||
if (padding)
|
||||
m_Stream.Write((short)0); // padding compensates for a client bug
|
||||
else
|
||||
m_Stream.Write((byte)0);
|
||||
}
|
||||
|
||||
public string SafeString(string v)
|
||||
{
|
||||
if (v == null)
|
||||
return string.Empty;
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
129
Projects/Scripts/Items/Misc/ClockworkAssembly.cs
Normal file
129
Projects/Scripts/Items/Misc/ClockworkAssembly.cs
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class ClockworkAssembly : Item
|
||||
{
|
||||
[Constructible]
|
||||
public ClockworkAssembly() : base(0x1EA8)
|
||||
{
|
||||
Weight = 5.0;
|
||||
Hue = 1102;
|
||||
}
|
||||
|
||||
public ClockworkAssembly(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "clockwork assembly";
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
|
||||
return;
|
||||
}
|
||||
|
||||
double tinkerSkill = from.Skills.Tinkering.Value;
|
||||
|
||||
if (tinkerSkill < 60.0)
|
||||
{
|
||||
from.SendMessage("You must have at least 60.0 skill in tinkering to construct a golem.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (from.Followers + 4 > from.FollowersMax)
|
||||
{
|
||||
from.SendLocalizedMessage(1049607); // You have too many followers to control that creature.
|
||||
return;
|
||||
}
|
||||
|
||||
double scalar;
|
||||
|
||||
if (tinkerSkill >= 100.0)
|
||||
scalar = 1.0;
|
||||
else if (tinkerSkill >= 90.0)
|
||||
scalar = 0.9;
|
||||
else if (tinkerSkill >= 80.0)
|
||||
scalar = 0.8;
|
||||
else if (tinkerSkill >= 70.0)
|
||||
scalar = 0.7;
|
||||
else
|
||||
scalar = 0.6;
|
||||
|
||||
Container pack = from.Backpack;
|
||||
|
||||
if (pack == null)
|
||||
return;
|
||||
|
||||
int res = pack.ConsumeTotal(
|
||||
new[]
|
||||
{
|
||||
typeof(PowerCrystal),
|
||||
typeof(IronIngot),
|
||||
typeof(BronzeIngot),
|
||||
typeof(Gears)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
1,
|
||||
50,
|
||||
50,
|
||||
5
|
||||
});
|
||||
|
||||
switch (res)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
from.SendMessage("You must have a power crystal to construct the golem.");
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
from.SendMessage("You must have 50 iron ingots to construct the golem.");
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
from.SendMessage("You must have 50 bronze ingots to construct the golem.");
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
from.SendMessage("You must have 5 gears to construct the golem.");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
Golem g = new Golem(true, scalar);
|
||||
|
||||
if (g.SetControlMaster(from))
|
||||
{
|
||||
Delete();
|
||||
|
||||
g.MoveToWorld(from.Location, from.Map);
|
||||
from.PlaySound(0x241);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
450
Projects/Scripts/Items/Misc/CommunicationCrystals.cs
Normal file
450
Projects/Scripts/Items/Misc/CommunicationCrystals.cs
Normal file
|
|
@ -0,0 +1,450 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Network;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class CrystalRechargeInfo
|
||||
{
|
||||
public static readonly CrystalRechargeInfo[] Table =
|
||||
{
|
||||
new CrystalRechargeInfo(typeof(Citrine), 500),
|
||||
new CrystalRechargeInfo(typeof(Amber), 500),
|
||||
new CrystalRechargeInfo(typeof(Tourmaline), 750),
|
||||
new CrystalRechargeInfo(typeof(Emerald), 1000),
|
||||
new CrystalRechargeInfo(typeof(Sapphire), 1000),
|
||||
new CrystalRechargeInfo(typeof(Amethyst), 1000),
|
||||
new CrystalRechargeInfo(typeof(StarSapphire), 1250),
|
||||
new CrystalRechargeInfo(typeof(Diamond), 2000)
|
||||
};
|
||||
|
||||
private CrystalRechargeInfo(Type type, int amount)
|
||||
{
|
||||
Type = type;
|
||||
Amount = amount;
|
||||
}
|
||||
|
||||
public Type Type{ get; }
|
||||
|
||||
public int Amount{ get; }
|
||||
|
||||
public static CrystalRechargeInfo Get(Type type)
|
||||
{
|
||||
foreach (CrystalRechargeInfo info in Table)
|
||||
if (info.Type == type)
|
||||
return info;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class BroadcastCrystal : Item
|
||||
{
|
||||
public static readonly int MaxCharges = 2000;
|
||||
|
||||
private int m_Charges;
|
||||
|
||||
[Constructible]
|
||||
public BroadcastCrystal(int charges = 2000) : base(0x1ED0)
|
||||
{
|
||||
Light = LightType.Circle150;
|
||||
|
||||
m_Charges = charges;
|
||||
|
||||
Receivers = new List<ReceiverCrystal>();
|
||||
}
|
||||
|
||||
public BroadcastCrystal(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1060740; // communication crystal
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool Active
|
||||
{
|
||||
get => ItemID == 0x1ECD;
|
||||
set
|
||||
{
|
||||
ItemID = value ? 0x1ECD : 0x1ED0;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Charges
|
||||
{
|
||||
get => m_Charges;
|
||||
set
|
||||
{
|
||||
m_Charges = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public List<ReceiverCrystal> Receivers{ get; private set; }
|
||||
|
||||
public override bool HandlesOnSpeech => true;
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
list.Add(Active ? 1060742 : 1060743); // active / inactive
|
||||
list.Add(1060745); // broadcast
|
||||
list.Add(1060741, Charges.ToString()); // charges: ~1_val~
|
||||
|
||||
if (Receivers.Count > 0)
|
||||
list.Add(1060746, Receivers.Count.ToString()); // links: ~1_val~
|
||||
}
|
||||
|
||||
public override void OnSingleClick(Mobile from)
|
||||
{
|
||||
base.OnSingleClick(from);
|
||||
|
||||
LabelTo(from, Active ? 1060742 : 1060743); // active / inactive
|
||||
LabelTo(from, 1060745); // broadcast
|
||||
LabelTo(from, 1060741, Charges.ToString()); // charges: ~1_val~
|
||||
|
||||
if (Receivers.Count > 0)
|
||||
LabelTo(from, 1060746, Receivers.Count.ToString()); // links: ~1_val~
|
||||
}
|
||||
|
||||
public override void OnSpeech(SpeechEventArgs e)
|
||||
{
|
||||
if (!Active || Receivers.Count == 0 || RootParent != null && !(RootParent is Mobile))
|
||||
return;
|
||||
|
||||
if (e.Type == MessageType.Emote)
|
||||
return;
|
||||
|
||||
Mobile from = e.Mobile;
|
||||
string speech = e.Speech;
|
||||
|
||||
foreach (ReceiverCrystal receiver in new List<ReceiverCrystal>(Receivers))
|
||||
if (receiver.Deleted)
|
||||
{
|
||||
Receivers.Remove(receiver);
|
||||
}
|
||||
else if (Charges > 0)
|
||||
{
|
||||
receiver.TransmitMessage(from, speech);
|
||||
Charges--;
|
||||
}
|
||||
else
|
||||
{
|
||||
Active = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!from.InRange(GetWorldLocation(), 2))
|
||||
{
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
|
||||
return;
|
||||
}
|
||||
|
||||
from.Target = new InternalTarget(this);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.WriteEncodedInt(m_Charges);
|
||||
writer.WriteItemList(Receivers);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
m_Charges = reader.ReadEncodedInt();
|
||||
Receivers = reader.ReadStrongItemList<ReceiverCrystal>();
|
||||
}
|
||||
|
||||
private class InternalTarget : Target
|
||||
{
|
||||
private BroadcastCrystal m_Crystal;
|
||||
|
||||
public InternalTarget(BroadcastCrystal crystal) : base(2, false, TargetFlags.None)
|
||||
{
|
||||
m_Crystal = crystal;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (!m_Crystal.IsAccessibleTo(from))
|
||||
return;
|
||||
|
||||
if (from.Map != m_Crystal.Map || !from.InRange(m_Crystal.GetWorldLocation(), 2))
|
||||
{
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
|
||||
return;
|
||||
}
|
||||
|
||||
if (targeted == m_Crystal)
|
||||
{
|
||||
if (m_Crystal.Active)
|
||||
{
|
||||
m_Crystal.Active = false;
|
||||
from.SendLocalizedMessage(500672); // You turn the crystal off.
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_Crystal.Charges > 0)
|
||||
{
|
||||
m_Crystal.Active = true;
|
||||
from.SendLocalizedMessage(500673); // You turn the crystal on.
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(500676); // This crystal is out of charges.
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (targeted is ReceiverCrystal receiver)
|
||||
{
|
||||
if (m_Crystal.Receivers.Count >= 10)
|
||||
{
|
||||
from.SendLocalizedMessage(1010042); // This broadcast crystal is already linked to 10 receivers.
|
||||
}
|
||||
else if (receiver.Sender == m_Crystal)
|
||||
{
|
||||
from.SendLocalizedMessage(500674); // This crystal is already linked with that crystal.
|
||||
}
|
||||
else if (receiver.Sender != null)
|
||||
{
|
||||
from.SendLocalizedMessage(
|
||||
1010043); // That receiver crystal is already linked to another broadcast crystal.
|
||||
}
|
||||
else
|
||||
{
|
||||
receiver.Sender = m_Crystal;
|
||||
from.SendLocalizedMessage(500675); // That crystal has been linked to this crystal.
|
||||
}
|
||||
}
|
||||
else if (targeted == from)
|
||||
{
|
||||
foreach (ReceiverCrystal rc in new List<ReceiverCrystal>(m_Crystal.Receivers)) rc.Sender = null;
|
||||
|
||||
from.SendLocalizedMessage(1010046); // You unlink the broadcast crystal from all of its receivers.
|
||||
}
|
||||
else
|
||||
{
|
||||
if (targeted is Item targItem && targItem.VerifyMove(from))
|
||||
{
|
||||
CrystalRechargeInfo info = CrystalRechargeInfo.Get(targItem.GetType());
|
||||
|
||||
if (info != null)
|
||||
{
|
||||
if (m_Crystal.Charges >= MaxCharges)
|
||||
{
|
||||
from.SendLocalizedMessage(500678); // This crystal is already fully charged.
|
||||
}
|
||||
else
|
||||
{
|
||||
targItem.Consume();
|
||||
|
||||
if (m_Crystal.Charges + info.Amount >= MaxCharges)
|
||||
{
|
||||
m_Crystal.Charges = MaxCharges;
|
||||
from.SendLocalizedMessage(500679); // You completely recharge the crystal.
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Crystal.Charges += info.Amount;
|
||||
from.SendLocalizedMessage(500680); // You recharge the crystal.
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
from.SendLocalizedMessage(500681); // You cannot use this crystal on that.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ReceiverCrystal : Item
|
||||
{
|
||||
private BroadcastCrystal m_Sender;
|
||||
|
||||
[Constructible]
|
||||
public ReceiverCrystal() : base(0x1ED0)
|
||||
{
|
||||
Light = LightType.Circle150;
|
||||
}
|
||||
|
||||
public ReceiverCrystal(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1060740; // communication crystal
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool Active
|
||||
{
|
||||
get => ItemID == 0x1ED1;
|
||||
set
|
||||
{
|
||||
ItemID = value ? 0x1ED1 : 0x1ED0;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public BroadcastCrystal Sender
|
||||
{
|
||||
get => m_Sender;
|
||||
set
|
||||
{
|
||||
if (m_Sender != null)
|
||||
{
|
||||
m_Sender.Receivers.Remove(this);
|
||||
m_Sender.InvalidateProperties();
|
||||
}
|
||||
|
||||
m_Sender = value;
|
||||
|
||||
if (value != null)
|
||||
{
|
||||
value.Receivers.Add(this);
|
||||
value.InvalidateProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
list.Add(Active ? 1060742 : 1060743); // active / inactive
|
||||
list.Add(1060744); // receiver
|
||||
}
|
||||
|
||||
public override void OnSingleClick(Mobile from)
|
||||
{
|
||||
base.OnSingleClick(from);
|
||||
|
||||
LabelTo(from, Active ? 1060742 : 1060743); // active / inactive
|
||||
LabelTo(from, 1060744); // receiver
|
||||
}
|
||||
|
||||
public void TransmitMessage(Mobile from, string message)
|
||||
{
|
||||
if (!Active)
|
||||
return;
|
||||
|
||||
string text = $"{from.Name} says {message}";
|
||||
|
||||
if (RootParent is Mobile mobile)
|
||||
mobile.SendMessage(0x2B2, "Crystal: " + text);
|
||||
else if (RootParent is Item item)
|
||||
item.PublicOverheadMessage(MessageType.Regular, 0x2B2, false, "Crystal: " + text);
|
||||
else
|
||||
PublicOverheadMessage(MessageType.Regular, 0x2B2, false, text);
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!from.InRange(GetWorldLocation(), 2))
|
||||
{
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
|
||||
return;
|
||||
}
|
||||
|
||||
from.Target = new InternalTarget(this);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.WriteItem(m_Sender);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
m_Sender = reader.ReadItem<BroadcastCrystal>();
|
||||
}
|
||||
|
||||
private class InternalTarget : Target
|
||||
{
|
||||
private ReceiverCrystal m_Crystal;
|
||||
|
||||
public InternalTarget(ReceiverCrystal crystal) : base(-1, false, TargetFlags.None)
|
||||
{
|
||||
m_Crystal = crystal;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (!m_Crystal.IsAccessibleTo(from))
|
||||
return;
|
||||
|
||||
if (from.Map != m_Crystal.Map || !from.InRange(m_Crystal.GetWorldLocation(), 2))
|
||||
{
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
|
||||
return;
|
||||
}
|
||||
|
||||
if (targeted == m_Crystal)
|
||||
{
|
||||
if (m_Crystal.Active)
|
||||
{
|
||||
m_Crystal.Active = false;
|
||||
from.SendLocalizedMessage(500672); // You turn the crystal off.
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Crystal.Active = true;
|
||||
from.SendLocalizedMessage(500673); // You turn the crystal on.
|
||||
}
|
||||
}
|
||||
else if (targeted == from)
|
||||
{
|
||||
if (m_Crystal.Sender != null)
|
||||
{
|
||||
m_Crystal.Sender = null;
|
||||
from.SendLocalizedMessage(1010044); // You unlink the receiver crystal.
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1010045); // That receiver crystal is not linked.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (targeted is Item targItem && targItem.VerifyMove(from))
|
||||
{
|
||||
CrystalRechargeInfo info = CrystalRechargeInfo.Get(targItem.GetType());
|
||||
|
||||
if (info != null)
|
||||
{
|
||||
from.SendLocalizedMessage(500677); // This crystal cannot be recharged.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
from.SendLocalizedMessage(1010045); // That receiver crystal is not linked.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1173
Projects/Scripts/Items/Misc/Corpses/Corpse.cs
Normal file
1173
Projects/Scripts/Items/Misc/Corpses/Corpse.cs
Normal file
File diff suppressed because it is too large
Load diff
15
Projects/Scripts/Items/Misc/Corpses/CorpseNameAttribute.cs
Normal file
15
Projects/Scripts/Items/Misc/Corpses/CorpseNameAttribute.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class CorpseNameAttribute : Attribute
|
||||
{
|
||||
public CorpseNameAttribute(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public string Name{ get; }
|
||||
}
|
||||
}
|
||||
111
Projects/Scripts/Items/Misc/Corpses/DecayedCorpse.cs
Normal file
111
Projects/Scripts/Items/Misc/Corpses/DecayedCorpse.cs
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class DecayedCorpse : Container
|
||||
{
|
||||
private static TimeSpan m_DefaultDecayTime = TimeSpan.FromMinutes(7.0);
|
||||
private DateTime m_DecayTime;
|
||||
private Timer m_DecayTimer;
|
||||
|
||||
public DecayedCorpse(string name) : base(Utility.Random(0xECA, 9))
|
||||
{
|
||||
Movable = false;
|
||||
Name = name;
|
||||
|
||||
BeginDecay(m_DefaultDecayTime);
|
||||
}
|
||||
|
||||
public DecayedCorpse(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
// Do not display (x items, y stones)
|
||||
public override bool DisplaysContent => false;
|
||||
|
||||
public void BeginDecay(TimeSpan delay)
|
||||
{
|
||||
m_DecayTimer?.Stop();
|
||||
|
||||
m_DecayTime = DateTime.UtcNow + delay;
|
||||
|
||||
m_DecayTimer = new InternalTimer(this, delay);
|
||||
m_DecayTimer.Start();
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
m_DecayTimer?.Stop();
|
||||
|
||||
m_DecayTimer = null;
|
||||
}
|
||||
|
||||
// Do not display (x items, y stones)
|
||||
public override bool CheckContentDisplay(Mobile from)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void AddNameProperty(ObjectPropertyList list)
|
||||
{
|
||||
list.Add(1046414, Name); // the remains of ~1_NAME~
|
||||
}
|
||||
|
||||
public override void OnSingleClick(Mobile from)
|
||||
{
|
||||
LabelTo(from, 1046414, Name); // the remains of ~1_NAME~
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1); // version
|
||||
|
||||
writer.Write(m_DecayTimer != null);
|
||||
|
||||
if (m_DecayTimer != null)
|
||||
writer.WriteDeltaTime(m_DecayTime);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
BeginDecay(m_DefaultDecayTime);
|
||||
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
if (reader.ReadBool())
|
||||
BeginDecay(reader.ReadDeltaTime() - DateTime.UtcNow);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class InternalTimer : Timer
|
||||
{
|
||||
private DecayedCorpse m_Corpse;
|
||||
|
||||
public InternalTimer(DecayedCorpse c, TimeSpan delay) : base(delay)
|
||||
{
|
||||
m_Corpse = c;
|
||||
Priority = TimerPriority.FiveSeconds;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Corpse.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
198
Projects/Scripts/Items/Misc/Corpses/Packets.cs
Normal file
198
Projects/Scripts/Items/Misc/Corpses/Packets.cs
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Network
|
||||
{
|
||||
public sealed class CorpseEquip : Packet
|
||||
{
|
||||
public CorpseEquip(Mobile beholder, Corpse beheld) : base(0x89)
|
||||
{
|
||||
List<Item> list = beheld.EquipItems;
|
||||
|
||||
int count = list.Count;
|
||||
if (beheld.Hair != null && beheld.Hair.ItemID > 0)
|
||||
count++;
|
||||
if (beheld.FacialHair != null && beheld.FacialHair.ItemID > 0)
|
||||
count++;
|
||||
|
||||
EnsureCapacity(8 + count * 5);
|
||||
|
||||
m_Stream.Write(beheld.Serial);
|
||||
|
||||
for (int i = 0; i < list.Count; ++i)
|
||||
{
|
||||
Item item = list[i];
|
||||
|
||||
if (!item.Deleted && beholder.CanSee(item) && item.Parent == beheld)
|
||||
{
|
||||
m_Stream.Write((byte)(item.Layer + 1));
|
||||
m_Stream.Write(item.Serial);
|
||||
}
|
||||
}
|
||||
|
||||
if (beheld.Hair != null && beheld.Hair.ItemID > 0)
|
||||
{
|
||||
m_Stream.Write((byte)(Layer.Hair + 1));
|
||||
m_Stream.Write(HairInfo.FakeSerial(beheld.Owner) - 2);
|
||||
}
|
||||
|
||||
if (beheld.FacialHair != null && beheld.FacialHair.ItemID > 0)
|
||||
{
|
||||
m_Stream.Write((byte)(Layer.FacialHair + 1));
|
||||
m_Stream.Write(FacialHairInfo.FakeSerial(beheld.Owner) - 2);
|
||||
}
|
||||
|
||||
m_Stream.Write((byte)Layer.Invalid);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class CorpseContent : Packet
|
||||
{
|
||||
public CorpseContent(Mobile beholder, Corpse beheld)
|
||||
: base(0x3C)
|
||||
{
|
||||
List<Item> items = beheld.EquipItems;
|
||||
int count = items.Count;
|
||||
|
||||
if (beheld.Hair != null && beheld.Hair.ItemID > 0)
|
||||
count++;
|
||||
if (beheld.FacialHair != null && beheld.FacialHair.ItemID > 0)
|
||||
count++;
|
||||
|
||||
EnsureCapacity(5 + count * 19);
|
||||
|
||||
long pos = m_Stream.Position;
|
||||
|
||||
int written = 0;
|
||||
|
||||
m_Stream.Write((ushort)0);
|
||||
|
||||
for (int i = 0; i < items.Count; ++i)
|
||||
{
|
||||
Item child = items[i];
|
||||
|
||||
if (!child.Deleted && child.Parent == beheld && beholder.CanSee(child))
|
||||
{
|
||||
m_Stream.Write(child.Serial);
|
||||
m_Stream.Write((ushort)child.ItemID);
|
||||
m_Stream.Write((byte)0); // signed, itemID offset
|
||||
m_Stream.Write((ushort)child.Amount);
|
||||
m_Stream.Write((short)child.X);
|
||||
m_Stream.Write((short)child.Y);
|
||||
m_Stream.Write(beheld.Serial);
|
||||
m_Stream.Write((ushort)child.Hue);
|
||||
|
||||
++written;
|
||||
}
|
||||
}
|
||||
|
||||
if (beheld.Hair != null && beheld.Hair.ItemID > 0)
|
||||
{
|
||||
m_Stream.Write(HairInfo.FakeSerial(beheld.Owner) - 2);
|
||||
m_Stream.Write((ushort)beheld.Hair.ItemID);
|
||||
m_Stream.Write((byte)0); // signed, itemID offset
|
||||
m_Stream.Write((ushort)1);
|
||||
m_Stream.Write((short)0);
|
||||
m_Stream.Write((short)0);
|
||||
m_Stream.Write(beheld.Serial);
|
||||
m_Stream.Write((ushort)beheld.Hair.Hue);
|
||||
|
||||
++written;
|
||||
}
|
||||
|
||||
if (beheld.FacialHair != null && beheld.FacialHair.ItemID > 0)
|
||||
{
|
||||
m_Stream.Write(FacialHairInfo.FakeSerial(beheld.Owner) - 2);
|
||||
m_Stream.Write((ushort)beheld.FacialHair.ItemID);
|
||||
m_Stream.Write((byte)0); // signed, itemID offset
|
||||
m_Stream.Write((ushort)1);
|
||||
m_Stream.Write((short)0);
|
||||
m_Stream.Write((short)0);
|
||||
m_Stream.Write(beheld.Serial);
|
||||
m_Stream.Write((ushort)beheld.FacialHair.Hue);
|
||||
|
||||
++written;
|
||||
}
|
||||
|
||||
m_Stream.Seek(pos, SeekOrigin.Begin);
|
||||
m_Stream.Write((ushort)written);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class CorpseContent6017 : Packet
|
||||
{
|
||||
public CorpseContent6017(Mobile beholder, Corpse beheld)
|
||||
: base(0x3C)
|
||||
{
|
||||
List<Item> items = beheld.EquipItems;
|
||||
int count = items.Count;
|
||||
|
||||
if (beheld.Hair != null && beheld.Hair.ItemID > 0)
|
||||
count++;
|
||||
if (beheld.FacialHair != null && beheld.FacialHair.ItemID > 0)
|
||||
count++;
|
||||
|
||||
EnsureCapacity(5 + count * 20);
|
||||
|
||||
long pos = m_Stream.Position;
|
||||
|
||||
int written = 0;
|
||||
|
||||
m_Stream.Write((ushort)0);
|
||||
|
||||
for (int i = 0; i < items.Count; ++i)
|
||||
{
|
||||
Item child = items[i];
|
||||
|
||||
if (!child.Deleted && child.Parent == beheld && beholder.CanSee(child))
|
||||
{
|
||||
m_Stream.Write(child.Serial);
|
||||
m_Stream.Write((ushort)child.ItemID);
|
||||
m_Stream.Write((byte)0); // signed, itemID offset
|
||||
m_Stream.Write((ushort)child.Amount);
|
||||
m_Stream.Write((short)child.X);
|
||||
m_Stream.Write((short)child.Y);
|
||||
m_Stream.Write((byte)0); // Grid Location?
|
||||
m_Stream.Write(beheld.Serial);
|
||||
m_Stream.Write((ushort)child.Hue);
|
||||
|
||||
++written;
|
||||
}
|
||||
}
|
||||
|
||||
if (beheld.Hair != null && beheld.Hair.ItemID > 0)
|
||||
{
|
||||
m_Stream.Write(HairInfo.FakeSerial(beheld.Owner) - 2);
|
||||
m_Stream.Write((ushort)beheld.Hair.ItemID);
|
||||
m_Stream.Write((byte)0); // signed, itemID offset
|
||||
m_Stream.Write((ushort)1);
|
||||
m_Stream.Write((short)0);
|
||||
m_Stream.Write((short)0);
|
||||
m_Stream.Write((byte)0); // Grid Location?
|
||||
m_Stream.Write(beheld.Serial);
|
||||
m_Stream.Write((ushort)beheld.Hair.Hue);
|
||||
|
||||
++written;
|
||||
}
|
||||
|
||||
if (beheld.FacialHair != null && beheld.FacialHair.ItemID > 0)
|
||||
{
|
||||
m_Stream.Write(FacialHairInfo.FakeSerial(beheld.Owner) - 2);
|
||||
m_Stream.Write((ushort)beheld.FacialHair.ItemID);
|
||||
m_Stream.Write((byte)0); // signed, itemID offset
|
||||
m_Stream.Write((ushort)1);
|
||||
m_Stream.Write((short)0);
|
||||
m_Stream.Write((short)0);
|
||||
m_Stream.Write((byte)0); // Grid Location?
|
||||
m_Stream.Write(beheld.Serial);
|
||||
m_Stream.Write((ushort)beheld.FacialHair.Hue);
|
||||
|
||||
++written;
|
||||
}
|
||||
|
||||
m_Stream.Seek(pos, SeekOrigin.Begin);
|
||||
m_Stream.Write((ushort)written);
|
||||
}
|
||||
}
|
||||
}
|
||||
233
Projects/Scripts/Items/Misc/DeceitBrazier.cs
Normal file
233
Projects/Scripts/Items/Misc/DeceitBrazier.cs
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
using System;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class DeceitBrazier : Item
|
||||
{
|
||||
private Timer m_Timer;
|
||||
|
||||
[Constructible]
|
||||
public DeceitBrazier() : base(0xE31)
|
||||
{
|
||||
Movable = false;
|
||||
Light = LightType.Circle225;
|
||||
NextSpawn = DateTime.UtcNow;
|
||||
NextSpawnDelay = TimeSpan.FromMinutes(15.0);
|
||||
SpawnRange = 5;
|
||||
}
|
||||
|
||||
public DeceitBrazier(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public static Type[] Creatures{ get; } =
|
||||
{
|
||||
#region Animals
|
||||
|
||||
typeof(FireSteed), //Set the tents up people!
|
||||
|
||||
#endregion
|
||||
|
||||
#region Undead
|
||||
|
||||
typeof(Skeleton), typeof(SkeletalKnight), typeof(SkeletalMage), typeof(Mummy),
|
||||
typeof(BoneKnight), typeof(Lich), typeof(LichLord), typeof(BoneMagi),
|
||||
typeof(Wraith), typeof(Shade), typeof(Spectre), typeof(Zombie),
|
||||
typeof(RottingCorpse), typeof(Ghoul),
|
||||
|
||||
#endregion
|
||||
|
||||
#region Demons
|
||||
|
||||
typeof(Balron), typeof(Daemon), typeof(Imp), typeof(GreaterMongbat),
|
||||
typeof(Mongbat), typeof(IceFiend), typeof(Gargoyle), typeof(StoneGargoyle),
|
||||
typeof(FireGargoyle), typeof(HordeMinion),
|
||||
|
||||
#endregion
|
||||
|
||||
#region Gazers
|
||||
|
||||
typeof(Gazer), typeof(ElderGazer), typeof(GazerLarva),
|
||||
|
||||
#endregion
|
||||
|
||||
#region Uncategorized
|
||||
|
||||
typeof(Harpy), typeof(StoneHarpy), typeof(HeadlessOne), typeof(HellHound),
|
||||
typeof(HellCat), typeof(Phoenix), typeof(LavaLizard), typeof(SandVortex),
|
||||
typeof(ShadowWisp), typeof(SwampTentacle), typeof(PredatorHellCat), typeof(Wisp),
|
||||
|
||||
#endregion
|
||||
|
||||
#region Arachnid
|
||||
|
||||
typeof(GiantSpider), typeof(DreadSpider), typeof(FrostSpider), typeof(Scorpion),
|
||||
|
||||
#endregion
|
||||
|
||||
#region Repond
|
||||
|
||||
typeof(ArcticOgreLord), typeof(Cyclops), typeof(Ettin), typeof(EvilMage),
|
||||
typeof(FrostTroll), typeof(Ogre), typeof(OgreLord), typeof(Orc),
|
||||
typeof(OrcishLord), typeof(OrcishMage), typeof(OrcBrute), typeof(Ratman),
|
||||
typeof(RatmanMage), typeof(OrcCaptain), typeof(Troll), typeof(Titan),
|
||||
typeof(EvilMageLord), typeof(OrcBomber), typeof(RatmanArcher),
|
||||
|
||||
#endregion
|
||||
|
||||
#region Reptilian
|
||||
|
||||
typeof(Dragon), typeof(Drake), typeof(Snake), typeof(GreaterDragon),
|
||||
typeof(IceSerpent), typeof(GiantSerpent), typeof(IceSnake), typeof(LavaSerpent),
|
||||
typeof(Lizardman), typeof(Wyvern), typeof(WhiteWyrm),
|
||||
typeof(ShadowWyrm), typeof(SilverSerpent), typeof(LavaSnake),
|
||||
|
||||
#endregion
|
||||
|
||||
#region Elementals
|
||||
|
||||
typeof(EarthElemental), typeof(PoisonElemental), typeof(FireElemental), typeof(SnowElemental),
|
||||
typeof(IceElemental), typeof(AcidElemental), typeof(WaterElemental), typeof(Efreet),
|
||||
typeof(AirElemental), typeof(Golem),
|
||||
|
||||
#endregion
|
||||
|
||||
#region Random Critters
|
||||
|
||||
typeof(SewerRat), typeof(GiantRat), typeof(DireWolf), typeof(TimberWolf),
|
||||
typeof(Cougar), typeof(Alligator)
|
||||
|
||||
#endregion
|
||||
};
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DateTime NextSpawn{ get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int SpawnRange{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TimeSpan NextSpawnDelay{ get; set; }
|
||||
|
||||
public override int LabelNumber => 1023633; // Brazier
|
||||
|
||||
public override bool HandlesOnMovement => true;
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write(SpawnRange);
|
||||
writer.Write(NextSpawnDelay);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if (version >= 0)
|
||||
{
|
||||
SpawnRange = reader.ReadInt();
|
||||
NextSpawnDelay = reader.ReadTimeSpan();
|
||||
}
|
||||
|
||||
NextSpawn = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public virtual void HeedWarning()
|
||||
{
|
||||
PublicOverheadMessage(MessageType.Regular, 0x3B2,
|
||||
500761); // Heed this warning well, and use this brazier at your own peril.
|
||||
}
|
||||
|
||||
public override void OnMovement(Mobile m, Point3D oldLocation)
|
||||
{
|
||||
if (NextSpawn < DateTime.UtcNow) // means we haven't spawned anything if the next spawn is below
|
||||
if (Utility.InRange(m.Location, Location, 1) && !Utility.InRange(oldLocation, Location, 1) && m.Player &&
|
||||
!(m.AccessLevel > AccessLevel.Player || m.Hidden))
|
||||
if (m_Timer == null || !m_Timer.Running)
|
||||
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(2), HeedWarning);
|
||||
|
||||
base.OnMovement(m, oldLocation);
|
||||
}
|
||||
|
||||
public Point3D GetSpawnPosition()
|
||||
{
|
||||
Map map = Map;
|
||||
|
||||
if (map == null)
|
||||
return Location;
|
||||
|
||||
// Try 10 times to find a Spawnable location.
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
int x = Location.X + (Utility.Random(SpawnRange * 2 + 1) - SpawnRange);
|
||||
int y = Location.Y + (Utility.Random(SpawnRange * 2 + 1) - SpawnRange);
|
||||
int z = Map.GetAverageZ(x, y);
|
||||
|
||||
if (Map.CanSpawnMobile(new Point2D(x, y), Z))
|
||||
return new Point3D(x, y, Z);
|
||||
if (Map.CanSpawnMobile(new Point2D(x, y), z))
|
||||
return new Point3D(x, y, z);
|
||||
}
|
||||
|
||||
return Location;
|
||||
}
|
||||
|
||||
public virtual void DoEffect(Point3D loc, Map map)
|
||||
{
|
||||
Effects.SendLocationParticles(EffectItem.Create(loc, map, EffectItem.DefaultDuration), 0x3709, 10, 30, 5052);
|
||||
Effects.PlaySound(loc, map, 0x225);
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (Utility.InRange(from.Location, Location, 2))
|
||||
try
|
||||
{
|
||||
if (NextSpawn < DateTime.UtcNow)
|
||||
{
|
||||
Map map = Map;
|
||||
BaseCreature bc =
|
||||
(BaseCreature)Activator.CreateInstance(Creatures[Utility.Random(Creatures.Length)]);
|
||||
|
||||
Point3D spawnLoc = GetSpawnPosition();
|
||||
|
||||
DoEffect(spawnLoc, map);
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(1), delegate
|
||||
{
|
||||
bc.Home = Location;
|
||||
bc.RangeHome = SpawnRange;
|
||||
bc.FightMode = FightMode.Closest;
|
||||
|
||||
bc.MoveToWorld(spawnLoc, map);
|
||||
|
||||
DoEffect(spawnLoc, map);
|
||||
|
||||
bc.ForceReacquire();
|
||||
});
|
||||
|
||||
NextSpawn = DateTime.UtcNow + NextSpawnDelay;
|
||||
}
|
||||
else
|
||||
{
|
||||
PublicOverheadMessage(MessageType.Regular, 0x3B2,
|
||||
500760); // The brazier fizzes and pops, but nothing seems to happen.
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
else
|
||||
from.SendLocalizedMessage(500446); // That is too far away.
|
||||
}
|
||||
}
|
||||
}
|
||||
340
Projects/Scripts/Items/Misc/EffectController.cs
Normal file
340
Projects/Scripts/Items/Misc/EffectController.cs
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public enum ECEffectType
|
||||
{
|
||||
None,
|
||||
Moving,
|
||||
Location,
|
||||
Target,
|
||||
Lightning
|
||||
}
|
||||
|
||||
public enum EffectTriggerType
|
||||
{
|
||||
None,
|
||||
Sequenced,
|
||||
DoubleClick,
|
||||
InRange
|
||||
}
|
||||
|
||||
public class EffectController : Item
|
||||
{
|
||||
private IEntity m_Source;
|
||||
private IEntity m_Target;
|
||||
|
||||
[Constructible]
|
||||
public EffectController() : base(0x1B72)
|
||||
{
|
||||
Movable = false;
|
||||
Visible = false;
|
||||
TriggerType = EffectTriggerType.Sequenced;
|
||||
EffectLayer = (EffectLayer)255;
|
||||
}
|
||||
|
||||
public EffectController(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public ECEffectType EffectType{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public EffectTriggerType TriggerType{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public EffectLayer EffectLayer{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TimeSpan EffectDelay{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TimeSpan TriggerDelay{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TimeSpan SoundDelay{ get; set; }
|
||||
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Item SourceItem
|
||||
{
|
||||
get => m_Source as Item;
|
||||
set => m_Source = value;
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Mobile SourceMobile
|
||||
{
|
||||
get => m_Source as Mobile;
|
||||
set => m_Source = value;
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool SourceNull
|
||||
{
|
||||
get => m_Source == null;
|
||||
set
|
||||
{
|
||||
if (value) m_Source = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Item TargetItem
|
||||
{
|
||||
get => m_Target as Item;
|
||||
set => m_Target = value;
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Mobile TargetMobile
|
||||
{
|
||||
get => m_Target as Mobile;
|
||||
set => m_Target = value;
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool TargetNull
|
||||
{
|
||||
get => m_Target == null;
|
||||
set
|
||||
{
|
||||
if (value) m_Target = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public EffectController Sequence{ get; set; }
|
||||
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
private bool FixedDirection{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
private bool Explodes{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
private bool PlaySoundAtTrigger{ get; set; }
|
||||
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int EffectItemID{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int EffectHue{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int RenderMode{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Speed{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Duration{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ParticleEffect{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ExplodeParticleEffect{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ExplodeSound{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Unknown{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int SoundID{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int TriggerRange{ get; set; }
|
||||
|
||||
public override string DefaultName => "Effect Controller";
|
||||
|
||||
public override bool HandlesOnMovement => TriggerType == EffectTriggerType.InRange;
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (TriggerType == EffectTriggerType.DoubleClick)
|
||||
DoEffect(from);
|
||||
}
|
||||
|
||||
public override void OnMovement(Mobile m, Point3D oldLocation)
|
||||
{
|
||||
if (m.Location != oldLocation && TriggerType == EffectTriggerType.InRange &&
|
||||
Utility.InRange(GetWorldLocation(), m.Location, TriggerRange) &&
|
||||
!Utility.InRange(GetWorldLocation(), oldLocation, TriggerRange))
|
||||
DoEffect(m);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write(EffectDelay);
|
||||
writer.Write(TriggerDelay);
|
||||
writer.Write(SoundDelay);
|
||||
|
||||
if (m_Source is Item srcItem)
|
||||
writer.Write(srcItem);
|
||||
else
|
||||
writer.Write(m_Source as Mobile);
|
||||
|
||||
if (m_Target is Item targItem)
|
||||
writer.Write(targItem);
|
||||
else
|
||||
writer.Write(m_Target as Mobile);
|
||||
|
||||
writer.Write(Sequence);
|
||||
|
||||
writer.Write(FixedDirection);
|
||||
writer.Write(Explodes);
|
||||
writer.Write(PlaySoundAtTrigger);
|
||||
|
||||
writer.WriteEncodedInt((int)EffectType);
|
||||
writer.WriteEncodedInt((int)EffectLayer);
|
||||
writer.WriteEncodedInt((int)TriggerType);
|
||||
|
||||
writer.WriteEncodedInt(EffectItemID);
|
||||
writer.WriteEncodedInt(EffectHue);
|
||||
writer.WriteEncodedInt(RenderMode);
|
||||
writer.WriteEncodedInt(Speed);
|
||||
writer.WriteEncodedInt(Duration);
|
||||
writer.WriteEncodedInt(ParticleEffect);
|
||||
writer.WriteEncodedInt(ExplodeParticleEffect);
|
||||
writer.WriteEncodedInt(ExplodeSound);
|
||||
writer.WriteEncodedInt(Unknown);
|
||||
writer.WriteEncodedInt(SoundID);
|
||||
writer.WriteEncodedInt(TriggerRange);
|
||||
}
|
||||
|
||||
private IEntity ReadEntity(GenericReader reader)
|
||||
{
|
||||
return World.FindEntity(reader.ReadUInt());
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
EffectDelay = reader.ReadTimeSpan();
|
||||
TriggerDelay = reader.ReadTimeSpan();
|
||||
SoundDelay = reader.ReadTimeSpan();
|
||||
|
||||
m_Source = ReadEntity(reader);
|
||||
m_Target = ReadEntity(reader);
|
||||
Sequence = reader.ReadItem() as EffectController;
|
||||
|
||||
FixedDirection = reader.ReadBool();
|
||||
Explodes = reader.ReadBool();
|
||||
PlaySoundAtTrigger = reader.ReadBool();
|
||||
|
||||
EffectType = (ECEffectType)reader.ReadEncodedInt();
|
||||
EffectLayer = (EffectLayer)reader.ReadEncodedInt();
|
||||
TriggerType = (EffectTriggerType)reader.ReadEncodedInt();
|
||||
|
||||
EffectItemID = reader.ReadEncodedInt();
|
||||
EffectHue = reader.ReadEncodedInt();
|
||||
RenderMode = reader.ReadEncodedInt();
|
||||
Speed = reader.ReadEncodedInt();
|
||||
Duration = reader.ReadEncodedInt();
|
||||
ParticleEffect = reader.ReadEncodedInt();
|
||||
ExplodeParticleEffect = reader.ReadEncodedInt();
|
||||
ExplodeSound = reader.ReadEncodedInt();
|
||||
Unknown = reader.ReadEncodedInt();
|
||||
SoundID = reader.ReadEncodedInt();
|
||||
TriggerRange = reader.ReadEncodedInt();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void PlaySound(IEntity trigger)
|
||||
{
|
||||
IEntity ent = null;
|
||||
|
||||
if (PlaySoundAtTrigger)
|
||||
ent = trigger;
|
||||
|
||||
if (ent == null)
|
||||
ent = this;
|
||||
|
||||
Effects.PlaySound((ent as Item)?.GetWorldLocation() ?? ent.Location, ent.Map, SoundID);
|
||||
}
|
||||
|
||||
public void DoEffect(IEntity trigger)
|
||||
{
|
||||
if (Deleted || TriggerType == EffectTriggerType.None)
|
||||
return;
|
||||
|
||||
if (trigger is Mobile mobile && mobile.Hidden && mobile.AccessLevel > AccessLevel.Player)
|
||||
return;
|
||||
|
||||
if (SoundID > 0)
|
||||
Timer.DelayCall(SoundDelay, PlaySound, trigger);
|
||||
|
||||
if (Sequence != null)
|
||||
Timer.DelayCall(TriggerDelay, Sequence.DoEffect, trigger);
|
||||
|
||||
if (EffectType != ECEffectType.None)
|
||||
Timer.DelayCall(EffectDelay, InternalDoEffect, trigger);
|
||||
}
|
||||
|
||||
public void InternalDoEffect(IEntity trigger)
|
||||
{
|
||||
IEntity from = m_Source, to = m_Target;
|
||||
|
||||
if (from == null)
|
||||
from = trigger;
|
||||
|
||||
if (to == null)
|
||||
to = trigger;
|
||||
|
||||
switch (EffectType)
|
||||
{
|
||||
case ECEffectType.Lightning:
|
||||
{
|
||||
Effects.SendBoltEffect(from, false, EffectHue);
|
||||
break;
|
||||
}
|
||||
case ECEffectType.Location:
|
||||
{
|
||||
Effects.SendLocationParticles(EffectItem.Create(from.Location, from.Map, EffectItem.DefaultDuration),
|
||||
EffectItemID, Speed, Duration, EffectHue, RenderMode, ParticleEffect, Unknown);
|
||||
break;
|
||||
}
|
||||
case ECEffectType.Moving:
|
||||
{
|
||||
if (from == this)
|
||||
from = EffectItem.Create(from.Location, from.Map, EffectItem.DefaultDuration);
|
||||
|
||||
if (to == this)
|
||||
to = EffectItem.Create(to.Location, to.Map, EffectItem.DefaultDuration);
|
||||
|
||||
Effects.SendMovingParticles(from, to, EffectItemID, Speed, Duration, FixedDirection, Explodes, EffectHue,
|
||||
RenderMode, ParticleEffect, ExplodeParticleEffect, ExplodeSound, EffectLayer, Unknown);
|
||||
break;
|
||||
}
|
||||
case ECEffectType.Target:
|
||||
{
|
||||
Effects.SendTargetParticles(from, EffectItemID, Speed, Duration, EffectHue, RenderMode, ParticleEffect,
|
||||
EffectLayer, Unknown);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
87
Projects/Scripts/Items/Misc/EffectItem.cs
Normal file
87
Projects/Scripts/Items/Misc/EffectItem.cs
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class EffectItem : Item
|
||||
{
|
||||
private static List<EffectItem> m_Free = new List<EffectItem>(); // List of available EffectItems
|
||||
|
||||
public static readonly TimeSpan DefaultDuration = TimeSpan.FromSeconds(5.0);
|
||||
|
||||
private EffectItem() : base(1) // nodraw
|
||||
{
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public EffectItem(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool Decays => true;
|
||||
|
||||
public static EffectItem Create(Point3D p, Map map, TimeSpan duration)
|
||||
{
|
||||
EffectItem item = null;
|
||||
|
||||
for (int i = m_Free.Count - 1; item == null && i >= 0; --i) // We reuse new entries first so decay works better
|
||||
{
|
||||
EffectItem free = m_Free[i];
|
||||
|
||||
m_Free.RemoveAt(i);
|
||||
|
||||
if (!free.Deleted && free.Map == Map.Internal)
|
||||
item = free;
|
||||
}
|
||||
|
||||
if (item == null)
|
||||
item = new EffectItem();
|
||||
else
|
||||
item.ItemID = 1;
|
||||
|
||||
item.MoveToWorld(p, map);
|
||||
item.BeginFree(duration);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public void BeginFree(TimeSpan duration)
|
||||
{
|
||||
new FreeTimer(this, duration).Start();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Delete();
|
||||
}
|
||||
|
||||
private class FreeTimer : Timer
|
||||
{
|
||||
private EffectItem m_Item;
|
||||
|
||||
public FreeTimer(EffectItem item, TimeSpan delay) : base(delay)
|
||||
{
|
||||
m_Item = item;
|
||||
Priority = TimerPriority.OneSecond;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Item.Internalize();
|
||||
|
||||
m_Free.Add(m_Item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
29
Projects/Scripts/Items/Misc/ExecutionersCap.cs
Normal file
29
Projects/Scripts/Items/Misc/ExecutionersCap.cs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class ExecutionersCap : Item
|
||||
{
|
||||
[Constructible]
|
||||
public ExecutionersCap() : base(0xF83)
|
||||
{
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
public ExecutionersCap(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
286
Projects/Scripts/Items/Misc/Firebomb.cs
Normal file
286
Projects/Scripts/Items/Misc/Firebomb.cs
Normal file
|
|
@ -0,0 +1,286 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Server.Network;
|
||||
using Server.Spells;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class Firebomb : Item
|
||||
{
|
||||
private Mobile m_LitBy;
|
||||
private int m_Ticks;
|
||||
private Timer m_Timer;
|
||||
private List<Mobile> m_Users;
|
||||
|
||||
[Constructible]
|
||||
public Firebomb(int itemID = 0x99B) : base(itemID)
|
||||
{
|
||||
//Name = "a firebomb";
|
||||
Weight = 2.0;
|
||||
Hue = 1260;
|
||||
}
|
||||
|
||||
public Firebomb(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
|
||||
return;
|
||||
}
|
||||
|
||||
if (Core.AOS && (from.Paralyzed || from.Frozen || from.Spell != null && from.Spell.IsCasting))
|
||||
{
|
||||
// to prevent exploiting for pvp
|
||||
from.SendLocalizedMessage(1075857); // You cannot use that while paralyzed.
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_Timer == null)
|
||||
{
|
||||
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), OnFirebombTimerTick);
|
||||
m_LitBy = from;
|
||||
from.SendLocalizedMessage(1060582); // You light the firebomb. Throw it now!
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1060581); // You've already lit it! Better throw it now!
|
||||
}
|
||||
|
||||
if (m_Users == null)
|
||||
m_Users = new List<Mobile>();
|
||||
|
||||
if (!m_Users.Contains(from))
|
||||
m_Users.Add(from);
|
||||
|
||||
from.Target = new ThrowTarget(this);
|
||||
}
|
||||
|
||||
private void OnFirebombTimerTick()
|
||||
{
|
||||
if (Deleted)
|
||||
{
|
||||
m_Timer.Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Map == Map.Internal && HeldBy == null)
|
||||
return;
|
||||
|
||||
switch (m_Ticks)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
{
|
||||
++m_Ticks;
|
||||
|
||||
if (HeldBy != null)
|
||||
HeldBy.PublicOverheadMessage(MessageType.Regular, 957, false, m_Ticks.ToString());
|
||||
else if (RootParent == null)
|
||||
PublicOverheadMessage(MessageType.Regular, 957, false, m_Ticks.ToString());
|
||||
else if (RootParent is Mobile mobile)
|
||||
mobile.PublicOverheadMessage(MessageType.Regular, 957, false, m_Ticks.ToString());
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
HeldBy?.DropHolding();
|
||||
|
||||
if (m_Users != null)
|
||||
{
|
||||
foreach (Mobile m in m_Users)
|
||||
if (m.Target is ThrowTarget targ && targ.Bomb == this)
|
||||
Target.Cancel(m);
|
||||
|
||||
m_Users.Clear();
|
||||
m_Users = null;
|
||||
}
|
||||
|
||||
if (RootParent is Mobile parent)
|
||||
{
|
||||
parent.SendLocalizedMessage(1060583); // The firebomb explodes in your hand!
|
||||
AOS.Damage(parent, Utility.Random(3) + 4, 0, 100, 0, 0, 0);
|
||||
}
|
||||
else if (RootParent == null)
|
||||
{
|
||||
IPooledEnumerable<Mobile> eable = Map.GetMobilesInRange(Location, 1);
|
||||
List<Mobile> toDamage = eable.ToList();
|
||||
|
||||
eable.Free();
|
||||
|
||||
for (int i = 0; i < toDamage.Count; ++i)
|
||||
{
|
||||
Mobile victim = toDamage[i];
|
||||
|
||||
if (m_LitBy == null || SpellHelper.ValidIndirectTarget(m_LitBy, victim) &&
|
||||
m_LitBy.CanBeHarmful(victim, false))
|
||||
{
|
||||
m_LitBy?.DoHarmful(victim);
|
||||
|
||||
AOS.Damage(victim, m_LitBy, Utility.Random(3) + 4, 0, 100, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
new FirebombField(m_LitBy, toDamage).MoveToWorld(Location, Map);
|
||||
}
|
||||
|
||||
m_Timer.Stop();
|
||||
Delete();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnFirebombTarget(Mobile from, object obj)
|
||||
{
|
||||
if (Deleted || Map == Map.Internal || !IsChildOf(from.Backpack))
|
||||
return;
|
||||
|
||||
if (!(obj is IPoint3D p))
|
||||
return;
|
||||
|
||||
SpellHelper.GetSurfaceTop(ref p);
|
||||
|
||||
from.RevealingAction();
|
||||
|
||||
IEntity to = p as IEntity ?? new Entity(Serial.Zero, new Point3D(p), Map);
|
||||
|
||||
Effects.SendMovingEffect(from, to, ItemID, 7, 0, false, false, Hue);
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(1.0), () => FirebombReposition_OnTick(p, Map));
|
||||
Internalize();
|
||||
}
|
||||
|
||||
private void FirebombReposition_OnTick(IPoint3D p, Map map)
|
||||
{
|
||||
if (Deleted)
|
||||
return;
|
||||
|
||||
MoveToWorld(new Point3D(p), map);
|
||||
}
|
||||
|
||||
private class ThrowTarget : Target
|
||||
{
|
||||
public ThrowTarget(Firebomb bomb)
|
||||
: base(12, true, TargetFlags.None)
|
||||
{
|
||||
Bomb = bomb;
|
||||
}
|
||||
|
||||
public Firebomb Bomb{ get; }
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
Bomb.OnFirebombTarget(from, targeted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class FirebombField : Item
|
||||
{
|
||||
private List<Mobile> m_Burning;
|
||||
private DateTime m_Expire;
|
||||
private Mobile m_LitBy;
|
||||
private Timer m_Timer;
|
||||
|
||||
public FirebombField(Mobile litBy, List<Mobile> toDamage) : base(0x376A)
|
||||
{
|
||||
Movable = false;
|
||||
m_LitBy = litBy;
|
||||
m_Expire = DateTime.UtcNow + TimeSpan.FromSeconds(10);
|
||||
m_Burning = toDamage;
|
||||
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(1.0), OnFirebombFieldTimerTick);
|
||||
}
|
||||
|
||||
public FirebombField(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
// Don't serialize these...
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool OnMoveOver(Mobile m)
|
||||
{
|
||||
if (ItemID == 0x398C && m_LitBy == null ||
|
||||
SpellHelper.ValidIndirectTarget(m_LitBy, m) && m_LitBy.CanBeHarmful(m, false))
|
||||
{
|
||||
m_LitBy?.DoHarmful(m);
|
||||
|
||||
AOS.Damage(m, m_LitBy, 2, 0, 100, 0, 0, 0);
|
||||
m.PlaySound(0x208);
|
||||
|
||||
if (!m_Burning.Contains(m))
|
||||
m_Burning.Add(m);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void OnFirebombFieldTimerTick()
|
||||
{
|
||||
if (Deleted)
|
||||
{
|
||||
m_Timer.Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
if (ItemID == 0x376A)
|
||||
{
|
||||
ItemID = 0x398C;
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_Burning.Count;)
|
||||
{
|
||||
Mobile victim = m_Burning[i];
|
||||
|
||||
if (victim.Location == Location && victim.Map == Map &&
|
||||
(m_LitBy == null || SpellHelper.ValidIndirectTarget(m_LitBy, victim) &&
|
||||
m_LitBy.CanBeHarmful(victim, false)))
|
||||
{
|
||||
m_LitBy?.DoHarmful(victim);
|
||||
|
||||
AOS.Damage(victim, m_LitBy, Utility.Random(3) + 4, 0, 100, 0, 0, 0);
|
||||
++i;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Burning.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (DateTime.UtcNow >= m_Expire)
|
||||
{
|
||||
m_Timer.Stop();
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
117
Projects/Scripts/Items/Misc/FlippableAddonAttribute.cs
Normal file
117
Projects/Scripts/Items/Misc/FlippableAddonAttribute.cs
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
using Server.Multis;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class FlippableAddonAttribute : Attribute
|
||||
{
|
||||
private static string m_MethodName = "Flip";
|
||||
|
||||
private static Type[] m_Params =
|
||||
{
|
||||
typeof(Mobile), typeof(Direction)
|
||||
};
|
||||
|
||||
public FlippableAddonAttribute(params Direction[] directions)
|
||||
{
|
||||
Directions = directions;
|
||||
}
|
||||
|
||||
public Direction[] Directions{ get; }
|
||||
|
||||
public virtual void Flip(Mobile from, Item addon)
|
||||
{
|
||||
if (Directions?.Length > 1)
|
||||
try
|
||||
{
|
||||
MethodInfo flipMethod = addon.GetType().GetMethod(m_MethodName, m_Params);
|
||||
|
||||
if (flipMethod != null)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
for (int i = 0; i < Directions.Length; i++)
|
||||
if (addon.Direction == Directions[i])
|
||||
{
|
||||
index = i + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (index >= Directions.Length)
|
||||
index = 0;
|
||||
|
||||
ClearComponents(addon);
|
||||
|
||||
flipMethod.Invoke(addon, new object[] { from, Directions[index] });
|
||||
|
||||
BaseHouse house = null;
|
||||
AddonFitResult result = AddonFitResult.Valid;
|
||||
|
||||
addon.Map = Map.Internal;
|
||||
|
||||
if (addon is BaseAddon baseAddon)
|
||||
result = baseAddon.CouldFit(baseAddon.Location, from.Map, from, ref house);
|
||||
else if (addon is BaseAddonContainer container)
|
||||
result = container.CouldFit(container.Location, from.Map, from, ref house);
|
||||
|
||||
addon.Map = from.Map;
|
||||
|
||||
if (result != AddonFitResult.Valid)
|
||||
{
|
||||
if (index == 0)
|
||||
index = Directions.Length - 1;
|
||||
else
|
||||
index -= 1;
|
||||
|
||||
ClearComponents(addon);
|
||||
|
||||
flipMethod.Invoke(addon, new object[2] { from, Directions[index] });
|
||||
|
||||
if (result == AddonFitResult.Blocked)
|
||||
from.SendLocalizedMessage(500269); // You cannot build that there.
|
||||
else if (result == AddonFitResult.NotInHouse)
|
||||
from.SendLocalizedMessage(500274); // You can only place this in a house that you own!
|
||||
else if (result == AddonFitResult.DoorsNotClosed)
|
||||
from.SendMessage("You must close all house doors before placing this.");
|
||||
else if (result == AddonFitResult.DoorTooClose)
|
||||
from.SendLocalizedMessage(500271); // You cannot build near the door.
|
||||
else if (result == AddonFitResult.NoWall)
|
||||
from.SendLocalizedMessage(500268); // This object needs to be mounted on something.
|
||||
}
|
||||
|
||||
addon.Direction = Directions[index];
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearComponents(Item item)
|
||||
{
|
||||
if (item is BaseAddon addon)
|
||||
{
|
||||
foreach (AddonComponent c in addon.Components)
|
||||
{
|
||||
c.Addon = null;
|
||||
c.Delete();
|
||||
}
|
||||
|
||||
addon.Components.Clear();
|
||||
}
|
||||
else if (item is BaseAddonContainer addonContainer)
|
||||
{
|
||||
foreach (AddonContainerComponent c in addonContainer.Components)
|
||||
{
|
||||
c.Addon = null;
|
||||
c.Delete();
|
||||
}
|
||||
|
||||
addonContainer.Components.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
95
Projects/Scripts/Items/Misc/FlippableAttribute.cs
Normal file
95
Projects/Scripts/Items/Misc/FlippableAttribute.cs
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
using System;
|
||||
using Server.Commands;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class FlipCommandHandlers
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("Flip", AccessLevel.GameMaster, Flip_OnCommand);
|
||||
}
|
||||
|
||||
[Usage("Flip")]
|
||||
[Description("Turns an item.")]
|
||||
public static void Flip_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
e.Mobile.Target = new FlipTarget();
|
||||
}
|
||||
|
||||
private class FlipTarget : Target
|
||||
{
|
||||
public FlipTarget()
|
||||
: base(-1, false, TargetFlags.None)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (targeted is Item item)
|
||||
{
|
||||
if (item.Movable == false && from.AccessLevel == AccessLevel.Player)
|
||||
return;
|
||||
|
||||
Type type = item.GetType();
|
||||
|
||||
FlippableAttribute[] AttributeArray =
|
||||
(FlippableAttribute[])type.GetCustomAttributes(typeof(FlippableAttribute), false);
|
||||
|
||||
if (AttributeArray.Length == 0) return;
|
||||
|
||||
FlippableAttribute fa = AttributeArray[0];
|
||||
|
||||
fa.Flip(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class DynamicFlipingAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class FlippableAttribute : Attribute
|
||||
{
|
||||
public FlippableAttribute(params int[] itemIDs)
|
||||
{
|
||||
ItemIDs = itemIDs;
|
||||
}
|
||||
|
||||
public int[] ItemIDs{ get; }
|
||||
|
||||
public virtual void Flip(Item item)
|
||||
{
|
||||
if (ItemIDs == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
item.GetType().GetMethod("Flip", Type.EmptyTypes)?.Invoke(item, new object[0]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = 0;
|
||||
for (int i = 0; i < ItemIDs.Length; i++)
|
||||
if (item.ItemID == ItemIDs[i])
|
||||
{
|
||||
index = i + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (index > ItemIDs.Length - 1)
|
||||
index = 0;
|
||||
|
||||
item.ItemID = ItemIDs[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1216
Projects/Scripts/Items/Misc/GlassItems.cs
Normal file
1216
Projects/Scripts/Items/Misc/GlassItems.cs
Normal file
File diff suppressed because it is too large
Load diff
122
Projects/Scripts/Items/Misc/Gold.cs
Normal file
122
Projects/Scripts/Items/Misc/Gold.cs
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
using System;
|
||||
using Server.Accounting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class Gold : Item
|
||||
{
|
||||
[Constructible]
|
||||
public Gold(int amountFrom, int amountTo) : this(Utility.RandomMinMax(amountFrom, amountTo))
|
||||
{
|
||||
}
|
||||
|
||||
[Constructible]
|
||||
public Gold(int amount = 1) : base(0xEED)
|
||||
{
|
||||
Stackable = true;
|
||||
Amount = amount;
|
||||
}
|
||||
|
||||
public Gold(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override double DefaultWeight => Core.ML ? 0.02 / 3 : 0.02;
|
||||
|
||||
public override int GetDropSound()
|
||||
{
|
||||
if (Amount <= 1)
|
||||
return 0x2E4;
|
||||
if (Amount <= 5)
|
||||
return 0x2E5;
|
||||
return 0x2E6;
|
||||
}
|
||||
|
||||
protected override void OnAmountChange(int oldValue)
|
||||
{
|
||||
int newValue = Amount;
|
||||
|
||||
UpdateTotal(this, TotalType.Gold, newValue - oldValue);
|
||||
}
|
||||
|
||||
public override void OnAdded(IEntity parent)
|
||||
{
|
||||
base.OnAdded(parent);
|
||||
|
||||
if (!AccountGold.Enabled) return;
|
||||
|
||||
Mobile owner = null;
|
||||
SecureTradeInfo tradeInfo = null;
|
||||
|
||||
Container root = parent as Container;
|
||||
|
||||
while (root?.Parent is Container container)
|
||||
root = container;
|
||||
|
||||
parent = root ?? parent;
|
||||
|
||||
if (parent is SecureTradeContainer trade && AccountGold.ConvertOnTrade)
|
||||
{
|
||||
if (trade.Trade.From.Container == trade)
|
||||
{
|
||||
tradeInfo = trade.Trade.From;
|
||||
owner = tradeInfo.Mobile;
|
||||
}
|
||||
else if (trade.Trade.To.Container == trade)
|
||||
{
|
||||
tradeInfo = trade.Trade.To;
|
||||
owner = tradeInfo.Mobile;
|
||||
}
|
||||
}
|
||||
else if (parent is BankBox box && AccountGold.ConvertOnBank)
|
||||
{
|
||||
owner = box.Owner;
|
||||
}
|
||||
|
||||
if (owner?.Account == null || !owner.Account.DepositGold(Amount)) return;
|
||||
|
||||
if (tradeInfo != null)
|
||||
{
|
||||
if (owner.NetState?.NewSecureTrading == false)
|
||||
{
|
||||
int plat = Math.DivRem(Amount, AccountGold.CurrencyThreshold, out int gold);
|
||||
|
||||
tradeInfo.Plat += plat;
|
||||
tradeInfo.Gold += gold;
|
||||
}
|
||||
|
||||
tradeInfo.VirtualCheck?.UpdateTrade(tradeInfo.Mobile);
|
||||
}
|
||||
|
||||
owner.SendLocalizedMessage(1042763, Amount.ToString("#,0"));
|
||||
|
||||
Delete();
|
||||
|
||||
((Container)parent).UpdateTotals();
|
||||
}
|
||||
|
||||
public override int GetTotal(TotalType type)
|
||||
{
|
||||
int baseTotal = base.GetTotal(type);
|
||||
|
||||
if (type == TotalType.Gold)
|
||||
baseTotal += Amount;
|
||||
|
||||
return baseTotal;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
115
Projects/Scripts/Items/Misc/Guillotine.cs
Normal file
115
Projects/Scripts/Items/Misc/Guillotine.cs
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
using System;
|
||||
using Server.Network;
|
||||
using Server.Spells;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class Guillotine : Item
|
||||
{
|
||||
private DateTime m_NextUse;
|
||||
|
||||
[Constructible]
|
||||
public Guillotine()
|
||||
: base(4656)
|
||||
{
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public Guillotine(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!from.InRange(GetWorldLocation(), 2) || !from.InLOS(this))
|
||||
{
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that
|
||||
}
|
||||
else if (Visible && (ItemID == 4656 || ItemID == 4702) && DateTime.UtcNow >= m_NextUse)
|
||||
{
|
||||
Point3D p = GetWorldLocation();
|
||||
|
||||
if (1 > Utility.Random(Math.Max(Math.Abs(from.X - p.X), Math.Abs(from.Y - p.Y))))
|
||||
{
|
||||
Effects.PlaySound(from.Location, from.Map, from.GetHurtSound());
|
||||
from.PublicOverheadMessage(MessageType.Regular, from.SpeechHue, true, "Ouch!");
|
||||
SpellHelper.Damage(TimeSpan.FromSeconds(0.5), from, Utility.Dice(2, 10, 5));
|
||||
}
|
||||
|
||||
Effects.PlaySound(GetWorldLocation(), Map, 0x387);
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(0.25), Down1);
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(0.50), Down2);
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(5.00), BackUp);
|
||||
|
||||
m_NextUse = DateTime.UtcNow + TimeSpan.FromSeconds(10.0);
|
||||
}
|
||||
}
|
||||
|
||||
private void Down1()
|
||||
{
|
||||
ItemID = ItemID == 4656 ? 4678 : 4712;
|
||||
}
|
||||
|
||||
private void Down2()
|
||||
{
|
||||
ItemID = ItemID == 4678 ? 4679 : 4713;
|
||||
|
||||
Point3D p = GetWorldLocation();
|
||||
Map f = Map;
|
||||
|
||||
if (f == null)
|
||||
return;
|
||||
|
||||
new Blood(4650).MoveToWorld(p, f);
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
int x = p.X - 2 + Utility.Random(5);
|
||||
int y = p.Y - 2 + Utility.Random(5);
|
||||
int z = p.Z;
|
||||
|
||||
if (!f.CanFit(x, y, z, 1, false, false))
|
||||
{
|
||||
z = f.GetAverageZ(x, y);
|
||||
|
||||
if (!f.CanFit(x, y, z, 1, false, false))
|
||||
continue;
|
||||
}
|
||||
|
||||
Point3D loc = f.GetRandomNearbyLocation(p, 2, -2, 4, 1);
|
||||
|
||||
new Blood().MoveToWorld(loc, f);
|
||||
}
|
||||
}
|
||||
|
||||
private void BackUp()
|
||||
{
|
||||
if (ItemID == 4678 || ItemID == 4679)
|
||||
ItemID = 4656;
|
||||
else if (ItemID == 4712 || ItemID == 4713)
|
||||
ItemID = 4702;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((byte)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadByte();
|
||||
|
||||
if (ItemID == 4678 || ItemID == 4679)
|
||||
ItemID = 4656;
|
||||
else if (ItemID == 4712 || ItemID == 4713)
|
||||
ItemID = 4702;
|
||||
}
|
||||
}
|
||||
}
|
||||
169
Projects/Scripts/Items/Misc/HairDye.cs
Normal file
169
Projects/Scripts/Items/Misc/HairDye.cs
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class HairDye : Item
|
||||
{
|
||||
[Constructible]
|
||||
public HairDye() : base(0xEFF)
|
||||
{
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
public HairDye(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1041060; // Hair Dye
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from.InRange(GetWorldLocation(), 1))
|
||||
{
|
||||
from.CloseGump<HairDyeGump>();
|
||||
from.SendGump(new HairDyeGump(this));
|
||||
}
|
||||
else
|
||||
{
|
||||
from.LocalOverheadMessage(MessageType.Regular, 906, 1019045); // I can't reach that.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class HairDyeGump : Gump
|
||||
{
|
||||
private static HairDyeEntry[] m_Entries =
|
||||
{
|
||||
new HairDyeEntry("*****", 1602, 26),
|
||||
new HairDyeEntry("*****", 1628, 27),
|
||||
new HairDyeEntry("*****", 1502, 32),
|
||||
new HairDyeEntry("*****", 1302, 32),
|
||||
new HairDyeEntry("*****", 1402, 32),
|
||||
new HairDyeEntry("*****", 1202, 24),
|
||||
new HairDyeEntry("*****", 2402, 29),
|
||||
new HairDyeEntry("*****", 2213, 6),
|
||||
new HairDyeEntry("*****", 1102, 8),
|
||||
new HairDyeEntry("*****", 1110, 8),
|
||||
new HairDyeEntry("*****", 1118, 16),
|
||||
new HairDyeEntry("*****", 1134, 16)
|
||||
};
|
||||
|
||||
private HairDye m_HairDye;
|
||||
|
||||
public HairDyeGump(HairDye dye) : base(50, 50)
|
||||
{
|
||||
m_HairDye = dye;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
AddBackground(100, 10, 350, 355, 2600);
|
||||
AddBackground(120, 54, 110, 270, 5100);
|
||||
|
||||
AddHtmlLocalized(70, 25, 400, 35, 1011013); // <center>Hair Color Selection Menu</center>
|
||||
|
||||
AddButton(149, 328, 4005, 4007, 1);
|
||||
AddHtmlLocalized(185, 329, 250, 35, 1011014); // Dye my hair this color!
|
||||
|
||||
for (int i = 0; i < m_Entries.Length; ++i)
|
||||
{
|
||||
AddLabel(130, 59 + i * 22, m_Entries[i].HueStart - 1, m_Entries[i].Name);
|
||||
AddButton(207, 60 + i * 22, 5224, 5224, 0, GumpButtonType.Page, i + 1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_Entries.Length; ++i)
|
||||
{
|
||||
HairDyeEntry e = m_Entries[i];
|
||||
|
||||
AddPage(i + 1);
|
||||
|
||||
for (int j = 0; j < e.HueCount; ++j)
|
||||
{
|
||||
AddLabel(278 + j / 16 * 80, 52 + j % 16 * 17, e.HueStart + j - 1, "*****");
|
||||
AddRadio(260 + j / 16 * 80, 52 + j % 16 * 17, 210, 211, false, i * 100 + j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState from, RelayInfo info)
|
||||
{
|
||||
if (m_HairDye.Deleted)
|
||||
return;
|
||||
|
||||
Mobile m = from.Mobile;
|
||||
int[] switches = info.Switches;
|
||||
|
||||
if (!m_HairDye.IsChildOf(m.Backpack))
|
||||
{
|
||||
m.SendLocalizedMessage(1042010); //You must have the objectin your backpack to use it.
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.ButtonID != 0 && switches.Length > 0)
|
||||
{
|
||||
if (m.HairItemID == 0 && m.FacialHairItemID == 0)
|
||||
{
|
||||
m.SendLocalizedMessage(502623); // You have no hair to dye and cannot use this
|
||||
}
|
||||
else
|
||||
{
|
||||
// To prevent this from being exploited, the hue is abstracted into an internal list
|
||||
|
||||
int entryIndex = switches[0] / 100;
|
||||
int hueOffset = switches[0] % 100;
|
||||
|
||||
if (entryIndex >= 0 && entryIndex < m_Entries.Length)
|
||||
{
|
||||
HairDyeEntry e = m_Entries[entryIndex];
|
||||
|
||||
if (hueOffset >= 0 && hueOffset < e.HueCount)
|
||||
{
|
||||
int hue = e.HueStart + hueOffset;
|
||||
|
||||
m.HairHue = hue;
|
||||
m.FacialHairHue = hue;
|
||||
|
||||
m.SendLocalizedMessage(501199); // You dye your hair
|
||||
m_HairDye.Delete();
|
||||
m.PlaySound(0x4E);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m.SendLocalizedMessage(501200); // You decide not to dye your hair
|
||||
}
|
||||
}
|
||||
|
||||
private class HairDyeEntry
|
||||
{
|
||||
public HairDyeEntry(string name, int hueStart, int hueCount)
|
||||
{
|
||||
Name = name;
|
||||
HueStart = hueStart;
|
||||
HueCount = hueCount;
|
||||
}
|
||||
|
||||
public string Name{ get; }
|
||||
|
||||
public int HueStart{ get; }
|
||||
|
||||
public int HueCount{ get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
30
Projects/Scripts/Items/Misc/HoveringWisp.cs
Normal file
30
Projects/Scripts/Items/Misc/HoveringWisp.cs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class HoveringWisp : Item
|
||||
{
|
||||
[Constructible]
|
||||
public HoveringWisp() : base(0x2100)
|
||||
{
|
||||
}
|
||||
|
||||
public HoveringWisp(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1072881; // hovering wisp
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
21
Projects/Scripts/Items/Misc/IDurability.cs
Normal file
21
Projects/Scripts/Items/Misc/IDurability.cs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
internal interface IDurability
|
||||
{
|
||||
bool CanFortify{ get; }
|
||||
|
||||
int InitMinHits{ get; }
|
||||
int InitMaxHits{ get; }
|
||||
|
||||
int HitPoints{ get; set; }
|
||||
int MaxHitPoints{ get; set; }
|
||||
|
||||
void ScaleDurability();
|
||||
void UnscaleDurability();
|
||||
}
|
||||
|
||||
internal interface IWearableDurability : IDurability
|
||||
{
|
||||
int OnHit(BaseWeapon weapon, int damageTaken);
|
||||
}
|
||||
}
|
||||
336
Projects/Scripts/Items/Misc/InteriorDecorator.cs
Normal file
336
Projects/Scripts/Items/Misc/InteriorDecorator.cs
Normal file
|
|
@ -0,0 +1,336 @@
|
|||
using Server.Gumps;
|
||||
using Server.Multis;
|
||||
using Server.Network;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public enum DecorateCommand
|
||||
{
|
||||
None,
|
||||
Turn,
|
||||
Up,
|
||||
Down
|
||||
}
|
||||
|
||||
public class InteriorDecorator : Item
|
||||
{
|
||||
private DecorateCommand m_Command;
|
||||
|
||||
[Constructible]
|
||||
public InteriorDecorator() : base(0xFC1)
|
||||
{
|
||||
Weight = 1.0;
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public InteriorDecorator(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DecorateCommand Command
|
||||
{
|
||||
get => m_Command;
|
||||
set
|
||||
{
|
||||
m_Command = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1041280; // an interior decorator
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
if (m_Command != DecorateCommand.None)
|
||||
list.Add(1018322 + (int)m_Command); // Turn/Up/Down
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!CheckUse(this, from))
|
||||
return;
|
||||
|
||||
if (!from.HasGump<InternalGump>())
|
||||
from.SendGump(new InternalGump(this));
|
||||
|
||||
if (m_Command != DecorateCommand.None)
|
||||
from.Target = new InternalTarget(this);
|
||||
}
|
||||
|
||||
public static bool InHouse(Mobile from)
|
||||
{
|
||||
BaseHouse house = BaseHouse.FindHouseAt(from);
|
||||
|
||||
return house?.IsCoOwner(from) == true;
|
||||
}
|
||||
|
||||
public static bool CheckUse(InteriorDecorator tool, Mobile from)
|
||||
{
|
||||
/*if ( tool.Deleted || !tool.IsChildOf( from.Backpack ) )
|
||||
from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
|
||||
else*/
|
||||
if (!InHouse(from))
|
||||
from.SendLocalizedMessage(502092); // You must be in your house to do this.
|
||||
else
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private class InternalGump : Gump
|
||||
{
|
||||
private InteriorDecorator m_Decorator;
|
||||
|
||||
public InternalGump(InteriorDecorator decorator) : base(150, 50)
|
||||
{
|
||||
m_Decorator = decorator;
|
||||
|
||||
AddBackground(0, 0, 200, 200, 2600);
|
||||
|
||||
AddButton(50, 45, decorator.Command == DecorateCommand.Turn ? 2154 : 2152, 2154, 1);
|
||||
AddHtmlLocalized(90, 50, 70, 40, 1018323); // Turn
|
||||
|
||||
AddButton(50, 95, decorator.Command == DecorateCommand.Up ? 2154 : 2152, 2154, 2);
|
||||
AddHtmlLocalized(90, 100, 70, 40, 1018324); // Up
|
||||
|
||||
AddButton(50, 145, decorator.Command == DecorateCommand.Down ? 2154 : 2152, 2154, 3);
|
||||
AddHtmlLocalized(90, 150, 70, 40, 1018325); // Down
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
DecorateCommand command = DecorateCommand.None;
|
||||
|
||||
switch (info.ButtonID)
|
||||
{
|
||||
case 1:
|
||||
command = DecorateCommand.Turn;
|
||||
break;
|
||||
case 2:
|
||||
command = DecorateCommand.Up;
|
||||
break;
|
||||
case 3:
|
||||
command = DecorateCommand.Down;
|
||||
break;
|
||||
}
|
||||
|
||||
if (command != DecorateCommand.None)
|
||||
{
|
||||
m_Decorator.Command = command;
|
||||
sender.Mobile.SendGump(new InternalGump(m_Decorator));
|
||||
sender.Mobile.Target = new InternalTarget(m_Decorator);
|
||||
}
|
||||
else
|
||||
{
|
||||
Target.Cancel(sender.Mobile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class InternalTarget : Target
|
||||
{
|
||||
private InteriorDecorator m_Decorator;
|
||||
|
||||
public InternalTarget(InteriorDecorator decorator) : base(-1, false, TargetFlags.None)
|
||||
{
|
||||
CheckLOS = false;
|
||||
|
||||
m_Decorator = decorator;
|
||||
}
|
||||
|
||||
protected override void OnTargetNotAccessible(Mobile from, object targeted)
|
||||
{
|
||||
OnTarget(from, targeted);
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (targeted is Item item && CheckUse(m_Decorator, from))
|
||||
{
|
||||
BaseHouse house = BaseHouse.FindHouseAt(from);
|
||||
|
||||
bool isDecorableComponent = false;
|
||||
object addon = null;
|
||||
int count = 0;
|
||||
|
||||
if (item is AddonComponent component)
|
||||
{
|
||||
count = component.Addon.Components.Count;
|
||||
addon = component.Addon;
|
||||
}
|
||||
else if (item is AddonContainerComponent containerComponent)
|
||||
{
|
||||
count = containerComponent.Addon.Components.Count;
|
||||
addon = containerComponent.Addon;
|
||||
}
|
||||
else if (item is BaseAddonContainer container)
|
||||
{
|
||||
count = container.Components.Count;
|
||||
addon = container;
|
||||
}
|
||||
|
||||
if (addon != null)
|
||||
{
|
||||
if (count == 1 && Core.SE)
|
||||
isDecorableComponent = true;
|
||||
|
||||
if (m_Decorator.Command == DecorateCommand.Turn)
|
||||
{
|
||||
FlippableAddonAttribute[] attributes =
|
||||
(FlippableAddonAttribute[])addon.GetType()
|
||||
.GetCustomAttributes(typeof(FlippableAddonAttribute), false);
|
||||
|
||||
if (attributes.Length > 0)
|
||||
isDecorableComponent = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (house == null || !house.IsCoOwner(from))
|
||||
{
|
||||
from.SendLocalizedMessage(502092); // You must be in your house to do this.
|
||||
}
|
||||
else if (item.Parent != null || !house.IsInside(item))
|
||||
{
|
||||
from.SendLocalizedMessage(1042270); // That is not in your house.
|
||||
}
|
||||
else if (!house.HasLockedDownItem(item) && !house.HasSecureItem(item) && !isDecorableComponent)
|
||||
{
|
||||
if (item is AddonComponent && m_Decorator.Command == DecorateCommand.Up)
|
||||
from.SendLocalizedMessage(1042274); // You cannot raise it up any higher.
|
||||
else if (item is AddonComponent && m_Decorator.Command == DecorateCommand.Down)
|
||||
from.SendLocalizedMessage(1042275); // You cannot lower it down any further.
|
||||
else
|
||||
from.SendLocalizedMessage(1042271); // That is not locked down.
|
||||
}
|
||||
else if (item is VendorRentalContract)
|
||||
{
|
||||
from.SendLocalizedMessage(1062491); // You cannot use the house decorator on that object.
|
||||
}
|
||||
else if (item.TotalWeight + item.PileWeight > 100)
|
||||
{
|
||||
from.SendLocalizedMessage(1042272); // That is too heavy.
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (m_Decorator.Command)
|
||||
{
|
||||
case DecorateCommand.Up:
|
||||
Up(item, from);
|
||||
break;
|
||||
case DecorateCommand.Down:
|
||||
Down(item, from);
|
||||
break;
|
||||
case DecorateCommand.Turn:
|
||||
Turn(item, from);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
from.Target = new InternalTarget(m_Decorator);
|
||||
}
|
||||
|
||||
protected override void OnTargetCancel(Mobile from, TargetCancelType cancelType)
|
||||
{
|
||||
if (cancelType == TargetCancelType.Canceled)
|
||||
from.CloseGump<InternalGump>();
|
||||
}
|
||||
|
||||
private static void Turn(Item item, Mobile from)
|
||||
{
|
||||
object addon = null;
|
||||
|
||||
if (item is AddonComponent component)
|
||||
addon = component.Addon;
|
||||
else if (item is AddonContainerComponent containerComponent)
|
||||
addon = containerComponent.Addon;
|
||||
else if (item is BaseAddonContainer container)
|
||||
addon = container;
|
||||
|
||||
if (addon != null)
|
||||
{
|
||||
FlippableAddonAttribute[] aAttributes =
|
||||
(FlippableAddonAttribute[])addon.GetType()
|
||||
.GetCustomAttributes(typeof(FlippableAddonAttribute), false);
|
||||
|
||||
if (aAttributes.Length > 0)
|
||||
{
|
||||
aAttributes[0].Flip(from, (Item)addon);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
FlippableAttribute[] attributes =
|
||||
(FlippableAttribute[])item.GetType().GetCustomAttributes(typeof(FlippableAttribute), false);
|
||||
|
||||
if (attributes.Length > 0)
|
||||
attributes[0].Flip(item);
|
||||
else
|
||||
from.SendLocalizedMessage(1042273); // You cannot turn that.
|
||||
}
|
||||
|
||||
private static void Up(Item item, Mobile from)
|
||||
{
|
||||
int floorZ = GetFloorZ(item);
|
||||
|
||||
if (floorZ > int.MinValue && item.Z < floorZ + 15) // Confirmed : no height checks here
|
||||
item.Location = new Point3D(item.Location, item.Z + 1);
|
||||
else
|
||||
from.SendLocalizedMessage(1042274); // You cannot raise it up any higher.
|
||||
}
|
||||
|
||||
private static void Down(Item item, Mobile from)
|
||||
{
|
||||
int floorZ = GetFloorZ(item);
|
||||
|
||||
if (floorZ > int.MinValue && item.Z > GetFloorZ(item))
|
||||
item.Location = new Point3D(item.Location, item.Z - 1);
|
||||
else
|
||||
from.SendLocalizedMessage(1042275); // You cannot lower it down any further.
|
||||
}
|
||||
|
||||
private static int GetFloorZ(Item item)
|
||||
{
|
||||
Map map = item.Map;
|
||||
|
||||
if (map == null)
|
||||
return int.MinValue;
|
||||
|
||||
StaticTile[] tiles = map.Tiles.GetStaticTiles(item.X, item.Y, true);
|
||||
|
||||
int z = int.MinValue;
|
||||
|
||||
for (int i = 0; i < tiles.Length; ++i)
|
||||
{
|
||||
StaticTile tile = tiles[i];
|
||||
ItemData id = TileData.ItemTable[tile.ID & TileData.MaxItemValue];
|
||||
|
||||
int top = tile.Z; // Confirmed : no height checks here
|
||||
|
||||
if (id.Surface && !id.Impassable && top > z && top <= item.Z)
|
||||
z = top;
|
||||
}
|
||||
|
||||
return z;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
391
Projects/Scripts/Items/Misc/Key.cs
Normal file
391
Projects/Scripts/Items/Misc/Key.cs
Normal file
|
|
@ -0,0 +1,391 @@
|
|||
using Server.Network;
|
||||
using Server.Prompts;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public enum KeyType
|
||||
{
|
||||
Copper = 0x100E,
|
||||
Gold = 0x100F,
|
||||
Iron = 0x1010,
|
||||
Rusty = 0x1013
|
||||
}
|
||||
|
||||
public interface ILockable
|
||||
{
|
||||
bool Locked{ get; set; }
|
||||
uint KeyValue{ get; set; }
|
||||
}
|
||||
|
||||
public class Key : Item
|
||||
{
|
||||
private string m_Description;
|
||||
private uint m_KeyVal;
|
||||
|
||||
[Constructible]
|
||||
public Key(uint val = 0) : this(KeyType.Iron, val)
|
||||
{
|
||||
}
|
||||
|
||||
public Key(KeyType type, uint val = 0, Item link = null) : base((int)type)
|
||||
{
|
||||
Weight = 1.0;
|
||||
|
||||
MaxRange = 3;
|
||||
m_KeyVal = val;
|
||||
Link = link;
|
||||
}
|
||||
|
||||
public Key(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string Description
|
||||
{
|
||||
get => m_Description;
|
||||
set
|
||||
{
|
||||
m_Description = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int MaxRange{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public uint KeyValue
|
||||
{
|
||||
get => m_KeyVal;
|
||||
|
||||
set
|
||||
{
|
||||
m_KeyVal = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Item Link{ get; set; }
|
||||
|
||||
public static uint RandomValue()
|
||||
{
|
||||
return (uint)(0xFFFFFFFE * Utility.RandomDouble()) + 1;
|
||||
}
|
||||
|
||||
public static void RemoveKeys(Mobile m, uint keyValue)
|
||||
{
|
||||
if (keyValue == 0)
|
||||
return;
|
||||
|
||||
RemoveKeys(m.Backpack, keyValue);
|
||||
RemoveKeys(m.BankBox, keyValue);
|
||||
}
|
||||
|
||||
public static void RemoveKeys(Container cont, uint keyValue)
|
||||
{
|
||||
if (cont == null || keyValue == 0)
|
||||
return;
|
||||
|
||||
Item[] items = cont.FindItemsByType(new[] { typeof(Key), typeof(KeyRing) });
|
||||
|
||||
foreach (Item item in items)
|
||||
if (item is Key key)
|
||||
{
|
||||
if (key.KeyValue == keyValue)
|
||||
key.Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
KeyRing keyRing = (KeyRing)item;
|
||||
|
||||
keyRing.RemoveKeys(keyValue);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool ContainsKey(Container cont, uint keyValue)
|
||||
{
|
||||
if (cont == null)
|
||||
return false;
|
||||
|
||||
Item[] items = cont.FindItemsByType(new[] { typeof(Key), typeof(KeyRing) });
|
||||
|
||||
foreach (Item item in items)
|
||||
if (item is Key key)
|
||||
{
|
||||
if (key.KeyValue == keyValue)
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
KeyRing keyRing = (KeyRing)item;
|
||||
|
||||
if (keyRing.ContainsKey(keyValue))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(2); // version
|
||||
|
||||
writer.Write(MaxRange);
|
||||
|
||||
writer.Write(Link);
|
||||
|
||||
writer.Write(m_Description);
|
||||
writer.Write(m_KeyVal);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 2:
|
||||
{
|
||||
MaxRange = reader.ReadInt();
|
||||
|
||||
goto case 1;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
Link = reader.ReadItem();
|
||||
|
||||
goto case 0;
|
||||
}
|
||||
case 0:
|
||||
{
|
||||
if (version < 2 || MaxRange == 0)
|
||||
MaxRange = 3;
|
||||
|
||||
m_Description = reader.ReadString();
|
||||
|
||||
m_KeyVal = reader.ReadUInt();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(501661); // That key is unreachable.
|
||||
return;
|
||||
}
|
||||
|
||||
Target t;
|
||||
int number;
|
||||
|
||||
if (m_KeyVal != 0)
|
||||
{
|
||||
number = 501662; // What shall I use this key on?
|
||||
t = new UnlockTarget(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
number = 501663; // This key is a key blank. Which key would you like to make a copy of?
|
||||
t = new CopyTarget(this);
|
||||
}
|
||||
|
||||
from.SendLocalizedMessage(number);
|
||||
from.Target = t;
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
string desc;
|
||||
|
||||
if (m_KeyVal == 0)
|
||||
desc = "(blank)";
|
||||
else if ((desc = m_Description) == null || (desc = desc.Trim()).Length <= 0)
|
||||
desc = null;
|
||||
|
||||
if (desc != null)
|
||||
list.Add(desc);
|
||||
}
|
||||
|
||||
public override void OnSingleClick(Mobile from)
|
||||
{
|
||||
base.OnSingleClick(from);
|
||||
|
||||
string desc;
|
||||
|
||||
if (m_KeyVal == 0)
|
||||
desc = "(blank)";
|
||||
else if ((desc = m_Description) == null || (desc = desc.Trim()).Length <= 0)
|
||||
desc = "";
|
||||
|
||||
if (desc.Length > 0)
|
||||
from.Send(new UnicodeMessage(Serial, ItemID, MessageType.Regular, 0x3B2, 3, "ENU", "", desc));
|
||||
}
|
||||
|
||||
public bool UseOn(Mobile from, ILockable o)
|
||||
{
|
||||
if (o.KeyValue == KeyValue)
|
||||
{
|
||||
if (o is BaseDoor door && !door.UseLocks())
|
||||
return false;
|
||||
|
||||
o.Locked = !o.Locked;
|
||||
|
||||
if (o is LockableContainer cont1)
|
||||
if (cont1.LockLevel == -255)
|
||||
cont1.LockLevel = cont1.RequiredSkill - 10;
|
||||
|
||||
if (o is Item item)
|
||||
{
|
||||
if (o.Locked)
|
||||
item.SendLocalizedMessageTo(from, 1048000); // You lock it.
|
||||
else
|
||||
item.SendLocalizedMessageTo(from, 1048001); // You unlock it.
|
||||
|
||||
if (item is LockableContainer cont && cont.TrapType != TrapType.None && cont.TrapOnLockpick)
|
||||
{
|
||||
if (o.Locked)
|
||||
cont.SendLocalizedMessageTo(from, 501673); // You re-enable the trap.
|
||||
else
|
||||
cont.SendLocalizedMessageTo(from,
|
||||
501672); // You disable the trap temporarily. Lock it again to re-enable it.
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private class RenamePrompt : Prompt
|
||||
{
|
||||
private Key m_Key;
|
||||
|
||||
public RenamePrompt(Key key)
|
||||
{
|
||||
m_Key = key;
|
||||
}
|
||||
|
||||
public override void OnResponse(Mobile from, string text)
|
||||
{
|
||||
if (m_Key.Deleted || !m_Key.IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(501661); // That key is unreachable.
|
||||
return;
|
||||
}
|
||||
|
||||
m_Key.Description = Utility.FixHtml(text);
|
||||
}
|
||||
}
|
||||
|
||||
private class UnlockTarget : Target
|
||||
{
|
||||
private Key m_Key;
|
||||
|
||||
public UnlockTarget(Key key) : base(key.MaxRange, false, TargetFlags.None)
|
||||
{
|
||||
m_Key = key;
|
||||
CheckLOS = false;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (m_Key.Deleted || !m_Key.IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(501661); // That key is unreachable.
|
||||
return;
|
||||
}
|
||||
|
||||
int number;
|
||||
|
||||
if (targeted == m_Key)
|
||||
{
|
||||
number = 501665; // Enter a description for this key.
|
||||
|
||||
from.Prompt = new RenamePrompt(m_Key);
|
||||
}
|
||||
else if (targeted is ILockable lockable)
|
||||
{
|
||||
if (m_Key.UseOn(from, lockable))
|
||||
number = -1;
|
||||
else
|
||||
number = 501668; // This key doesn't seem to unlock that.
|
||||
}
|
||||
else
|
||||
{
|
||||
number = 501666; // You can't unlock that!
|
||||
}
|
||||
|
||||
if (number != -1) from.SendLocalizedMessage(number);
|
||||
}
|
||||
}
|
||||
|
||||
private class CopyTarget : Target
|
||||
{
|
||||
private Key m_Key;
|
||||
|
||||
public CopyTarget(Key key) : base(3, false, TargetFlags.None)
|
||||
{
|
||||
m_Key = key;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (m_Key.Deleted || !m_Key.IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(501661); // That key is unreachable.
|
||||
return;
|
||||
}
|
||||
|
||||
int number;
|
||||
|
||||
if (targeted is Key k)
|
||||
{
|
||||
if (k.m_KeyVal == 0)
|
||||
{
|
||||
number = 501675; // This key is also blank.
|
||||
}
|
||||
else if (from.CheckTargetSkill(SkillName.Tinkering, k, 0, 75.0))
|
||||
{
|
||||
number = 501676; // You make a copy of the key.
|
||||
|
||||
m_Key.Description = k.Description;
|
||||
m_Key.KeyValue = k.KeyValue;
|
||||
m_Key.Link = k.Link;
|
||||
m_Key.MaxRange = k.MaxRange;
|
||||
}
|
||||
else if (Utility.RandomDouble() <= 0.1) // 10% chance to destroy the key
|
||||
{
|
||||
from.SendLocalizedMessage(501677); // You fail to make a copy of the key.
|
||||
|
||||
number = 501678; // The key was destroyed in the attempt.
|
||||
|
||||
m_Key.Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
number = 501677; // You fail to make a copy of the key.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
number = 501688; // Not a key.
|
||||
}
|
||||
|
||||
from.SendLocalizedMessage(number);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
188
Projects/Scripts/Items/Misc/KeyRing.cs
Normal file
188
Projects/Scripts/Items/Misc/KeyRing.cs
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
using System.Collections.Generic;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class KeyRing : Item
|
||||
{
|
||||
public static readonly int MaxKeys = 20;
|
||||
|
||||
[Constructible]
|
||||
public KeyRing() : base(0x1011)
|
||||
{
|
||||
Weight = 1.0; // They seem to have no weight on OSI ?!
|
||||
|
||||
Keys = new List<Key>();
|
||||
}
|
||||
|
||||
public KeyRing(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public List<Key> Keys{ get; private set; }
|
||||
|
||||
public override bool OnDragDrop(Mobile from, Item dropped)
|
||||
{
|
||||
if (!IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1060640); // The item must be in your backpack to use it.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(dropped is Key key) || key.KeyValue == 0)
|
||||
{
|
||||
from.SendLocalizedMessage(501689); // Only non-blank keys can be put on a keyring.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Keys.Count >= MaxKeys)
|
||||
{
|
||||
from.SendLocalizedMessage(1008138); // This keyring is full.
|
||||
return false;
|
||||
}
|
||||
|
||||
Add(key);
|
||||
from.SendLocalizedMessage(501691); // You put the key on the keyring.
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1060640); // The item must be in your backpack to use it.
|
||||
return;
|
||||
}
|
||||
|
||||
from.SendLocalizedMessage(501680); // What do you want to unlock?
|
||||
from.Target = new InternalTarget(this);
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
base.OnDelete();
|
||||
|
||||
foreach (Key key in Keys) key.Delete();
|
||||
|
||||
Keys.Clear();
|
||||
}
|
||||
|
||||
public void Add(Key key)
|
||||
{
|
||||
key.Internalize();
|
||||
Keys.Add(key);
|
||||
|
||||
UpdateItemID();
|
||||
}
|
||||
|
||||
public void Open(Mobile from)
|
||||
{
|
||||
if (!(Parent is Container cont))
|
||||
return;
|
||||
|
||||
for (int i = Keys.Count - 1; i >= 0; i--)
|
||||
{
|
||||
Key key = Keys[i];
|
||||
|
||||
if (!key.Deleted && !cont.TryDropItem(from, key, true))
|
||||
break;
|
||||
|
||||
Keys.RemoveAt(i);
|
||||
}
|
||||
|
||||
UpdateItemID();
|
||||
}
|
||||
|
||||
public void RemoveKeys(uint keyValue)
|
||||
{
|
||||
for (int i = Keys.Count - 1; i >= 0; i--)
|
||||
{
|
||||
Key key = Keys[i];
|
||||
|
||||
if (key.KeyValue == keyValue)
|
||||
{
|
||||
key.Delete();
|
||||
Keys.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateItemID();
|
||||
}
|
||||
|
||||
public bool ContainsKey(uint keyValue)
|
||||
{
|
||||
foreach (Key key in Keys)
|
||||
if (key.KeyValue == keyValue)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void UpdateItemID()
|
||||
{
|
||||
if (Keys.Count < 1)
|
||||
ItemID = 0x1011;
|
||||
else if (Keys.Count < 3)
|
||||
ItemID = 0x1769;
|
||||
else if (Keys.Count < 5)
|
||||
ItemID = 0x176A;
|
||||
else
|
||||
ItemID = 0x176B;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.WriteItemList(Keys);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
Keys = reader.ReadStrongItemList<Key>();
|
||||
}
|
||||
|
||||
private class InternalTarget : Target
|
||||
{
|
||||
private KeyRing m_KeyRing;
|
||||
|
||||
public InternalTarget(KeyRing keyRing) : base(-1, false, TargetFlags.None)
|
||||
{
|
||||
m_KeyRing = keyRing;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (m_KeyRing.Deleted || !m_KeyRing.IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1060640); // The item must be in your backpack to use it.
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_KeyRing == targeted)
|
||||
{
|
||||
m_KeyRing.Open(from);
|
||||
from.SendLocalizedMessage(501685); // You open the keyring.
|
||||
}
|
||||
else if (targeted is ILockable o)
|
||||
{
|
||||
foreach (Key key in m_KeyRing.Keys)
|
||||
if (key.UseOn(from, o))
|
||||
return;
|
||||
|
||||
from.SendLocalizedMessage(1008140); // You do not have a key for that.
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(501666); // You can't unlock that!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
113
Projects/Scripts/Items/Misc/LOSBlocker.cs
Normal file
113
Projects/Scripts/Items/Misc/LOSBlocker.cs
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class LOSBlocker : Item
|
||||
{
|
||||
[Constructible]
|
||||
public LOSBlocker() : base(0x21A2)
|
||||
{
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public LOSBlocker(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "no line of sight";
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
TileData.ItemTable[0x21A2].Flags = TileFlag.Wall | TileFlag.NoShoot;
|
||||
TileData.ItemTable[0x21A2].Height = 20;
|
||||
}
|
||||
|
||||
protected override Packet GetWorldPacketFor(NetState state)
|
||||
{
|
||||
Mobile mob = state.Mobile;
|
||||
|
||||
if (mob?.AccessLevel >= AccessLevel.GameMaster) return new GMItemPacket(this);
|
||||
|
||||
return base.GetWorldPacketFor(state);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if (version < 1 && ItemID == 0x2199)
|
||||
ItemID = 0x21A2;
|
||||
}
|
||||
|
||||
public sealed class GMItemPacket : Packet
|
||||
{
|
||||
public GMItemPacket(Item item) : base(0x1A)
|
||||
{
|
||||
EnsureCapacity(20);
|
||||
|
||||
// 14 base length
|
||||
// +2 - Amount
|
||||
// +2 - Hue
|
||||
// +1 - Flags
|
||||
|
||||
uint serial = item.Serial.Value;
|
||||
int itemID = 0x36FF;
|
||||
int amount = item.Amount;
|
||||
Point3D loc = item.Location;
|
||||
int x = loc.X;
|
||||
int y = loc.Y;
|
||||
int hue = item.Hue;
|
||||
int flags = item.GetPacketFlags();
|
||||
int direction = (int)item.Direction;
|
||||
|
||||
if (amount != 0)
|
||||
serial |= 0x80000000;
|
||||
else
|
||||
serial &= 0x7FFFFFFF;
|
||||
|
||||
m_Stream.Write(serial);
|
||||
m_Stream.Write((short)(itemID & 0x7FFF));
|
||||
|
||||
if (amount != 0)
|
||||
m_Stream.Write((short)amount);
|
||||
|
||||
x &= 0x7FFF;
|
||||
|
||||
if (direction != 0)
|
||||
x |= 0x8000;
|
||||
|
||||
m_Stream.Write((short)x);
|
||||
|
||||
y &= 0x3FFF;
|
||||
|
||||
if (hue != 0)
|
||||
y |= 0x8000;
|
||||
|
||||
if (flags != 0)
|
||||
y |= 0x4000;
|
||||
|
||||
m_Stream.Write((short)y);
|
||||
|
||||
if (direction != 0)
|
||||
m_Stream.Write((byte)direction);
|
||||
|
||||
m_Stream.Write((sbyte)loc.Z);
|
||||
|
||||
if (hue != 0)
|
||||
m_Stream.Write((ushort)hue);
|
||||
|
||||
if (flags != 0)
|
||||
m_Stream.Write((byte)flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Projects/Scripts/Items/Misc/Labyrinth/MinotaurArtifact.cs
Normal file
36
Projects/Scripts/Items/Misc/Labyrinth/MinotaurArtifact.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class MinotaurArtifact : Item
|
||||
{
|
||||
[Constructible]
|
||||
public MinotaurArtifact() : base(Utility.RandomList(0xB46, 0xB48, 0x9ED))
|
||||
{
|
||||
if (ItemID == 0x9ED)
|
||||
Weight = 30;
|
||||
|
||||
LootType = LootType.Blessed;
|
||||
Hue = 0x100;
|
||||
}
|
||||
|
||||
public MinotaurArtifact(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1074826; // Minotaur Artifact
|
||||
public override double DefaultWeight => 5.0;
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
205
Projects/Scripts/Items/Misc/Moonstone.cs
Normal file
205
Projects/Scripts/Items/Misc/Moonstone.cs
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
using System;
|
||||
using Server.Factions;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public enum MoonstoneType
|
||||
{
|
||||
Felucca,
|
||||
Trammel
|
||||
}
|
||||
|
||||
public class Moonstone : Item
|
||||
{
|
||||
private MoonstoneType m_Type;
|
||||
|
||||
[Constructible]
|
||||
public Moonstone(MoonstoneType type) : base(0xF8B)
|
||||
{
|
||||
Weight = 1.0;
|
||||
m_Type = type;
|
||||
}
|
||||
|
||||
public Moonstone(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public MoonstoneType Type
|
||||
{
|
||||
get => m_Type;
|
||||
set
|
||||
{
|
||||
m_Type = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1041490 + (int)m_Type;
|
||||
|
||||
public override void OnSingleClick(Mobile from)
|
||||
{
|
||||
if (IsChildOf(from.Backpack))
|
||||
{
|
||||
Hue = Utility.RandomBirdHue();
|
||||
ProcessDelta();
|
||||
from.SendLocalizedMessage(1005398); // The stone's substance shifts as you examine it.
|
||||
}
|
||||
|
||||
base.OnSingleClick(from);
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
|
||||
}
|
||||
else if (from.Mounted)
|
||||
{
|
||||
from.SendLocalizedMessage(1005399); // You can not bury a stone while you sit on a mount.
|
||||
}
|
||||
else if (!from.Body.IsHuman)
|
||||
{
|
||||
from.SendLocalizedMessage(1005400); // You can not bury a stone in this form.
|
||||
}
|
||||
else if (Sigil.ExistsOn(from))
|
||||
{
|
||||
from.SendLocalizedMessage(1061632); // You can't do that while carrying the sigil.
|
||||
}
|
||||
else if (from.Map == GetTargetMap() || from.Map != Map.Trammel && from.Map != Map.Felucca)
|
||||
{
|
||||
from.SendLocalizedMessage(1005401); // You cannot bury the stone here.
|
||||
}
|
||||
else if (from is PlayerMobile mobile && mobile.Young)
|
||||
{
|
||||
mobile.SendLocalizedMessage(1049543); // You decide against traveling to Felucca while you are still young.
|
||||
}
|
||||
else if (from.Kills >= 5)
|
||||
{
|
||||
from.SendLocalizedMessage(
|
||||
1005402); // The magic of the stone cannot be evoked by someone with blood on their hands.
|
||||
}
|
||||
else if (from.Criminal)
|
||||
{
|
||||
from.SendLocalizedMessage(1005403); // The magic of the stone cannot be evoked by the lawless.
|
||||
}
|
||||
else if (!Region.Find(from.Location, from.Map).IsDefault ||
|
||||
!Region.Find(from.Location, GetTargetMap()).IsDefault)
|
||||
{
|
||||
from.SendLocalizedMessage(1005401); // You cannot bury the stone here.
|
||||
}
|
||||
else if (!GetTargetMap().CanFit(from.Location, 16))
|
||||
{
|
||||
from.SendLocalizedMessage(1005408); // Something is blocking the facet gate exit.
|
||||
}
|
||||
else
|
||||
{
|
||||
Movable = false;
|
||||
MoveToWorld(from.Location, from.Map);
|
||||
|
||||
from.Animate(32, 5, 1, true, false, 0);
|
||||
|
||||
new SettleTimer(this, from.Location, from.Map, GetTargetMap(), from).Start();
|
||||
}
|
||||
}
|
||||
|
||||
public Map GetTargetMap()
|
||||
{
|
||||
return m_Type == MoonstoneType.Felucca ? Map.Felucca : Map.Trammel;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write((int)m_Type);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_Type = (MoonstoneType)reader.ReadInt();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class SettleTimer : Timer
|
||||
{
|
||||
private Mobile m_Caster;
|
||||
private int m_Count;
|
||||
private Point3D m_Location;
|
||||
private Map m_Map, m_TargetMap;
|
||||
private Item m_Stone;
|
||||
|
||||
public SettleTimer(Item stone, Point3D loc, Map map, Map targetMap, Mobile caster) : base(
|
||||
TimeSpan.FromSeconds(2.5), TimeSpan.FromSeconds(1.0))
|
||||
{
|
||||
m_Stone = stone;
|
||||
|
||||
m_Location = loc;
|
||||
m_Map = map;
|
||||
m_TargetMap = targetMap;
|
||||
|
||||
m_Caster = caster;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
++m_Count;
|
||||
|
||||
if (m_Count == 1)
|
||||
{
|
||||
m_Stone.PublicOverheadMessage(MessageType.Regular, 0x3B2, 1005414); // The stone settles into the ground.
|
||||
}
|
||||
else if (m_Count >= 10)
|
||||
{
|
||||
m_Stone.Location = new Point3D(m_Stone.X, m_Stone.Y, m_Stone.Z - 1);
|
||||
|
||||
if (m_Count == 16)
|
||||
{
|
||||
if (!Region.Find(m_Location, m_Map).IsDefault || !Region.Find(m_Location, m_TargetMap).IsDefault)
|
||||
{
|
||||
m_Stone.Movable = true;
|
||||
m_Caster.AddToBackpack(m_Stone);
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_TargetMap.CanFit(m_Location, 16))
|
||||
{
|
||||
m_Stone.Movable = true;
|
||||
m_Caster.AddToBackpack(m_Stone);
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
int hue = m_Stone.Hue;
|
||||
|
||||
if (hue == 0)
|
||||
hue = Utility.RandomBirdHue();
|
||||
|
||||
new MoonstoneGate(m_Location, m_TargetMap, m_Map, m_Caster, hue);
|
||||
new MoonstoneGate(m_Location, m_Map, m_TargetMap, m_Caster, hue);
|
||||
|
||||
m_Stone.Delete();
|
||||
Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
83
Projects/Scripts/Items/Misc/MoonstoneGate.cs
Normal file
83
Projects/Scripts/Items/Misc/MoonstoneGate.cs
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
using System;
|
||||
using Server.Engines.PartySystem;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class MoonstoneGate : Moongate
|
||||
{
|
||||
private Mobile m_Caster;
|
||||
|
||||
public MoonstoneGate(Point3D loc, Map map, Map targetMap, Mobile caster, int hue) : base(loc, targetMap)
|
||||
{
|
||||
MoveToWorld(loc, map);
|
||||
Dispellable = false;
|
||||
Hue = hue;
|
||||
|
||||
m_Caster = caster;
|
||||
|
||||
new InternalTimer(this).Start();
|
||||
|
||||
Effects.PlaySound(loc, map, 0x20E);
|
||||
}
|
||||
|
||||
public MoonstoneGate(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void CheckGate(Mobile m, int range)
|
||||
{
|
||||
if (m.Kills >= 5)
|
||||
return;
|
||||
|
||||
Party casterParty = Party.Get(m_Caster);
|
||||
Party userParty = Party.Get(m);
|
||||
|
||||
if (m == m_Caster || casterParty != null && userParty == casterParty)
|
||||
base.CheckGate(m, range);
|
||||
}
|
||||
|
||||
public override void UseGate(Mobile m)
|
||||
{
|
||||
if (m.Kills >= 5)
|
||||
return;
|
||||
|
||||
Party casterParty = Party.Get(m_Caster);
|
||||
Party userParty = Party.Get(m);
|
||||
|
||||
if (m == m_Caster || casterParty != null && userParty == casterParty)
|
||||
base.UseGate(m);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Delete();
|
||||
}
|
||||
|
||||
private class InternalTimer : Timer
|
||||
{
|
||||
private Item m_Item;
|
||||
|
||||
public InternalTimer(Item item) : base(TimeSpan.FromSeconds(30.0))
|
||||
{
|
||||
m_Item = item;
|
||||
Priority = TimerPriority.OneSecond;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Item.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
132
Projects/Scripts/Items/Misc/MorphItem.cs
Normal file
132
Projects/Scripts/Items/Misc/MorphItem.cs
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class MorphItem : Item
|
||||
{
|
||||
private int m_InRange;
|
||||
private int m_OutRange;
|
||||
|
||||
[Constructible]
|
||||
public MorphItem(int inactiveItemID, int activeItemID, int range) : this(inactiveItemID, activeItemID, range, range)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructible]
|
||||
public MorphItem(int inactiveItemID, int activeItemID, int inRange, int outRange) : base(inactiveItemID)
|
||||
{
|
||||
Movable = false;
|
||||
|
||||
InactiveItemID = inactiveItemID;
|
||||
ActiveItemID = activeItemID;
|
||||
InRange = inRange;
|
||||
OutRange = outRange;
|
||||
}
|
||||
|
||||
public MorphItem(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int InactiveItemID{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ActiveItemID{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int InRange
|
||||
{
|
||||
get => m_InRange;
|
||||
set
|
||||
{
|
||||
if (value > 18) value = 18;
|
||||
m_InRange = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int OutRange
|
||||
{
|
||||
get => m_OutRange;
|
||||
set
|
||||
{
|
||||
if (value > 18) value = 18;
|
||||
m_OutRange = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int CurrentRange => ItemID == InactiveItemID ? InRange : OutRange;
|
||||
|
||||
public override bool HandlesOnMovement => true;
|
||||
|
||||
public override void OnMovement(Mobile m, Point3D oldLocation)
|
||||
{
|
||||
if (Utility.InRange(m.Location, Location, CurrentRange) || Utility.InRange(oldLocation, Location, CurrentRange))
|
||||
Refresh();
|
||||
}
|
||||
|
||||
public override void OnMapChange()
|
||||
{
|
||||
if (!Deleted)
|
||||
Refresh();
|
||||
}
|
||||
|
||||
public override void OnLocationChange(Point3D oldLoc)
|
||||
{
|
||||
if (!Deleted)
|
||||
Refresh();
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
bool found = GetMobilesInRange(CurrentRange).Any(mob => !mob.Hidden || mob.AccessLevel <= AccessLevel.Player);
|
||||
ItemID = found ? ActiveItemID : InactiveItemID;
|
||||
|
||||
Visible = ItemID != 0x1;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1); // version
|
||||
|
||||
writer.Write(m_OutRange);
|
||||
|
||||
writer.Write(InactiveItemID);
|
||||
writer.Write(ActiveItemID);
|
||||
writer.Write(m_InRange);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
m_OutRange = reader.ReadInt();
|
||||
goto case 0;
|
||||
}
|
||||
case 0:
|
||||
{
|
||||
InactiveItemID = reader.ReadInt();
|
||||
ActiveItemID = reader.ReadInt();
|
||||
m_InRange = reader.ReadInt();
|
||||
|
||||
if (version < 1)
|
||||
m_OutRange = m_InRange;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Timer.DelayCall(TimeSpan.Zero, Refresh);
|
||||
}
|
||||
}
|
||||
}
|
||||
151
Projects/Scripts/Items/Misc/OilCloth.cs
Normal file
151
Projects/Scripts/Items/Misc/OilCloth.cs
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
using System;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class OilCloth : Item, IScissorable, IDyable
|
||||
{
|
||||
[Constructible]
|
||||
public OilCloth() : base(0x175D)
|
||||
{
|
||||
Hue = 2001;
|
||||
}
|
||||
|
||||
public OilCloth(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1041498; // oil cloth
|
||||
|
||||
public override double DefaultWeight => 1.0;
|
||||
|
||||
public bool Dye(Mobile from, DyeTub sender)
|
||||
{
|
||||
if (Deleted)
|
||||
return false;
|
||||
|
||||
Hue = sender.DyedHue;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Scissor(Mobile from, Scissors scissors)
|
||||
{
|
||||
if (Deleted || !from.CanSee(this))
|
||||
return false;
|
||||
|
||||
base.ScissorHelper(from, new Bandage(), 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (IsChildOf(from.Backpack))
|
||||
{
|
||||
from.BeginTarget(-1, false, TargetFlags.None, OnTarget);
|
||||
from.SendLocalizedMessage(1005424); // Select the weapon or armor you wish to use the cloth on.
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
|
||||
}
|
||||
}
|
||||
|
||||
public void OnTarget(Mobile from, object obj)
|
||||
{
|
||||
// TODO: Need details on how oil cloths should get consumed here
|
||||
|
||||
if (!IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
|
||||
}
|
||||
else if (obj is Item item && item.RootParent != from)
|
||||
{
|
||||
from.SendLocalizedMessage(1005425); // You may only wipe down items you are holding or carrying.
|
||||
}
|
||||
else if (obj is BaseWeapon weapon)
|
||||
{
|
||||
if (weapon.Poison == null || weapon.PoisonCharges <= 0)
|
||||
{
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2,
|
||||
1005422); // Hmmmm... this does not need to be cleaned.
|
||||
}
|
||||
else
|
||||
{
|
||||
if (weapon.PoisonCharges < 2)
|
||||
weapon.PoisonCharges = 0;
|
||||
else
|
||||
weapon.PoisonCharges -= 2;
|
||||
|
||||
if (weapon.PoisonCharges > 0)
|
||||
from.SendLocalizedMessage(1005423); // You have removed some of the caustic substance, but not all.
|
||||
else
|
||||
from.SendLocalizedMessage(1010497); // You have cleaned the item.
|
||||
}
|
||||
}
|
||||
else if (obj == from && obj is PlayerMobile pm)
|
||||
{
|
||||
if (pm.BodyMod == 183 || pm.BodyMod == 184)
|
||||
{
|
||||
pm.SavagePaintExpiration = TimeSpan.Zero;
|
||||
|
||||
pm.BodyMod = 0;
|
||||
pm.HueMod = -1;
|
||||
|
||||
from.SendLocalizedMessage(1040006); // You wipe away all of your body paint.
|
||||
|
||||
Consume();
|
||||
}
|
||||
else
|
||||
{
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2,
|
||||
1005422); // Hmmmm... this does not need to be cleaned.
|
||||
}
|
||||
}
|
||||
|
||||
#region Firebomb
|
||||
|
||||
else if (obj is BaseBeverage beverage)
|
||||
{
|
||||
if (beverage.Content == BeverageType.Liquor)
|
||||
{
|
||||
Firebomb bomb = new Firebomb(beverage.ItemID);
|
||||
bomb.Name = beverage.Name;
|
||||
|
||||
beverage.ReplaceWith(bomb);
|
||||
|
||||
from.SendLocalizedMessage(1060580); // You prepare a firebomb.
|
||||
Consume();
|
||||
}
|
||||
}
|
||||
else if (obj is Firebomb)
|
||||
{
|
||||
from.SendLocalizedMessage(1060579); // That is already a firebomb!
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1005426); // The cloth will not work on that.
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
245
Projects/Scripts/Items/Misc/Origami.cs
Normal file
245
Projects/Scripts/Items/Misc/Origami.cs
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class OrigamiPaper : Item
|
||||
{
|
||||
[Constructible]
|
||||
public OrigamiPaper() : base(0x2830)
|
||||
{
|
||||
}
|
||||
|
||||
public OrigamiPaper(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1030288; // origami paper
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
|
||||
}
|
||||
else
|
||||
{
|
||||
Delete();
|
||||
|
||||
Item i = null;
|
||||
|
||||
switch (Utility.Random(from.BAC >= 5 ? 6 : 5))
|
||||
{
|
||||
case 0:
|
||||
i = new OrigamiButterfly();
|
||||
break;
|
||||
case 1:
|
||||
i = new OrigamiSwan();
|
||||
break;
|
||||
case 2:
|
||||
i = new OrigamiFrog();
|
||||
break;
|
||||
case 3:
|
||||
i = new OrigamiShape();
|
||||
break;
|
||||
case 4:
|
||||
i = new OrigamiSongbird();
|
||||
break;
|
||||
case 5:
|
||||
i = new OrigamiFish();
|
||||
break;
|
||||
}
|
||||
|
||||
if (i != null)
|
||||
from.AddToBackpack(i);
|
||||
|
||||
from.SendLocalizedMessage(1070822); // You fold the paper into an interesting shape.
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class OrigamiButterfly : Item
|
||||
{
|
||||
[Constructible]
|
||||
public OrigamiButterfly() : base(0x2838)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public OrigamiButterfly(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1030296; // a delicate origami butterfly
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class OrigamiSwan : Item
|
||||
{
|
||||
[Constructible]
|
||||
public OrigamiSwan() : base(0x2839)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public OrigamiSwan(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1030297; // a delicate origami swan
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class OrigamiFrog : Item
|
||||
{
|
||||
[Constructible]
|
||||
public OrigamiFrog() : base(0x283A)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public OrigamiFrog(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1030298; // a delicate origami frog
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class OrigamiShape : Item
|
||||
{
|
||||
[Constructible]
|
||||
public OrigamiShape() : base(0x283B)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public OrigamiShape(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1030299; // an intricate geometric origami shape
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class OrigamiSongbird : Item
|
||||
{
|
||||
[Constructible]
|
||||
public OrigamiSongbird() : base(0x283C)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public OrigamiSongbird(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1030300; // a delicate origami songbird
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class OrigamiFish : Item
|
||||
{
|
||||
[Constructible]
|
||||
public OrigamiFish() : base(0x283D)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public OrigamiFish(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1030301; // a delicate origami fish
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
32
Projects/Scripts/Items/Misc/Painted Caves/GrobusFur.cs
Normal file
32
Projects/Scripts/Items/Misc/Painted Caves/GrobusFur.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class GrobusFur : Item
|
||||
{
|
||||
[Constructible]
|
||||
public GrobusFur() : base(0x11F4)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
Hue = 0x455;
|
||||
}
|
||||
|
||||
public GrobusFur(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1074676; // Grobu's Fur
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
32
Projects/Scripts/Items/Misc/Painted Caves/PrimitiveFetish.cs
Normal file
32
Projects/Scripts/Items/Misc/Painted Caves/PrimitiveFetish.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class PrimitiveFetish : Item
|
||||
{
|
||||
[Constructible]
|
||||
public PrimitiveFetish() : base(0x23F)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
Hue = 0x244;
|
||||
}
|
||||
|
||||
public PrimitiveFetish(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1074675; // Primitive Fetish
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class AcidProofRope : Item
|
||||
{
|
||||
[Constructible]
|
||||
public AcidProofRope() : base(0x20D)
|
||||
{
|
||||
Hue = 0x3D1; // TODO check
|
||||
}
|
||||
|
||||
public AcidProofRope(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1074886; // Acid Proof Rope
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class ParoxysmusCorrodedStein : Item
|
||||
{
|
||||
[Constructible]
|
||||
public ParoxysmusCorrodedStein() : base(0x9D6)
|
||||
{
|
||||
}
|
||||
|
||||
public ParoxysmusCorrodedStein(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1072083; // Paroxysmus' Corroded Stein
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class ParoxysmusDinner : Item
|
||||
{
|
||||
[Constructible]
|
||||
public ParoxysmusDinner() : base(0x1E95)
|
||||
{
|
||||
}
|
||||
|
||||
public ParoxysmusDinner(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1072086; // Paroxysmus' Dinner
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class StringOfPartsOfParoxysmusVictims : Item
|
||||
{
|
||||
[Constructible]
|
||||
public StringOfPartsOfParoxysmusVictims() : base(0xFD2)
|
||||
{
|
||||
}
|
||||
|
||||
public StringOfPartsOfParoxysmusVictims(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1072082; // String of Parts of Paroxysmus' Victims
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class SweatOfParoxysmus : Item
|
||||
{
|
||||
[Constructible]
|
||||
public SweatOfParoxysmus() : base(0xF01)
|
||||
{
|
||||
}
|
||||
|
||||
public SweatOfParoxysmus(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1072081; // Sweat of Paroxysmus
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
600
Projects/Scripts/Items/Misc/PlayerBulletinBoards.cs
Normal file
600
Projects/Scripts/Items/Misc/PlayerBulletinBoards.cs
Normal file
|
|
@ -0,0 +1,600 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Gumps;
|
||||
using Server.Multis;
|
||||
using Server.Prompts;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
using Server.ContextMenus;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class PlayerBBSouth : BasePlayerBB
|
||||
{
|
||||
public override int LabelNumber => 1062421; // bulletin board (south)
|
||||
|
||||
[Constructible]
|
||||
public PlayerBBSouth() : base( 0x2311 )
|
||||
{
|
||||
Weight = 15.0;
|
||||
}
|
||||
|
||||
public PlayerBBSouth( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class PlayerBBEast : BasePlayerBB
|
||||
{
|
||||
public override int LabelNumber => 1062420; // bulletin board (east)
|
||||
|
||||
[Constructible]
|
||||
public PlayerBBEast() : base( 0x2312 )
|
||||
{
|
||||
Weight = 15.0;
|
||||
}
|
||||
|
||||
public PlayerBBEast( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class BasePlayerBB : Item, ISecurable
|
||||
{
|
||||
public List<PlayerBBMessage> Messages { get; private set; }
|
||||
|
||||
public PlayerBBMessage Greeting { get; set; }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public string Title { get; set; }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public SecureLevel Level { get; set; }
|
||||
|
||||
public BasePlayerBB( int itemID ) : base( itemID )
|
||||
{
|
||||
Messages = new List<PlayerBBMessage>();
|
||||
Level = SecureLevel.Anyone;
|
||||
}
|
||||
|
||||
public BasePlayerBB( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
|
||||
{
|
||||
base.GetContextMenuEntries( from, list );
|
||||
SetSecureLevelEntry.AddTo( from, this, list );
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( 1 );
|
||||
|
||||
writer.Write( (int) Level );
|
||||
|
||||
writer.Write( Title );
|
||||
|
||||
if ( Greeting != null )
|
||||
{
|
||||
writer.Write( true );
|
||||
Greeting.Serialize( writer );
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write( false );
|
||||
}
|
||||
|
||||
writer.WriteEncodedInt( Messages.Count );
|
||||
|
||||
for ( int i = 0; i < Messages.Count; ++i )
|
||||
Messages[i].Serialize( writer );
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
Level = (SecureLevel)reader.ReadInt();
|
||||
goto case 0;
|
||||
}
|
||||
case 0:
|
||||
{
|
||||
if ( version < 1 )
|
||||
Level = SecureLevel.Anyone;
|
||||
|
||||
Title = reader.ReadString();
|
||||
|
||||
if ( reader.ReadBool() )
|
||||
Greeting = new PlayerBBMessage( reader );
|
||||
|
||||
int count = reader.ReadEncodedInt();
|
||||
|
||||
Messages = new List<PlayerBBMessage>( count );
|
||||
|
||||
for ( int i = 0; i < count; ++i )
|
||||
Messages.Add( new PlayerBBMessage( reader ) );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool CheckAccess( BaseHouse house, Mobile from )
|
||||
{
|
||||
if ( house.Public || !house.IsAosRules )
|
||||
return !house.IsBanned( from );
|
||||
|
||||
return house.HasAccess( from );
|
||||
}
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
BaseHouse house = BaseHouse.FindHouseAt( this );
|
||||
|
||||
if ( house == null || !house.HasLockedDownItem( this ) )
|
||||
from.SendLocalizedMessage( 1062396 ); // This bulletin board must be locked down in a house to be usable.
|
||||
else if ( !from.InRange( GetWorldLocation(), 2 ) || !from.InLOS( this ) )
|
||||
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
|
||||
else if ( CheckAccess( house, from ) )
|
||||
from.SendGump( new PlayerBBGump( from, house, this, 0 ) );
|
||||
}
|
||||
|
||||
public class PostPrompt : Prompt
|
||||
{
|
||||
private int m_Page;
|
||||
private BaseHouse m_House;
|
||||
private BasePlayerBB m_Board;
|
||||
private bool m_Greeting;
|
||||
|
||||
public PostPrompt( int page, BaseHouse house, BasePlayerBB board, bool greeting )
|
||||
{
|
||||
m_Page = page;
|
||||
m_House = house;
|
||||
m_Board = board;
|
||||
m_Greeting = greeting;
|
||||
}
|
||||
|
||||
public override void OnCancel( Mobile from )
|
||||
{
|
||||
OnResponse( from, "" );
|
||||
}
|
||||
|
||||
public override void OnResponse( Mobile from, string text )
|
||||
{
|
||||
int page = m_Page;
|
||||
BaseHouse house = m_House;
|
||||
BasePlayerBB board = m_Board;
|
||||
|
||||
if ( house == null || !house.HasLockedDownItem( board ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1062396 ); // This bulletin board must be locked down in a house to be usable.
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !from.InRange( board.GetWorldLocation(), 2 ) || !from.InLOS( board ) )
|
||||
{
|
||||
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
|
||||
return;
|
||||
}
|
||||
if ( !CheckAccess( house, from ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1062398 ); // You are not allowed to post to this bulletin board.
|
||||
return;
|
||||
}
|
||||
if ( m_Greeting && !house.IsOwner( from ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
text = text.Trim();
|
||||
|
||||
if ( text.Length > 255 )
|
||||
text = text.Substring( 0, 255 );
|
||||
|
||||
if ( text.Length > 0 )
|
||||
{
|
||||
PlayerBBMessage message = new PlayerBBMessage( DateTime.UtcNow, from, text );
|
||||
|
||||
if ( m_Greeting )
|
||||
{
|
||||
board.Greeting = message;
|
||||
}
|
||||
else
|
||||
{
|
||||
board.Messages.Add( message );
|
||||
|
||||
if ( board.Messages.Count > 50 )
|
||||
{
|
||||
board.Messages.RemoveAt( 0 );
|
||||
|
||||
if ( page > 0 )
|
||||
--page;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
from.SendGump( new PlayerBBGump( from, house, board, page ) );
|
||||
}
|
||||
}
|
||||
|
||||
public class SetTitlePrompt : Prompt
|
||||
{
|
||||
private int m_Page;
|
||||
private BaseHouse m_House;
|
||||
private BasePlayerBB m_Board;
|
||||
|
||||
public SetTitlePrompt( int page, BaseHouse house, BasePlayerBB board )
|
||||
{
|
||||
m_Page = page;
|
||||
m_House = house;
|
||||
m_Board = board;
|
||||
}
|
||||
|
||||
public override void OnCancel( Mobile from )
|
||||
{
|
||||
OnResponse( from, "" );
|
||||
}
|
||||
|
||||
public override void OnResponse( Mobile from, string text )
|
||||
{
|
||||
int page = m_Page;
|
||||
BaseHouse house = m_House;
|
||||
BasePlayerBB board = m_Board;
|
||||
|
||||
if ( house == null || !house.HasLockedDownItem( board ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1062396 ); // This bulletin board must be locked down in a house to be usable.
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !from.InRange( board.GetWorldLocation(), 2 ) || !from.InLOS( board ) )
|
||||
{
|
||||
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
|
||||
return;
|
||||
}
|
||||
if ( !CheckAccess( house, from ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1062398 ); // You are not allowed to post to this bulletin board.
|
||||
return;
|
||||
}
|
||||
|
||||
text = text.Trim();
|
||||
|
||||
if ( text.Length > 255 )
|
||||
text = text.Substring( 0, 255 );
|
||||
|
||||
if ( text.Length > 0 )
|
||||
board.Title = text;
|
||||
|
||||
from.SendGump( new PlayerBBGump( from, house, board, page ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class PlayerBBMessage
|
||||
{
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public DateTime Time { get; set; }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public Mobile Poster { get; set; }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public string Message { get; set; }
|
||||
|
||||
public PlayerBBMessage( DateTime time, Mobile poster, string message )
|
||||
{
|
||||
Time = time;
|
||||
Poster = poster;
|
||||
Message = message;
|
||||
}
|
||||
|
||||
public PlayerBBMessage( GenericReader reader )
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Time = reader.ReadDateTime();
|
||||
Poster = reader.ReadMobile();
|
||||
Message = reader.ReadString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Serialize( GenericWriter writer )
|
||||
{
|
||||
writer.WriteEncodedInt( 0 ); // version
|
||||
|
||||
writer.Write( Time );
|
||||
writer.Write( Poster );
|
||||
writer.Write( Message );
|
||||
}
|
||||
}
|
||||
|
||||
public class PlayerBBGump : Gump
|
||||
{
|
||||
private int m_Page;
|
||||
private Mobile m_From;
|
||||
private BaseHouse m_House;
|
||||
private BasePlayerBB m_Board;
|
||||
|
||||
private const int LabelColor = 0x7FFF;
|
||||
private const int LabelHue = 1153;
|
||||
|
||||
public override void OnResponse( NetState sender, RelayInfo info )
|
||||
{
|
||||
int page = m_Page;
|
||||
Mobile from = m_From;
|
||||
BaseHouse house = m_House;
|
||||
BasePlayerBB board = m_Board;
|
||||
|
||||
if ( house == null || !house.HasLockedDownItem( board ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1062396 ); // This bulletin board must be locked down in a house to be usable.
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !from.InRange( board.GetWorldLocation(), 2 ) || !from.InLOS( board ) )
|
||||
{
|
||||
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
|
||||
return;
|
||||
}
|
||||
if ( !BasePlayerBB.CheckAccess( house, from ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1062398 ); // You are not allowed to post to this bulletin board.
|
||||
return;
|
||||
}
|
||||
|
||||
switch ( info.ButtonID )
|
||||
{
|
||||
case 1: // Post message
|
||||
{
|
||||
from.Prompt = new BasePlayerBB.PostPrompt( page, house, board, false );
|
||||
from.SendLocalizedMessage( 1062397 ); // Please enter your message:
|
||||
|
||||
break;
|
||||
}
|
||||
case 2: // Set title
|
||||
{
|
||||
if ( house.IsOwner( from ) )
|
||||
{
|
||||
from.Prompt = new BasePlayerBB.SetTitlePrompt( page, house, board );
|
||||
from.SendLocalizedMessage( 1062402 ); // Enter new title:
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 3: // Post greeting
|
||||
{
|
||||
if ( house.IsOwner( from ) )
|
||||
{
|
||||
from.Prompt = new BasePlayerBB.PostPrompt( page, house, board, true );
|
||||
from.SendLocalizedMessage( 1062404 ); // Enter new greeting (this will always be the first post):
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 4: // Scroll up
|
||||
{
|
||||
if ( page == 0 )
|
||||
page = board.Messages.Count;
|
||||
else
|
||||
page -= 1;
|
||||
|
||||
from.SendGump( new PlayerBBGump( from, house, board, page ) );
|
||||
|
||||
break;
|
||||
}
|
||||
case 5: // Scroll down
|
||||
{
|
||||
page += 1;
|
||||
page %= board.Messages.Count + 1;
|
||||
|
||||
from.SendGump( new PlayerBBGump( from, house, board, page ) );
|
||||
|
||||
break;
|
||||
}
|
||||
case 6: // Banish poster
|
||||
{
|
||||
if ( house.IsOwner( from ) )
|
||||
{
|
||||
if ( page >= 1 && page <= board.Messages.Count )
|
||||
{
|
||||
PlayerBBMessage message = board.Messages[page - 1];
|
||||
Mobile poster = message.Poster;
|
||||
|
||||
if ( poster == null )
|
||||
{
|
||||
from.SendGump( new PlayerBBGump( from, house, board, page ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( poster.AccessLevel > AccessLevel.Player && from.AccessLevel <= poster.AccessLevel )
|
||||
{
|
||||
from.SendLocalizedMessage( 501354 ); // Uh oh...a bigger boot may be required.
|
||||
}
|
||||
else if ( house.IsFriend( poster ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1060750 ); // That person is a friend, co-owner, or owner of this house, and therefore cannot be banished!
|
||||
}
|
||||
else if ( poster is PlayerVendor )
|
||||
{
|
||||
from.SendLocalizedMessage( 501351 ); // You cannot eject a vendor.
|
||||
}
|
||||
else if ( house.Bans.Count >= BaseHouse.MaxBans )
|
||||
{
|
||||
from.SendLocalizedMessage( 501355 ); // The ban limit for this house has been reached!
|
||||
}
|
||||
else if ( house.IsBanned( poster ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 501356 ); // This person is already banned!
|
||||
}
|
||||
else if ( poster is BaseCreature creature && creature.NoHouseRestrictions )
|
||||
{
|
||||
from.SendLocalizedMessage( 1062040 ); // You cannot ban that.
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !house.Bans.Contains( poster ) )
|
||||
house.Bans.Add( poster );
|
||||
|
||||
from.SendLocalizedMessage( 1062417 ); // That person has been banned from this house.
|
||||
|
||||
if ( house.IsInside( poster ) && !BasePlayerBB.CheckAccess( house, poster ) )
|
||||
poster.MoveToWorld( house.BanLocation, house.Map );
|
||||
}
|
||||
}
|
||||
|
||||
from.SendGump( new PlayerBBGump( from, house, board, page ) );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 7: // Delete message
|
||||
{
|
||||
if ( house.IsOwner( from ) )
|
||||
{
|
||||
if ( page >= 1 && page <= board.Messages.Count )
|
||||
board.Messages.RemoveAt( page - 1 );
|
||||
|
||||
from.SendGump( new PlayerBBGump( from, house, board, 0 ) );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 8: // Post props
|
||||
{
|
||||
if ( from.AccessLevel >= AccessLevel.GameMaster )
|
||||
{
|
||||
PlayerBBMessage message = board.Greeting;
|
||||
|
||||
if ( page >= 1 && page <= board.Messages.Count )
|
||||
message = board.Messages[page - 1];
|
||||
|
||||
from.SendGump( new PlayerBBGump( from, house, board, page ) );
|
||||
from.SendGump( new PropertiesGump( from, message ) );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public PlayerBBGump( Mobile from, BaseHouse house, BasePlayerBB board, int page ) : base( 50, 10 )
|
||||
{
|
||||
from.CloseGump<PlayerBBGump>();
|
||||
|
||||
m_Page = page;
|
||||
m_From = from;
|
||||
m_House = house;
|
||||
m_Board = board;
|
||||
|
||||
AddPage( 0 );
|
||||
|
||||
AddImage( 30, 30, 5400 );
|
||||
|
||||
AddButton( 393, 145, 2084, 2084, 4); // Scroll up
|
||||
AddButton( 390, 371, 2085, 2085, 5); // Scroll down
|
||||
|
||||
AddButton( 32, 183, 5412, 5413, 1); // Post message
|
||||
|
||||
if ( house.IsOwner( from ) )
|
||||
{
|
||||
AddButton( 63, 90, 5601, 5605, 2);
|
||||
AddHtmlLocalized( 81, 89, 230, 20, 1062400, LabelColor ); // Set title
|
||||
|
||||
AddButton( 63, 109, 5601, 5605, 3);
|
||||
AddHtmlLocalized( 81, 108, 230, 20, 1062401, LabelColor ); // Post greeting
|
||||
}
|
||||
|
||||
string title = board.Title;
|
||||
|
||||
if ( title != null )
|
||||
AddHtml( 183, 68, 180, 23, title );
|
||||
|
||||
AddHtmlLocalized( 385, 89, 60, 20, 1062409, LabelColor ); // Post
|
||||
|
||||
AddLabel( 440, 89, LabelHue, page.ToString() );
|
||||
AddLabel( 455, 89, LabelHue, "/" );
|
||||
AddLabel( 470, 89, LabelHue, board.Messages.Count.ToString() );
|
||||
|
||||
PlayerBBMessage message = board.Greeting;
|
||||
|
||||
if ( page >= 1 && page <= board.Messages.Count )
|
||||
message = board.Messages[page - 1];
|
||||
|
||||
AddImageTiled( 150, 220, 240, 1, 2700 ); // Separator
|
||||
|
||||
AddHtmlLocalized( 150, 180, 100, 20, 1062405, 16715 ); // Posted On:
|
||||
AddHtmlLocalized( 150, 200, 100, 20, 1062406, 16715 ); // Posted By:
|
||||
|
||||
if ( message != null )
|
||||
{
|
||||
AddHtml( 255, 180, 150, 20, message.Time.ToString( "yyyy-MM-dd HH:mm:ss" ) );
|
||||
|
||||
Mobile poster = message.Poster;
|
||||
string name = poster?.Name;
|
||||
|
||||
if ( name == null || (name = name.Trim()).Length == 0 )
|
||||
name = "Someone";
|
||||
|
||||
AddHtml( 255, 200, 150, 20, name );
|
||||
|
||||
AddHtml( 150, 240, 250, 100, message.Message ?? "" );
|
||||
|
||||
if ( message != board.Greeting && house.IsOwner( from ) )
|
||||
{
|
||||
AddButton( 130, 395, 1209, 1210, 6);
|
||||
AddHtmlLocalized( 150, 393, 150, 20, 1062410, LabelColor ); // Banish Poster
|
||||
|
||||
AddButton( 310, 395, 1209, 1210, 7);
|
||||
AddHtmlLocalized( 330, 393, 150, 20, 1062411, LabelColor ); // Delete Message
|
||||
}
|
||||
|
||||
if ( from.AccessLevel >= AccessLevel.GameMaster )
|
||||
AddButton( 135, 242, 1209, 1210, 8); // Post props
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
105
Projects/Scripts/Items/Misc/PlayerVendorDeed.cs
Normal file
105
Projects/Scripts/Items/Misc/PlayerVendorDeed.cs
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
using Server.Mobiles;
|
||||
using Server.Multis;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class ContractOfEmployment : Item
|
||||
{
|
||||
[Constructible]
|
||||
public ContractOfEmployment() : base(0x14F0)
|
||||
{
|
||||
Weight = 1.0;
|
||||
//LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public ContractOfEmployment(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1041243; // a contract of employment
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); //version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
|
||||
}
|
||||
else if (from.AccessLevel >= AccessLevel.GameMaster)
|
||||
{
|
||||
from.SendLocalizedMessage(503248); // Your godly powers allow you to place this vendor whereever you wish.
|
||||
|
||||
Mobile v = new PlayerVendor(from, BaseHouse.FindHouseAt(from));
|
||||
|
||||
v.Direction = from.Direction & Direction.Mask;
|
||||
v.MoveToWorld(from.Location, from.Map);
|
||||
|
||||
v.SayTo(from, 503246); // Ah! it feels good to be working again.
|
||||
|
||||
Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseHouse house = BaseHouse.FindHouseAt(from);
|
||||
|
||||
if (house == null)
|
||||
{
|
||||
from.SendLocalizedMessage(503240); // Vendors can only be placed in houses.
|
||||
}
|
||||
else if (!BaseHouse.NewVendorSystem && !house.IsFriend(from))
|
||||
{
|
||||
from.SendLocalizedMessage(
|
||||
503242); // You must ask the owner of this building to name you a friend of the household in order to place a vendor here.
|
||||
}
|
||||
else if (BaseHouse.NewVendorSystem && !house.IsOwner(from))
|
||||
{
|
||||
from.SendLocalizedMessage(
|
||||
1062423); // Only the house owner can directly place vendors. Please ask the house owner to offer you a vendor contract so that you may place a vendor in this house.
|
||||
}
|
||||
else if (!house.Public || !house.CanPlaceNewVendor())
|
||||
{
|
||||
from.SendLocalizedMessage(
|
||||
503241); // You cannot place this vendor or barkeep. Make sure the house is public and has sufficient storage available.
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseHouse.IsThereVendor(from.Location, from.Map, out bool vendor, out bool contract);
|
||||
|
||||
if (vendor)
|
||||
{
|
||||
from.SendLocalizedMessage(1062677); // You cannot place a vendor or barkeep at this location.
|
||||
}
|
||||
else if (contract)
|
||||
{
|
||||
from.SendLocalizedMessage(
|
||||
1062678); // You cannot place a vendor or barkeep on top of a rental contract!
|
||||
}
|
||||
else
|
||||
{
|
||||
Mobile v = new PlayerVendor(from, house);
|
||||
|
||||
v.Direction = from.Direction & Direction.Mask;
|
||||
v.MoveToWorld(from.Location, from.Map);
|
||||
|
||||
v.SayTo(from, 503246); // Ah! it feels good to be working again.
|
||||
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
95
Projects/Scripts/Items/Misc/PoolOfAcid.cs
Normal file
95
Projects/Scripts/Items/Misc/PoolOfAcid.cs
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
using System;
|
||||
using Server.Mobiles;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class PoolOfAcid : Item
|
||||
{
|
||||
private TimeSpan m_Duration;
|
||||
private int m_MinDamage;
|
||||
private int m_MaxDamage;
|
||||
private DateTime m_Created;
|
||||
private bool m_Drying;
|
||||
private Timer m_Timer;
|
||||
|
||||
[Constructible]
|
||||
public PoolOfAcid() : this( TimeSpan.FromSeconds( 10.0 ), 2, 5 )
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "a pool of acid";
|
||||
|
||||
[Constructible]
|
||||
public PoolOfAcid( TimeSpan duration, int minDamage, int maxDamage )
|
||||
: base( 0x122A )
|
||||
{
|
||||
Hue = 0x3F;
|
||||
Movable = false;
|
||||
|
||||
m_MinDamage = minDamage;
|
||||
m_MaxDamage = maxDamage;
|
||||
m_Created = DateTime.UtcNow;
|
||||
m_Duration = duration;
|
||||
|
||||
m_Timer = Timer.DelayCall( TimeSpan.Zero, TimeSpan.FromSeconds( 1 ), OnTick );
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
m_Timer?.Stop();
|
||||
}
|
||||
|
||||
private void OnTick()
|
||||
{
|
||||
DateTime now = DateTime.UtcNow;
|
||||
TimeSpan age = now - m_Created;
|
||||
|
||||
if ( age > m_Duration ) {
|
||||
Delete();
|
||||
} else {
|
||||
if ( !m_Drying && age > (m_Duration - age) )
|
||||
{
|
||||
m_Drying = true;
|
||||
ItemID = 0x122B;
|
||||
}
|
||||
|
||||
List<Mobile> toDamage = new List<Mobile>();
|
||||
|
||||
foreach( Mobile m in GetMobilesInRange( 0 ) )
|
||||
{
|
||||
if ( m.Alive && !m.IsDeadBondedPet && (!(m is BaseCreature bc) || bc.Controlled || bc.Summoned) )
|
||||
{
|
||||
toDamage.Add( m );
|
||||
}
|
||||
}
|
||||
|
||||
for ( int i = 0; i < toDamage.Count; i++ )
|
||||
Damage( toDamage[i] );
|
||||
}
|
||||
}
|
||||
public override bool OnMoveOver( Mobile m )
|
||||
{
|
||||
Damage( m );
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Damage ( Mobile m )
|
||||
{
|
||||
m.Damage( Utility.RandomMinMax( m_MinDamage, m_MaxDamage ) );
|
||||
}
|
||||
|
||||
public PoolOfAcid( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
//Don't serialize these
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
41
Projects/Scripts/Items/Misc/PowerCrystal.cs
Normal file
41
Projects/Scripts/Items/Misc/PowerCrystal.cs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class PowerCrystal : Item
|
||||
{
|
||||
[Constructible]
|
||||
public PowerCrystal() : base(0x1F1C)
|
||||
{
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
public PowerCrystal(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "power crystal";
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!from.InRange(GetWorldLocation(), 3))
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
|
||||
else
|
||||
from.SendAsciiMessage("This looks like part of a larger contraption.");
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
549
Projects/Scripts/Items/Misc/PowerGenerator.cs
Normal file
549
Projects/Scripts/Items/Misc/PowerGenerator.cs
Normal file
|
|
@ -0,0 +1,549 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class PowerGenerator : BaseAddon
|
||||
{
|
||||
[Constructible]
|
||||
public PowerGenerator() : this(Utility.RandomMinMax(3, 6))
|
||||
{
|
||||
}
|
||||
|
||||
[Constructible]
|
||||
public PowerGenerator(int sideLength)
|
||||
{
|
||||
AddGeneratorComponent(0x4FA1, 0, 0, 0);
|
||||
AddGeneratorComponent(0x76, -1, 0, 0);
|
||||
AddGeneratorComponent(0x75, 0, -1, 0);
|
||||
AddGeneratorComponent(0x37F4, 0, 0, 13);
|
||||
|
||||
AddComponent(new ControlPanel(sideLength), 1, 0, -2);
|
||||
}
|
||||
|
||||
public PowerGenerator(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool ShareHue => false;
|
||||
|
||||
private void AddGeneratorComponent(int itemID, int x, int y, int z)
|
||||
{
|
||||
AddonComponent component = new AddonComponent(itemID);
|
||||
component.Name = "a power generator";
|
||||
component.Hue = 0x451;
|
||||
|
||||
AddComponent(component, x, y, z);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class ControlPanel : AddonComponent
|
||||
{
|
||||
private static readonly TimeSpan m_UseTimeout = TimeSpan.FromMinutes(2.0);
|
||||
|
||||
private HashSet<Mobile> m_DamageTable = new HashSet<Mobile>();
|
||||
private DateTime m_LastUse;
|
||||
|
||||
private int m_SideLength;
|
||||
|
||||
private Mobile m_User;
|
||||
|
||||
public ControlPanel(int sideLength) : base(0xBDC)
|
||||
{
|
||||
Hue = 0x835;
|
||||
|
||||
SideLength = sideLength;
|
||||
}
|
||||
|
||||
public ControlPanel(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int SideLength
|
||||
{
|
||||
get => m_SideLength;
|
||||
set
|
||||
{
|
||||
if (value < 3)
|
||||
value = 3;
|
||||
else if (value > 6)
|
||||
value = 6;
|
||||
|
||||
if (m_SideLength != value)
|
||||
{
|
||||
m_SideLength = value;
|
||||
InitPath();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Node[] Path{ get; private set; }
|
||||
|
||||
public override string DefaultName => "a control panel";
|
||||
|
||||
public void InitPath()
|
||||
{
|
||||
// Depth-First Search algorithm
|
||||
|
||||
int totalNodes = SideLength * SideLength;
|
||||
|
||||
Node[] stack = new Node[totalNodes];
|
||||
Node current = stack[0] = new Node(0, 0);
|
||||
int stackSize = 1;
|
||||
|
||||
bool[,] visited = new bool[SideLength, SideLength];
|
||||
visited[0, 0] = true;
|
||||
|
||||
while (true)
|
||||
{
|
||||
PathDirection[] choices = new PathDirection[4];
|
||||
int count = 0;
|
||||
|
||||
if (current.X > 0 && !visited[current.X - 1, current.Y])
|
||||
choices[count++] = PathDirection.Left;
|
||||
|
||||
if (current.Y > 0 && !visited[current.X, current.Y - 1])
|
||||
choices[count++] = PathDirection.Up;
|
||||
|
||||
if (current.X < SideLength - 1 && !visited[current.X + 1, current.Y])
|
||||
choices[count++] = PathDirection.Right;
|
||||
|
||||
if (current.Y < SideLength - 1 && !visited[current.X, current.Y + 1])
|
||||
choices[count++] = PathDirection.Down;
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
PathDirection dir = choices[Utility.Random(count)];
|
||||
|
||||
switch (dir)
|
||||
{
|
||||
case PathDirection.Left:
|
||||
current = new Node(current.X - 1, current.Y);
|
||||
break;
|
||||
case PathDirection.Up:
|
||||
current = new Node(current.X, current.Y - 1);
|
||||
break;
|
||||
case PathDirection.Right:
|
||||
current = new Node(current.X + 1, current.Y);
|
||||
break;
|
||||
default:
|
||||
current = new Node(current.X, current.Y + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
stack[stackSize++] = current;
|
||||
|
||||
if (current.X == SideLength - 1 && current.Y == SideLength - 1)
|
||||
break;
|
||||
|
||||
visited[current.X, current.Y] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
current = stack[--stackSize - 1];
|
||||
}
|
||||
}
|
||||
|
||||
Path = new Node[stackSize];
|
||||
|
||||
for (int i = 0; i < stackSize; i++) Path[i] = stack[i];
|
||||
|
||||
if (m_User != null)
|
||||
{
|
||||
m_User.CloseGump<GameGump>();
|
||||
m_User = null;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!from.InRange(this, 3))
|
||||
{
|
||||
from.SendLocalizedMessage(500446); // That is too far away.
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_User != null)
|
||||
{
|
||||
if (m_User == from)
|
||||
return;
|
||||
|
||||
if (m_User.Deleted || m_User.Map != Map || !m_User.InRange(this, 3)
|
||||
|| m_User.NetState == null || DateTime.UtcNow - m_LastUse >= m_UseTimeout)
|
||||
{
|
||||
m_User.CloseGump<GameGump>();
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage("Someone is currently using the control panel.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_User = from;
|
||||
m_LastUse = DateTime.UtcNow;
|
||||
|
||||
from.SendGump(new GameGump(this, from, 0, false));
|
||||
}
|
||||
|
||||
public void DoDamage(Mobile to)
|
||||
{
|
||||
to.Send(new UnicodeMessage(Serial, ItemID, MessageType.Regular, 0x3B2, 3, "", "",
|
||||
"The generator shoots an arc of electricity at you!"));
|
||||
to.BoltEffect(0);
|
||||
to.LocalOverheadMessage(MessageType.Regular, 0xC9, true, "* Your body convulses from electric shock *");
|
||||
to.NonlocalOverheadMessage(MessageType.Regular, 0xC9, true, $"* {to.Name} spasms from electric shock *");
|
||||
|
||||
AOS.Damage(to, to, 60, 0, 0, 0, 0, 100);
|
||||
|
||||
if (!to.Alive)
|
||||
return;
|
||||
|
||||
if (!m_DamageTable.Contains(to))
|
||||
{
|
||||
to.Frozen = true;
|
||||
|
||||
DamageTimer timer = new DamageTimer(this, to);
|
||||
m_DamageTable.Add(to);
|
||||
|
||||
timer.Start();
|
||||
}
|
||||
}
|
||||
|
||||
public void Solve(Mobile from)
|
||||
{
|
||||
Effects.PlaySound(Location, Map, 0x211);
|
||||
Effects.PlaySound(Location, Map, 0x1F3);
|
||||
|
||||
Effects.SendLocationEffect(Location, Map, 0x36B0, 4, 4);
|
||||
Effects.SendLocationEffect(new Point3D(X - 1, Y - 1, Z + 2), Map, 0x36B0, 4, 4);
|
||||
Effects.SendLocationEffect(new Point3D(X - 2, Y - 1, Z + 2), Map, 0x36B0, 4, 4);
|
||||
|
||||
from.SendMessage("You scrounge some gems from the wreckage.");
|
||||
|
||||
for (int i = 0; i < SideLength; i++) from.AddToBackpack(new ArcaneGem());
|
||||
|
||||
from.AddToBackpack(new Diamond(SideLength));
|
||||
|
||||
Item ore = new ShadowIronOre(9);
|
||||
ore.MoveToWorld(new Point3D(X - 1, Y, Z + 2), Map);
|
||||
|
||||
ore = new ShadowIronOre(14);
|
||||
ore.MoveToWorld(new Point3D(X - 2, Y - 1, Z + 2), Map);
|
||||
|
||||
Delete();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.WriteEncodedInt(m_SideLength);
|
||||
|
||||
writer.WriteEncodedInt(Path.Length);
|
||||
for (int i = 0; i < Path.Length; i++)
|
||||
{
|
||||
Node cur = Path[i];
|
||||
|
||||
writer.WriteEncodedInt(cur.X);
|
||||
writer.WriteEncodedInt(cur.Y);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
m_SideLength = reader.ReadEncodedInt();
|
||||
|
||||
Path = new Node[reader.ReadEncodedInt()];
|
||||
for (int i = 0; i < Path.Length; i++) Path[i] = new Node(reader.ReadEncodedInt(), reader.ReadEncodedInt());
|
||||
}
|
||||
|
||||
public struct Node
|
||||
{
|
||||
public int X{ get; set; }
|
||||
|
||||
public int Y{ get; set; }
|
||||
|
||||
public Node(int x, int y)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
}
|
||||
|
||||
private enum PathDirection
|
||||
{
|
||||
Left,
|
||||
Up,
|
||||
Right,
|
||||
Down
|
||||
}
|
||||
|
||||
private class GameGump : Gump
|
||||
{
|
||||
private Mobile m_From;
|
||||
|
||||
private ControlPanel m_Panel;
|
||||
private int m_Step;
|
||||
|
||||
public GameGump(ControlPanel panel, Mobile from, int step, bool hint) : base(5, 30)
|
||||
{
|
||||
m_Panel = panel;
|
||||
m_From = from;
|
||||
m_Step = step;
|
||||
|
||||
int sideLength = panel.SideLength;
|
||||
|
||||
AddBackground(50, 0, 530, 410, 0xA28);
|
||||
|
||||
AddImage(0, 0, 0x28C8);
|
||||
AddImage(547, 0, 0x28C9);
|
||||
|
||||
AddBackground(95, 20, 442, 90, 0xA28);
|
||||
|
||||
AddHtml(229, 35, 300, 45, "GENERATOR CONTROL PANEL");
|
||||
|
||||
AddHtml(223, 60, 300, 70, "Use the Directional Controls to");
|
||||
AddHtml(253, 75, 300, 85, "Close the Grid Circuit");
|
||||
|
||||
AddImage(140, 40, 0x28D3);
|
||||
AddImage(420, 40, 0x28D3);
|
||||
|
||||
AddBackground(365, 120, 178, 210, 0x1400);
|
||||
|
||||
AddImage(365, 115, 0x28D4);
|
||||
AddImage(365, 288, 0x28D4);
|
||||
|
||||
AddImage(414, 189, 0x589);
|
||||
AddImage(435, 210, 0xA52);
|
||||
|
||||
AddButton(408, 222, 0x29EA, 0x29EC, 1); // Left
|
||||
AddButton(448, 185, 0x29CC, 0x29CE, 2); // Up
|
||||
AddButton(473, 222, 0x29D6, 0x29D8, 3); // Right
|
||||
AddButton(448, 243, 0x29E0, 0x29E2, 4); // Down
|
||||
|
||||
AddBackground(90, 115, 30 + 40 * sideLength, 30 + 40 * sideLength, 0xA28);
|
||||
AddBackground(100, 125, 10 + 40 * sideLength, 10 + 40 * sideLength, 0x1400);
|
||||
|
||||
for (int i = 0; i < sideLength; i++)
|
||||
for (int j = 0; j < sideLength - 1; j++)
|
||||
AddImage(120 + 40 * i, 162 + 40 * j, 0x13F9);
|
||||
|
||||
for (int i = 0; i < sideLength - 1; i++)
|
||||
for (int j = 0; j < sideLength; j++)
|
||||
AddImage(138 + 40 * i, 147 + 40 * j, 0x13FD);
|
||||
|
||||
Node[] path = panel.Path;
|
||||
|
||||
NodeHue[,] hues = new NodeHue[sideLength, sideLength];
|
||||
|
||||
for (int i = 0; i <= step; i++)
|
||||
{
|
||||
Node n = path[i];
|
||||
hues[n.X, n.Y] = NodeHue.Blue;
|
||||
}
|
||||
|
||||
Node lastNode = path[path.Length - 1];
|
||||
hues[lastNode.X, lastNode.Y] = NodeHue.Red;
|
||||
|
||||
for (int i = 0; i < sideLength; i++)
|
||||
for (int j = 0; j < sideLength; j++)
|
||||
AddNode(110 + 40 * i, 135 + 40 * j, hues[i, j]);
|
||||
|
||||
Node curNode = path[step];
|
||||
AddImage(118 + 40 * curNode.X, 143 + 40 * curNode.Y, 0x13A8);
|
||||
|
||||
if (hint)
|
||||
{
|
||||
Node nextNode = path[step + 1];
|
||||
AddImage(119 + 40 * nextNode.X, 143 + 40 * nextNode.Y, 0x939);
|
||||
}
|
||||
|
||||
if (from.Skills.Lockpicking.Value >= 65.0)
|
||||
{
|
||||
AddButton(365, 350, 0xFA6, 0xFA7, 5);
|
||||
AddHtml(405, 345, 140, 40, "Attempt to Decipher the Circuit Path");
|
||||
}
|
||||
}
|
||||
|
||||
private void AddNode(int x, int y, NodeHue hue)
|
||||
{
|
||||
int id;
|
||||
switch (hue)
|
||||
{
|
||||
case NodeHue.Gray:
|
||||
id = 0x25F8;
|
||||
break;
|
||||
case NodeHue.Blue:
|
||||
id = 0x868;
|
||||
break;
|
||||
default:
|
||||
id = 0x9A8;
|
||||
break;
|
||||
}
|
||||
|
||||
AddImage(x, y, id);
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (m_Panel.Deleted || info.ButtonID == 0 || !m_From.CheckAlive())
|
||||
{
|
||||
m_Panel.m_User = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_From.Map != m_Panel.Map || !m_From.InRange(m_Panel, 3))
|
||||
{
|
||||
m_From.SendLocalizedMessage(500446); // That is too far away.
|
||||
m_Panel.m_User = null;
|
||||
return;
|
||||
}
|
||||
|
||||
Node nextNode = m_Panel.Path[m_Step + 1];
|
||||
|
||||
if (info.ButtonID == 5) // Attempt to Decipher
|
||||
{
|
||||
double lockpicking = m_From.Skills.Lockpicking.Value;
|
||||
|
||||
if (lockpicking < 65.0)
|
||||
return;
|
||||
|
||||
m_From.PlaySound(0x241);
|
||||
|
||||
if (40.0 + Utility.RandomDouble() * 80.0 < lockpicking)
|
||||
{
|
||||
m_From.SendGump(new GameGump(m_Panel, m_From, m_Step, true));
|
||||
m_Panel.m_LastUse = DateTime.UtcNow;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Panel.DoDamage(m_From);
|
||||
m_Panel.m_User = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Node curNode = m_Panel.Path[m_Step];
|
||||
|
||||
int newX, newY;
|
||||
switch (info.ButtonID)
|
||||
{
|
||||
case 1: // Left
|
||||
newX = curNode.X - 1;
|
||||
newY = curNode.Y;
|
||||
break;
|
||||
case 2: // Up
|
||||
newX = curNode.X;
|
||||
newY = curNode.Y - 1;
|
||||
break;
|
||||
case 3: // Right
|
||||
newX = curNode.X + 1;
|
||||
newY = curNode.Y;
|
||||
break;
|
||||
case 4: // Down
|
||||
newX = curNode.X;
|
||||
newY = curNode.Y + 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (nextNode.X == newX && nextNode.Y == newY)
|
||||
{
|
||||
if (m_Step + 1 == m_Panel.Path.Length - 1)
|
||||
{
|
||||
m_Panel.Solve(m_From);
|
||||
m_Panel.m_User = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_From.PlaySound(0x1F4);
|
||||
m_From.SendGump(new GameGump(m_Panel, m_From, m_Step + 1, false));
|
||||
m_Panel.m_LastUse = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Panel.DoDamage(m_From);
|
||||
m_Panel.m_User = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private enum NodeHue
|
||||
{
|
||||
Gray,
|
||||
Blue,
|
||||
Red
|
||||
}
|
||||
}
|
||||
|
||||
private class DamageTimer : Timer
|
||||
{
|
||||
private ControlPanel m_Panel;
|
||||
private int m_Step;
|
||||
private Mobile m_To;
|
||||
|
||||
public DamageTimer(ControlPanel panel, Mobile to) : base(TimeSpan.FromSeconds(5.0), TimeSpan.FromSeconds(5.0))
|
||||
{
|
||||
m_Panel = panel;
|
||||
m_To = to;
|
||||
m_Step = 0;
|
||||
|
||||
Priority = TimerPriority.TwoFiftyMS;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if (m_Panel.Deleted || m_To.Deleted || !m_To.Alive)
|
||||
{
|
||||
End();
|
||||
return;
|
||||
}
|
||||
|
||||
m_To.PlaySound(0x28);
|
||||
|
||||
m_To.LocalOverheadMessage(MessageType.Regular, 0xC9, true, "* Your body convulses from electric shock *");
|
||||
m_To.NonlocalOverheadMessage(MessageType.Regular, 0xC9, true,
|
||||
$"* {m_To.Name} spasms from electric shock *");
|
||||
|
||||
AOS.Damage(m_To, m_To, 20, 0, 0, 0, 0, 100);
|
||||
|
||||
if (++m_Step >= 3 || !m_To.Alive) End();
|
||||
}
|
||||
|
||||
private void End()
|
||||
{
|
||||
m_Panel.m_DamageTable.Remove(m_To);
|
||||
m_To.Frozen = false;
|
||||
|
||||
Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class CrystallineFragments : Item
|
||||
{
|
||||
[Constructible]
|
||||
public CrystallineFragments() : base(0x223B)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
Hue = 0x47E;
|
||||
}
|
||||
|
||||
public CrystallineFragments(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1073160; // Crystalline Fragments
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
30
Projects/Scripts/Items/Misc/Prism of Light/IcyHeart.cs
Normal file
30
Projects/Scripts/Items/Misc/Prism of Light/IcyHeart.cs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class IcyHeart : Item
|
||||
{
|
||||
[Constructible]
|
||||
public IcyHeart() : base(0x24B)
|
||||
{
|
||||
}
|
||||
|
||||
public IcyHeart(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1073162; // Icy Heart
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
29
Projects/Scripts/Items/Misc/Prism of Light/LuckyDagger.cs
Normal file
29
Projects/Scripts/Items/Misc/Prism of Light/LuckyDagger.cs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class LuckyDagger : Item
|
||||
{
|
||||
[Constructible]
|
||||
public LuckyDagger() : base(0xF52)
|
||||
{
|
||||
Hue = 0x8A5;
|
||||
}
|
||||
|
||||
public LuckyDagger(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class ProtectorsEssence : Item
|
||||
{
|
||||
[Constructible]
|
||||
public ProtectorsEssence() : base(0x23F)
|
||||
{
|
||||
}
|
||||
|
||||
public ProtectorsEssence(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1073159; // Protector's Essence
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class ShimmeringCrystals : Item
|
||||
{
|
||||
private static readonly int[] m_ItemIDs =
|
||||
{
|
||||
0x2206, 0x2207, 0x2208, 0x2209, 0x220A, 0x220B, 0x220C, 0x220D, 0x220E,
|
||||
0x2210, 0x2211, 0x2212, 0x2213, 0x2214, 0x2215, 0x2216, 0x2217, 0x2218,
|
||||
0x221A, 0x221B, 0x221C, 0x221D, 0x221E, 0x221F, 0x2220, 0x2221, 0x2222,
|
||||
0x2224, 0x2225, 0x2226, 0x2227, 0x2228, 0x2229, 0x222A, 0x222B, 0x222C
|
||||
};
|
||||
|
||||
[Constructible]
|
||||
public ShimmeringCrystals() : base(Utility.RandomList(m_ItemIDs))
|
||||
{
|
||||
}
|
||||
|
||||
public ShimmeringCrystals(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1075095; // Shimmering Crystals
|
||||
public override bool ForceShowProperties => true;
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
156
Projects/Scripts/Items/Misc/PromotionalToken.cs
Normal file
156
Projects/Scripts/Items/Misc/PromotionalToken.cs
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public abstract class PromotionalToken : Item
|
||||
{
|
||||
public abstract Item CreateItemFor( Mobile from );
|
||||
|
||||
public abstract TextDefinition ItemName{ get; }
|
||||
public abstract TextDefinition ItemReceiveMessage { get; }
|
||||
public abstract TextDefinition ItemGumpName { get; }
|
||||
|
||||
public PromotionalToken() : base( 0x2AAA )
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
Light = LightType.Circle300;
|
||||
Weight = 5.0;
|
||||
}
|
||||
|
||||
public PromotionalToken( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void GetProperties( ObjectPropertyList list )
|
||||
{
|
||||
base.GetProperties( list );
|
||||
|
||||
list.Add( 1070998, ItemName.ToString() ); // Use this to redeem<br>your ~1_PROMO~
|
||||
}
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
if ( !IsChildOf( from.Backpack ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1062334 ); // This item must be in your backpack to be used.
|
||||
}
|
||||
else
|
||||
{
|
||||
from.CloseGump<PromotionalTokenGump>();
|
||||
from.SendGump( new PromotionalTokenGump( this ) );
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnRemoved(IEntity parent)
|
||||
{
|
||||
Mobile m = null;
|
||||
|
||||
if ( parent is Item item )
|
||||
m = item.RootParent as Mobile;
|
||||
else if ( parent is Mobile mobile )
|
||||
m = mobile;
|
||||
|
||||
m?.CloseGump<PromotionalTokenGump>();
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( 0 );
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1070997; // A promotional token
|
||||
|
||||
|
||||
private class PromotionalTokenGump : Gump
|
||||
{
|
||||
private PromotionalToken m_Token;
|
||||
|
||||
public PromotionalTokenGump( PromotionalToken token ) : base( 10, 10 )
|
||||
{
|
||||
m_Token = token;
|
||||
|
||||
AddPage( 0 );
|
||||
|
||||
AddBackground( 0, 0, 240, 135, 0x2422 );
|
||||
AddHtmlLocalized( 15, 15, 210, 75, 1070972, 0x0, true ); // Click "OKAY" to redeem the following promotional item:
|
||||
TextDefinition.AddHtmlText( this, 15, 60, 210, 75, m_Token.ItemGumpName, false, false );
|
||||
|
||||
AddButton( 160, 95, 0xF7, 0xF8, 1); //Okay
|
||||
AddButton( 90, 95, 0xF2, 0xF1, 0); //Cancel
|
||||
}
|
||||
|
||||
public override void OnResponse( NetState sender, RelayInfo info )
|
||||
{
|
||||
if ( info.ButtonID != 1 )
|
||||
return;
|
||||
|
||||
Mobile from = sender.Mobile;
|
||||
|
||||
if ( !m_Token.IsChildOf( from.Backpack ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1062334 ); // This item must be in your backpack to be used.
|
||||
}
|
||||
else
|
||||
{
|
||||
Item i = m_Token.CreateItemFor( from );
|
||||
|
||||
if ( i != null )
|
||||
{
|
||||
from.BankBox.AddItem( i );
|
||||
TextDefinition.SendMessageTo( from, m_Token.ItemReceiveMessage );
|
||||
m_Token.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SoulstoneFragmentToken : PromotionalToken
|
||||
{
|
||||
|
||||
public override Item CreateItemFor( Mobile from )
|
||||
{
|
||||
if ( from?.Account != null )
|
||||
return new SoulstoneFragment( from.Account.ToString() );
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public override TextDefinition ItemGumpName => 1070999;// <center>Soulstone Fragment</center>
|
||||
public override TextDefinition ItemName => 1071000;//soulstone fragment
|
||||
public override TextDefinition ItemReceiveMessage => 1070976; // A soulstone fragment has been created in your bank box.
|
||||
|
||||
[Constructible]
|
||||
public SoulstoneFragmentToken()
|
||||
{
|
||||
}
|
||||
|
||||
public SoulstoneFragmentToken( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( 0 );
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
421
Projects/Scripts/Items/Misc/PublicMoongate.cs
Normal file
421
Projects/Scripts/Items/Misc/PublicMoongate.cs
Normal file
|
|
@ -0,0 +1,421 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Commands;
|
||||
using Server.Factions;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
using Server.Spells;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class PublicMoongate : Item
|
||||
{
|
||||
[Constructible]
|
||||
public PublicMoongate() : base(0xF6C)
|
||||
{
|
||||
Movable = false;
|
||||
Light = LightType.Circle300;
|
||||
}
|
||||
|
||||
public PublicMoongate(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool ForceShowProperties => ObjectPropertyList.Enabled;
|
||||
|
||||
public override bool HandlesOnMovement => true;
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!from.Player)
|
||||
return;
|
||||
|
||||
if (from.InRange(GetWorldLocation(), 1))
|
||||
UseGate(from);
|
||||
else
|
||||
from.SendLocalizedMessage(500446); // That is too far away.
|
||||
}
|
||||
|
||||
public override bool OnMoveOver(Mobile m)
|
||||
{
|
||||
// Changed so criminals are not blocked by it.
|
||||
if (m.Player)
|
||||
UseGate(m);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void OnMovement(Mobile m, Point3D oldLocation)
|
||||
{
|
||||
if (m is PlayerMobile)
|
||||
if (!Utility.InRange(m.Location, Location, 1) && Utility.InRange(oldLocation, Location, 1))
|
||||
m.CloseGump<MoongateGump>();
|
||||
}
|
||||
|
||||
public bool UseGate(Mobile m)
|
||||
{
|
||||
if (m.Criminal)
|
||||
{
|
||||
m.SendLocalizedMessage(1005561, "", 0x22); // Thou'rt a criminal and cannot escape so easily.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SpellHelper.CheckCombat(m))
|
||||
{
|
||||
m.SendLocalizedMessage(1005564, "", 0x22); // Wouldst thou flee during the heat of battle??
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m.Spell != null)
|
||||
{
|
||||
m.SendLocalizedMessage(1049616); // You are too busy to do that at the moment.
|
||||
return false;
|
||||
}
|
||||
|
||||
m.CloseGump<MoongateGump>();
|
||||
m.SendGump(new MoongateGump(m, this));
|
||||
|
||||
if (!m.Hidden || m.AccessLevel == AccessLevel.Player)
|
||||
Effects.PlaySound(m.Location, m.Map, 0x20E);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("MoonGen", AccessLevel.Administrator, MoonGen_OnCommand);
|
||||
}
|
||||
|
||||
[Usage("MoonGen")]
|
||||
[Description("Generates public moongates. Removes all old moongates.")]
|
||||
public static void MoonGen_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
DeleteAll();
|
||||
|
||||
int count = 0;
|
||||
|
||||
count += MoonGen(PMList.Trammel);
|
||||
count += MoonGen(PMList.Felucca);
|
||||
count += MoonGen(PMList.Ilshenar);
|
||||
count += MoonGen(PMList.Malas);
|
||||
count += MoonGen(PMList.Tokuno);
|
||||
|
||||
World.Broadcast(0x35, true, "{0} moongates generated.", count);
|
||||
}
|
||||
|
||||
private static void DeleteAll()
|
||||
{
|
||||
List<Item> list = new List<Item>();
|
||||
|
||||
foreach (Item item in World.Items.Values)
|
||||
if (item is PublicMoongate)
|
||||
list.Add(item);
|
||||
|
||||
foreach (Item item in list)
|
||||
item.Delete();
|
||||
|
||||
if (list.Count > 0)
|
||||
World.Broadcast(0x35, true, "{0} moongates removed.", list.Count);
|
||||
}
|
||||
|
||||
private static int MoonGen(PMList list)
|
||||
{
|
||||
foreach (PMEntry entry in list.Entries)
|
||||
{
|
||||
Item item = new PublicMoongate();
|
||||
|
||||
item.MoveToWorld(entry.Location, list.Map);
|
||||
|
||||
if (entry.Number == 1060642) // Umbra
|
||||
item.Hue = 0x497;
|
||||
}
|
||||
|
||||
return list.Entries.Length;
|
||||
}
|
||||
}
|
||||
|
||||
public class PMEntry
|
||||
{
|
||||
public PMEntry(Point3D loc, int number)
|
||||
{
|
||||
Location = loc;
|
||||
Number = number;
|
||||
}
|
||||
|
||||
public Point3D Location{ get; }
|
||||
|
||||
public int Number{ get; }
|
||||
}
|
||||
|
||||
public class PMList
|
||||
{
|
||||
public static readonly PMList Trammel =
|
||||
new PMList(1012000, 1012012, Map.Trammel, new[]
|
||||
{
|
||||
new PMEntry(new Point3D(4467, 1283, 5), 1012003), // Moonglow
|
||||
new PMEntry(new Point3D(1336, 1997, 5), 1012004), // Britain
|
||||
new PMEntry(new Point3D(1499, 3771, 5), 1012005), // Jhelom
|
||||
new PMEntry(new Point3D(771, 752, 5), 1012006), // Yew
|
||||
new PMEntry(new Point3D(2701, 692, 5), 1012007), // Minoc
|
||||
new PMEntry(new Point3D(1828, 2948, -20), 1012008), // Trinsic
|
||||
new PMEntry(new Point3D(643, 2067, 5), 1012009), // Skara Brae
|
||||
/* Dynamic Z for Magincia to support both old and new maps. */
|
||||
new PMEntry(new Point3D(3563, 2139, Map.Trammel.GetAverageZ(3563, 2139)), 1012010), // (New) Magincia
|
||||
new PMEntry(new Point3D(3450, 2677, 25), 1078098) // New Haven
|
||||
});
|
||||
|
||||
public static readonly PMList Felucca =
|
||||
new PMList(1012001, 1012013, Map.Felucca, new[]
|
||||
{
|
||||
new PMEntry(new Point3D(4467, 1283, 5), 1012003), // Moonglow
|
||||
new PMEntry(new Point3D(1336, 1997, 5), 1012004), // Britain
|
||||
new PMEntry(new Point3D(1499, 3771, 5), 1012005), // Jhelom
|
||||
new PMEntry(new Point3D(771, 752, 5), 1012006), // Yew
|
||||
new PMEntry(new Point3D(2701, 692, 5), 1012007), // Minoc
|
||||
new PMEntry(new Point3D(1828, 2948, -20), 1012008), // Trinsic
|
||||
new PMEntry(new Point3D(643, 2067, 5), 1012009), // Skara Brae
|
||||
/* Dynamic Z for Magincia to support both old and new maps. */
|
||||
new PMEntry(new Point3D(3563, 2139, Map.Felucca.GetAverageZ(3563, 2139)), 1012010), // (New) Magincia
|
||||
new PMEntry(new Point3D(2711, 2234, 0), 1019001) // Buccaneer's Den
|
||||
});
|
||||
|
||||
public static readonly PMList Ilshenar =
|
||||
new PMList(1012002, 1012014, Map.Ilshenar, new[]
|
||||
{
|
||||
new PMEntry(new Point3D(1215, 467, -13), 1012015), // Compassion
|
||||
new PMEntry(new Point3D(722, 1366, -60), 1012016), // Honesty
|
||||
new PMEntry(new Point3D(744, 724, -28), 1012017), // Honor
|
||||
new PMEntry(new Point3D(281, 1016, 0), 1012018), // Humility
|
||||
new PMEntry(new Point3D(987, 1011, -32), 1012019), // Justice
|
||||
new PMEntry(new Point3D(1174, 1286, -30), 1012020), // Sacrifice
|
||||
new PMEntry(new Point3D(1532, 1340, -3), 1012021), // Spirituality
|
||||
new PMEntry(new Point3D(528, 216, -45), 1012022), // Valor
|
||||
new PMEntry(new Point3D(1721, 218, 96), 1019000) // Chaos
|
||||
});
|
||||
|
||||
public static readonly PMList Malas =
|
||||
new PMList(1060643, 1062039, Map.Malas, new[]
|
||||
{
|
||||
new PMEntry(new Point3D(1015, 527, -65), 1060641), // Luna
|
||||
new PMEntry(new Point3D(1997, 1386, -85), 1060642) // Umbra
|
||||
});
|
||||
|
||||
public static readonly PMList Tokuno =
|
||||
new PMList(1063258, 1063415, Map.Tokuno, new[]
|
||||
{
|
||||
new PMEntry(new Point3D(1169, 998, 41), 1063412), // Isamu-Jima
|
||||
new PMEntry(new Point3D(802, 1204, 25), 1063413), // Makoto-Jima
|
||||
new PMEntry(new Point3D(270, 628, 15), 1063414) // Homare-Jima
|
||||
});
|
||||
|
||||
public static readonly PMList[] UORLists = { Trammel, Felucca };
|
||||
public static readonly PMList[] UORListsYoung = { Trammel };
|
||||
public static readonly PMList[] LBRLists = { Trammel, Felucca, Ilshenar };
|
||||
public static readonly PMList[] LBRListsYoung = { Trammel, Ilshenar };
|
||||
public static readonly PMList[] AOSLists = { Trammel, Felucca, Ilshenar, Malas };
|
||||
public static readonly PMList[] AOSListsYoung = { Trammel, Ilshenar, Malas };
|
||||
public static readonly PMList[] SELists = { Trammel, Felucca, Ilshenar, Malas, Tokuno };
|
||||
public static readonly PMList[] SEListsYoung = { Trammel, Ilshenar, Malas, Tokuno };
|
||||
public static readonly PMList[] RedLists = { Felucca };
|
||||
public static readonly PMList[] SigilLists = { Felucca };
|
||||
|
||||
public PMList(int number, int selNumber, Map map, PMEntry[] entries)
|
||||
{
|
||||
Number = number;
|
||||
SelNumber = selNumber;
|
||||
Map = map;
|
||||
Entries = entries;
|
||||
}
|
||||
|
||||
public int Number{ get; }
|
||||
|
||||
public int SelNumber{ get; }
|
||||
|
||||
public Map Map{ get; }
|
||||
|
||||
public PMEntry[] Entries{ get; }
|
||||
}
|
||||
|
||||
public class MoongateGump : Gump
|
||||
{
|
||||
private PMList[] m_Lists;
|
||||
private Mobile m_Mobile;
|
||||
private Item m_Moongate;
|
||||
|
||||
public MoongateGump(Mobile mobile, Item moongate) : base(100, 100)
|
||||
{
|
||||
m_Mobile = mobile;
|
||||
m_Moongate = moongate;
|
||||
|
||||
PMList[] checkLists;
|
||||
|
||||
if (mobile.Player)
|
||||
{
|
||||
if (Sigil.ExistsOn(mobile))
|
||||
{
|
||||
checkLists = PMList.SigilLists;
|
||||
}
|
||||
else if (mobile.Kills >= 5)
|
||||
{
|
||||
checkLists = PMList.RedLists;
|
||||
}
|
||||
else
|
||||
{
|
||||
ClientFlags flags = mobile.NetState?.Flags ?? ClientFlags.None;
|
||||
bool young = mobile is PlayerMobile playerMobile && playerMobile.Young;
|
||||
|
||||
if (Core.SE && (flags & ClientFlags.Tokuno) != 0)
|
||||
checkLists = young ? PMList.SEListsYoung : PMList.SELists;
|
||||
else if (Core.AOS && (flags & ClientFlags.Malas) != 0)
|
||||
checkLists = young ? PMList.AOSListsYoung : PMList.AOSLists;
|
||||
else if ((flags & ClientFlags.Ilshenar) != 0)
|
||||
checkLists = young ? PMList.LBRListsYoung : PMList.LBRLists;
|
||||
else
|
||||
checkLists = young ? PMList.UORListsYoung : PMList.UORLists;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
checkLists = PMList.SELists;
|
||||
}
|
||||
|
||||
m_Lists = new PMList[checkLists.Length];
|
||||
|
||||
for (int i = 0; i < m_Lists.Length; ++i)
|
||||
m_Lists[i] = checkLists[i];
|
||||
|
||||
for (int i = 0; i < m_Lists.Length; ++i)
|
||||
if (m_Lists[i].Map == mobile.Map)
|
||||
{
|
||||
PMList temp = m_Lists[i];
|
||||
|
||||
m_Lists[i] = m_Lists[0];
|
||||
m_Lists[0] = temp;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
AddPage(0);
|
||||
|
||||
AddBackground(0, 0, 380, 280, 5054);
|
||||
|
||||
AddButton(10, 210, 4005, 4007, 1);
|
||||
AddHtmlLocalized(45, 210, 140, 25, 1011036); // OKAY
|
||||
|
||||
AddButton(10, 235, 4005, 4007, 0);
|
||||
AddHtmlLocalized(45, 235, 140, 25, 1011012); // CANCEL
|
||||
|
||||
AddHtmlLocalized(5, 5, 200, 20, 1012011); // Pick your destination:
|
||||
|
||||
for (int i = 0; i < checkLists.Length; ++i)
|
||||
{
|
||||
AddButton(10, 35 + i * 25, 2117, 2118, 0, GumpButtonType.Page, Array.IndexOf(m_Lists, checkLists[i]) + 1);
|
||||
AddHtmlLocalized(30, 35 + i * 25, 150, 20, checkLists[i].Number);
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_Lists.Length; ++i)
|
||||
RenderPage(i, Array.IndexOf(checkLists, m_Lists[i]));
|
||||
}
|
||||
|
||||
private void RenderPage(int index, int offset)
|
||||
{
|
||||
PMList list = m_Lists[index];
|
||||
|
||||
AddPage(index + 1);
|
||||
|
||||
AddButton(10, 35 + offset * 25, 2117, 2118, 0, GumpButtonType.Page, index + 1);
|
||||
AddHtmlLocalized(30, 35 + offset * 25, 150, 20, list.SelNumber);
|
||||
|
||||
PMEntry[] entries = list.Entries;
|
||||
|
||||
for (int i = 0; i < entries.Length; ++i)
|
||||
{
|
||||
AddRadio(200, 35 + i * 25, 210, 211, false, index * 100 + i);
|
||||
AddHtmlLocalized(225, 35 + i * 25, 150, 20, entries[i].Number);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState state, RelayInfo info)
|
||||
{
|
||||
if (info.ButtonID == 0) // Cancel
|
||||
return;
|
||||
if (m_Mobile.Deleted || m_Moongate.Deleted || m_Mobile.Map == null)
|
||||
return;
|
||||
|
||||
int[] switches = info.Switches;
|
||||
|
||||
if (switches.Length == 0)
|
||||
return;
|
||||
|
||||
int switchID = switches[0];
|
||||
int listIndex = switchID / 100;
|
||||
int listEntry = switchID % 100;
|
||||
|
||||
if (listIndex < 0 || listIndex >= m_Lists.Length)
|
||||
return;
|
||||
|
||||
PMList list = m_Lists[listIndex];
|
||||
|
||||
if (listEntry < 0 || listEntry >= list.Entries.Length)
|
||||
return;
|
||||
|
||||
PMEntry entry = list.Entries[listEntry];
|
||||
|
||||
if (!m_Mobile.InRange(m_Moongate.GetWorldLocation(), 1) || m_Mobile.Map != m_Moongate.Map)
|
||||
{
|
||||
m_Mobile.SendLocalizedMessage(1019002); // You are too far away to use the gate.
|
||||
}
|
||||
else if (m_Mobile.Player && m_Mobile.Kills >= 5 && list.Map != Map.Felucca)
|
||||
{
|
||||
m_Mobile.SendLocalizedMessage(1019004); // You are not allowed to travel there.
|
||||
}
|
||||
else if (Sigil.ExistsOn(m_Mobile) && list.Map != Faction.Facet)
|
||||
{
|
||||
m_Mobile.SendLocalizedMessage(1019004); // You are not allowed to travel there.
|
||||
}
|
||||
else if (m_Mobile.Criminal)
|
||||
{
|
||||
m_Mobile.SendLocalizedMessage(1005561, "", 0x22); // Thou'rt a criminal and cannot escape so easily.
|
||||
}
|
||||
else if (SpellHelper.CheckCombat(m_Mobile))
|
||||
{
|
||||
m_Mobile.SendLocalizedMessage(1005564, "", 0x22); // Wouldst thou flee during the heat of battle??
|
||||
}
|
||||
else if (m_Mobile.Spell != null)
|
||||
{
|
||||
m_Mobile.SendLocalizedMessage(1049616); // You are too busy to do that at the moment.
|
||||
}
|
||||
else if (m_Mobile.Map == list.Map && m_Mobile.InRange(entry.Location, 1))
|
||||
{
|
||||
m_Mobile.SendLocalizedMessage(1019003); // You are already there.
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseCreature.TeleportPets(m_Mobile, entry.Location, list.Map);
|
||||
|
||||
m_Mobile.Combatant = null;
|
||||
m_Mobile.Warmode = false;
|
||||
m_Mobile.Hidden = true;
|
||||
|
||||
m_Mobile.MoveToWorld(entry.Location, list.Map);
|
||||
|
||||
Effects.PlaySound(entry.Location, list.Map, 0x1FE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
662
Projects/Scripts/Items/Misc/Rares.cs
Normal file
662
Projects/Scripts/Items/Misc/Rares.cs
Normal file
|
|
@ -0,0 +1,662 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class Rope : Item
|
||||
{
|
||||
[Constructible]
|
||||
public Rope(int amount = 1) : base(0x14F8)
|
||||
{
|
||||
Stackable = true;
|
||||
Weight = 1.0;
|
||||
Amount = amount;
|
||||
}
|
||||
|
||||
|
||||
public Rope(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class IronWire : Item
|
||||
{
|
||||
[Constructible]
|
||||
public IronWire(int amount = 1) : base(0x1876)
|
||||
{
|
||||
Stackable = true;
|
||||
Weight = 5.0;
|
||||
Amount = amount;
|
||||
}
|
||||
|
||||
|
||||
public IronWire(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if (version < 1 && Weight == 2.0)
|
||||
Weight = 5.0;
|
||||
}
|
||||
}
|
||||
|
||||
public class SilverWire : Item
|
||||
{
|
||||
[Constructible]
|
||||
public SilverWire(int amount = 1) : base(0x1877)
|
||||
{
|
||||
Stackable = true;
|
||||
Weight = 5.0;
|
||||
Amount = amount;
|
||||
}
|
||||
|
||||
|
||||
public SilverWire(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if (version < 1 && Weight == 2.0)
|
||||
Weight = 5.0;
|
||||
}
|
||||
}
|
||||
|
||||
public class GoldWire : Item
|
||||
{
|
||||
[Constructible]
|
||||
public GoldWire(int amount = 1) : base(0x1878)
|
||||
{
|
||||
Stackable = true;
|
||||
Weight = 5.0;
|
||||
Amount = amount;
|
||||
}
|
||||
|
||||
|
||||
public GoldWire(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if (version < 1 && Weight == 2.0)
|
||||
Weight = 5.0;
|
||||
}
|
||||
}
|
||||
|
||||
public class CopperWire : Item
|
||||
{
|
||||
[Constructible]
|
||||
public CopperWire(int amount = 1) : base(0x1879)
|
||||
{
|
||||
Stackable = true;
|
||||
Weight = 5.0;
|
||||
Amount = amount;
|
||||
}
|
||||
|
||||
|
||||
public CopperWire(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if (version < 1 && Weight == 2.0)
|
||||
Weight = 5.0;
|
||||
}
|
||||
}
|
||||
|
||||
public class WhiteDriedFlowers : Item
|
||||
{
|
||||
[Constructible]
|
||||
public WhiteDriedFlowers(int amount = 1) : base(0xC3C)
|
||||
{
|
||||
Stackable = true;
|
||||
Weight = 1.0;
|
||||
Amount = amount;
|
||||
}
|
||||
|
||||
|
||||
public WhiteDriedFlowers(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class GreenDriedFlowers : Item
|
||||
{
|
||||
[Constructible]
|
||||
public GreenDriedFlowers(int amount = 1) : base(0xC3E)
|
||||
{
|
||||
Stackable = true;
|
||||
Weight = 1.0;
|
||||
Amount = amount;
|
||||
}
|
||||
|
||||
|
||||
public GreenDriedFlowers(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class DriedOnions : Item
|
||||
{
|
||||
[Constructible]
|
||||
public DriedOnions(int amount = 1) : base(0xC40)
|
||||
{
|
||||
Stackable = true;
|
||||
Weight = 1.0;
|
||||
Amount = amount;
|
||||
}
|
||||
|
||||
|
||||
public DriedOnions(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class DriedHerbs : Item
|
||||
{
|
||||
[Constructible]
|
||||
public DriedHerbs(int amount = 1) : base(0xC42)
|
||||
{
|
||||
Stackable = true;
|
||||
Weight = 1.0;
|
||||
Amount = amount;
|
||||
}
|
||||
|
||||
|
||||
public DriedHerbs(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class HorseShoes : Item
|
||||
{
|
||||
[Constructible]
|
||||
public HorseShoes() : base(0xFB6)
|
||||
{
|
||||
Weight = 3.0;
|
||||
}
|
||||
|
||||
public HorseShoes(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class ForgedMetal : Item
|
||||
{
|
||||
[Constructible]
|
||||
public ForgedMetal() : base(0xFB8)
|
||||
{
|
||||
Weight = 5.0;
|
||||
}
|
||||
|
||||
public ForgedMetal(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class Whip : Item
|
||||
{
|
||||
[Constructible]
|
||||
public Whip() : base(0x166E)
|
||||
{
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
public Whip(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class PaintsAndBrush : Item
|
||||
{
|
||||
[Constructible]
|
||||
public PaintsAndBrush() : base(0xFC1)
|
||||
{
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
public PaintsAndBrush(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class PenAndInk : Item
|
||||
{
|
||||
[Constructible]
|
||||
public PenAndInk() : base(0xFBF)
|
||||
{
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
public PenAndInk(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class ChiselsNorth : Item
|
||||
{
|
||||
[Constructible]
|
||||
public ChiselsNorth() : base(0x1026)
|
||||
{
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
public ChiselsNorth(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class ChiselsWest : Item
|
||||
{
|
||||
[Constructible]
|
||||
public ChiselsWest() : base(0x1027)
|
||||
{
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
public ChiselsWest(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class DirtyPan : Item
|
||||
{
|
||||
[Constructible]
|
||||
public DirtyPan() : base(0x9E8)
|
||||
{
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
public DirtyPan(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class DirtySmallRoundPot : Item
|
||||
{
|
||||
[Constructible]
|
||||
public DirtySmallRoundPot() : base(0x9E7)
|
||||
{
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
public DirtySmallRoundPot(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class DirtyPot : Item
|
||||
{
|
||||
[Constructible]
|
||||
public DirtyPot() : base(0x9E6)
|
||||
{
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
public DirtyPot(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class DirtyRoundPot : Item
|
||||
{
|
||||
[Constructible]
|
||||
public DirtyRoundPot() : base(0x9DF)
|
||||
{
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
public DirtyRoundPot(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class DirtyFrypan : Item
|
||||
{
|
||||
[Constructible]
|
||||
public DirtyFrypan() : base(0x9DE)
|
||||
{
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
public DirtyFrypan(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class DirtySmallPot : Item
|
||||
{
|
||||
[Constructible]
|
||||
public DirtySmallPot() : base(0x9DD)
|
||||
{
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
public DirtySmallPot(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class DirtyKettle : Item
|
||||
{
|
||||
[Constructible]
|
||||
public DirtyKettle() : base(0x9DC)
|
||||
{
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
public DirtyKettle(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
87
Projects/Scripts/Items/Misc/Scales.cs
Normal file
87
Projects/Scripts/Items/Misc/Scales.cs
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
using Server.Targeting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class Scales : Item
|
||||
{
|
||||
[Constructible]
|
||||
public Scales() : base(0x1852)
|
||||
{
|
||||
Weight = 4.0;
|
||||
}
|
||||
|
||||
public Scales(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
from.SendLocalizedMessage(502431); // What would you like to weigh?
|
||||
from.Target = new InternalTarget(this);
|
||||
}
|
||||
|
||||
private class InternalTarget : Target
|
||||
{
|
||||
private Scales m_Item;
|
||||
|
||||
public InternalTarget(Scales item) : base(1, false, TargetFlags.None)
|
||||
{
|
||||
m_Item = item;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
string message;
|
||||
|
||||
if (targeted == m_Item)
|
||||
{
|
||||
message = "It cannot weight itself.";
|
||||
}
|
||||
else if (targeted is Item item)
|
||||
{
|
||||
IEntity root = item.RootParent;
|
||||
|
||||
if (root != null && root != from || item.Parent == from)
|
||||
{
|
||||
message = "You decide that item's current location is too awkward to get an accurate result.";
|
||||
}
|
||||
else if (item.Movable)
|
||||
{
|
||||
message = item.Amount > 1 ? "You place one item on the scale. " : "You place that item on the scale. ";
|
||||
|
||||
double weight = item.Weight;
|
||||
|
||||
if (weight <= 0.0)
|
||||
message += "It is lighter than a feather.";
|
||||
else
|
||||
message += $"It weighs {weight} stones.";
|
||||
}
|
||||
else
|
||||
{
|
||||
message = "You cannot weigh that object.";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
message = "You cannot weigh that object.";
|
||||
}
|
||||
|
||||
from.SendMessage(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
103
Projects/Scripts/Items/Misc/SerpentPillar.cs
Normal file
103
Projects/Scripts/Items/Misc/SerpentPillar.cs
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
using Server.Multis;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class SerpentPillar : Item
|
||||
{
|
||||
[Constructible]
|
||||
public SerpentPillar() : this(null, new Rectangle2D(), false)
|
||||
{
|
||||
}
|
||||
|
||||
public SerpentPillar(string word, Rectangle2D destination, bool active = true) : base(0x233F)
|
||||
{
|
||||
Movable = false;
|
||||
|
||||
Active = active;
|
||||
Word = word;
|
||||
Destination = destination;
|
||||
}
|
||||
|
||||
public SerpentPillar(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool Active{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string Word{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Rectangle2D Destination{ get; set; }
|
||||
|
||||
public override bool HandlesOnSpeech => true;
|
||||
|
||||
public override void OnSpeech(SpeechEventArgs e)
|
||||
{
|
||||
Mobile from = e.Mobile;
|
||||
|
||||
if (!e.Handled && from.InRange(this, 10) && e.Speech.ToLower() == Word)
|
||||
{
|
||||
BaseBoat boat = BaseBoat.FindBoatAt(from, from.Map);
|
||||
|
||||
if (boat == null)
|
||||
return;
|
||||
|
||||
if (!Active)
|
||||
{
|
||||
boat.TillerMan
|
||||
?.Say(502507); // Ar, Legend has it that these pillars are inactive! No man knows how it might be undone!
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Map map = from.Map;
|
||||
|
||||
for (int i = 0; i < 5; i++) // Try 5 times
|
||||
{
|
||||
int x = Utility.Random(Destination.X, Destination.Width);
|
||||
int y = Utility.Random(Destination.Y, Destination.Height);
|
||||
int z = map.GetAverageZ(x, y);
|
||||
|
||||
Point3D dest = new Point3D(x, y, z);
|
||||
|
||||
if (boat.CanFit(dest, map, boat.ItemID))
|
||||
{
|
||||
int xOffset = x - boat.X;
|
||||
int yOffset = y - boat.Y;
|
||||
int zOffset = z - boat.Z;
|
||||
|
||||
boat.Teleport(xOffset, yOffset, zOffset);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
boat.TillerMan?.Say(502508); // Ar, I refuse to take that matey through here!
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.Write(Active);
|
||||
writer.Write(Word);
|
||||
writer.Write(Destination);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
Active = reader.ReadBool();
|
||||
Word = reader.ReadString();
|
||||
Destination = reader.ReadRect2D();
|
||||
}
|
||||
}
|
||||
}
|
||||
162
Projects/Scripts/Items/Misc/SpecialBeardDye.cs
Normal file
162
Projects/Scripts/Items/Misc/SpecialBeardDye.cs
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class SpecialBeardDye : Item
|
||||
{
|
||||
[Constructible]
|
||||
public SpecialBeardDye() : base(0xE26)
|
||||
{
|
||||
Weight = 1.0;
|
||||
LootType = LootType.Newbied;
|
||||
}
|
||||
|
||||
public SpecialBeardDye(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1041087; // Special Beard Dye
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from.InRange(GetWorldLocation(), 1))
|
||||
{
|
||||
from.CloseGump<SpecialBeardDyeGump>();
|
||||
from.SendGump(new SpecialBeardDyeGump(this));
|
||||
}
|
||||
else
|
||||
{
|
||||
from.LocalOverheadMessage(MessageType.Regular, 906, 1019045); // I can't reach that.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SpecialBeardDyeGump : Gump
|
||||
{
|
||||
private static SpecialBeardDyeEntry[] m_Entries =
|
||||
{
|
||||
new SpecialBeardDyeEntry("*****", 12, 10),
|
||||
new SpecialBeardDyeEntry("*****", 32, 5),
|
||||
new SpecialBeardDyeEntry("*****", 38, 8),
|
||||
new SpecialBeardDyeEntry("*****", 54, 3),
|
||||
new SpecialBeardDyeEntry("*****", 62, 10),
|
||||
new SpecialBeardDyeEntry("*****", 81, 2),
|
||||
new SpecialBeardDyeEntry("*****", 89, 2),
|
||||
new SpecialBeardDyeEntry("*****", 1153, 2)
|
||||
};
|
||||
|
||||
private SpecialBeardDye m_SpecialBeardDye;
|
||||
|
||||
public SpecialBeardDyeGump(SpecialBeardDye dye) : base(0, 0)
|
||||
{
|
||||
m_SpecialBeardDye = dye;
|
||||
|
||||
AddPage(0);
|
||||
AddBackground(150, 60, 350, 358, 2600);
|
||||
AddBackground(170, 104, 110, 270, 5100);
|
||||
AddHtmlLocalized(230, 75, 200, 20, 1011013); // Hair Color Selection Menu
|
||||
AddHtmlLocalized(235, 380, 300, 20, 1013007); // Dye my beard this color!
|
||||
AddButton(200, 380, 0xFA5, 0xFA7, 1); // DYE HAIR
|
||||
|
||||
for (int i = 0; i < m_Entries.Length; ++i)
|
||||
{
|
||||
AddLabel(180, 109 + i * 22, m_Entries[i].HueStart - 1, m_Entries[i].Name);
|
||||
AddButton(257, 110 + i * 22, 5224, 5224, 0, GumpButtonType.Page, i + 1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_Entries.Length; ++i)
|
||||
{
|
||||
SpecialBeardDyeEntry e = m_Entries[i];
|
||||
|
||||
AddPage(i + 1);
|
||||
|
||||
for (int j = 0; j < e.HueCount; ++j)
|
||||
{
|
||||
AddLabel(328 + j / 16 * 80, 102 + j % 16 * 17, e.HueStart + j - 1, "*****");
|
||||
AddRadio(310 + j / 16 * 80, 102 + j % 16 * 17, 210, 211, false, i * 100 + j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState from, RelayInfo info)
|
||||
{
|
||||
if (m_SpecialBeardDye.Deleted)
|
||||
return;
|
||||
|
||||
Mobile m = from.Mobile;
|
||||
int[] switches = info.Switches;
|
||||
|
||||
if (!m_SpecialBeardDye.IsChildOf(m.Backpack))
|
||||
{
|
||||
m.SendLocalizedMessage(1042010); //You must have the objectin your backpack to use it.
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.ButtonID != 0 && switches.Length > 0)
|
||||
{
|
||||
if (m.FacialHairItemID == 0)
|
||||
{
|
||||
m.SendLocalizedMessage(502623); // You have no hair to dye and cannot use this
|
||||
}
|
||||
else
|
||||
{
|
||||
// To prevent this from being exploited, the hue is abstracted into an internal list
|
||||
|
||||
int entryIndex = switches[0] / 100;
|
||||
int hueOffset = switches[0] % 100;
|
||||
|
||||
if (entryIndex >= 0 && entryIndex < m_Entries.Length)
|
||||
{
|
||||
SpecialBeardDyeEntry e = m_Entries[entryIndex];
|
||||
|
||||
if (hueOffset >= 0 && hueOffset < e.HueCount)
|
||||
{
|
||||
int hue = e.HueStart + hueOffset;
|
||||
|
||||
m.FacialHairHue = hue;
|
||||
|
||||
m.SendLocalizedMessage(501199); // You dye your hair
|
||||
m_SpecialBeardDye.Delete();
|
||||
m.PlaySound(0x4E);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m.SendLocalizedMessage(501200); // You decide not to dye your hair
|
||||
}
|
||||
}
|
||||
|
||||
private class SpecialBeardDyeEntry
|
||||
{
|
||||
public SpecialBeardDyeEntry(string name, int hueStart, int hueCount)
|
||||
{
|
||||
Name = name;
|
||||
HueStart = hueStart;
|
||||
HueCount = hueCount;
|
||||
}
|
||||
|
||||
public string Name{ get; }
|
||||
|
||||
public int HueStart{ get; }
|
||||
|
||||
public int HueCount{ get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
163
Projects/Scripts/Items/Misc/SpecialHairDye.cs
Normal file
163
Projects/Scripts/Items/Misc/SpecialHairDye.cs
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class SpecialHairDye : Item
|
||||
{
|
||||
[Constructible]
|
||||
public SpecialHairDye() : base(0xE26)
|
||||
{
|
||||
Weight = 1.0;
|
||||
LootType = LootType.Newbied;
|
||||
}
|
||||
|
||||
public SpecialHairDye(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "Special Hair Dye";
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from.InRange(GetWorldLocation(), 1))
|
||||
{
|
||||
from.CloseGump<SpecialHairDyeGump>();
|
||||
from.SendGump(new SpecialHairDyeGump(this));
|
||||
}
|
||||
else
|
||||
{
|
||||
from.LocalOverheadMessage(MessageType.Regular, 906, 1019045); // I can't reach that.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SpecialHairDyeGump : Gump
|
||||
{
|
||||
private static SpecialHairDyeEntry[] m_Entries =
|
||||
{
|
||||
new SpecialHairDyeEntry("*****", 12, 10),
|
||||
new SpecialHairDyeEntry("*****", 32, 5),
|
||||
new SpecialHairDyeEntry("*****", 38, 8),
|
||||
new SpecialHairDyeEntry("*****", 54, 3),
|
||||
new SpecialHairDyeEntry("*****", 62, 10),
|
||||
new SpecialHairDyeEntry("*****", 81, 2),
|
||||
new SpecialHairDyeEntry("*****", 89, 2),
|
||||
new SpecialHairDyeEntry("*****", 1153, 2)
|
||||
};
|
||||
|
||||
private SpecialHairDye m_SpecialHairDye;
|
||||
|
||||
public SpecialHairDyeGump(SpecialHairDye dye) : base(0, 0)
|
||||
{
|
||||
m_SpecialHairDye = dye;
|
||||
|
||||
AddPage(0);
|
||||
AddBackground(150, 60, 350, 358, 2600);
|
||||
AddBackground(170, 104, 110, 270, 5100);
|
||||
AddHtmlLocalized(230, 75, 200, 20, 1011013); // Hair Color Selection Menu
|
||||
AddHtmlLocalized(235, 380, 300, 20, 1011014); // Dye my hair this color!
|
||||
AddButton(200, 380, 0xFA5, 0xFA7, 1); // DYE HAIR
|
||||
|
||||
for (int i = 0; i < m_Entries.Length; ++i)
|
||||
{
|
||||
AddLabel(180, 109 + i * 22, m_Entries[i].HueStart - 1, m_Entries[i].Name);
|
||||
AddButton(257, 110 + i * 22, 5224, 5224, 0, GumpButtonType.Page, i + 1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_Entries.Length; ++i)
|
||||
{
|
||||
SpecialHairDyeEntry e = m_Entries[i];
|
||||
|
||||
AddPage(i + 1);
|
||||
|
||||
for (int j = 0; j < e.HueCount; ++j)
|
||||
{
|
||||
AddLabel(328 + j / 16 * 80, 102 + j % 16 * 17, e.HueStart + j - 1, "*****");
|
||||
AddRadio(310 + j / 16 * 80, 102 + j % 16 * 17, 210, 211, false, i * 100 + j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState from, RelayInfo info)
|
||||
{
|
||||
if (m_SpecialHairDye.Deleted)
|
||||
return;
|
||||
|
||||
Mobile m = from.Mobile;
|
||||
int[] switches = info.Switches;
|
||||
|
||||
if (!m_SpecialHairDye.IsChildOf(m.Backpack))
|
||||
{
|
||||
m.SendLocalizedMessage(1042010); //You must have the objectin your backpack to use it.
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.ButtonID != 0 && switches.Length > 0)
|
||||
{
|
||||
if (m.HairItemID == 0)
|
||||
{
|
||||
m.SendLocalizedMessage(502623); // You have no hair to dye and cannot use this
|
||||
}
|
||||
else
|
||||
{
|
||||
// To prevent this from being exploited, the hue is abstracted into an internal list
|
||||
|
||||
int entryIndex = switches[0] / 100;
|
||||
int hueOffset = switches[0] % 100;
|
||||
|
||||
if (entryIndex >= 0 && entryIndex < m_Entries.Length)
|
||||
{
|
||||
SpecialHairDyeEntry e = m_Entries[entryIndex];
|
||||
|
||||
if (hueOffset >= 0 && hueOffset < e.HueCount)
|
||||
{
|
||||
m_SpecialHairDye.Delete();
|
||||
|
||||
int hue = e.HueStart + hueOffset;
|
||||
|
||||
m.HairHue = hue;
|
||||
|
||||
m.SendLocalizedMessage(501199); // You dye your hair
|
||||
m.PlaySound(0x4E);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m.SendLocalizedMessage(501200); // You decide not to dye your hair
|
||||
}
|
||||
}
|
||||
|
||||
private class SpecialHairDyeEntry
|
||||
{
|
||||
public SpecialHairDyeEntry(string name, int hueStart, int hueCount)
|
||||
{
|
||||
Name = name;
|
||||
HueStart = hueStart;
|
||||
HueCount = hueCount;
|
||||
}
|
||||
|
||||
public string Name{ get; }
|
||||
|
||||
public int HueStart{ get; }
|
||||
|
||||
public int HueCount{ get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
99
Projects/Scripts/Items/Misc/Static.cs
Normal file
99
Projects/Scripts/Items/Misc/Static.cs
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class Static : Item
|
||||
{
|
||||
public Static() : base(0x80)
|
||||
{
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
[Constructible]
|
||||
public Static(int itemID) : base(itemID)
|
||||
{
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
[Constructible]
|
||||
public Static(int itemID, int count) : this(Utility.Random(itemID, count))
|
||||
{
|
||||
}
|
||||
|
||||
public Static(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(1); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if (version == 0 && Weight == 0)
|
||||
Weight = -1;
|
||||
}
|
||||
}
|
||||
|
||||
public class LocalizedStatic : Static
|
||||
{
|
||||
private int m_LabelNumber;
|
||||
|
||||
[Constructible]
|
||||
public LocalizedStatic(int itemID) : this(itemID, itemID < 0x4000 ? 1020000 + itemID : 1078872 + itemID)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructible]
|
||||
public LocalizedStatic(int itemID, int labelNumber) : base(itemID)
|
||||
{
|
||||
m_LabelNumber = labelNumber;
|
||||
}
|
||||
|
||||
public LocalizedStatic(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Number
|
||||
{
|
||||
get => m_LabelNumber;
|
||||
set
|
||||
{
|
||||
m_LabelNumber = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public override int LabelNumber => m_LabelNumber;
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((byte)0); // version
|
||||
writer.WriteEncodedInt(m_LabelNumber);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadByte();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_LabelNumber = reader.ReadEncodedInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
32
Projects/Scripts/Items/Misc/SwarmOfFlies.cs
Normal file
32
Projects/Scripts/Items/Misc/SwarmOfFlies.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class SwarmOfFlies : Item
|
||||
{
|
||||
[Constructible]
|
||||
public SwarmOfFlies() : base(0x91B)
|
||||
{
|
||||
Hue = 1;
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public SwarmOfFlies(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "a swarm of flies";
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
1182
Projects/Scripts/Items/Misc/Teleporter.cs
Normal file
1182
Projects/Scripts/Items/Misc/Teleporter.cs
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,31 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class DragonFlameSectBadge : Item
|
||||
{
|
||||
[Constructible]
|
||||
public DragonFlameSectBadge() : base(0x23E)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public DragonFlameSectBadge(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1073141; // A Dragon Flame Sect Badge
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
31
Projects/Scripts/Items/Misc/The Citadel/OrdersFromMinax.cs
Normal file
31
Projects/Scripts/Items/Misc/The Citadel/OrdersFromMinax.cs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class OrdersFromMinax : Item
|
||||
{
|
||||
[Constructible]
|
||||
public OrdersFromMinax() : base(0x2279)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public OrdersFromMinax(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1074639; // Orders from Minax
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class SerpentFangSectBadge : Item
|
||||
{
|
||||
[Constructible]
|
||||
public SerpentFangSectBadge() : base(0x23C)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public SerpentFangSectBadge(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1073139; // A Serpent Fang Sect Badge
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class TigerClawSectBadge : Item
|
||||
{
|
||||
[Constructible]
|
||||
public TigerClawSectBadge() : base(0x23D)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public TigerClawSectBadge(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1073140; // A Tiger Claw Sect Badge
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class TravestysCollectionOfShells : Item
|
||||
{
|
||||
[Constructible]
|
||||
public TravestysCollectionOfShells() : base(0xFD3)
|
||||
{
|
||||
}
|
||||
|
||||
public TravestysCollectionOfShells(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1072090; // Travesty's Collection of Shells
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class TravestysFineTeakwoodTray : Item
|
||||
{
|
||||
[Constructible]
|
||||
public TravestysFineTeakwoodTray() : base(Utility.Random(0x991, 2))
|
||||
{
|
||||
}
|
||||
|
||||
public TravestysFineTeakwoodTray(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1075094; // Travesty's Fine Teakwood Tray
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class TravestysSushiPreparations : Item
|
||||
{
|
||||
[Constructible]
|
||||
public TravestysSushiPreparations() : base(Utility.Random(0x1E15, 2))
|
||||
{
|
||||
}
|
||||
|
||||
public TravestysSushiPreparations(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1075093; // Travesty's Sushi Preparations
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
147
Projects/Scripts/Items/Misc/TrashBarrel.cs
Normal file
147
Projects/Scripts/Items/Misc/TrashBarrel.cs
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Multis;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class TrashBarrel : Container, IChopable
|
||||
{
|
||||
private Timer m_Timer;
|
||||
|
||||
[Constructible]
|
||||
public TrashBarrel() : base(0xE77)
|
||||
{
|
||||
Hue = 0x3B2;
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public TrashBarrel(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1041064; // a trash barrel
|
||||
|
||||
public override int DefaultMaxWeight => 0; // A value of 0 signals unlimited weight
|
||||
|
||||
public override bool IsDecoContainer => false;
|
||||
|
||||
public void OnChop(Mobile from)
|
||||
{
|
||||
BaseHouse house = BaseHouse.FindHouseAt(from);
|
||||
|
||||
if (house?.IsCoOwner(from) == true)
|
||||
{
|
||||
Effects.PlaySound(Location, Map, 0x3B3);
|
||||
from.SendLocalizedMessage(500461); // You destroy the item.
|
||||
Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if (Items.Count > 0)
|
||||
{
|
||||
m_Timer = new EmptyTimer(this);
|
||||
m_Timer.Start();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnDragDrop(Mobile from, Item dropped)
|
||||
{
|
||||
if (!base.OnDragDrop(from, dropped))
|
||||
return false;
|
||||
|
||||
if (TotalItems >= 50)
|
||||
{
|
||||
Empty(501478); // The trash is full! Emptying!
|
||||
}
|
||||
else
|
||||
{
|
||||
SendLocalizedMessageTo(from, 1010442); // The item will be deleted in three minutes
|
||||
|
||||
if (m_Timer != null)
|
||||
m_Timer.Stop();
|
||||
else
|
||||
m_Timer = new EmptyTimer(this);
|
||||
|
||||
m_Timer.Start();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnDragDropInto(Mobile from, Item item, Point3D p)
|
||||
{
|
||||
if (!base.OnDragDropInto(from, item, p))
|
||||
return false;
|
||||
|
||||
if (TotalItems >= 50)
|
||||
{
|
||||
Empty(501478); // The trash is full! Emptying!
|
||||
}
|
||||
else
|
||||
{
|
||||
SendLocalizedMessageTo(from, 1010442); // The item will be deleted in three minutes
|
||||
|
||||
if (m_Timer != null)
|
||||
m_Timer.Stop();
|
||||
else
|
||||
m_Timer = new EmptyTimer(this);
|
||||
|
||||
m_Timer.Start();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Empty(int message)
|
||||
{
|
||||
List<Item> items = Items;
|
||||
|
||||
if (items.Count > 0)
|
||||
{
|
||||
PublicOverheadMessage(MessageType.Regular, 0x3B2, message, "");
|
||||
|
||||
for (int i = items.Count - 1; i >= 0; --i)
|
||||
{
|
||||
if (i >= items.Count)
|
||||
continue;
|
||||
|
||||
items[i].Delete();
|
||||
}
|
||||
}
|
||||
|
||||
m_Timer?.Stop();
|
||||
|
||||
m_Timer = null;
|
||||
}
|
||||
|
||||
private class EmptyTimer : Timer
|
||||
{
|
||||
private TrashBarrel m_Barrel;
|
||||
|
||||
public EmptyTimer(TrashBarrel barrel) : base(TimeSpan.FromMinutes(3.0))
|
||||
{
|
||||
m_Barrel = barrel;
|
||||
Priority = TimerPriority.FiveSeconds;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Barrel.Empty(501479); // Emptying the trashcan!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
58
Projects/Scripts/Items/Misc/TrashChest.cs
Normal file
58
Projects/Scripts/Items/Misc/TrashChest.cs
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
[Flippable(0xE41, 0xE40)]
|
||||
public class TrashChest : Container
|
||||
{
|
||||
[Constructible]
|
||||
public TrashChest() : base(0xE41)
|
||||
{
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public TrashChest(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int DefaultMaxWeight => 0; // A value of 0 signals unlimited weight
|
||||
|
||||
public override bool IsDecoContainer => false;
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
|
||||
public override bool OnDragDrop(Mobile from, Item dropped)
|
||||
{
|
||||
if (!base.OnDragDrop(from, dropped))
|
||||
return false;
|
||||
|
||||
PublicOverheadMessage(MessageType.Regular, 0x3B2, Utility.Random(1042891, 8));
|
||||
dropped.Delete();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnDragDropInto(Mobile from, Item item, Point3D p)
|
||||
{
|
||||
if (!base.OnDragDropInto(from, item, p))
|
||||
return false;
|
||||
|
||||
PublicOverheadMessage(MessageType.Regular, 0x3B2, Utility.Random(1042891, 8));
|
||||
item.Delete();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
38
Projects/Scripts/Items/Misc/TribalBerry.cs
Normal file
38
Projects/Scripts/Items/Misc/TribalBerry.cs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class TribalBerry : Item
|
||||
{
|
||||
[Constructible]
|
||||
public TribalBerry(int amount = 1) : base(0x9D0)
|
||||
{
|
||||
Weight = 1.0;
|
||||
Stackable = true;
|
||||
Amount = amount;
|
||||
Hue = 6;
|
||||
}
|
||||
|
||||
public TribalBerry(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1040001; // tribal berry
|
||||
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if (Hue == 4)
|
||||
Hue = 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
89
Projects/Scripts/Items/Misc/TribalPaint.cs
Normal file
89
Projects/Scripts/Items/Misc/TribalPaint.cs
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
using System;
|
||||
using Server.Factions;
|
||||
using Server.Mobiles;
|
||||
using Server.Spells;
|
||||
using Server.Spells.Fifth;
|
||||
using Server.Spells.Ninjitsu;
|
||||
using Server.Spells.Seventh;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class TribalPaint : Item
|
||||
{
|
||||
[Constructible]
|
||||
public TribalPaint() : base(0x9EC)
|
||||
{
|
||||
Hue = 2101;
|
||||
Weight = 2.0;
|
||||
Stackable = Core.ML;
|
||||
}
|
||||
|
||||
public TribalPaint(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1040000; // savage kin paint
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (IsChildOf(from.Backpack))
|
||||
{
|
||||
if (Sigil.ExistsOn(from))
|
||||
{
|
||||
from.SendLocalizedMessage(1010465); // You cannot disguise yourself while holding a sigil.
|
||||
}
|
||||
else if (!from.CanBeginAction<IncognitoSpell>())
|
||||
{
|
||||
from.SendLocalizedMessage(501698); // You cannot disguise yourself while incognitoed.
|
||||
}
|
||||
else if (!from.CanBeginAction<PolymorphSpell>())
|
||||
{
|
||||
from.SendLocalizedMessage(501699); // You cannot disguise yourself while polymorphed.
|
||||
}
|
||||
else if (TransformationSpellHelper.UnderTransformation(from))
|
||||
{
|
||||
from.SendLocalizedMessage(501699); // You cannot disguise yourself while polymorphed.
|
||||
}
|
||||
else if (AnimalForm.UnderTransformation(from))
|
||||
{
|
||||
from.SendLocalizedMessage(1061634); // You cannot disguise yourself while in that form.
|
||||
}
|
||||
else if (from.IsBodyMod || from.FindItemOnLayer(Layer.Helm) is OrcishKinMask)
|
||||
{
|
||||
from.SendLocalizedMessage(501605); // You are already disguised.
|
||||
}
|
||||
else
|
||||
{
|
||||
from.BodyMod = from.Female ? 184 : 183;
|
||||
from.HueMod = 0;
|
||||
|
||||
if (from is PlayerMobile mobile)
|
||||
mobile.SavagePaintExpiration = TimeSpan.FromDays(7.0);
|
||||
|
||||
from.SendLocalizedMessage(
|
||||
1042537); // You now bear the markings of the savage tribe. Your body paint will last about a week or you can remove it with an oil cloth.
|
||||
|
||||
Consume();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
[Flippable(0x315C, 0x315D)]
|
||||
public class HornOfTheDreadhorn : Item
|
||||
{
|
||||
[Constructible]
|
||||
public HornOfTheDreadhorn() : base(0x315C)
|
||||
{
|
||||
}
|
||||
|
||||
public HornOfTheDreadhorn(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1072089; // Horn of the Dread
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
[Flippable(0x3156, 0x3157)]
|
||||
public class MangledHeadOfDreadhorn : Item
|
||||
{
|
||||
[Constructible]
|
||||
public MangledHeadOfDreadhorn() : base(0x3156)
|
||||
{
|
||||
}
|
||||
|
||||
public MangledHeadOfDreadhorn(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1072088; // The Mangled Head of Dread Horn
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
31
Projects/Scripts/Items/Misc/Twisted Weald/TaintedMushroom.cs
Normal file
31
Projects/Scripts/Items/Misc/Twisted Weald/TaintedMushroom.cs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
namespace Server.Items
|
||||
{
|
||||
public class TaintedMushroom : Item
|
||||
{
|
||||
[Constructible]
|
||||
public TaintedMushroom() : base(Utility.RandomMinMax(0x222E, 0x2231))
|
||||
{
|
||||
}
|
||||
|
||||
public TaintedMushroom(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1075088; // Dread Horn Tainted Mushroom
|
||||
public override bool ForceShowProperties => true;
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
137
Projects/Scripts/Items/Misc/UnholyBone.cs
Normal file
137
Projects/Scripts/Items/Misc/UnholyBone.cs
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
using System;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class UnholyBone : Item, ICarvable
|
||||
{
|
||||
private SpawnTimer m_Timer;
|
||||
|
||||
[Constructible]
|
||||
public UnholyBone() : base(0xF7E)
|
||||
{
|
||||
Movable = false;
|
||||
Hue = 0x497;
|
||||
|
||||
m_Timer = new SpawnTimer(this);
|
||||
m_Timer.Start();
|
||||
}
|
||||
|
||||
public UnholyBone(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "unholy bone";
|
||||
|
||||
public void Carve(Mobile from, Item item)
|
||||
{
|
||||
Effects.PlaySound(GetWorldLocation(), Map, 0x48F);
|
||||
Effects.SendLocationEffect(GetWorldLocation(), Map, 0x3728, 10, 10, 0, 0);
|
||||
|
||||
if (0.3 > Utility.RandomDouble())
|
||||
{
|
||||
if (ItemID == 0xF7E)
|
||||
from.SendMessage("You destroy the bone.");
|
||||
else
|
||||
from.SendMessage("You destroy the bone pile.");
|
||||
|
||||
Gold gold = new Gold(25, 100);
|
||||
|
||||
gold.MoveToWorld(GetWorldLocation(), Map);
|
||||
|
||||
Delete();
|
||||
|
||||
m_Timer.Stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ItemID == 0xF7E)
|
||||
from.SendMessage("You damage the bone.");
|
||||
else
|
||||
from.SendMessage("You damage the bone pile.");
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
m_Timer = new SpawnTimer(this);
|
||||
m_Timer.Start();
|
||||
}
|
||||
|
||||
private class SpawnTimer : Timer
|
||||
{
|
||||
private Item m_Item;
|
||||
|
||||
public SpawnTimer(Item item) : base(TimeSpan.FromSeconds(Utility.RandomMinMax(5, 10)))
|
||||
{
|
||||
Priority = TimerPriority.FiftyMS;
|
||||
|
||||
m_Item = item;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if (m_Item.Deleted)
|
||||
return;
|
||||
|
||||
Mobile spawn;
|
||||
|
||||
switch (Utility.Random(12))
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
spawn = new Skeleton();
|
||||
break;
|
||||
case 1:
|
||||
spawn = new Zombie();
|
||||
break;
|
||||
case 2:
|
||||
spawn = new Wraith();
|
||||
break;
|
||||
case 3:
|
||||
spawn = new Spectre();
|
||||
break;
|
||||
case 4:
|
||||
spawn = new Ghoul();
|
||||
break;
|
||||
case 5:
|
||||
spawn = new Mummy();
|
||||
break;
|
||||
case 6:
|
||||
spawn = new Bogle();
|
||||
break;
|
||||
case 7:
|
||||
spawn = new RottingCorpse();
|
||||
break;
|
||||
case 8:
|
||||
spawn = new BoneKnight();
|
||||
break;
|
||||
case 9:
|
||||
spawn = new SkeletalKnight();
|
||||
break;
|
||||
case 10:
|
||||
spawn = new Lich();
|
||||
break;
|
||||
case 11:
|
||||
spawn = new LichLord();
|
||||
break;
|
||||
}
|
||||
|
||||
spawn.MoveToWorld(m_Item.Location, m_Item.Map);
|
||||
|
||||
m_Item.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
216
Projects/Scripts/Items/Misc/WarningItem.cs
Normal file
216
Projects/Scripts/Items/Misc/WarningItem.cs
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class WarningItem : Item
|
||||
{
|
||||
private bool m_Broadcasting;
|
||||
|
||||
private DateTime m_LastBroadcast;
|
||||
private int m_Range;
|
||||
|
||||
[Constructible]
|
||||
public WarningItem(int itemID, int range, int warning) : base(itemID)
|
||||
{
|
||||
if (range > 18)
|
||||
range = 18;
|
||||
|
||||
Movable = false;
|
||||
|
||||
WarningNumber = warning;
|
||||
m_Range = range;
|
||||
}
|
||||
|
||||
[Constructible]
|
||||
public WarningItem(int itemID, int range, string warning) : base(itemID)
|
||||
{
|
||||
if (range > 18)
|
||||
range = 18;
|
||||
|
||||
Movable = false;
|
||||
|
||||
WarningString = warning;
|
||||
m_Range = range;
|
||||
}
|
||||
|
||||
public WarningItem(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string WarningString{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int WarningNumber{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Range
|
||||
{
|
||||
get => m_Range;
|
||||
set
|
||||
{
|
||||
if (value > 18) value = 18;
|
||||
m_Range = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TimeSpan ResetDelay{ get; set; }
|
||||
|
||||
public virtual bool OnlyToTriggerer => false;
|
||||
public virtual int NeighborRange => 5;
|
||||
|
||||
public override bool HandlesOnMovement => true;
|
||||
|
||||
public virtual void SendMessage(Mobile triggerer, bool onlyToTriggerer, string messageString, int messageNumber)
|
||||
{
|
||||
if (onlyToTriggerer)
|
||||
{
|
||||
if (messageString != null)
|
||||
triggerer.SendMessage(messageString);
|
||||
else
|
||||
triggerer.SendLocalizedMessage(messageNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (messageString != null)
|
||||
PublicOverheadMessage(MessageType.Regular, 0x3B2, false, messageString);
|
||||
else
|
||||
PublicOverheadMessage(MessageType.Regular, 0x3B2, messageNumber);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Broadcast(Mobile triggerer)
|
||||
{
|
||||
if (m_Broadcasting || DateTime.UtcNow < m_LastBroadcast + ResetDelay)
|
||||
return;
|
||||
|
||||
m_LastBroadcast = DateTime.UtcNow;
|
||||
|
||||
m_Broadcasting = true;
|
||||
|
||||
SendMessage(triggerer, OnlyToTriggerer, WarningString, WarningNumber);
|
||||
|
||||
if (NeighborRange >= 0)
|
||||
{
|
||||
List<WarningItem> list = new List<WarningItem>();
|
||||
|
||||
foreach (Item item in GetItemsInRange(NeighborRange))
|
||||
if (item != this && item is WarningItem warningItem)
|
||||
list.Add(warningItem);
|
||||
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
list[i].Broadcast(triggerer);
|
||||
}
|
||||
|
||||
Timer.DelayCall(TimeSpan.Zero, InternalCallback);
|
||||
}
|
||||
|
||||
private void InternalCallback()
|
||||
{
|
||||
m_Broadcasting = false;
|
||||
}
|
||||
|
||||
public override void OnMovement(Mobile m, Point3D oldLocation)
|
||||
{
|
||||
if (m.Player && Utility.InRange(m.Location, Location, m_Range) &&
|
||||
!Utility.InRange(oldLocation, Location, m_Range))
|
||||
Broadcast(m);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(WarningString);
|
||||
writer.Write(WarningNumber);
|
||||
writer.Write(m_Range);
|
||||
|
||||
writer.Write(ResetDelay);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
WarningString = reader.ReadString();
|
||||
WarningNumber = reader.ReadInt();
|
||||
m_Range = reader.ReadInt();
|
||||
ResetDelay = reader.ReadTimeSpan();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class HintItem : WarningItem
|
||||
{
|
||||
[Constructible]
|
||||
public HintItem(int itemID, int range, int warning, int hint) : base(itemID, range, warning)
|
||||
{
|
||||
HintNumber = hint;
|
||||
}
|
||||
|
||||
[Constructible]
|
||||
public HintItem(int itemID, int range, string warning, string hint) : base(itemID, range, warning)
|
||||
{
|
||||
HintString = hint;
|
||||
}
|
||||
|
||||
public HintItem(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string HintString{ get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int HintNumber{ get; set; }
|
||||
|
||||
public override bool OnlyToTriggerer => true;
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
SendMessage(from, true, HintString, HintNumber);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(HintString);
|
||||
writer.Write(HintNumber);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
HintString = reader.ReadString();
|
||||
HintNumber = reader.ReadInt();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
146
Projects/Scripts/Items/Misc/Waypoint.cs
Normal file
146
Projects/Scripts/Items/Misc/Waypoint.cs
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
using Server.Commands;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
[Flippable(0x1f14, 0x1f15, 0x1f16, 0x1f17)]
|
||||
public class WayPoint : Item
|
||||
{
|
||||
private WayPoint m_Next;
|
||||
|
||||
[Constructible]
|
||||
public WayPoint(WayPoint prev = null) : base(0x1f14)
|
||||
{
|
||||
Hue = 0x498;
|
||||
Visible = false;
|
||||
//this.Movable = false;
|
||||
if (prev != null)
|
||||
prev.NextPoint = this;
|
||||
}
|
||||
|
||||
public WayPoint(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName => "AI Way Point";
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public WayPoint NextPoint
|
||||
{
|
||||
get => m_Next;
|
||||
set
|
||||
{
|
||||
if (m_Next != this)
|
||||
m_Next = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("WayPointSeq", AccessLevel.GameMaster, WayPointSeq_OnCommand);
|
||||
}
|
||||
|
||||
public static void WayPointSeq_OnCommand(CommandEventArgs arg)
|
||||
{
|
||||
arg.Mobile.SendMessage("Target the position of the first way point.");
|
||||
arg.Mobile.Target = new WayPointSeqTarget(null);
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from.AccessLevel >= AccessLevel.GameMaster)
|
||||
{
|
||||
from.SendMessage("Target the next way point in the sequence.");
|
||||
|
||||
from.Target = new NextPointTarget(this);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnSingleClick(Mobile from)
|
||||
{
|
||||
base.OnSingleClick(from);
|
||||
|
||||
if (m_Next == null)
|
||||
LabelTo(from, "(Unlinked)");
|
||||
else
|
||||
LabelTo(from, "(Linked: {0})", m_Next.Location);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_Next = reader.ReadItem() as WayPoint;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(m_Next);
|
||||
}
|
||||
}
|
||||
|
||||
public class NextPointTarget : Target
|
||||
{
|
||||
private WayPoint m_Point;
|
||||
|
||||
public NextPointTarget(WayPoint pt) : base(-1, false, TargetFlags.None)
|
||||
{
|
||||
m_Point = pt;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object target)
|
||||
{
|
||||
if (target is WayPoint point && m_Point != null)
|
||||
m_Point.NextPoint = point;
|
||||
else
|
||||
from.SendMessage("Target a way point.");
|
||||
}
|
||||
}
|
||||
|
||||
public class WayPointSeqTarget : Target
|
||||
{
|
||||
private WayPoint m_Last;
|
||||
|
||||
public WayPointSeqTarget(WayPoint last) : base(-1, true, TargetFlags.None)
|
||||
{
|
||||
m_Last = last;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (targeted is WayPoint wayPoint)
|
||||
{
|
||||
if (m_Last != null)
|
||||
m_Last.NextPoint = wayPoint;
|
||||
}
|
||||
else if (targeted is IPoint3D d)
|
||||
{
|
||||
Point3D p = new Point3D(d);
|
||||
|
||||
WayPoint point = new WayPoint(m_Last);
|
||||
point.MoveToWorld(p, from.Map);
|
||||
|
||||
from.Target = new WayPointSeqTarget(point);
|
||||
from.SendMessage(
|
||||
"Target the position of the next way point in the sequence, or target a way point link the newest way point to.");
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage("Target a position, or another way point.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
183
Projects/Scripts/Items/Misc/WindChimes.cs
Normal file
183
Projects/Scripts/Items/Misc/WindChimes.cs
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
using Server.Gumps;
|
||||
using Server.Multis;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public abstract class BaseWindChimes : Item
|
||||
{
|
||||
private bool m_TurnedOn;
|
||||
|
||||
public BaseWindChimes(int itemID) : base(itemID)
|
||||
{
|
||||
}
|
||||
|
||||
public BaseWindChimes(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool TurnedOn
|
||||
{
|
||||
get => m_TurnedOn;
|
||||
set
|
||||
{
|
||||
m_TurnedOn = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public static int[] Sounds{ get; } = { 0x505, 0x506, 0x507 };
|
||||
|
||||
public override bool HandlesOnMovement => m_TurnedOn && IsLockedDown;
|
||||
|
||||
public override void OnMovement(Mobile m, Point3D oldLocation)
|
||||
{
|
||||
if (m_TurnedOn && IsLockedDown && (!m.Hidden || m.AccessLevel == AccessLevel.Player) &&
|
||||
Utility.InRange(m.Location, Location, 2) && !Utility.InRange(oldLocation, Location, 2))
|
||||
Effects.PlaySound(Location, Map, Sounds[Utility.Random(Sounds.Length)]);
|
||||
|
||||
base.OnMovement(m, oldLocation);
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
if (m_TurnedOn)
|
||||
list.Add(502695); // turned on
|
||||
else
|
||||
list.Add(502696); // turned off
|
||||
}
|
||||
|
||||
public bool IsOwner(Mobile mob)
|
||||
{
|
||||
return BaseHouse.FindHouseAt(this)?.IsOwner(mob) == true;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (IsOwner(from))
|
||||
{
|
||||
from.SendGump(new OnOffGump(this));
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(502691); // You must be the owner to use this.
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write(m_TurnedOn);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_TurnedOn = reader.ReadBool();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class OnOffGump : Gump
|
||||
{
|
||||
private BaseWindChimes m_Chimes;
|
||||
|
||||
public OnOffGump(BaseWindChimes chimes) : base(150, 200)
|
||||
{
|
||||
m_Chimes = chimes;
|
||||
|
||||
AddBackground(0, 0, 300, 150, 0xA28);
|
||||
AddHtmlLocalized(45, 20, 300, 35, chimes.TurnedOn ? 1011035 : 1011034); // [De]Activate this item
|
||||
AddButton(40, 53, 0xFA5, 0xFA7, 1);
|
||||
AddHtmlLocalized(80, 55, 65, 35, 1011036); // OKAY
|
||||
AddButton(150, 53, 0xFA5, 0xFA7, 0);
|
||||
AddHtmlLocalized(190, 55, 100, 35, 1011012); // CANCEL
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
Mobile from = sender.Mobile;
|
||||
|
||||
if (info.ButtonID == 1)
|
||||
{
|
||||
bool newValue = !m_Chimes.TurnedOn;
|
||||
|
||||
m_Chimes.TurnedOn = newValue;
|
||||
|
||||
if (newValue && !m_Chimes.IsLockedDown)
|
||||
from.SendLocalizedMessage(502693); // Remember, this only works when locked down.
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(502694); // Cancelled action.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class WindChimes : BaseWindChimes
|
||||
{
|
||||
[Constructible]
|
||||
public WindChimes() : base(0x2832)
|
||||
{
|
||||
}
|
||||
|
||||
public WindChimes(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1030290;
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class FancyWindChimes : BaseWindChimes
|
||||
{
|
||||
[Constructible]
|
||||
public FancyWindChimes() : base(0x2833)
|
||||
{
|
||||
}
|
||||
|
||||
public FancyWindChimes(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber => 1030291;
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue