using Server; using System; using Server.Mobiles; using System.Collections.Generic; using System.Linq; namespace Server.Items { public class EodonPotionContext { public PotionEffect Type { get { return Potion.PotionEffect; } } public DateTime StartTime { get; set; } public DateTime Expires { get; set; } public EodonianPotion Potion { get; set; } public Timer Timer { get; set; } public EodonPotionContext(EodonianPotion potion) { Potion = potion; Expires = DateTime.UtcNow + potion.Cooldown; StartTime = DateTime.UtcNow; } public void OnTick(Mobile m) { if (DateTime.UtcNow >= Expires) { Potion.EndEffects(m); } else Potion.OnTick(m); } public void StopTimer() { if (Timer != null) { Timer.Stop(); Timer = null; } } } public class EodonianPotion : BasePotion { public static Dictionary> Contexts { get; set; } public static Timer Timer { get; set; } public virtual TimeSpan Cooldown { get { return TimeSpan.FromMinutes(20); } } public override int LabelNumber { get { switch (this.PotionEffect) { default: case PotionEffect.Barrab: return 1156724; case PotionEffect.Jukari: return 1156726; case PotionEffect.Kurak: return 1156728; case PotionEffect.Barako: return 1156729; case PotionEffect.Urali: return 1156734; case PotionEffect.Sakkhra: return 1156732; } } } public static void Initialize() { EventSink.PlayerDeath += new PlayerDeathEventHandler(EventSink_PlayerDeath); } public EodonianPotion(int id, PotionEffect effect) : base(id, effect) { } public override void Drink(Mobile m) { if (CanDoEffects(m)) { m.FixedEffect(0x375A, 10, 15); m.PlaySound(0x1E7); DoEffects(m); BasePotion.PlayDrinkEffect(m); Consume(); } } public virtual void OnTick(Mobile m) { } public virtual bool CanDoEffects(Mobile m) { if (IsUnderEffects(m, this.PotionEffect)) { m.SendLocalizedMessage(502173); // You are already under a similar effect. return false; } return true; } public virtual void DoEffects(Mobile m) { if (Contexts == null) Contexts = new Dictionary>(); if (!Contexts.ContainsKey(m) || Contexts[m] == null) Contexts[m] = new List(); AddBuff(m); Contexts[m].Add(new EodonPotionContext(this)); BeginTimer(); } public virtual void EndEffects(Mobile m) { RemoveContext(m); } public void RemoveContext(Mobile m) { EodonPotionContext context = GetContext(m, this.PotionEffect); if (context != null) RemoveContext(m, context); } public virtual void AddBuff(Mobile m) { switch (this.PotionEffect) { case PotionEffect.Barrab: BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.BarrabHemolymphConcentrate, LabelNumber, 1156738,"100\t10\t10\t5")); break; case PotionEffect.Jukari: BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.JukariBurnPoiltice, LabelNumber, 1156739,"10\t10\t10\t5")); break; case PotionEffect.Kurak: BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.KurakAmbushersEssence, LabelNumber, 1156740,"200")); break; case PotionEffect.Barako: BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.BarakoDraftOfMight, LabelNumber, 1156741,"10\t10\t5\t10")); break; case PotionEffect.Urali: BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.UraliTranceTonic, LabelNumber, 1156742,"10\t10\t10\t5")); break; case PotionEffect.Sakkhra: BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.SakkhraProphylaxis, LabelNumber, 1156743,"10\t10\t5\t10")); break; } } public virtual void RemoveBuff(Mobile m) { switch (this.PotionEffect) { case PotionEffect.Barrab: BuffInfo.RemoveBuff(m, BuffIcon.BarrabHemolymphConcentrate); break; case PotionEffect.Jukari: BuffInfo.RemoveBuff(m, BuffIcon.JukariBurnPoiltice); break; case PotionEffect.Kurak: BuffInfo.RemoveBuff(m, BuffIcon.KurakAmbushersEssence); break; case PotionEffect.Barako: BuffInfo.RemoveBuff(m, BuffIcon.BarakoDraftOfMight); break; case PotionEffect.Urali: BuffInfo.RemoveBuff(m, BuffIcon.UraliTranceTonic); break; case PotionEffect.Sakkhra: BuffInfo.RemoveBuff(m, BuffIcon.SakkhraProphylaxis); break; } } public static bool IsUnderEffects(Mobile m, PotionEffect effect) { return GetContext(m, effect) != null; } public static void RemoveEffects(Mobile m, PotionEffect effect) { RemoveContext(m, GetContext(m, effect)); } public static EodonPotionContext GetContext(Mobile m, PotionEffect effect) { if (m == null) return null; if (Contexts == null || !Contexts.ContainsKey(m) || Contexts[m] == null) return null; return Contexts[m].FirstOrDefault(c => c.Type == effect); } public static void RemoveContext(Mobile m, PotionEffect effect) { RemoveContext(m, GetContext(m, effect)); } public static void RemoveContext(Mobile m, EodonPotionContext context) { if (context == null) return; if (context.Potion != null) context.Potion.RemoveBuff(m); if (Contexts.ContainsKey(m)) { if (Contexts[m] != null && Contexts[m].Contains(context)) { Contexts[m].Remove(context); } if (Contexts[m] == null || Contexts[m].Count == 0) Contexts.Remove(m); if (Contexts.Count == 0) EndTimer(); m.Delta(MobileDelta.WeaponDamage); } } public static void BeginTimer() { if (Timer == null || !Timer.Running) { Timer = Timer.DelayCall(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), OnTick); Timer.Start(); } } public static void EndTimer() { if(Timer != null) { Timer.Stop(); Timer = null; } } public static void OnTick() { if (Contexts == null) EndTimer(); else { var dictionary = new Dictionary>(Contexts); foreach (var kvp in dictionary) { var contexts = new List(kvp.Value); foreach (var context in contexts) { context.OnTick(kvp.Key); } ColUtility.Free(contexts); } dictionary.Clear(); } } public static void EventSink_PlayerDeath(PlayerDeathEventArgs e) { if (Contexts != null) { if (e.Mobile != null && Contexts.ContainsKey(e.Mobile)) Contexts.Remove(e.Mobile); if (Contexts.Count == 0) EndTimer(); } } public EodonianPotion(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 BarrabHemolymphConcentrate : EodonianPotion { [Constructable] public BarrabHemolymphConcentrate() : this(1) { } [Constructable] public BarrabHemolymphConcentrate(int amount) : base(3846, PotionEffect.Barrab) { Hue = 1272; Stackable = true; Amount = amount; } public override bool CanDoEffects(Mobile m) { if (MortalStrike.IsWounded(m)) { m.SendLocalizedMessage(1156869); // You may not use this with a mortal wound! } else if (m.Poison != null) { m.SendLocalizedMessage(1156868); // You may not use this while poisoned! } else if (Server.Spells.Bushido.Confidence.IsConfident(m)) { m.SendLocalizedMessage(1156873); // You may not use this while under the effects of confidence! } return base.CanDoEffects(m); } public static int GetHitBuff(Mobile m) { EodonPotionContext c = GetContext(m, PotionEffect.Barrab); if (c != null && c.StartTime + TimeSpan.FromMinutes(5) > DateTime.UtcNow) return 10; return 0; } public static int HPRegenBonus(Mobile m) { EodonPotionContext c = GetContext(m, PotionEffect.Barrab); if (c != null && c.StartTime + TimeSpan.FromMinutes(10) > DateTime.UtcNow) return 100; return 0; } public BarrabHemolymphConcentrate(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 JukariBurnPoiltice : EodonianPotion { [Constructable] public JukariBurnPoiltice() : this(1) { } [Constructable] public JukariBurnPoiltice(int amount) : base(3846, PotionEffect.Jukari) { Hue = 2727; Stackable = true; Amount = amount; } public override void DoEffects(Mobile m) { base.DoEffects(m); ResistanceMod mod = new ResistanceMod(ResistanceType.Fire, 10); m.AddResistanceMod(mod); Timer.DelayCall(TimeSpan.FromMinutes(10), () => m.RemoveResistanceMod(mod)); } public static int GetStamBuff(Mobile m) { EodonPotionContext c = GetContext(m, PotionEffect.Jukari); if (c != null && c.StartTime + TimeSpan.FromMinutes(5) > DateTime.UtcNow) return 10; return 0; } public JukariBurnPoiltice(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 KurakAmbushersEssence : EodonianPotion { public override TimeSpan Cooldown { get { return TimeSpan.FromMinutes(10); } } [Constructable] public KurakAmbushersEssence() : this(1) { } [Constructable] public KurakAmbushersEssence(int amount) : base(3846, PotionEffect.Kurak) { Hue = 1260; Stackable = true; Amount = amount; } public KurakAmbushersEssence(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 BarakoDraftOfMight : EodonianPotion { [Constructable] public BarakoDraftOfMight() : this(1) { } [Constructable] public BarakoDraftOfMight(int amount) : base(3846, PotionEffect.Barako) { Hue = 1072; Stackable = true; Amount = amount; } public override void DoEffects(Mobile m) { base.DoEffects(m); ResistanceMod mod1 = new ResistanceMod(ResistanceType.Physical, 10); m.AddResistanceMod(mod1); Timer.DelayCall(TimeSpan.FromMinutes(10), () => m.RemoveResistanceMod(mod1)); ResistanceMod mod2 = new ResistanceMod(ResistanceType.Cold, 5); m.AddResistanceMod(mod1); Timer.DelayCall(TimeSpan.FromMinutes(10), () => m.RemoveResistanceMod(mod2)); } public BarakoDraftOfMight(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 UraliTranceTonic : EodonianPotion { [Constructable] public UraliTranceTonic() : this(1) { } [Constructable] public UraliTranceTonic(int amount) : base(3846, PotionEffect.Urali) { Hue = 1098; Stackable = true; Amount = amount; } public override void DoEffects(Mobile m) { base.DoEffects(m); //TODO: Message? } public override void OnTick(Mobile m) { var context = GetContext(m, this.PotionEffect); if (context != null && context.StartTime + TimeSpan.FromMinutes(10) > DateTime.UtcNow) { m.Mana += 10; //TODO: Message? } } public static int GetManaBuff(Mobile m) { EodonPotionContext c = GetContext(m, PotionEffect.Urali); if (c != null && c.StartTime + TimeSpan.FromMinutes(5) > DateTime.UtcNow) return 10; return 0; } public UraliTranceTonic(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 SakkhraProphylaxisPotion : EodonianPotion { [Constructable] public SakkhraProphylaxisPotion() : this(1) { } [Constructable] public SakkhraProphylaxisPotion(int amount) : base(3846, PotionEffect.Sakkhra) { Hue = 2531; Stackable = true; Amount = amount; } public override void DoEffects(Mobile m) { base.DoEffects(m); ResistanceMod mod1 = new ResistanceMod(ResistanceType.Poison, 10); m.AddResistanceMod(mod1); Timer.DelayCall(TimeSpan.FromMinutes(10), () => m.RemoveResistanceMod(mod1)); ResistanceMod mod2 = new ResistanceMod(ResistanceType.Energy, 5); m.AddResistanceMod(mod2); Timer.DelayCall(TimeSpan.FromMinutes(10), () => m.RemoveResistanceMod(mod2)); } public SakkhraProphylaxisPotion(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(); } } // resources public class MyrmidexEggsac : Item, ICommodity { public override int LabelNumber { get { return 1156725; } } // Myrmidex Eggsac [Constructable] public MyrmidexEggsac() : this(1) { } [Constructable] public MyrmidexEggsac(int amount) : base(10248) { Hue = 1272; Stackable = true; Amount = amount; } public MyrmidexEggsac(Serial serial) : base(serial) { } TextDefinition ICommodity.Description { get { return LabelNumber; } } bool ICommodity.IsDeedable { get { 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(); } } public class LavaBerry : Item { // TODO: Harvested near Jukari Village public override int LabelNumber { get { return 1156727; } } // Lava Berry [Constructable] public LavaBerry() : this(1) { } [Constructable] public LavaBerry(int amount) : base(22326) { Hue = 1955; Stackable = true; Weight = 1.0; Amount = amount; } public LavaBerry(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 LavaBerryBush : Item { // TODO: Harvested near Jukari Village public override int LabelNumber { get { return 1156735; } } // Lava Berry Bush [Constructable] public LavaBerryBush() : base(Utility.RandomBool() ? 0xDC4 : 0xDC5) { Hue = 2075; Movable = false; Weight = 0.0; } public override void OnDoubleClick(Mobile from) { if (from.InRange(this.Location, 2)) { var berry = new LavaBerry(1); from.AddToBackpack(berry); from.PrivateOverheadMessage(Server.Network.MessageType.Regular, 1154, 1156736, "#1156727", from.NetState); Delete(); } else from.LocalOverheadMessage(Server.Network.MessageType.Regular, 0x3B2, 1019045); // I can't reach that. } public LavaBerryBush(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 PerfectBanana : Item { public override int LabelNumber { get { return 1156730; } } // Perfect Bananas [Constructable] public PerfectBanana() : this(1) { } [Constructable] public PerfectBanana(int amount) : base(5922) { Hue = 1119; Stackable = true; Amount = amount; } public PerfectBanana(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 RiverMossDecorate : Item { // TODO: Harvested near Urali Village public override int LabelNumber { get { return 1156731; } } // River Moss [Constructable] public RiverMossDecorate() : base(3378) { Hue = 1272; Movable = false; Weight = 0.0; } public override void OnDoubleClick(Mobile from) { if (from.InRange(this.Location, 2)) { var rm = new RiverMoss(1); from.AddToBackpack(rm); from.PrivateOverheadMessage(Server.Network.MessageType.Regular, 1154, 1156736, "#1156731", from.NetState); Delete(); } else from.LocalOverheadMessage(Server.Network.MessageType.Regular, 0x3B2, 1019045); // I can't reach that. } public RiverMossDecorate(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 RiverMoss : Item, ICommodity { // TODO: Harvested near Urali Village public override int LabelNumber { get { return 1156731; } } // River Moss [Constructable] public RiverMoss() : this(1) { } [Constructable] public RiverMoss(int amount) : base(22333) { Hue = 1272; Stackable = true; Amount = amount; } public RiverMoss(Serial serial) : base(serial) { } TextDefinition ICommodity.Description { get { return LabelNumber; } } bool ICommodity.IsDeedable { get { 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(); } } public class BlueCorn : EarOfCorn { // TODO: Harvestable from Sakkhra corn fields public override int LabelNumber { get { return 1156733; } } // Blue Corn [Constructable] public BlueCorn() : this(1) { } [Constructable] public BlueCorn(int amount) { Hue = 1284; Amount = amount; } public BlueCorn(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 CornStalk : Item { public override int LabelNumber { get { return 1035639; } } // corn stalk private int m_Used; [CommandProperty(AccessLevel.GameMaster)] public int Used { get { return m_Used; } set { m_Used = value; } } [Constructable] public CornStalk() : base(3197) { m_Used = Utility.RandomMinMax(1, 4); Movable = false; } public override void OnDoubleClick(Mobile from) { if (from.InRange(this.Location, 3)) { Item corn; if (Utility.RandomDouble() < 0.70) { corn = new EarOfCorn(1); from.PrivateOverheadMessage(Server.Network.MessageType.Regular, 1154, 1156736, "#1156737", from.NetState); } else { corn = new BlueCorn(1); from.PrivateOverheadMessage(Server.Network.MessageType.Regular, 1154, 1156736, "#1156733", from.NetState); } from.AddToBackpack(corn); if (Used > 1) { Used--; } else { Delete(); } } else { from.LocalOverheadMessage(Server.Network.MessageType.Regular, 0x3B2, 1019045); // I can't reach that. } } public CornStalk(Serial serial) : base(serial) { } public override void Serialize(GenericWriter writer) { base.Serialize(writer); writer.Write(0); writer.Write((int)m_Used); } public override void Deserialize(GenericReader reader) { base.Deserialize(reader); int version = reader.ReadInt(); m_Used = reader.ReadInt(); } } public class MoonstoneCrystalShard : Item { public override int LabelNumber { get { return 1124142; } } // Moonstone Crystal Shards [Constructable] public MoonstoneCrystalShard() : this(1) { } [Constructable] public MoonstoneCrystalShard(int amount) : base(40118) { Stackable = true; Amount = amount; } public MoonstoneCrystalShard(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(); } } }