Files
abysmal-isle/Scripts/Services/ViceVsVirtue/Items/Rewards/VvVPotions.cs
Unstable Kitsune b918192e4e Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
2023-11-28 23:20:26 -05:00

614 lines
18 KiB
C#

using Server;
using System;
using Server.Items;
using Server.Mobiles;
using System.Collections.Generic;
using Server.Factions;
namespace Server.Engines.VvV
{
public enum PotionType
{
None = 0x0,
AntiParalysis = 0x1,
Supernova = 0x2,
StatLossRemoval = 0x4,
GreaterStamina = 0x8,
}
public class VvVPotionKeg : Item
{
private PotionType _PotionType;
private int _Charges;
[CommandProperty(AccessLevel.GameMaster)]
public PotionType PotionType { get { return _PotionType; } set { _PotionType = value; InvalidateProperties(); } }
[CommandProperty(AccessLevel.GameMaster)]
public int Charges { get { return _Charges; } set { _Charges = value; if (_Charges <= 0) Delete(); else InvalidateProperties(); } }
public override double DefaultWeight
{
get
{
return 10 + _Charges * 1.8;
}
}
[Constructable]
public VvVPotionKeg(PotionType type)
: base(6870)
{
PotionType = type;
Charges = 10;
switch (type)
{
default:
case PotionType.AntiParalysis: Hue = 2543; break;
case PotionType.Supernova: Hue = 13; break;
case PotionType.StatLossRemoval: Hue = 2500; break;
case PotionType.GreaterStamina: Hue = 437; break;
}
}
public override void AddNameProperty(ObjectPropertyList list)
{
string str;
switch (_PotionType)
{
default:
case PotionType.AntiParalysis: str = "#1155543"; break;
case PotionType.Supernova: str = "#1094718"; break;
case PotionType.StatLossRemoval: str = "#1155541"; break;
case PotionType.GreaterStamina: str = "#1094764"; break;
}
list.Add(1155535, str); // A Batch of ~1_ITEMS~
}
public override void OnDoubleClick(Mobile m)
{
if (IsChildOf(m.Backpack))
{
if (!ViceVsVirtueSystem.IsVvV(m))
{
m.SendLocalizedMessage(1155496); // This item can only be used by VvV participants!
}
else
{
Item potion = null;
switch (_PotionType)
{
case PotionType.AntiParalysis: potion = new AntiParalysisPotion(); break;
case PotionType.Supernova: potion = new SupernovaPotion(); break;
case PotionType.StatLossRemoval: potion = new StatLossRemovalPotion(); break;
case PotionType.GreaterStamina: potion = new GreaterStaminaPotion(); break;
}
if (potion != null)
{
m.SendLocalizedMessage(502242); // You pour some of the keg's contents into an empty bottle...
if (m.Backpack == null || !m.Backpack.TryDropItem(m, potion, false))
{
m.SendLocalizedMessage(1155570); // Your backpack could not hold the item. Free up some space and try again.
potion.Delete();
}
else
{
m.SendLocalizedMessage(502243); // ...and place it into your backpack.
m.PlaySound(0x240);
Charges--;
}
}
}
}
else
{
m.SendLocalizedMessage(1042004); // That must be in your pack for you to use it
}
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
list.Add(1155569, Charges.ToString()); // Potions: ~1_val~
list.Add(1154937); // VvV Item
}
public VvVPotionKeg(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
writer.Write((int)PotionType);
writer.Write(Charges);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
PotionType = (PotionType)reader.ReadInt();
Charges = reader.ReadInt();
}
}
public abstract class VvVPotion : Item, IFactionItem
{
#region Factions
private FactionItem m_FactionState;
public FactionItem FactionItemState
{
get { return m_FactionState; }
set
{
m_FactionState = value;
}
}
#endregion
public virtual TimeSpan CooldownDuration { get { return TimeSpan.MinValue; } }
public virtual PotionType CooldownType { get { return PotionType.None; } }
public static Dictionary<Mobile, Dictionary<PotionType, DateTime>> _Cooldown = new Dictionary<Mobile, Dictionary<PotionType, DateTime>>();
public static void RemoveFromCooldown(Mobile m, PotionType type)
{
if (_Cooldown.ContainsKey(m) && _Cooldown[m].ContainsKey(type))
{
_Cooldown[m].Remove(type);
if (_Cooldown[m].Count == 0)
_Cooldown.Remove(m);
}
}
public static void CheckCooldown()
{
List<Mobile> toRemove = new List<Mobile>();
foreach (KeyValuePair<Mobile, Dictionary<PotionType, DateTime>> kvp in _Cooldown)
{
List<PotionType> removeTypes = new List<PotionType>();
foreach (KeyValuePair<PotionType, DateTime> values in kvp.Value)
{
if (values.Value < DateTime.UtcNow)
removeTypes.Add(values.Key);
}
foreach (PotionType t in removeTypes)
kvp.Value.Remove(t);
if (kvp.Value.Count == 0)
toRemove.Add(kvp.Key);
removeTypes.Clear();
removeTypes.TrimExcess();
}
foreach (Mobile mob in toRemove)
_Cooldown.Remove(mob);
toRemove.Clear();
toRemove.TrimExcess();
}
public override int LabelNumber
{
get
{
switch (CooldownType)
{
case PotionType.AntiParalysis: return 1155543;
case PotionType.Supernova: return 1094718;
case PotionType.StatLossRemoval: return 1155541;
case PotionType.GreaterStamina: return 1094764;
}
return base.LabelNumber;
}
}
public VvVPotion()
: base(3849)
{
Stackable = true;
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
if (!FactionEquipment.AddFactionProperties(this, list))
{
list.Add(1154937); // VvV Item
}
}
public bool IsInCooldown(Mobile m, ref DateTime dt)
{
if (_Cooldown.ContainsKey(m))
{
if (_Cooldown[m].ContainsKey(PotionType.GreaterStamina))
{
dt = _Cooldown[m][PotionType.GreaterStamina];
if (dt < DateTime.UtcNow)
{
RemoveFromCooldown(m, PotionType.GreaterStamina);
return false;
}
return true;
}
if (_Cooldown[m].ContainsKey(CooldownType))
{
dt = _Cooldown[m][CooldownType];
if (dt < DateTime.UtcNow)
{
RemoveFromCooldown(m, CooldownType);
return false;
}
return true;
}
}
return false;
}
public void AddToCooldown(Mobile m)
{
if (!_Cooldown.ContainsKey(m))
_Cooldown[m] = new Dictionary<PotionType, DateTime>();
_Cooldown[m][CooldownType] = DateTime.UtcNow + CooldownDuration;
}
public override void OnDoubleClick(Mobile m)
{
if (!Movable)
return;
if (IsChildOf(m.Backpack))
{
DateTime dt = DateTime.UtcNow;
if (ViceVsVirtueSystem.Enabled && !ViceVsVirtueSystem.IsVvV(m))
{
m.SendLocalizedMessage(1155496); // This item can only be used by VvV participants!
}
else if (Server.Factions.Settings.Enabled && !FactionEquipment.CanUse(this, m))
{
}
else if (!BasePotion.HasFreeHand(m))
{
m.SendLocalizedMessage(502172); // You must have a free hand to drink a potion.
}
else if (IsInCooldown(m, ref dt))
{
TimeSpan left = dt - DateTime.UtcNow;
if (left.TotalMinutes > 2)
{
m.SendLocalizedMessage(1114110, ((int)left.TotalMinutes).ToString()); // You must wait ~1_minutes~ minutes before using another one of these.
}
else
{
m.SendLocalizedMessage(1114109, ((int)left.TotalSeconds).ToString()); // You must wait ~1_seconds~ seconds before using another one of these.
}
}
else if (CheckUse(m))
{
UseEffects(m);
Use(m);
}
}
else
{
m.SendLocalizedMessage(1042004); // That must be in your pack for you to use it
}
}
public virtual bool CheckUse(Mobile m)
{
return true;
}
public abstract void Use(Mobile m);
public virtual void UseEffects(Mobile m)
{
m.RevealingAction();
m.PlaySound(0x2D6);
if (m.Body.IsHuman && !m.Mounted)
m.Animate(34, 5, 1, true, false, 0);
if (CooldownDuration != TimeSpan.MinValue)
{
AddToCooldown(m);
}
Timer.DelayCall<Mobile>(TimeSpan.FromMilliseconds(500), DrinkEffects, m);
}
public virtual void DrinkEffects(Mobile m)
{
}
public VvVPotion(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 AntiParalysisPotion : VvVPotion
{
public override PotionType CooldownType { get { return PotionType.AntiParalysis; } }
[Constructable]
public AntiParalysisPotion()
{
Hue = 2543;
}
public override bool CheckUse(Mobile m)
{
if (!m.Paralyzed)
{
m.SendLocalizedMessage(1155544); // You are not currently paralyzed
return false;
}
return true;
}
public override void Use(Mobile m)
{
m.Paralyzed = false;
m.Stam /= 2;
Consume();
}
public override void DrinkEffects(Mobile m)
{
m.FixedEffect(0x375A, 10, 15);
m.PlaySound(0x1E7);
}
public AntiParalysisPotion(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 SupernovaPotion : VvVPotion
{
public override TimeSpan CooldownDuration { get { return TimeSpan.FromMinutes(2); } }
public override PotionType CooldownType { get { return PotionType.Supernova; } }
[Constructable]
public SupernovaPotion()
{
Hue = 13;
}
public override void Use(Mobile m)
{
Effects.SendMovingEffect(m, new Entity(Serial.Zero, new Point3D(m.X, m.Y, m.Z + 25), m.Map), this.ItemID, 3, 0, false, false, this.Hue, 0);
int count = 5;
Timer.DelayCall(TimeSpan.FromSeconds(1), () =>
{
m.PlaySound(0x1DD);
for (int i = 0; i < count; i++)
{
Timer.DelayCall(TimeSpan.FromMilliseconds(i * 170), index =>
{
Server.Misc.Geometry.Circle2D(m.Location, m.Map, index, (pnt, map) =>
{
Effects.SendLocationEffect(pnt, map, 0x3709, 30, 10, 0, 5);
});
}, i);
}
});
Timer.DelayCall(TimeSpan.FromMilliseconds(170 * count), () =>
{
IPooledEnumerable eable = m.Map.GetMobilesInRange(m.Location, count);
foreach (Mobile mob in eable)
{
if (mob != m && Server.Spells.SpellHelper.ValidIndirectTarget(m, mob) && m.CanBeHarmful(mob, false))
{
m.DoHarmful(mob);
AOS.Damage(mob, m, Utility.RandomMinMax(40, 60), 0, 100, 0, 0, 0);
}
}
eable.Free();
});
if (m.AccessLevel == AccessLevel.Player)
Consume();
}
public override void UseEffects(Mobile m)
{
AddToCooldown(m);
}
public SupernovaPotion(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 StatLossRemovalPotion : VvVPotion
{
public override TimeSpan CooldownDuration { get { return TimeSpan.FromMinutes(20); } }
public override PotionType CooldownType { get { return PotionType.StatLossRemoval; } }
[Constructable]
public StatLossRemovalPotion()
{
Hue = 2500;
}
public override bool CheckUse(Mobile m)
{
if (!Server.Factions.Faction.InSkillLoss(m))
{
m.SendLocalizedMessage(1155542); // You are not currently under the effects of stat loss.
return false;
}
return true;
}
public override void Use(Mobile m)
{
m.SendLocalizedMessage(1155540); // You feel the effects of your stat loss fade.
Server.Factions.Faction.ClearSkillLoss(m);
Consume();
}
public override void DrinkEffects(Mobile m)
{
m.PlaySound(0xF6);
m.PlaySound(0x1F7);
m.FixedParticles(0x3709, 1, 30, 9963, 13, 3, EffectLayer.Head);
}
public StatLossRemovalPotion(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 GreaterStaminaPotion : VvVPotion
{
public override TimeSpan CooldownDuration { get { return TimeSpan.FromSeconds(10); } }
public override PotionType CooldownType { get { return PotionType.GreaterStamina; } }
[Constructable]
public GreaterStaminaPotion()
{
Hue = 437;
}
public override bool CheckUse(Mobile m)
{
//TODO: Message? Stam check?
return true;
}
public override void Use(Mobile m)
{
Timer.DelayCall(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), 10, () =>
{
int gain = Utility.RandomMinMax(10, 13);
if (m.Stam + gain > m.StamMax)
gain = m.StamMax - m.Stam;
m.FixedParticles(0x376A, 9, 32, 5005, EffectLayer.Waist);
m.Stam += gain;
});
Consume();
}
public override void DrinkEffects(Mobile m)
{
m.FixedEffect(0x375A, 10, 15);
m.PlaySound(0x1E7);
}
public GreaterStaminaPotion(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();
}
}
}