Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
134
Scripts/Spells/Mysticism/MysticSpell.cs
Normal file
134
Scripts/Spells/Mysticism/MysticSpell.cs
Normal file
@@ -0,0 +1,134 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Spells.Mysticism
|
||||
{
|
||||
public abstract class MysticSpell : Spell
|
||||
{
|
||||
public MysticSpell(Mobile caster, Item scroll, SpellInfo info)
|
||||
: base(caster, scroll, info)
|
||||
{
|
||||
}
|
||||
|
||||
public abstract SpellCircle Circle { get; }
|
||||
|
||||
private static int[] m_ManaTable = new int[] { 4, 6, 9, 11, 14, 20, 40, 50 };
|
||||
|
||||
public override TimeSpan CastDelayBase { get { return TimeSpan.FromMilliseconds(((4 + (int)Circle) * CastDelaySecondsPerTick) * 1000); } }
|
||||
public override double CastDelayFastScalar { get { return 1.0; } }
|
||||
|
||||
public double ChanceOffset { get { return Caster is Server.Mobiles.PlayerMobile ? 20.0 : 30.0; } }
|
||||
private const double ChanceLength = 100.0 / 7.0;
|
||||
|
||||
public override void GetCastSkills(out double min, out double max)
|
||||
{
|
||||
int circle = (int)Circle;
|
||||
|
||||
if (Scroll != null)
|
||||
circle -= 2;
|
||||
|
||||
double avg = ChanceLength * circle;
|
||||
|
||||
min = avg - ChanceOffset;
|
||||
max = avg + ChanceOffset;
|
||||
}
|
||||
|
||||
public override SkillName CastSkill { get { return SkillName.Mysticism; } }
|
||||
|
||||
public override SkillName DamageSkill
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Caster.Skills[SkillName.Imbuing].Value >= Caster.Skills[SkillName.Focus].Value)
|
||||
return SkillName.Imbuing;
|
||||
return SkillName.Focus;
|
||||
}
|
||||
}
|
||||
|
||||
public override void SendCastEffect()
|
||||
{
|
||||
if(Caster.Player)
|
||||
Caster.FixedEffect(0x37C4, 87, (int)(GetCastDelay().TotalSeconds * 28), 0x66C, 3);
|
||||
}
|
||||
|
||||
public override int GetMana()
|
||||
{
|
||||
if (Core.TOL && this is HailStormSpell)
|
||||
return 50;
|
||||
|
||||
return m_ManaTable[(int)Circle];
|
||||
}
|
||||
|
||||
public override TimeSpan GetCastRecovery()
|
||||
{
|
||||
if (Scroll is SpellStone)
|
||||
return TimeSpan.Zero;
|
||||
|
||||
return base.GetCastRecovery();
|
||||
}
|
||||
|
||||
public override TimeSpan GetCastDelay()
|
||||
{
|
||||
if (Scroll is SpellStone)
|
||||
return TimeSpan.Zero;
|
||||
|
||||
return base.GetCastDelay();
|
||||
}
|
||||
|
||||
public override bool CheckCast()
|
||||
{
|
||||
if (!base.CheckCast())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool CheckResisted(Mobile target)
|
||||
{
|
||||
double n = GetResistPercent(target);
|
||||
|
||||
n /= 100.0;
|
||||
|
||||
if (n <= 0.0)
|
||||
return false;
|
||||
|
||||
if (n >= 1.0)
|
||||
return true;
|
||||
|
||||
int circle = Math.Max(5, 1 + (int)Circle);
|
||||
|
||||
int maxSkill = circle * 10;
|
||||
maxSkill += (circle / 6) * 25;
|
||||
|
||||
if (target.Skills[SkillName.MagicResist].Value < maxSkill)
|
||||
target.CheckSkill(SkillName.MagicResist, 0.0, target.Skills[SkillName.MagicResist].Cap);
|
||||
|
||||
return (n >= Utility.RandomDouble());
|
||||
}
|
||||
|
||||
public virtual double GetResistPercentForCircle(Mobile target, SpellCircle circle)
|
||||
{
|
||||
double value = GetResistSkill(target);
|
||||
double firstPercent = value / 5.0;
|
||||
double secondPercent = value - (((Caster.Skills[CastSkill].Value - 20.0) / 5.0) + (Math.Max(5, 1 + (int)circle)) * 5.0);
|
||||
|
||||
return (firstPercent > secondPercent ? firstPercent : secondPercent) / 2.0; // Seems should be about half of what stratics says.
|
||||
}
|
||||
|
||||
public virtual double GetResistPercent(Mobile target)
|
||||
{
|
||||
return GetResistPercentForCircle(target, Circle);
|
||||
}
|
||||
|
||||
public static double GetBaseSkill(Mobile m)
|
||||
{
|
||||
return m.Skills[SkillName.Mysticism].Value;
|
||||
}
|
||||
|
||||
public static double GetBoostSkill(Mobile m)
|
||||
{
|
||||
return Math.Max(m.Skills[SkillName.Imbuing].Value, m.Skills[SkillName.Focus].Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Spells.Mysticism
|
||||
{
|
||||
public class AnimatedWeaponSpell : MysticSpell
|
||||
{
|
||||
public override SpellCircle Circle { get { return SpellCircle.Fourth; } }
|
||||
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Animated Weapon", "In Jux Por Ylem",
|
||||
230,
|
||||
9022,
|
||||
Reagent.BlackPearl,
|
||||
Reagent.MandrakeRoot,
|
||||
Reagent.Nightshade,
|
||||
Reagent.Bone
|
||||
);
|
||||
|
||||
public AnimatedWeaponSpell(Mobile caster, Item scroll) : base(caster, scroll, m_Info)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
Caster.Target = new InternalTarget(this);
|
||||
}
|
||||
|
||||
public void Target(IPoint3D p)
|
||||
{
|
||||
if ((Caster.Followers + 4) > Caster.FollowersMax)
|
||||
{
|
||||
Caster.SendLocalizedMessage(1049645); // You have too many followers to summon that creature.
|
||||
return;
|
||||
}
|
||||
|
||||
Map map = Caster.Map;
|
||||
|
||||
SpellHelper.GetSurfaceTop(ref p);
|
||||
|
||||
if (map == null || (Caster.IsPlayer() && !map.CanSpawnMobile(p.X, p.Y, p.Z)))
|
||||
{
|
||||
Caster.SendLocalizedMessage(501942); // That location is blocked.
|
||||
}
|
||||
else if (SpellHelper.CheckTown(p, Caster) && CheckSequence())
|
||||
{
|
||||
int level = (int)((GetBaseSkill(Caster) + GetBoostSkill(Caster)) / 2.0);
|
||||
|
||||
TimeSpan duration = TimeSpan.FromSeconds(10 + level);
|
||||
|
||||
BaseCreature summon = new AnimatedWeapon(Caster, level);
|
||||
BaseCreature.Summon(summon, false, Caster, new Point3D(p), 0x212, duration);
|
||||
|
||||
summon.PlaySound(0x64A);
|
||||
|
||||
Effects.SendTargetParticles(summon, 0x3728, 10, 10, 0x13AA, (EffectLayer)255);
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
|
||||
public class InternalTarget : Target
|
||||
{
|
||||
private AnimatedWeaponSpell m_Owner;
|
||||
|
||||
public InternalTarget(AnimatedWeaponSpell owner)
|
||||
: base(12, true, TargetFlags.None)
|
||||
{
|
||||
m_Owner = owner;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object o)
|
||||
{
|
||||
if (o is IPoint3D)
|
||||
m_Owner.Target((IPoint3D)o);
|
||||
}
|
||||
|
||||
protected override void OnTargetFinish(Mobile from)
|
||||
{
|
||||
m_Owner.FinishSequence();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
120
Scripts/Spells/Mysticism/SpellDefinitions/BombardSpell.cs
Normal file
120
Scripts/Spells/Mysticism/SpellDefinitions/BombardSpell.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Spells.Mysticism
|
||||
{
|
||||
public class BombardSpell : MysticSpell
|
||||
{
|
||||
public override SpellCircle Circle { get { return SpellCircle.Sixth; } }
|
||||
public override bool DelayedDamage { get { return true; } }
|
||||
public override bool DelayedDamageStacking { get { return false; } }
|
||||
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Bombard", "Corp Por Ylem",
|
||||
230,
|
||||
9022,
|
||||
Reagent.Bloodmoss,
|
||||
Reagent.Garlic,
|
||||
Reagent.SulfurousAsh,
|
||||
Reagent.DragonBlood
|
||||
);
|
||||
|
||||
public BombardSpell(Mobile caster, Item scroll) : base(caster, scroll, m_Info)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
Caster.Target = new InternalTarget(this);
|
||||
}
|
||||
|
||||
public void OnTarget(IDamageable d)
|
||||
{
|
||||
if (d == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (CheckHSequence(d))
|
||||
{
|
||||
IDamageable target = d;
|
||||
IDamageable source = Caster;
|
||||
|
||||
SpellHelper.Turn(Caster, target);
|
||||
|
||||
if (Core.SA && HasDelayContext(target))
|
||||
{
|
||||
DoHurtFizzle();
|
||||
return;
|
||||
}
|
||||
|
||||
if (SpellHelper.CheckReflect((int)Circle, ref source, ref target))
|
||||
{
|
||||
Server.Timer.DelayCall(TimeSpan.FromSeconds(.5), () =>
|
||||
{
|
||||
source.MovingEffect(target, 0x1363, 12, 1, false, true, 0, 0);
|
||||
source.PlaySound(0x64B);
|
||||
});
|
||||
}
|
||||
|
||||
Caster.MovingEffect(d, 0x1363, 12, 1, false, true, 0, 0);
|
||||
Caster.PlaySound(0x64B);
|
||||
|
||||
SpellHelper.Damage(this, target, (int)GetNewAosDamage(40, 1, 5, target), 100, 0, 0, 0, 0);
|
||||
|
||||
if (target is Mobile)
|
||||
{
|
||||
Timer.DelayCall(TimeSpan.FromMilliseconds(1200), () =>
|
||||
{
|
||||
if (!CheckResisted((Mobile)target))
|
||||
{
|
||||
int secs = (int)((GetDamageSkill(this.Caster) / 10) - (GetResistSkill((Mobile)target) / 10));
|
||||
|
||||
if (secs < 0)
|
||||
secs = 0;
|
||||
|
||||
((Mobile)target).Paralyze(TimeSpan.FromSeconds(secs));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
|
||||
public class InternalTarget : Target
|
||||
{
|
||||
public BombardSpell Owner { get; set; }
|
||||
|
||||
public InternalTarget(BombardSpell owner)
|
||||
: this(owner, false)
|
||||
{
|
||||
}
|
||||
|
||||
public InternalTarget(BombardSpell owner, bool allowland)
|
||||
: base(12, allowland, TargetFlags.Harmful)
|
||||
{
|
||||
Owner = owner;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object o)
|
||||
{
|
||||
if (o == null)
|
||||
return;
|
||||
|
||||
if (!from.CanSee(o))
|
||||
from.SendLocalizedMessage(500237); // Target can not be seen.
|
||||
else if (o is IDamageable)
|
||||
{
|
||||
SpellHelper.Turn(from, o);
|
||||
Owner.OnTarget((IDamageable)o);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnTargetFinish(Mobile from)
|
||||
{
|
||||
Owner.FinishSequence();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
264
Scripts/Spells/Mysticism/SpellDefinitions/CleansingWindsSpell.cs
Normal file
264
Scripts/Spells/Mysticism/SpellDefinitions/CleansingWindsSpell.cs
Normal file
@@ -0,0 +1,264 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Server.Engines.PartySystem;
|
||||
using Server.Items;
|
||||
using Server.Spells.First;
|
||||
using Server.Spells.Fourth;
|
||||
using Server.Spells.Necromancy;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Spells.Mysticism
|
||||
{
|
||||
public class CleansingWindsSpell : MysticSpell
|
||||
{
|
||||
public override SpellCircle Circle { get { return SpellCircle.Sixth; } }
|
||||
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Cleansing Winds", "In Vas Mani Hur",
|
||||
230,
|
||||
9022,
|
||||
Reagent.Garlic,
|
||||
Reagent.Ginseng,
|
||||
Reagent.MandrakeRoot,
|
||||
Reagent.DragonBlood
|
||||
);
|
||||
|
||||
public CleansingWindsSpell(Mobile caster, Item scroll)
|
||||
: base(caster, scroll, m_Info)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
Caster.Target = new InternalTarget(this);
|
||||
}
|
||||
|
||||
public void OnTarget(object o)
|
||||
{
|
||||
var targeted = o as Mobile;
|
||||
|
||||
if (targeted == null)
|
||||
return;
|
||||
|
||||
if (CheckBSequence(targeted))
|
||||
{
|
||||
/* Soothing winds attempt to neutralize poisons, lift curses, and heal a valid
|
||||
* Target. The Caster's Mysticism and either Focus or Imbuing (whichever is
|
||||
* greater) skills determine the effectiveness of the Cleansing Winds.
|
||||
*/
|
||||
|
||||
Caster.PlaySound(0x64C);
|
||||
|
||||
var targets = new List<Mobile> { targeted };
|
||||
targets.AddRange(FindAdditionalTargets(targeted).Take(3)); // This effect can hit up to 3 additional players beyond the primary target.
|
||||
|
||||
double primarySkill = Caster.Skills[CastSkill].Value;
|
||||
double secondarySkill = Caster.Skills[DamageSkill].Value;
|
||||
|
||||
var toHeal = (int)((primarySkill + secondarySkill) / 4.0) + Utility.RandomMinMax(-3, 3);
|
||||
toHeal /= targets.Count; // The effectiveness of the spell is reduced by the number of targets affected.
|
||||
|
||||
foreach (var target in targets)
|
||||
{
|
||||
// WARNING: This spell will flag the caster as a criminal if a criminal or murderer party member is close enough
|
||||
// to the target to receive the benefits from the area of effect.
|
||||
Caster.DoBeneficial(target);
|
||||
|
||||
PlayEffect(target);
|
||||
|
||||
int toHealMod = toHeal;
|
||||
|
||||
if (target.Poisoned)
|
||||
{
|
||||
int poisonLevel = target.Poison.RealLevel + 1;
|
||||
int chanceToCure = (10000 + (int)((primarySkill + secondarySkill) / 2 * 75) - (poisonLevel * 1750)) / 100;
|
||||
|
||||
if (chanceToCure > Utility.Random(100) && target.CurePoison(Caster))
|
||||
{
|
||||
// Poison reduces healing factor by 15% per level of poison.
|
||||
toHealMod -= (int)(toHeal * poisonLevel * 0.15);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the cure fails, the target will not be healed.
|
||||
toHealMod = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Cleansing Winds will not heal the target after removing mortal wound.
|
||||
if (MortalStrike.IsWounded(target))
|
||||
{
|
||||
toHealMod = 0;
|
||||
}
|
||||
|
||||
var curseLevel = RemoveCurses(target);
|
||||
|
||||
if (toHealMod > 0 && curseLevel > 0)
|
||||
{
|
||||
// Each Curse reduces healing by 3 points + 1% per curse level.
|
||||
toHealMod = toHealMod - (curseLevel * 3);
|
||||
toHealMod = toHealMod - (int)((double)toHealMod * ((double)curseLevel / 100.0));
|
||||
}
|
||||
|
||||
if (toHealMod > 0)
|
||||
SpellHelper.Heal(toHealMod, target, Caster);
|
||||
}
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
|
||||
private static void PlayEffect(Mobile m)
|
||||
{
|
||||
m.FixedParticles(0x3709, 1, 30, 9963, 13, 3, EffectLayer.Head);
|
||||
|
||||
var from = new Entity(Serial.Zero, new Point3D(m.X, m.Y, m.Z - 10), m.Map);
|
||||
var to = new Entity(Serial.Zero, new Point3D(m.X, m.Y, m.Z + 50), m.Map);
|
||||
Effects.SendMovingParticles(from, to, 0x2255, 1, 0, false, false, 13, 3, 9501, 1, 0, EffectLayer.Head, 0x100);
|
||||
}
|
||||
|
||||
private IEnumerable<Mobile> FindAdditionalTargets(Mobile targeted)
|
||||
{
|
||||
var casterParty = Party.Get(Caster);
|
||||
|
||||
if (casterParty == null)
|
||||
yield break;
|
||||
|
||||
IPooledEnumerable eable = Caster.Map.GetMobilesInRange(new Point3D(targeted), 2);
|
||||
|
||||
foreach (Mobile m in eable)
|
||||
{
|
||||
if (m == null || m == targeted)
|
||||
continue;
|
||||
|
||||
// Players in the area must be in the casters party in order to receive the beneficial effects of the spell.
|
||||
if (Caster.CanBeBeneficial(m, false) && casterParty.Contains(m))
|
||||
yield return m;
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public static int RemoveCurses(Mobile m)
|
||||
{
|
||||
int curseLevel = 0;
|
||||
|
||||
if (SleepSpell.IsUnderSleepEffects(m))
|
||||
{
|
||||
SleepSpell.EndSleep(m);
|
||||
curseLevel += 2;
|
||||
}
|
||||
|
||||
if (EvilOmenSpell.TryEndEffect(m))
|
||||
{
|
||||
curseLevel += 1;
|
||||
}
|
||||
|
||||
if (StrangleSpell.RemoveCurse(m))
|
||||
{
|
||||
curseLevel += 2;
|
||||
}
|
||||
|
||||
if (CorpseSkinSpell.RemoveCurse(m))
|
||||
{
|
||||
curseLevel += 3;
|
||||
}
|
||||
|
||||
if (CurseSpell.UnderEffect(m))
|
||||
{
|
||||
CurseSpell.RemoveEffect(m);
|
||||
curseLevel += 4;
|
||||
}
|
||||
|
||||
if (BloodOathSpell.RemoveCurse(m))
|
||||
{
|
||||
curseLevel += 3;
|
||||
}
|
||||
|
||||
if (MindRotSpell.HasMindRotScalar(m))
|
||||
{
|
||||
MindRotSpell.ClearMindRotScalar(m);
|
||||
curseLevel += 2;
|
||||
}
|
||||
|
||||
if (SpellPlagueSpell.HasSpellPlague(m))
|
||||
{
|
||||
SpellPlagueSpell.RemoveFromList(m);
|
||||
curseLevel += 4;
|
||||
}
|
||||
|
||||
if (FeeblemindSpell.IsUnderEffects(m))
|
||||
{
|
||||
FeeblemindSpell.RemoveEffects(m);
|
||||
curseLevel += 1;
|
||||
}
|
||||
|
||||
if (ClumsySpell.IsUnderEffects(m))
|
||||
{
|
||||
ClumsySpell.RemoveEffects(m);
|
||||
curseLevel += 1;
|
||||
}
|
||||
|
||||
if (WeakenSpell.IsUnderEffects(m))
|
||||
{
|
||||
WeakenSpell.RemoveEffects(m);
|
||||
curseLevel += 1;
|
||||
}
|
||||
|
||||
if (MortalStrike.IsWounded(m))
|
||||
{
|
||||
MortalStrike.EndWound(m);
|
||||
curseLevel += 2;
|
||||
}
|
||||
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.Clumsy);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.FeebleMind);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.Weaken);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.Curse);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.MassCurse);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.MortalStrike);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.Mindrot);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.CorpseSkin);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.Strangle);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.EvilOmen);
|
||||
|
||||
return curseLevel;
|
||||
}
|
||||
|
||||
public class InternalTarget : Target
|
||||
{
|
||||
public CleansingWindsSpell Owner { get; set; }
|
||||
|
||||
public InternalTarget(CleansingWindsSpell owner)
|
||||
: this(owner, false)
|
||||
{
|
||||
}
|
||||
|
||||
public InternalTarget(CleansingWindsSpell owner, bool allowland)
|
||||
: base(12, allowland, TargetFlags.Beneficial)
|
||||
{
|
||||
Owner = owner;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object o)
|
||||
{
|
||||
if (o == null)
|
||||
return;
|
||||
|
||||
if (!from.CanSee(o))
|
||||
from.SendLocalizedMessage(500237); // Target can not be seen.
|
||||
else
|
||||
{
|
||||
SpellHelper.Turn(from, o);
|
||||
Owner.OnTarget(o);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnTargetFinish(Mobile from)
|
||||
{
|
||||
Owner.FinishSequence();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
112
Scripts/Spells/Mysticism/SpellDefinitions/EagleStrikeSpell.cs
Normal file
112
Scripts/Spells/Mysticism/SpellDefinitions/EagleStrikeSpell.cs
Normal file
@@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Spells;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Spells.Mysticism
|
||||
{
|
||||
public class EagleStrikeSpell : MysticSpell
|
||||
{
|
||||
public override SpellCircle Circle { get { return SpellCircle.Third; } }
|
||||
public override bool DelayedDamage { get { return true; } }
|
||||
public override bool DelayedDamageStacking { get { return false; } }
|
||||
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Eagle Strike", "Kal Por Xen",
|
||||
230,
|
||||
9022,
|
||||
Reagent.Bloodmoss,
|
||||
Reagent.Bone,
|
||||
Reagent.MandrakeRoot,
|
||||
Reagent.SpidersSilk
|
||||
);
|
||||
|
||||
public EagleStrikeSpell(Mobile caster, Item scroll) : base(caster, scroll, m_Info)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
Caster.Target = new InternalTarget(this);
|
||||
}
|
||||
|
||||
public void OnTarget(IDamageable d)
|
||||
{
|
||||
if (d == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (CheckHSequence(d))
|
||||
{
|
||||
IDamageable target = d;
|
||||
IDamageable source = Caster;
|
||||
|
||||
SpellHelper.Turn(Caster, target);
|
||||
|
||||
if (Core.SA && HasDelayContext(target))
|
||||
{
|
||||
DoHurtFizzle();
|
||||
return;
|
||||
}
|
||||
|
||||
if (SpellHelper.CheckReflect((int)Circle, ref source, ref target))
|
||||
{
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(.5), () =>
|
||||
{
|
||||
source.MovingEffect(target, 0x407A, 8, 1, false, true, 0, 0);
|
||||
source.PlaySound(0x2EE);
|
||||
});
|
||||
}
|
||||
|
||||
Caster.MovingEffect(d, 0x407A, 8, 1, false, true, 0, 0);
|
||||
Caster.PlaySound(0x2EE);
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(.5), () =>
|
||||
{
|
||||
Caster.PlaySound(0x64D);
|
||||
});
|
||||
|
||||
SpellHelper.Damage(this, target, (int)GetNewAosDamage(19, 1, 5, target), 0, 0, 0, 0, 100);
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
|
||||
public class InternalTarget : Target
|
||||
{
|
||||
public EagleStrikeSpell Owner { get; set; }
|
||||
|
||||
public InternalTarget(EagleStrikeSpell owner)
|
||||
: this(owner, false)
|
||||
{
|
||||
}
|
||||
|
||||
public InternalTarget(EagleStrikeSpell owner, bool allowland)
|
||||
: base(12, allowland, TargetFlags.Harmful)
|
||||
{
|
||||
Owner = owner;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object o)
|
||||
{
|
||||
if (o == null)
|
||||
return;
|
||||
|
||||
if (!from.CanSee(o))
|
||||
from.SendLocalizedMessage(500237); // Target can not be seen.
|
||||
else if (o is IDamageable)
|
||||
{
|
||||
SpellHelper.Turn(from, o);
|
||||
Owner.OnTarget((IDamageable)o);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnTargetFinish(Mobile from)
|
||||
{
|
||||
Owner.FinishSequence();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
94
Scripts/Spells/Mysticism/SpellDefinitions/EnchantGump.cs
Normal file
94
Scripts/Spells/Mysticism/SpellDefinitions/EnchantGump.cs
Normal file
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using System.Collections.Generic;
|
||||
using Server.Spells.Mysticism;
|
||||
using Server.Spells;
|
||||
|
||||
namespace Server.Gumps
|
||||
{
|
||||
public class EnchantSpellGump : Gump
|
||||
{
|
||||
private Mobile m_Caster;
|
||||
private Item m_Scroll;
|
||||
private BaseWeapon m_Weapon;
|
||||
|
||||
public EnchantSpellGump(Mobile caster, Item scroll, BaseWeapon weapon)
|
||||
: base(20, 20)
|
||||
{
|
||||
m_Caster = caster;
|
||||
m_Scroll = scroll;
|
||||
m_Weapon = weapon;
|
||||
|
||||
int font = 0x07FF;
|
||||
|
||||
AddBackground(0, 0, 260, 187, 3600);
|
||||
AddAlphaRegion(5, 15, 242, 170);
|
||||
|
||||
AddImageTiled(220, 15, 30, 162, 10464);
|
||||
|
||||
AddItem(0, 3, 6882);
|
||||
AddItem(-8, 170, 6880);
|
||||
AddItem(185, 3, 6883);
|
||||
AddItem(192, 170, 6881);
|
||||
|
||||
AddHtmlLocalized(20, 22, 150, 16, 1080133, font, false, false); //Select Enchant
|
||||
|
||||
AddButton(20, 50, 9702, 9703, 1, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(45, 50, 200, 16, 1079705, font, false, false); //Hit Lighting
|
||||
|
||||
AddButton(20, 75, 9702, 9703, 2, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(45, 75, 200, 16, 1079703, font, false, false); //Hit Fireball
|
||||
|
||||
AddButton(20, 100, 9702, 9703, 3, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(45, 100, 200, 16, 1079704, font, false, false); //Hit Harm
|
||||
|
||||
AddButton(20, 125, 9702, 9703, 4, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(45, 125, 200, 16, 1079706, font, false, false); //Hit Magic Arrow
|
||||
|
||||
AddButton(20, 150, 9702, 9703, 5, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(45, 150, 200, 16, 1079702, font, false, false); //Hit Dispel
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
AosWeaponAttribute attr = AosWeaponAttribute.HitLightning;
|
||||
|
||||
switch (info.ButtonID)
|
||||
{
|
||||
default:
|
||||
m_Caster.SendLocalizedMessage(1080132); //You decide not to enchant your weapon.
|
||||
return;
|
||||
case 1: //Hit Lightning
|
||||
{
|
||||
attr = AosWeaponAttribute.HitLightning;
|
||||
break;
|
||||
}
|
||||
case 2: //Hit Fireball
|
||||
{
|
||||
attr = AosWeaponAttribute.HitFireball;
|
||||
break;
|
||||
}
|
||||
case 3: //Hit Harm
|
||||
{
|
||||
attr = AosWeaponAttribute.HitHarm;
|
||||
break;
|
||||
}
|
||||
case 4: //Hit Magic Arrow
|
||||
{
|
||||
attr = AosWeaponAttribute.HitMagicArrow;
|
||||
break;
|
||||
}
|
||||
case 5: //Hit Dispel
|
||||
{
|
||||
attr = AosWeaponAttribute.HitDispel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Spell spell = new EnchantSpell(m_Caster, m_Scroll, m_Weapon, attr);
|
||||
spell.Cast();
|
||||
}
|
||||
}
|
||||
}
|
||||
259
Scripts/Spells/Mysticism/SpellDefinitions/EnchantSpell .cs
Normal file
259
Scripts/Spells/Mysticism/SpellDefinitions/EnchantSpell .cs
Normal file
@@ -0,0 +1,259 @@
|
||||
using System;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using System.Collections.Generic;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Spells;
|
||||
using Server.Network;
|
||||
using Server.Spells.Spellweaving;
|
||||
|
||||
namespace Server.Spells.Mysticism
|
||||
{
|
||||
public class EnchantSpell : MysticSpell
|
||||
{
|
||||
private static readonly string ModName = "EnchantAttribute";
|
||||
|
||||
public override SpellCircle Circle { get { return SpellCircle.Second; } }
|
||||
public override bool ClearHandsOnCast { get { return false; } }
|
||||
|
||||
public BaseWeapon Weapon { get; set; }
|
||||
public AosWeaponAttribute Attribute { get; set; }
|
||||
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Enchant", "In Ort Ylem",
|
||||
230,
|
||||
9022,
|
||||
Reagent.SpidersSilk,
|
||||
Reagent.MandrakeRoot,
|
||||
Reagent.SulfurousAsh
|
||||
);
|
||||
|
||||
public EnchantSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
|
||||
{
|
||||
}
|
||||
|
||||
public EnchantSpell( Mobile caster, Item scroll, BaseWeapon weapon, AosWeaponAttribute attribute ) : base( caster, scroll, m_Info )
|
||||
{
|
||||
Weapon = weapon;
|
||||
this.Attribute = attribute;
|
||||
}
|
||||
|
||||
public override bool CheckCast()
|
||||
{
|
||||
if (Weapon == null)
|
||||
{
|
||||
BaseWeapon wep = Caster.Weapon as BaseWeapon;
|
||||
|
||||
if (wep == null)
|
||||
{
|
||||
Caster.SendLocalizedMessage(501078); // You must be holding a weapon.
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Caster.HasGump(typeof(EnchantSpellGump)))
|
||||
{
|
||||
Caster.CloseGump(typeof(EnchantSpellGump));
|
||||
}
|
||||
|
||||
var gump = new EnchantSpellGump(Caster, Scroll, wep);
|
||||
int serial = gump.Serial;
|
||||
|
||||
Caster.SendGump(gump);
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(30), () =>
|
||||
{
|
||||
var current = Caster.FindGump(typeof(EnchantSpellGump));
|
||||
|
||||
if (current != null && current.Serial == serial)
|
||||
{
|
||||
Caster.CloseGump(typeof(EnchantSpellGump));
|
||||
FinishSequence();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
else if (IsUnderSpellEffects(Caster, Weapon))
|
||||
{
|
||||
Caster.SendLocalizedMessage(501775); // This spell is already in effect.
|
||||
return false;
|
||||
}
|
||||
else if (ImmolatingWeaponSpell.IsImmolating(Caster, Weapon) || Weapon.ConsecratedContext != null)
|
||||
{
|
||||
Caster.SendLocalizedMessage(1080128); //You cannot use this ability while your weapon is enchanted.
|
||||
return false;
|
||||
}
|
||||
else if (Weapon.FocusWeilder != null)
|
||||
{
|
||||
Caster.SendLocalizedMessage(1080446); // You cannot enchant an item that is under the effects of the ninjitsu focus attack ability.
|
||||
return false;
|
||||
}
|
||||
else if (Weapon.WeaponAttributes.HitLightning > 0 || Weapon.WeaponAttributes.HitFireball > 0 || Weapon.WeaponAttributes.HitHarm > 0 || Weapon.WeaponAttributes.HitMagicArrow > 0 || Weapon.WeaponAttributes.HitDispel > 0)
|
||||
{
|
||||
Caster.SendLocalizedMessage(1080127); // This weapon already has a hit spell effect and cannot be enchanted.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
BaseWeapon wep = Caster.Weapon as BaseWeapon;
|
||||
|
||||
if (wep == null || wep != Weapon)
|
||||
{
|
||||
Caster.SendLocalizedMessage(501078); // You must be holding a weapon.
|
||||
}
|
||||
else if (IsUnderSpellEffects(Caster, Weapon))
|
||||
{
|
||||
Caster.SendLocalizedMessage(501775); // This spell is already in effect.
|
||||
}
|
||||
else if (ImmolatingWeaponSpell.IsImmolating(Caster, Weapon) || Weapon.ConsecratedContext != null)
|
||||
{
|
||||
Caster.SendLocalizedMessage(1080128); //You cannot use this ability while your weapon is enchanted.
|
||||
}
|
||||
else if (Weapon.FocusWeilder != null)
|
||||
{
|
||||
Caster.SendLocalizedMessage(1080446); // You cannot enchant an item that is under the effects of the ninjitsu focus attack ability.
|
||||
}
|
||||
else if (Weapon.WeaponAttributes.HitLightning > 0 || Weapon.WeaponAttributes.HitFireball > 0 || Weapon.WeaponAttributes.HitHarm > 0 || Weapon.WeaponAttributes.HitMagicArrow > 0 || Weapon.WeaponAttributes.HitDispel > 0)
|
||||
{
|
||||
Caster.SendLocalizedMessage(1080127); // This weapon already has a hit spell effect and cannot be enchanted.
|
||||
}
|
||||
else if (CheckSequence() && Caster.Weapon == Weapon)
|
||||
{
|
||||
Caster.PlaySound(0x64E);
|
||||
Caster.FixedEffect(0x36CB, 1, 9, 1915, 0);
|
||||
|
||||
int prim = (int)Caster.Skills[CastSkill].Value;
|
||||
int sec = (int)Caster.Skills[DamageSkill].Value;
|
||||
|
||||
int value = (60 * (prim + sec)) / 240;
|
||||
double duration = ((double)(prim + sec) / 2.0) + 30.0;
|
||||
int malus = 0;
|
||||
|
||||
if (Table == null)
|
||||
Table = new Dictionary<Mobile, EnchantmentTimer>();
|
||||
|
||||
Enhancement.SetValue(Caster, this.Attribute, value, ModName);
|
||||
|
||||
if (prim >= 80 && sec >= 80 && Weapon.Attributes.SpellChanneling == 0)
|
||||
{
|
||||
Enhancement.SetValue(Caster, AosAttribute.SpellChanneling, 1, ModName);
|
||||
Enhancement.SetValue(Caster, AosAttribute.CastSpeed, -1, ModName);
|
||||
malus = 1;
|
||||
}
|
||||
|
||||
Table[Caster] = new EnchantmentTimer(Caster, Weapon, this.Attribute, value, malus, duration);
|
||||
|
||||
int loc;
|
||||
|
||||
switch (this.Attribute)
|
||||
{
|
||||
default:
|
||||
case AosWeaponAttribute.HitLightning: loc = 1060423; break;
|
||||
case AosWeaponAttribute.HitFireball: loc = 1060420; break;
|
||||
case AosWeaponAttribute.HitHarm: loc = 1060421; break;
|
||||
case AosWeaponAttribute.HitMagicArrow: loc = 1060426; break;
|
||||
case AosWeaponAttribute.HitDispel: loc = 1060417; break;
|
||||
}
|
||||
|
||||
BuffInfo.AddBuff(Caster, new BuffInfo(BuffIcon.Enchant, 1080126, loc, TimeSpan.FromSeconds(duration), Caster, value.ToString()));
|
||||
|
||||
Weapon.EnchantedWeilder = Caster;
|
||||
Weapon.InvalidateProperties();
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
|
||||
public static Dictionary<Mobile, EnchantmentTimer> Table { get; set; }
|
||||
|
||||
public static bool IsUnderSpellEffects(Mobile Caster, BaseWeapon wep)
|
||||
{
|
||||
if (Table == null)
|
||||
return false;
|
||||
|
||||
return Table.ContainsKey(Caster) && Table[Caster].Weapon == wep;
|
||||
}
|
||||
|
||||
public static AosWeaponAttribute BonusAttribute(Mobile from)
|
||||
{
|
||||
if (Table.ContainsKey(from))
|
||||
return Table[from].WeaponAttribute;
|
||||
|
||||
return AosWeaponAttribute.HitColdArea;
|
||||
}
|
||||
|
||||
public static int BonusValue(Mobile from)
|
||||
{
|
||||
if (Table.ContainsKey(from))
|
||||
return Table[from].AttributeValue;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static bool CastingMalus(Mobile from, BaseWeapon weapon)
|
||||
{
|
||||
if (Table.ContainsKey(from))
|
||||
return Table[from].CastingMalus > 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void RemoveEnchantment(Mobile caster)
|
||||
{
|
||||
if(Table != null && Table.ContainsKey(caster))
|
||||
{
|
||||
Table[caster].Stop();
|
||||
Table[caster] = null;
|
||||
Table.Remove(caster);
|
||||
|
||||
caster.SendLocalizedMessage(1115273); // The enchantment on your weapon has expired.
|
||||
caster.PlaySound(0x1E6);
|
||||
|
||||
Enhancement.RemoveMobile(caster);
|
||||
}
|
||||
}
|
||||
|
||||
public static void OnWeaponRemoved(BaseWeapon wep, Mobile from)
|
||||
{
|
||||
if(IsUnderSpellEffects(from, wep))
|
||||
RemoveEnchantment(from);
|
||||
|
||||
if (wep.EnchantedWeilder != null)
|
||||
wep.EnchantedWeilder = null;
|
||||
}
|
||||
}
|
||||
|
||||
public class EnchantmentTimer : Timer
|
||||
{
|
||||
public Mobile Owner { get; set; }
|
||||
public BaseWeapon Weapon { get; set; }
|
||||
public AosWeaponAttribute WeaponAttribute { get; set; }
|
||||
public int AttributeValue { get; set; }
|
||||
public int CastingMalus { get; set; }
|
||||
|
||||
public EnchantmentTimer(Mobile owner, BaseWeapon wep, AosWeaponAttribute attribute, int value, int malus, double duration) : base(TimeSpan.FromSeconds(duration))
|
||||
{
|
||||
Owner = owner;
|
||||
Weapon = wep;
|
||||
WeaponAttribute = attribute;
|
||||
AttributeValue = value;
|
||||
CastingMalus = malus;
|
||||
|
||||
this.Start();
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if(Weapon != null)
|
||||
Weapon.EnchantedWeilder = null;
|
||||
|
||||
EnchantSpell.RemoveEnchantment(Owner);
|
||||
}
|
||||
}
|
||||
}
|
||||
122
Scripts/Spells/Mysticism/SpellDefinitions/HailStormSpell.cs
Normal file
122
Scripts/Spells/Mysticism/SpellDefinitions/HailStormSpell.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Spells;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Spells.Mysticism
|
||||
{
|
||||
public class HailStormSpell : MysticSpell
|
||||
{
|
||||
public override SpellCircle Circle { get { return SpellCircle.Seventh; } }
|
||||
public override bool DelayedDamage { get { return true; } }
|
||||
public override DamageType SpellDamageType { get { return DamageType.SpellAOE; } }
|
||||
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Hail Storm", "Kal Des Ylem",
|
||||
230,
|
||||
9022,
|
||||
Reagent.BlackPearl,
|
||||
Reagent.Bloodmoss,
|
||||
Reagent.MandrakeRoot,
|
||||
Reagent.DragonBlood
|
||||
);
|
||||
|
||||
public HailStormSpell(Mobile caster, Item scroll)
|
||||
: base(caster, scroll, m_Info)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
Caster.Target = new InternalTarget(this);
|
||||
}
|
||||
|
||||
public void OnTarget(IPoint3D p)
|
||||
{
|
||||
if (SpellHelper.CheckTown(p, Caster) && CheckSequence())
|
||||
{
|
||||
SpellHelper.Turn(Caster, p);
|
||||
SpellHelper.GetSurfaceTop(ref p);
|
||||
|
||||
Map map = Caster.Map;
|
||||
|
||||
if (map == null)
|
||||
return;
|
||||
|
||||
Rectangle2D effectArea = new Rectangle2D(p.X - 3, p.Y - 3, 6, 6);
|
||||
Effects.PlaySound(p, map, 0x64F);
|
||||
|
||||
for (int x = effectArea.X; x <= effectArea.X + effectArea.Width; x++)
|
||||
{
|
||||
for (int y = effectArea.Y; y <= effectArea.Y + effectArea.Height; y++)
|
||||
{
|
||||
if (x == effectArea.X && y == effectArea.Y ||
|
||||
x >= effectArea.X + effectArea.Width - 1 && y >= effectArea.Y + effectArea.Height - 1 ||
|
||||
y >= effectArea.Y + effectArea.Height - 1 && x == effectArea.X ||
|
||||
y == effectArea.Y && x >= effectArea.X + effectArea.Width - 1)
|
||||
continue;
|
||||
|
||||
IPoint3D pnt = new Point3D(x, y, p.Z);
|
||||
SpellHelper.GetSurfaceTop(ref pnt);
|
||||
|
||||
Timer.DelayCall<Point3D>(TimeSpan.FromMilliseconds(Utility.RandomMinMax(100, 300)), point =>
|
||||
{
|
||||
Effects.SendLocationEffect(point, map, 0x3779, 12, 11, 0x63, 0);
|
||||
},
|
||||
new Point3D(pnt));
|
||||
}
|
||||
}
|
||||
|
||||
var list = AcquireIndirectTargets(p, 2).ToList();
|
||||
int count = list.Count;
|
||||
|
||||
foreach (var id in list)
|
||||
{
|
||||
if (id.Deleted)
|
||||
continue;
|
||||
|
||||
int damage = GetNewAosDamage(51, 1, 5, id is PlayerMobile, id);
|
||||
|
||||
if (count > 2)
|
||||
damage = (damage * 2) / count;
|
||||
|
||||
Caster.DoHarmful(id);
|
||||
SpellHelper.Damage(this, id, damage, 0, 0, 100, 0, 0);
|
||||
|
||||
Server.Effects.SendTargetParticles(id, 0x374A, 1, 15, 9502, 97, 3, (EffectLayer)255, 0);
|
||||
}
|
||||
|
||||
ColUtility.Free(list);
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
|
||||
public class InternalTarget : Target
|
||||
{
|
||||
private HailStormSpell m_Owner;
|
||||
|
||||
public InternalTarget(HailStormSpell owner)
|
||||
: base(10, true, TargetFlags.None)
|
||||
{
|
||||
m_Owner = owner;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object o)
|
||||
{
|
||||
if (o is IPoint3D)
|
||||
m_Owner.OnTarget((IPoint3D)o);
|
||||
}
|
||||
|
||||
protected override void OnTargetFinish(Mobile from)
|
||||
{
|
||||
m_Owner.FinishSequence();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Spells;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Spells.Mysticism
|
||||
{
|
||||
public class HealingStoneSpell : MysticSpell
|
||||
{
|
||||
public override SpellCircle Circle { get { return SpellCircle.First; } }
|
||||
|
||||
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds(5); } }
|
||||
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Healing Stone", "Kal In Mani",
|
||||
230,
|
||||
9022,
|
||||
Reagent.Bone,
|
||||
Reagent.Garlic,
|
||||
Reagent.Ginseng,
|
||||
Reagent.SpidersSilk
|
||||
);
|
||||
|
||||
public HealingStoneSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
if ( Caster.Backpack != null && CheckSequence() )
|
||||
{
|
||||
Item[] stones = Caster.Backpack.FindItemsByType( typeof( HealingStone ) );
|
||||
|
||||
for ( int i = 0; i < stones.Length; i++ )
|
||||
stones[i].Delete();
|
||||
|
||||
int amount = (int)((Caster.Skills[CastSkill].Value + Caster.Skills[DamageSkill].Value) * 1.5);
|
||||
int maxHeal = (int)((Caster.Skills[CastSkill].Value + Caster.Skills[DamageSkill].Value) / 5);
|
||||
|
||||
Caster.PlaySound( 0x650 );
|
||||
Caster.FixedParticles(0x3779, 1, 15, 0x251E, 0, 0, EffectLayer.Waist);
|
||||
|
||||
Caster.Backpack.DropItem( new HealingStone( Caster, amount, maxHeal ) );
|
||||
Caster.SendLocalizedMessage( 1080115 ); // A Healing Stone appears in your backpack.
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
}
|
||||
}
|
||||
84
Scripts/Spells/Mysticism/SpellDefinitions/MassSleepSpell.cs
Normal file
84
Scripts/Spells/Mysticism/SpellDefinitions/MassSleepSpell.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Spells.Mysticism
|
||||
{
|
||||
public class MassSleepSpell : MysticSpell
|
||||
{
|
||||
public override SpellCircle Circle { get { return SpellCircle.Fifth; } }
|
||||
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Mass Sleep", "Vas Zu",
|
||||
230,
|
||||
9022,
|
||||
Reagent.Ginseng,
|
||||
Reagent.Nightshade,
|
||||
Reagent.SpidersSilk
|
||||
);
|
||||
|
||||
public MassSleepSpell(Mobile caster, Item scroll) : base(caster, scroll, m_Info)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
Caster.Target = new InternalTarget(this);
|
||||
}
|
||||
|
||||
public class InternalTarget : Target
|
||||
{
|
||||
private MassSleepSpell m_Owner;
|
||||
|
||||
public InternalTarget(MassSleepSpell owner)
|
||||
: base(10, true, TargetFlags.None)
|
||||
{
|
||||
m_Owner = owner;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object o)
|
||||
{
|
||||
if (o is IPoint3D)
|
||||
m_Owner.Target((IPoint3D)o);
|
||||
}
|
||||
|
||||
protected override void OnTargetFinish(Mobile from)
|
||||
{
|
||||
m_Owner.FinishSequence();
|
||||
}
|
||||
}
|
||||
|
||||
public void Target(IPoint3D p)
|
||||
{
|
||||
if (!Caster.CanSee(p))
|
||||
{
|
||||
Caster.SendLocalizedMessage(500237); // Target can not be seen.
|
||||
}
|
||||
else if (SpellHelper.CheckTown(p, Caster) && CheckSequence())
|
||||
{
|
||||
Map map = Caster.Map;
|
||||
|
||||
if (map == null)
|
||||
return;
|
||||
|
||||
foreach (var m in AcquireIndirectTargets(p, 3).OfType<Mobile>())
|
||||
{
|
||||
double duration = ((Caster.Skills[CastSkill].Value + Caster.Skills[DamageSkill].Value) / 20) + 3;
|
||||
duration -= GetResistSkill(m) / 10;
|
||||
|
||||
if (duration > 0)
|
||||
{
|
||||
Caster.DoHarmful(m);
|
||||
|
||||
SleepSpell.DoSleep(Caster, m, TimeSpan.FromSeconds(duration));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server;
|
||||
using Server.Spells.Fifth;
|
||||
using Server.Spells.Seventh;
|
||||
|
||||
namespace Server.Spells.Mysticism
|
||||
{
|
||||
public abstract class MysticTransformationSpell : MysticSpell, ITransformationSpell
|
||||
{
|
||||
public abstract int Body{ get; }
|
||||
public virtual int Hue{ get{ return 0; } }
|
||||
|
||||
public virtual int PhysResistOffset{ get{ return 0; } }
|
||||
public virtual int FireResistOffset{ get{ return 0; } }
|
||||
public virtual int ColdResistOffset{ get{ return 0; } }
|
||||
public virtual int PoisResistOffset{ get{ return 0; } }
|
||||
public virtual int NrgyResistOffset{ get{ return 0; } }
|
||||
|
||||
public MysticTransformationSpell( Mobile caster, Item scroll, SpellInfo info ) : base( caster, scroll, info )
|
||||
{
|
||||
}
|
||||
|
||||
public override bool BlockedByHorrificBeast{ get{ return false; } }
|
||||
|
||||
public override bool CheckCast()
|
||||
{
|
||||
if( !TransformationSpellHelper.CheckCast( Caster, this ) )
|
||||
return false;
|
||||
|
||||
return base.CheckCast();
|
||||
}
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
TransformationSpellHelper.OnCast( Caster, this );
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
|
||||
public virtual double TickRate{ get{ return 1.0; } }
|
||||
|
||||
public virtual void OnTick( Mobile m )
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void DoEffect( Mobile m )
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void RemoveEffect( Mobile m )
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
105
Scripts/Spells/Mysticism/SpellDefinitions/NetherBoltSpell.cs
Normal file
105
Scripts/Spells/Mysticism/SpellDefinitions/NetherBoltSpell.cs
Normal file
@@ -0,0 +1,105 @@
|
||||
using System;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Spells.Mysticism
|
||||
{
|
||||
public class NetherBoltSpell : MysticSpell
|
||||
{
|
||||
public override SpellCircle Circle { get { return SpellCircle.First; } }
|
||||
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Nether Bolt", "In Corp Ylem",
|
||||
230,
|
||||
9022,
|
||||
Reagent.BlackPearl,
|
||||
Reagent.SulfurousAsh
|
||||
);
|
||||
|
||||
public NetherBoltSpell(Mobile caster, Item scroll) : base(caster, scroll, m_Info)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool DelayedDamage { get { return true; } }
|
||||
public override bool DelayedDamageStacking { get { return false; } }
|
||||
public override Type[] DelayDamageFamily { get { return new Type[] { typeof(Server.Spells.First.MagicArrowSpell) }; } }
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
Caster.Target = new InternalTarget(this);
|
||||
}
|
||||
|
||||
public void OnTarget(IDamageable d)
|
||||
{
|
||||
if (d == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (CheckHSequence(d))
|
||||
{
|
||||
IDamageable target = d;
|
||||
IDamageable source = Caster;
|
||||
|
||||
SpellHelper.Turn(Caster, target);
|
||||
|
||||
if (Core.SA && HasDelayContext(target))
|
||||
{
|
||||
DoHurtFizzle();
|
||||
return;
|
||||
}
|
||||
|
||||
if (SpellHelper.CheckReflect((int)Circle, ref source, ref target))
|
||||
{
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(.5), () =>
|
||||
{
|
||||
source.MovingParticles(target, 0x36D4, 7, 0, false, true, 0x49A, 0, 0, 9502, 4019, 0x160);
|
||||
source.PlaySound(0x211);
|
||||
});
|
||||
}
|
||||
|
||||
double damage = GetNewAosDamage(10, 1, 4, target);
|
||||
|
||||
SpellHelper.Damage(this, target, damage, 0, 0, 0, 0, 0, 100, 0);
|
||||
|
||||
Caster.MovingParticles(d, 0x36D4, 7, 0, false, true, 0x49A, 0, 0, 9502, 4019, 0x160);
|
||||
Caster.PlaySound(0x211);
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
|
||||
public class InternalTarget : Target
|
||||
{
|
||||
public NetherBoltSpell Owner { get; set; }
|
||||
|
||||
public InternalTarget(NetherBoltSpell owner)
|
||||
: this(owner, false)
|
||||
{
|
||||
}
|
||||
|
||||
public InternalTarget(NetherBoltSpell owner, bool allowland)
|
||||
: base(12, allowland, TargetFlags.Harmful)
|
||||
{
|
||||
Owner = owner;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object o)
|
||||
{
|
||||
if (o == null)
|
||||
return;
|
||||
|
||||
if (!from.CanSee(o))
|
||||
from.SendLocalizedMessage(500237); // Target can not be seen.
|
||||
else if (o is IDamageable)
|
||||
{
|
||||
SpellHelper.Turn(from, o);
|
||||
Owner.OnTarget((IDamageable)o);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnTargetFinish(Mobile from)
|
||||
{
|
||||
Owner.FinishSequence();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
146
Scripts/Spells/Mysticism/SpellDefinitions/NetherCycloneSpell.cs
Normal file
146
Scripts/Spells/Mysticism/SpellDefinitions/NetherCycloneSpell.cs
Normal file
@@ -0,0 +1,146 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Items;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Spells.Mysticism
|
||||
{
|
||||
public class NetherCycloneSpell : MysticSpell
|
||||
{
|
||||
public override SpellCircle Circle { get { return SpellCircle.Eighth; } }
|
||||
public override DamageType SpellDamageType { get { return DamageType.SpellAOE; } }
|
||||
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Nether Cyclone", "Grav Hur",
|
||||
230,
|
||||
9022,
|
||||
Reagent.MandrakeRoot,
|
||||
Reagent.Nightshade,
|
||||
Reagent.SulfurousAsh,
|
||||
Reagent.Bloodmoss
|
||||
);
|
||||
|
||||
public NetherCycloneSpell(Mobile caster, Item scroll) : base(caster, scroll, m_Info)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
Caster.Target = new InternalTarget(this);
|
||||
}
|
||||
|
||||
public void OnTarget(IPoint3D p)
|
||||
{
|
||||
if (p != null && CheckSequence())
|
||||
{
|
||||
SpellHelper.Turn(Caster, p);
|
||||
SpellHelper.GetSurfaceTop(ref p);
|
||||
Map map = Caster.Map;
|
||||
|
||||
if (map != null)
|
||||
{
|
||||
Rectangle2D effectArea = new Rectangle2D(p.X - 3, p.Y - 3, 6, 6);
|
||||
Effects.PlaySound(p, map, 0x64F);
|
||||
|
||||
for (int x = effectArea.X; x <= effectArea.X + effectArea.Width; x++)
|
||||
{
|
||||
for (int y = effectArea.Y; y <= effectArea.Y + effectArea.Height; y++)
|
||||
{
|
||||
if (x == effectArea.X && y == effectArea.Y ||
|
||||
x >= effectArea.X + effectArea.Width - 1 && y >= effectArea.Y + effectArea.Height - 1 ||
|
||||
y >= effectArea.Y + effectArea.Height - 1 && x == effectArea.X ||
|
||||
y == effectArea.Y && x >= effectArea.X + effectArea.Width - 1)
|
||||
continue;
|
||||
|
||||
IPoint3D pnt = new Point3D(x, y, p.Z);
|
||||
SpellHelper.GetSurfaceTop(ref pnt);
|
||||
|
||||
Timer.DelayCall<Point3D>(TimeSpan.FromMilliseconds(Utility.RandomMinMax(100, 300)), point =>
|
||||
{
|
||||
Effects.SendLocationEffect(point, map, 0x375A, 8, 11, 0x49A, 0);
|
||||
},
|
||||
new Point3D(pnt));
|
||||
}
|
||||
}
|
||||
|
||||
foreach(var d in AcquireIndirectTargets(p, 3))
|
||||
{
|
||||
Server.Effects.SendTargetParticles(d, 0x374A, 1, 15, 9502, 97, 3, (EffectLayer)255, 0);
|
||||
|
||||
double damage = (((Caster.Skills[CastSkill].Value + (Caster.Skills[DamageSkill].Value / 2)) * .66) + Utility.RandomMinMax(1, 6));
|
||||
|
||||
SpellHelper.Damage(this, d, damage, 0, 0, 0, 0, 0, 100, 0);
|
||||
|
||||
if (d is Mobile)
|
||||
{
|
||||
Mobile m = d as Mobile;
|
||||
|
||||
double stamSap = (damage / 3);
|
||||
double manaSap = (damage / 3);
|
||||
double mod = m.Skills[SkillName.MagicResist].Value - ((Caster.Skills[CastSkill].Value + Caster.Skills[DamageSkill].Value) / 2);
|
||||
|
||||
if (mod > 0)
|
||||
{
|
||||
mod /= 100;
|
||||
|
||||
stamSap *= mod;
|
||||
manaSap *= mod;
|
||||
}
|
||||
|
||||
m.Stam -= (int)stamSap;
|
||||
m.Mana -= (int)manaSap;
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(10), () =>
|
||||
{
|
||||
if (m.Alive)
|
||||
{
|
||||
m.Stam += (int)stamSap;
|
||||
m.Mana += (int)manaSap;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Effects.SendLocationParticles(EffectItem.Create(d.Location, map, EffectItem.DefaultDuration), 0x37CC, 1, 40, 97, 3, 9917, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
|
||||
public class InternalTarget : Target
|
||||
{
|
||||
public NetherCycloneSpell Owner { get; set; }
|
||||
|
||||
public InternalTarget(NetherCycloneSpell owner)
|
||||
: this(owner, false)
|
||||
{
|
||||
}
|
||||
|
||||
public InternalTarget(NetherCycloneSpell owner, bool allowland)
|
||||
: base(12, allowland, TargetFlags.None)
|
||||
{
|
||||
Owner = owner;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object o)
|
||||
{
|
||||
if (o == null)
|
||||
return;
|
||||
|
||||
if (!from.CanSee(o))
|
||||
from.SendLocalizedMessage(500237); // Target can not be seen.
|
||||
else if(o is IPoint3D)
|
||||
{
|
||||
SpellHelper.Turn(from, o);
|
||||
Owner.OnTarget((IPoint3D)o);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnTargetFinish(Mobile from)
|
||||
{
|
||||
Owner.FinishSequence();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
342
Scripts/Spells/Mysticism/SpellDefinitions/PurgeMagicSpell.cs
Normal file
342
Scripts/Spells/Mysticism/SpellDefinitions/PurgeMagicSpell.cs
Normal file
@@ -0,0 +1,342 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Spells;
|
||||
using Server.Targeting;
|
||||
using System.Collections.Generic;
|
||||
using Server.Spells.First;
|
||||
using Server.Spells.Second;
|
||||
using Server.Spells.Third;
|
||||
using Server.Spells.Fourth;
|
||||
using Server.Spells.Fifth;
|
||||
using Server.Spells.Ninjitsu;
|
||||
|
||||
namespace Server.Spells.Mysticism
|
||||
{
|
||||
public enum BuffType
|
||||
{
|
||||
None,
|
||||
MagicReflect,
|
||||
ReactiveArmor,
|
||||
Protection,
|
||||
Transformation,
|
||||
StrBonus,
|
||||
DexBonus,
|
||||
IntBonus,
|
||||
BarrabHemolymph,
|
||||
UraliTrance,
|
||||
Bless
|
||||
}
|
||||
|
||||
public class PurgeMagicSpell : MysticSpell
|
||||
{
|
||||
public override SpellCircle Circle { get { return SpellCircle.Second; } }
|
||||
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Purge", "An Ort Sanct ",
|
||||
230,
|
||||
9022,
|
||||
Reagent.Garlic,
|
||||
Reagent.MandrakeRoot,
|
||||
Reagent.SulfurousAsh,
|
||||
Reagent.FertileDirt
|
||||
);
|
||||
|
||||
public PurgeMagicSpell(Mobile caster, Item scroll) : base(caster, scroll, m_Info)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
Caster.Target = new InternalTarget(this);
|
||||
}
|
||||
|
||||
public void OnTarget(object o)
|
||||
{
|
||||
Mobile target = o as Mobile;
|
||||
|
||||
if (target == null)
|
||||
return;
|
||||
|
||||
if (m_CurseTable.ContainsKey(Caster))
|
||||
{
|
||||
Caster.SendLocalizedMessage(1154212); //You may not use the Purge Magic spell while you are under its curse.
|
||||
}
|
||||
else if (m_ImmuneTable.ContainsKey(target) || m_CurseTable.ContainsKey(target))
|
||||
{
|
||||
Caster.SendLocalizedMessage(1080119); // Your Purge Magic has been resisted!
|
||||
}
|
||||
else if (CheckHSequence(target))
|
||||
{
|
||||
if (CheckResisted(target))
|
||||
{
|
||||
target.SendLocalizedMessage(501783); // You feel yourself resisting magical energy.
|
||||
Caster.SendLocalizedMessage(1080119); //Your Purge Magic has been resisted!
|
||||
}
|
||||
else
|
||||
{
|
||||
SpellHelper.CheckReflect((int)Circle, Caster, ref target);
|
||||
|
||||
Caster.PlaySound(0x655);
|
||||
Effects.SendLocationParticles(EffectItem.Create(target.Location, target.Map, EffectItem.DefaultDuration), 0x3728, 1, 13, 0x834, 0, 0x13B2, 0);
|
||||
|
||||
BuffType type = GetRandomBuff(target);
|
||||
|
||||
if (type != BuffType.None)
|
||||
{
|
||||
string arg = "";
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case BuffType.MagicReflect:
|
||||
MagicReflectSpell.EndReflect(target);
|
||||
arg = "magic reflect";
|
||||
break;
|
||||
case BuffType.ReactiveArmor:
|
||||
ReactiveArmorSpell.EndArmor(target);
|
||||
arg = "reactive armor";
|
||||
break;
|
||||
case BuffType.Protection:
|
||||
ProtectionSpell.EndProtection(target);
|
||||
arg = "protection";
|
||||
break;
|
||||
case BuffType.Transformation:
|
||||
TransformationSpellHelper.RemoveContext(target, true);
|
||||
arg = "transformation spell";
|
||||
break;
|
||||
case BuffType.StrBonus:
|
||||
arg = "strength bonus";
|
||||
target.RemoveStatMod("[Magic] Str Buff");
|
||||
BuffInfo.RemoveBuff(target, BuffIcon.Strength);
|
||||
break;
|
||||
case BuffType.DexBonus:
|
||||
arg = "dexterity bonus";
|
||||
target.RemoveStatMod("[Magic] Dex Buff");
|
||||
BuffInfo.RemoveBuff(target, BuffIcon.Agility);
|
||||
break;
|
||||
case BuffType.IntBonus:
|
||||
arg = "intelligence bonus";
|
||||
target.RemoveStatMod("[Magic] Int Buff");
|
||||
BuffInfo.RemoveBuff(target, BuffIcon.Cunning);
|
||||
break;
|
||||
case BuffType.BarrabHemolymph:
|
||||
arg = "Barrab hemolymph";
|
||||
EodonianPotion.RemoveEffects(target, PotionEffect.Barrab);
|
||||
break;
|
||||
case BuffType.UraliTrance:
|
||||
arg = "Urali Trance";
|
||||
EodonianPotion.RemoveEffects(target, PotionEffect.Urali);
|
||||
break;
|
||||
case BuffType.Bless:
|
||||
arg = "bless";
|
||||
target.RemoveStatMod("[Magic] Str Buff");
|
||||
target.RemoveStatMod("[Magic] Dex Buff");
|
||||
target.RemoveStatMod("[Magic] Int Buff");
|
||||
BuffInfo.RemoveBuff(target, BuffIcon.Bless);
|
||||
BlessSpell.RemoveBless(target);
|
||||
break;
|
||||
}
|
||||
|
||||
target.SendLocalizedMessage(1080117, arg); //Your ~1_ABILITY_NAME~ has been purged.
|
||||
Caster.SendLocalizedMessage(1080118, arg); //Your target's ~1_ABILITY_NAME~ has been purged.
|
||||
|
||||
int duration = (int)((Caster.Skills[CastSkill].Value + Caster.Skills[DamageSkill].Value) / 15);
|
||||
|
||||
if (duration <= 0)
|
||||
duration = 1;
|
||||
|
||||
m_ImmuneTable.Add(target, new ImmuneTimer(target, TimeSpan.FromSeconds(duration)));
|
||||
}
|
||||
else
|
||||
{
|
||||
Caster.SendLocalizedMessage(1080120); //Your target has no magic that can be purged.
|
||||
|
||||
int duration = (int)((Caster.Skills[CastSkill].Value + Caster.Skills[DamageSkill].Value) / 28);
|
||||
|
||||
if (duration <= 0)
|
||||
duration = 1;
|
||||
|
||||
m_CurseTable.Add(target, new CurseTimer(target, Caster, TimeSpan.FromSeconds(duration)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
|
||||
public BuffType GetRandomBuff(Mobile target)
|
||||
{
|
||||
List<BuffType> buffs = new List<BuffType>();
|
||||
|
||||
if (MagicReflectSpell.HasReflect(target))
|
||||
buffs.Add(BuffType.MagicReflect);
|
||||
|
||||
if (ReactiveArmorSpell.HasArmor(target))
|
||||
buffs.Add(BuffType.ReactiveArmor);
|
||||
|
||||
if (ProtectionSpell.HasProtection(target))
|
||||
buffs.Add(BuffType.Protection);
|
||||
|
||||
TransformContext context = TransformationSpellHelper.GetContext(target);
|
||||
|
||||
if (context != null && context.Type != typeof(AnimalForm))
|
||||
buffs.Add(BuffType.Transformation);
|
||||
|
||||
if (BlessSpell.IsBlessed(target))
|
||||
{
|
||||
buffs.Add(BuffType.Bless);
|
||||
}
|
||||
else
|
||||
{
|
||||
StatMod mod = target.GetStatMod("[Magic] Str Buff");
|
||||
if (mod != null)
|
||||
buffs.Add(BuffType.StrBonus);
|
||||
|
||||
mod = target.GetStatMod("[Magic] Dex Buff");
|
||||
if (mod != null)
|
||||
buffs.Add(BuffType.DexBonus);
|
||||
|
||||
mod = target.GetStatMod("[Magic] Int Buff");
|
||||
if (mod != null)
|
||||
buffs.Add(BuffType.IntBonus);
|
||||
}
|
||||
|
||||
if (EodonianPotion.IsUnderEffects(target, PotionEffect.Barrab))
|
||||
buffs.Add(BuffType.BarrabHemolymph);
|
||||
|
||||
if (EodonianPotion.IsUnderEffects(target, PotionEffect.Urali))
|
||||
buffs.Add(BuffType.UraliTrance);
|
||||
|
||||
if (buffs.Count == 0)
|
||||
return BuffType.None;
|
||||
|
||||
BuffType type = buffs[Utility.Random(buffs.Count)];
|
||||
buffs.Clear();
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
private static Dictionary<Mobile, ImmuneTimer> m_ImmuneTable = new Dictionary<Mobile, ImmuneTimer>();
|
||||
private static Dictionary<Mobile, CurseTimer> m_CurseTable = new Dictionary<Mobile, CurseTimer>();
|
||||
|
||||
public static void RemoveImmunity(Mobile from)
|
||||
{
|
||||
if (m_ImmuneTable.ContainsKey(from))
|
||||
{
|
||||
m_ImmuneTable[from].Stop();
|
||||
m_ImmuneTable.Remove(from);
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemoveCurse(Mobile from, Mobile caster)
|
||||
{
|
||||
if (m_CurseTable.ContainsKey(from))
|
||||
{
|
||||
m_CurseTable[from].Stop();
|
||||
|
||||
if (DateTime.UtcNow > m_CurseTable[from].StartTime)
|
||||
{
|
||||
TimeSpan inEffect = DateTime.UtcNow - m_CurseTable[from].StartTime;
|
||||
|
||||
int damage = 5 * (int)inEffect.TotalSeconds;
|
||||
|
||||
from.FixedParticles(0x36BD, 20, 10, 5044, EffectLayer.Head);
|
||||
from.PlaySound(0x307);
|
||||
|
||||
m_CurseTable.Remove(from);
|
||||
|
||||
AOS.Damage(from, caster, damage, 0, 0, 0, 0, 0, 100, 0);
|
||||
}
|
||||
}
|
||||
|
||||
m_ImmuneTable[from] = new ImmuneTimer(from, TimeSpan.FromSeconds(16));
|
||||
}
|
||||
|
||||
public static void OnMobileDoDamage(Mobile from)
|
||||
{
|
||||
if (from != null && m_CurseTable.ContainsKey(from))
|
||||
RemoveCurse(from, m_CurseTable[from].Caster);
|
||||
}
|
||||
|
||||
public static bool IsUnderCurseEffects(Mobile from)
|
||||
{
|
||||
return m_CurseTable.ContainsKey(from);
|
||||
}
|
||||
|
||||
private class ImmuneTimer : Timer
|
||||
{
|
||||
private Mobile m_Mobile;
|
||||
|
||||
public ImmuneTimer(Mobile mob, TimeSpan duration) : base(duration)
|
||||
{
|
||||
m_Mobile = mob;
|
||||
Start();
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
PurgeMagicSpell.RemoveImmunity(m_Mobile);
|
||||
}
|
||||
}
|
||||
|
||||
private class CurseTimer : Timer
|
||||
{
|
||||
private Mobile m_Mobile;
|
||||
private Mobile m_Caster;
|
||||
private DateTime m_StartTime;
|
||||
|
||||
public DateTime StartTime { get { return m_StartTime; } }
|
||||
public Mobile Caster { get { return m_Caster; } }
|
||||
|
||||
public CurseTimer(Mobile mob, Mobile caster, TimeSpan duration)
|
||||
: base(duration)
|
||||
{
|
||||
m_Mobile = mob;
|
||||
m_Caster = caster;
|
||||
m_StartTime = DateTime.UtcNow;
|
||||
Start();
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
PurgeMagicSpell.RemoveCurse(m_Mobile, m_Caster);
|
||||
}
|
||||
}
|
||||
|
||||
public class InternalTarget : Target
|
||||
{
|
||||
public PurgeMagicSpell Owner { get; set; }
|
||||
|
||||
public InternalTarget(PurgeMagicSpell owner)
|
||||
: this(owner, false)
|
||||
{
|
||||
}
|
||||
|
||||
public InternalTarget(PurgeMagicSpell owner, bool allowland)
|
||||
: base(12, allowland, TargetFlags.Harmful)
|
||||
{
|
||||
Owner = owner;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object o)
|
||||
{
|
||||
if (o == null)
|
||||
return;
|
||||
|
||||
if (!from.CanSee(o))
|
||||
from.SendLocalizedMessage(500237); // Target can not be seen.
|
||||
else
|
||||
{
|
||||
SpellHelper.Turn(from, o);
|
||||
Owner.OnTarget(o);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnTargetFinish(Mobile from)
|
||||
{
|
||||
Owner.FinishSequence();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Spells;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Spells.Mysticism
|
||||
{
|
||||
public class RisingColossusSpell : MysticSpell
|
||||
{
|
||||
public override SpellCircle Circle { get { return SpellCircle.Eighth; } }
|
||||
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Rising Colossus", "Kal Vas Xen Corp Ylem",
|
||||
230,
|
||||
9022,
|
||||
Reagent.DaemonBone,
|
||||
Reagent.DragonBlood,
|
||||
Reagent.FertileDirt,
|
||||
Reagent.Nightshade
|
||||
);
|
||||
|
||||
public RisingColossusSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
Caster.Target = new InternalTarget(this);
|
||||
}
|
||||
|
||||
public void Target(IPoint3D p)
|
||||
{
|
||||
if ((Caster.Followers + 5) > Caster.FollowersMax)
|
||||
{
|
||||
Caster.SendLocalizedMessage(1049645); // You have too many followers to summon that creature.
|
||||
return;
|
||||
}
|
||||
|
||||
Map map = Caster.Map;
|
||||
|
||||
SpellHelper.GetSurfaceTop(ref p);
|
||||
|
||||
if (map == null || (Caster.IsPlayer() && !map.CanSpawnMobile(p.X, p.Y, p.Z)))
|
||||
{
|
||||
Caster.SendLocalizedMessage(501942); // That location is blocked.
|
||||
}
|
||||
else if (SpellHelper.CheckTown(p, Caster) && CheckSequence())
|
||||
{
|
||||
double baseskill = Caster.Skills[SkillName.Mysticism].Value;
|
||||
double boostskill = GetBoostSkill(Caster);
|
||||
|
||||
int level = (int)(baseskill + boostskill);
|
||||
|
||||
TimeSpan duration = TimeSpan.FromSeconds(level / 3);
|
||||
|
||||
BaseCreature summon = new RisingColossus(Caster, baseskill, boostskill);
|
||||
BaseCreature.Summon(summon, false, Caster, new Point3D(p), 0x656, duration);
|
||||
|
||||
Effects.SendTargetParticles(summon, 0x3728, 10, 10, 0x13AA, (EffectLayer)255);
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
|
||||
public class InternalTarget : Target
|
||||
{
|
||||
private RisingColossusSpell m_Owner;
|
||||
|
||||
public InternalTarget(RisingColossusSpell owner)
|
||||
: base(12, true, TargetFlags.None)
|
||||
{
|
||||
m_Owner = owner;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object o)
|
||||
{
|
||||
if (o is IPoint3D)
|
||||
m_Owner.Target((IPoint3D)o);
|
||||
}
|
||||
|
||||
protected override void OnTargetFinish(Mobile from)
|
||||
{
|
||||
m_Owner.FinishSequence();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
190
Scripts/Spells/Mysticism/SpellDefinitions/SleepSpell.cs
Normal file
190
Scripts/Spells/Mysticism/SpellDefinitions/SleepSpell.cs
Normal file
@@ -0,0 +1,190 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Targeting;
|
||||
using System.Collections.Generic;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Spells.Mysticism
|
||||
{
|
||||
public class SleepSpell : MysticSpell
|
||||
{
|
||||
public override SpellCircle Circle { get { return SpellCircle.Third; } }
|
||||
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Sleep", "In Zu",
|
||||
230,
|
||||
9022,
|
||||
Reagent.Nightshade,
|
||||
Reagent.SpidersSilk,
|
||||
Reagent.BlackPearl
|
||||
);
|
||||
|
||||
public SleepSpell(Mobile caster, Item scroll) : base(caster, scroll, m_Info)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
Caster.Target = new InternalTarget(this);
|
||||
}
|
||||
|
||||
public void OnTarget(object o)
|
||||
{
|
||||
Mobile target = o as Mobile;
|
||||
|
||||
if (target == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (target.Paralyzed)
|
||||
{
|
||||
Caster.SendLocalizedMessage(1080134); //Your target is already immobilized and cannot be slept.
|
||||
}
|
||||
else if (m_ImmunityList.Contains(target))
|
||||
{
|
||||
Caster.SendLocalizedMessage(1080135); //Your target cannot be put to sleep.
|
||||
}
|
||||
else if (CheckHSequence(target))
|
||||
{
|
||||
SpellHelper.CheckReflect((int)Circle, Caster, ref target);
|
||||
|
||||
double duration = ((Caster.Skills[CastSkill].Value + Caster.Skills[DamageSkill].Value) / 20) + 2;
|
||||
duration -= GetResistSkill(target) / 10;
|
||||
|
||||
if (duration <= 0 || StoneFormSpell.CheckImmunity(target))
|
||||
{
|
||||
Caster.SendLocalizedMessage(1080136); //Your target resists sleep.
|
||||
target.SendLocalizedMessage(1080137); //You resist sleep.
|
||||
}
|
||||
else
|
||||
DoSleep(Caster, target, TimeSpan.FromSeconds(duration));
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
|
||||
private static Dictionary<Mobile, SleepTimer> m_Table = new Dictionary<Mobile, SleepTimer>();
|
||||
private static List<Mobile> m_ImmunityList = new List<Mobile>();
|
||||
|
||||
public static void DoSleep(Mobile caster, Mobile target, TimeSpan duration)
|
||||
{
|
||||
target.Combatant = null;
|
||||
target.SendSpeedControl(SpeedControlType.WalkSpeed);
|
||||
|
||||
if (m_Table.ContainsKey(target))
|
||||
m_Table[target].Stop();
|
||||
|
||||
m_Table[target] = new SleepTimer(target, duration);
|
||||
|
||||
BuffInfo.AddBuff(target, new BuffInfo(BuffIcon.Sleep, 1080139, 1080140, duration, target));
|
||||
|
||||
target.Delta(MobileDelta.WeaponDamage);
|
||||
}
|
||||
|
||||
public static void AddToSleepTable(Mobile from, TimeSpan duration)
|
||||
{
|
||||
m_Table.Add(from, new SleepTimer(from, duration));
|
||||
}
|
||||
|
||||
public static bool IsUnderSleepEffects(Mobile from)
|
||||
{
|
||||
return m_Table.ContainsKey(from);
|
||||
}
|
||||
|
||||
public static void OnDamage(Mobile from)
|
||||
{
|
||||
if (m_Table.ContainsKey(from))
|
||||
EndSleep(from);
|
||||
}
|
||||
|
||||
public class SleepTimer : Timer
|
||||
{
|
||||
private Mobile m_Target;
|
||||
private DateTime m_EndTime;
|
||||
|
||||
public SleepTimer(Mobile target, TimeSpan duration)
|
||||
: base(TimeSpan.Zero, TimeSpan.FromSeconds(0.5))
|
||||
{
|
||||
m_EndTime = DateTime.UtcNow + duration;
|
||||
m_Target = target;
|
||||
Start();
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if (m_EndTime < DateTime.UtcNow)
|
||||
{
|
||||
EndSleep(m_Target);
|
||||
Stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
Effects.SendTargetParticles(m_Target, 0x3779, 1, 32, 0x13BA, EffectLayer.Head);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void EndSleep(Mobile target)
|
||||
{
|
||||
if (m_Table.ContainsKey(target))
|
||||
{
|
||||
target.SendSpeedControl(SpeedControlType.Disable);
|
||||
|
||||
m_Table[target].Stop();
|
||||
m_Table.Remove(target);
|
||||
|
||||
BuffInfo.RemoveBuff(target, BuffIcon.Sleep);
|
||||
|
||||
double immduration = target.Skills[SkillName.MagicResist].Value / 10;
|
||||
|
||||
m_ImmunityList.Add(target);
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(immduration), new TimerStateCallback(RemoveImmunity_Callback), target);
|
||||
|
||||
target.Delta(MobileDelta.WeaponDamage);
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemoveImmunity_Callback(object state)
|
||||
{
|
||||
Mobile m = (Mobile)state;
|
||||
|
||||
if (m_ImmunityList.Contains(m))
|
||||
m_ImmunityList.Remove(m);
|
||||
}
|
||||
|
||||
public class InternalTarget : Target
|
||||
{
|
||||
public SleepSpell Owner { get; set; }
|
||||
|
||||
public InternalTarget(SleepSpell owner)
|
||||
: this(owner, false)
|
||||
{
|
||||
}
|
||||
|
||||
public InternalTarget(SleepSpell owner, bool allowland)
|
||||
: base(12, allowland, TargetFlags.Harmful)
|
||||
{
|
||||
Owner = owner;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object o)
|
||||
{
|
||||
if (o == null)
|
||||
return;
|
||||
|
||||
if (!from.CanSee(o))
|
||||
from.SendLocalizedMessage(500237); // Target can not be seen.
|
||||
else
|
||||
{
|
||||
SpellHelper.Turn(from, o);
|
||||
Owner.OnTarget(o);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnTargetFinish(Mobile from)
|
||||
{
|
||||
Owner.FinishSequence();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
253
Scripts/Spells/Mysticism/SpellDefinitions/SpellPlague.cs
Normal file
253
Scripts/Spells/Mysticism/SpellDefinitions/SpellPlague.cs
Normal file
@@ -0,0 +1,253 @@
|
||||
using System;
|
||||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Spells.Mysticism
|
||||
{
|
||||
public class SpellPlagueSpell : MysticSpell
|
||||
{
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Spell Plague", "Vas Rel Jux Ort",
|
||||
230,
|
||||
9022,
|
||||
Reagent.DaemonBone,
|
||||
Reagent.DragonBlood,
|
||||
Reagent.Nightshade,
|
||||
Reagent.SulfurousAsh
|
||||
);
|
||||
|
||||
public override SpellCircle Circle { get { return SpellCircle.Seventh; } }
|
||||
|
||||
public SpellPlagueSpell(Mobile caster, Item scroll)
|
||||
: base(caster, scroll, m_Info)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
Caster.Target = new InternalTarget(this);
|
||||
}
|
||||
|
||||
public void OnTarget(object o)
|
||||
{
|
||||
Mobile m = o as Mobile;
|
||||
|
||||
if (m == null)
|
||||
return;
|
||||
|
||||
if (!(m is PlayerMobile || m is BaseCreature))
|
||||
{
|
||||
Caster.SendLocalizedMessage(1080194); // Your target cannot be affected by spell plague.
|
||||
}
|
||||
else if (CheckResisted(m))
|
||||
{
|
||||
m.SendLocalizedMessage(1080199); //You resist spell plague.
|
||||
Caster.SendLocalizedMessage(1080200); //Your target resists spell plague.
|
||||
}
|
||||
else if (CheckHSequence(m))
|
||||
{
|
||||
SpellHelper.CheckReflect((int)Circle, Caster, ref m);
|
||||
|
||||
SpellHelper.Turn(Caster, m);
|
||||
|
||||
Caster.PlaySound(0x658);
|
||||
|
||||
m.FixedParticles(0x375A, 1, 17, 9919, 1161, 7, EffectLayer.Waist);
|
||||
m.FixedParticles(0x3728, 1, 13, 9502, 1161, 7, (EffectLayer)255);
|
||||
|
||||
if (!m_Table.ContainsKey(m) || m_Table[m] == null)
|
||||
m_Table.Add(m, new List<SpellPlagueTimer>());
|
||||
|
||||
m_Table[m].Add(new SpellPlagueTimer(Caster, m, TimeSpan.FromSeconds(8)));
|
||||
|
||||
BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.SpellPlague, 1031690, 1080167, TimeSpan.FromSeconds(8), m));
|
||||
|
||||
DoExplosion(m, Caster, true, 1);
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
|
||||
private static Dictionary<Mobile, List<SpellPlagueTimer>> m_Table = new Dictionary<Mobile, List<SpellPlagueTimer>>();
|
||||
|
||||
public static bool HasSpellPlague(Mobile from)
|
||||
{
|
||||
foreach (KeyValuePair<Mobile, List<SpellPlagueTimer>> kvp in m_Table)
|
||||
{
|
||||
if (kvp.Value != null)
|
||||
{
|
||||
foreach (SpellPlagueTimer timer in kvp.Value)
|
||||
{
|
||||
if (timer.Caster == from)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void OnMobileDamaged(Mobile from)
|
||||
{
|
||||
if (m_Table.ContainsKey(from) && m_Table[from].Count > 0 && m_Table[from][0].NextUse < DateTime.UtcNow)
|
||||
{
|
||||
int amount = m_Table[from][0].Amount;
|
||||
bool doExplosion = false;
|
||||
double mod = from.Skills[SkillName.MagicResist].Value >= 70.0 ? (from.Skills[SkillName.MagicResist].Value / 1000 * 3) : 0.0;
|
||||
|
||||
if (mod < 0)
|
||||
mod = .01;
|
||||
|
||||
if (amount == 0 && .90 - mod > Utility.RandomDouble())
|
||||
doExplosion = true;
|
||||
else if (amount == 1 && .60 - mod > Utility.RandomDouble())
|
||||
doExplosion = true;
|
||||
else if (amount == 2 && .30 - mod > Utility.RandomDouble())
|
||||
doExplosion = true;
|
||||
|
||||
if (doExplosion)
|
||||
{
|
||||
SpellPlagueTimer timer = m_Table[from][0];
|
||||
|
||||
timer.NextUse = DateTime.UtcNow + TimeSpan.FromSeconds(1.5);
|
||||
|
||||
DoExplosion(from, timer.Caster, false, amount);
|
||||
timer.Amount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void DoExplosion(Mobile from, Mobile caster, bool initial, int amount)
|
||||
{
|
||||
double prim = caster.Skills[SkillName.Mysticism].Value;
|
||||
double sec = caster.Skills[SkillName.Imbuing].Value;
|
||||
|
||||
if (caster.Skills[SkillName.Focus].Value > sec)
|
||||
sec = caster.Skills[SkillName.Focus].Value;
|
||||
|
||||
int damage = (int)((prim + sec) / 12) + Utility.RandomMinMax(1, 6);
|
||||
|
||||
if (amount > 1)
|
||||
damage /= amount;
|
||||
|
||||
from.PlaySound(0x658);
|
||||
|
||||
from.FixedParticles(0x375A, 1, 17, 9919, 1161, 7, EffectLayer.Waist);
|
||||
from.FixedParticles(0x3728, 1, 13, 9502, 1161, 7, (EffectLayer)255);
|
||||
|
||||
int sdiBonus = SpellHelper.GetSpellDamageBonus(caster, from, SkillName.Mysticism, from is PlayerMobile);
|
||||
|
||||
damage *= (100 + sdiBonus);
|
||||
damage /= 100;
|
||||
|
||||
SpellHelper.Damage(null, TimeSpan.Zero, from, caster, damage, 0, 0, 0, 0, 0, DFAlgorithm.Standard, 100, 0);
|
||||
}
|
||||
|
||||
public static void RemoveFromList(Mobile from)
|
||||
{
|
||||
if (m_Table.ContainsKey(from) && m_Table[from].Count > 0)
|
||||
{
|
||||
Mobile caster = m_Table[from][0].Caster;
|
||||
|
||||
m_Table[from].Remove(m_Table[from][0]);
|
||||
|
||||
if (m_Table[from].Count == 0)
|
||||
{
|
||||
m_Table.Remove(from);
|
||||
BuffInfo.RemoveBuff(from, BuffIcon.SpellPlague);
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<Mobile, List<SpellPlagueTimer>> kvp in m_Table)
|
||||
{
|
||||
foreach (SpellPlagueTimer Ttimer in kvp.Value)
|
||||
{
|
||||
if (Ttimer.Caster == caster)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
BuffInfo.RemoveBuff(caster, BuffIcon.SpellPlague);
|
||||
}
|
||||
}
|
||||
|
||||
public class InternalTarget : Target
|
||||
{
|
||||
public SpellPlagueSpell Owner { get; set; }
|
||||
|
||||
public InternalTarget(SpellPlagueSpell owner)
|
||||
: this(owner, false)
|
||||
{
|
||||
}
|
||||
|
||||
public InternalTarget(SpellPlagueSpell owner, bool allowland)
|
||||
: base(12, allowland, TargetFlags.Harmful)
|
||||
{
|
||||
Owner = owner;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object o)
|
||||
{
|
||||
if (o == null)
|
||||
return;
|
||||
|
||||
if (!from.CanSee(o))
|
||||
from.SendLocalizedMessage(500237); // Target can not be seen.
|
||||
else
|
||||
{
|
||||
SpellHelper.Turn(from, o);
|
||||
Owner.OnTarget(o);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnTargetFinish(Mobile from)
|
||||
{
|
||||
Owner.FinishSequence();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SpellPlagueTimer : Timer
|
||||
{
|
||||
private Mobile m_Caster;
|
||||
private Mobile m_Owner;
|
||||
private int m_Amount;
|
||||
private DateTime m_NextUse;
|
||||
|
||||
public Mobile Caster { get { return m_Caster; } }
|
||||
public int Amount
|
||||
{
|
||||
get { return m_Amount; }
|
||||
set
|
||||
{
|
||||
m_Amount = value;
|
||||
|
||||
if (m_Amount >= 3)
|
||||
EndTimer();
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime NextUse { get { return m_NextUse; } set { m_NextUse = value; } }
|
||||
|
||||
public SpellPlagueTimer(Mobile caster, Mobile owner, TimeSpan duration)
|
||||
: base(duration)
|
||||
{
|
||||
m_Caster = caster;
|
||||
m_Owner = owner;
|
||||
m_Amount = 0;
|
||||
m_NextUse = DateTime.UtcNow;
|
||||
this.Start();
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
EndTimer();
|
||||
}
|
||||
|
||||
private void EndTimer()
|
||||
{
|
||||
this.Stop();
|
||||
SpellPlagueSpell.RemoveFromList(m_Owner);
|
||||
}
|
||||
}
|
||||
}
|
||||
307
Scripts/Spells/Mysticism/SpellDefinitions/SpellTriggerSpell.cs
Normal file
307
Scripts/Spells/Mysticism/SpellDefinitions/SpellTriggerSpell.cs
Normal file
@@ -0,0 +1,307 @@
|
||||
using System;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using System.Collections.Generic;
|
||||
using Server.ContextMenus;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Spells.Mysticism
|
||||
{
|
||||
public class SpellTriggerSpell : MysticSpell
|
||||
{
|
||||
public override SpellCircle Circle { get { return SpellCircle.Fifth; } }
|
||||
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Spell Trigger", "In Vas Ort Ex ",
|
||||
230,
|
||||
9022,
|
||||
Reagent.Garlic,
|
||||
Reagent.MandrakeRoot,
|
||||
Reagent.SpidersSilk,
|
||||
Reagent.DragonBlood
|
||||
);
|
||||
|
||||
public SpellTriggerSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
if (Caster.HasGump(typeof(SpellTriggerGump)))
|
||||
Caster.CloseGump(typeof(SpellTriggerGump));
|
||||
|
||||
var gump = new SpellTriggerGump(this, Caster);
|
||||
int serial = gump.Serial;
|
||||
|
||||
Caster.SendGump(gump);
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(30), () =>
|
||||
{
|
||||
var current = Caster.FindGump(typeof(SpellTriggerGump));
|
||||
|
||||
if (current != null && current.Serial == serial)
|
||||
{
|
||||
Caster.CloseGump(typeof(EnchantSpellGump));
|
||||
FinishSequence();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private class SpellTriggerGump : Gump
|
||||
{
|
||||
private Spell m_Spell;
|
||||
private int m_Skill;
|
||||
|
||||
public SpellTriggerGump(Spell spell, Mobile m)
|
||||
: base(60, 36)
|
||||
{
|
||||
m_Spell = spell;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
AddBackground(0, 0, 520, 404, 0x13BE);
|
||||
|
||||
AddImageTiled(10, 10, 500, 20, 0xA40);
|
||||
AddImageTiled(10, 40, 500, 324, 0xA40);
|
||||
AddImageTiled(10, 374, 500, 20, 0xA40);
|
||||
AddAlphaRegion(10, 10, 500, 384);
|
||||
|
||||
AddButton(10, 374, 0xFB1, 0xFB2, 0, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(45, 376, 450, 20, 1060051, 0x7FFF, false, false); // CANCEL
|
||||
|
||||
AddHtmlLocalized(14, 12, 500, 20, 1080151, 0x7FFF, false, false); // <center>Spell Trigger Selection Menu</center>
|
||||
|
||||
AddPage(1);
|
||||
|
||||
m_Skill = (int)(GetBaseSkill(m) + GetBoostSkill(m));
|
||||
int idx = 0;
|
||||
|
||||
for (int i = 0; i < m_Definitions.Length; i++)
|
||||
{
|
||||
SpellTriggerDef entry = m_Definitions[i];
|
||||
|
||||
if (m_Skill >= (entry.Rank * 40))
|
||||
{
|
||||
idx++;
|
||||
|
||||
if (idx == 11)
|
||||
{
|
||||
AddButton(400, 374, 0xFA5, 0xFA7, 0, GumpButtonType.Page, 2);
|
||||
AddHtmlLocalized(440, 376, 60, 20, 1043353, 0x7FFF, false, false); // Next
|
||||
|
||||
AddPage(2);
|
||||
|
||||
AddButton(300, 374, 0xFAE, 0xFB0, 0, GumpButtonType.Page, 1);
|
||||
AddHtmlLocalized(340, 376, 60, 20, 1011393, 0x7FFF, false, false); // Back
|
||||
|
||||
idx = 1;
|
||||
}
|
||||
|
||||
if ((idx % 2) != 0)
|
||||
{
|
||||
AddImageTiledButton(14, 44 + (64 * (idx - 1) / 2), 0x918, 0x919, 100 + i, GumpButtonType.Reply, 0, entry.ItemId, 0, 15, 20);
|
||||
AddTooltip(entry.Tooltip);
|
||||
AddHtmlLocalized(98, 44 + (64 * (idx - 1) / 2), 170, 60, entry.Cliloc, 0x7FFF, false, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddImageTiledButton(264, 44 + (64 * (idx - 2) / 2), 0x918, 0x919, 100 + i, GumpButtonType.Reply, 0, entry.ItemId, 0, 15, 20);
|
||||
AddTooltip(entry.Tooltip);
|
||||
AddHtmlLocalized(348, 44 + (64 * (idx - 2) / 2), 170, 60, entry.Cliloc, 0x7FFF, false, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
Mobile from = sender.Mobile;
|
||||
|
||||
if (from.Backpack != null && info.ButtonID >= 100 && info.ButtonID <= 110 && m_Spell.CheckSequence())
|
||||
{
|
||||
Item[] stones = from.Backpack.FindItemsByType(typeof(SpellStone));
|
||||
|
||||
for (int i = 0; i < stones.Length; i++)
|
||||
stones[i].Delete();
|
||||
|
||||
SpellTriggerDef entry = m_Definitions[info.ButtonID - 100];
|
||||
|
||||
if (m_Skill >= (entry.Rank * 40))
|
||||
{
|
||||
from.PlaySound(0x659);
|
||||
from.PlaceInBackpack(new SpellStone(entry));
|
||||
|
||||
from.SendLocalizedMessage(1080165); // A Spell Stone appears in your backpack
|
||||
}
|
||||
}
|
||||
|
||||
m_Spell.FinishSequence();
|
||||
}
|
||||
}
|
||||
|
||||
private static SpellTriggerDef[] m_Definitions = new SpellTriggerDef[]
|
||||
{
|
||||
new SpellTriggerDef( 677, "Nether Bolt", 1, 1031678, 1095193, 0x2D9E ),
|
||||
new SpellTriggerDef( 678, "Healing Stone", 1, 1031679, 1095194, 0x2D9F ),
|
||||
new SpellTriggerDef( 679, "Purge Magic", 2, 1031680, 1095195, 0x2DA0 ),
|
||||
new SpellTriggerDef( 680, "Enchant", 2, 1031681, 1095196, 0x2DA1 ),
|
||||
new SpellTriggerDef( 681, "Sleep", 3, 1031682, 1095197, 0x2DA2 ),
|
||||
new SpellTriggerDef( 682, "Eagle Strike", 3, 1031683, 1095198, 0x2DA3 ),
|
||||
new SpellTriggerDef( 683, "Animated Weapon", 4, 1031684, 1095199, 0x2DA4 ),
|
||||
new SpellTriggerDef( 684, "Stone Form", 4, 1031685, 1095200, 0x2DA5 ),
|
||||
new SpellTriggerDef( 686, "Mass Sleep", 5, 1031687, 1095202, 0x2DA7 ),
|
||||
new SpellTriggerDef( 687, "Cleansing Winds", 6, 1031688, 1095203, 0x2DA8 ),
|
||||
new SpellTriggerDef( 688, "Bombard", 6, 1031689, 1095204, 0x2DA9 )
|
||||
};
|
||||
|
||||
public static SpellTriggerDef[] Definitions { get { return m_Definitions; } }
|
||||
}
|
||||
|
||||
public class SpellTriggerDef
|
||||
{
|
||||
private int m_SpellId;
|
||||
private string m_Name;
|
||||
private int m_Rank;
|
||||
private int m_Cliloc;
|
||||
private int m_Tooltip;
|
||||
private int m_ItemId;
|
||||
|
||||
public int SpellId { get { return m_SpellId; } }
|
||||
public string Name { get { return m_Name; } }
|
||||
public int Rank { get { return m_Rank; } }
|
||||
public int Cliloc { get { return m_Cliloc; } }
|
||||
public int Tooltip { get { return m_Tooltip; } }
|
||||
public int ItemId { get { return m_ItemId; } }
|
||||
|
||||
public SpellTriggerDef(int spellId, string name, int rank, int cliloc, int tooltip, int itemId)
|
||||
{
|
||||
m_SpellId = spellId;
|
||||
m_Name = name;
|
||||
m_Rank = rank;
|
||||
m_Cliloc = cliloc;
|
||||
m_Tooltip = tooltip;
|
||||
m_ItemId = itemId;
|
||||
}
|
||||
}
|
||||
|
||||
public class SpellStone : SpellScroll
|
||||
{
|
||||
private SpellTriggerDef m_SpellDef;
|
||||
|
||||
public override bool Nontransferable { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public SpellStone(SpellTriggerDef spellDef)
|
||||
: base(spellDef.SpellId, 0x4079, 1)
|
||||
{
|
||||
this.m_SpellDef = spellDef;
|
||||
this.LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public override bool DropToWorld(Mobile from, Point3D p)
|
||||
{
|
||||
this.Delete();
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool AllowSecureTrade(Mobile from, Mobile to, Mobile newOwner, bool accepted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
|
||||
{
|
||||
}
|
||||
|
||||
private static Dictionary<Mobile, DateTime> m_CooldownTable = new Dictionary<Mobile, DateTime>();
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (m_CooldownTable.ContainsKey(from))
|
||||
{
|
||||
DateTime next = m_CooldownTable[from];
|
||||
int seconds = (int)(next - DateTime.UtcNow).TotalSeconds + 1;
|
||||
|
||||
// You must wait ~1_seconds~ seconds before you can use this item.
|
||||
from.SendLocalizedMessage(1079263, seconds.ToString());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
base.OnDoubleClick(from);
|
||||
}
|
||||
|
||||
public void Use(Mobile from)
|
||||
{
|
||||
m_CooldownTable[from] = DateTime.UtcNow + TimeSpan.FromSeconds(300.0);
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(300.0), new TimerCallback(
|
||||
delegate
|
||||
{
|
||||
m_CooldownTable.Remove(from);
|
||||
}));
|
||||
|
||||
Delete();
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
list.Add(1080166, m_SpellDef.Name); // Use: ~1_spellName~
|
||||
}
|
||||
|
||||
public SpellStone(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)1);
|
||||
|
||||
writer.Write((int)m_SpellDef.SpellId);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
int spellId = reader.ReadInt();
|
||||
|
||||
for (int i = 0; i < SpellTriggerSpell.Definitions.Length; i++)
|
||||
{
|
||||
SpellTriggerDef def = SpellTriggerSpell.Definitions[i];
|
||||
|
||||
if (def.SpellId == spellId)
|
||||
{
|
||||
m_SpellDef = def;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_SpellDef == null)
|
||||
Delete();
|
||||
|
||||
break;
|
||||
}
|
||||
case 0:
|
||||
{
|
||||
Delete();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
217
Scripts/Spells/Mysticism/SpellDefinitions/StoneForm.cs
Normal file
217
Scripts/Spells/Mysticism/SpellDefinitions/StoneForm.cs
Normal file
@@ -0,0 +1,217 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Spells.Mysticism
|
||||
{
|
||||
public class StoneFormSpell : MysticTransformationSpell
|
||||
{
|
||||
private static HashSet<Mobile> m_Effected = new HashSet<Mobile>();
|
||||
public static bool IsEffected(Mobile m)
|
||||
{
|
||||
return m_Effected.Contains(m);
|
||||
}
|
||||
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Stone Form", "In Rel Ylem",
|
||||
230,
|
||||
9022,
|
||||
Reagent.Bloodmoss,
|
||||
Reagent.FertileDirt,
|
||||
Reagent.Garlic
|
||||
);
|
||||
|
||||
private int m_ResisMod;
|
||||
|
||||
public override SpellCircle Circle { get { return SpellCircle.Fourth; } }
|
||||
|
||||
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds( 2.0 ); } }
|
||||
|
||||
public override int Body{ get{ return 705; } }
|
||||
public override int PhysResistOffset { get { return m_ResisMod; } }
|
||||
public override int FireResistOffset { get { return m_ResisMod; } }
|
||||
public override int ColdResistOffset { get { return m_ResisMod; } }
|
||||
public override int PoisResistOffset { get { return m_ResisMod; } }
|
||||
public override int NrgyResistOffset { get { return m_ResisMod; } }
|
||||
|
||||
public StoneFormSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
|
||||
{
|
||||
}
|
||||
|
||||
public override bool CheckCast()
|
||||
{
|
||||
bool doCast = base.CheckCast();
|
||||
|
||||
if (doCast && Caster.Flying)
|
||||
{
|
||||
Caster.SendLocalizedMessage(1112567); // You are flying.
|
||||
doCast = false;
|
||||
}
|
||||
|
||||
if (doCast)
|
||||
m_ResisMod = GetResBonus(Caster);
|
||||
|
||||
return doCast;
|
||||
}
|
||||
|
||||
public override void DoEffect( Mobile m )
|
||||
{
|
||||
m.PlaySound( 0x65A );
|
||||
m.FixedParticles( 0x3728, 1, 13, 9918, 92, 3, EffectLayer.Head );
|
||||
|
||||
Timer.DelayCall(new TimerCallback(MobileDelta_Callback));
|
||||
m_Effected.Add(m);
|
||||
|
||||
|
||||
if (!Core.HS)
|
||||
{
|
||||
m.SendSpeedControl(SpeedControlType.WalkSpeed);
|
||||
}
|
||||
|
||||
string args = String.Format("{0}\t{1}\t{2}\t{3}\t{4}", "-10", "-2", GetResBonus(m).ToString(), GetMaxResistance(m).ToString(), GetDamBonus(m).ToString());
|
||||
BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.StoneForm, 1080145, 1080146, args));
|
||||
BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.PoisonImmunity, 1153785, 1153814));
|
||||
}
|
||||
|
||||
public void MobileDelta_Callback()
|
||||
{
|
||||
Caster.Delta(MobileDelta.WeaponDamage);
|
||||
Caster.UpdateResistances();
|
||||
}
|
||||
|
||||
public override void RemoveEffect( Mobile m )
|
||||
{
|
||||
if (!Core.HS)
|
||||
{
|
||||
m.SendSpeedControl(SpeedControlType.Disable);
|
||||
}
|
||||
|
||||
m.Delta( MobileDelta.WeaponDamage );
|
||||
m_Effected.Remove(m);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.StoneForm);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.PoisonImmunity);
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
if (!Core.HS)
|
||||
{
|
||||
EventSink.Login += new LoginEventHandler(OnLogin);
|
||||
}
|
||||
}
|
||||
|
||||
public static void OnLogin(LoginEventArgs e)
|
||||
{
|
||||
TransformContext context = TransformationSpellHelper.GetContext(e.Mobile);
|
||||
|
||||
if (context != null && context.Type == typeof(StoneFormSpell))
|
||||
e.Mobile.SendSpeedControl(SpeedControlType.WalkSpeed);
|
||||
}
|
||||
|
||||
public static int GetMaxResistBonus(Mobile m)
|
||||
{
|
||||
if (TransformationSpellHelper.UnderTransformation(m, typeof(StoneFormSpell)))
|
||||
{
|
||||
return GetMaxResistance(m);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int GetResistanceBonus(Mobile m)
|
||||
{
|
||||
if (TransformationSpellHelper.UnderTransformation(m, typeof(StoneFormSpell)))
|
||||
{
|
||||
return GetResBonus(m);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int GetDamageBonus(Mobile m)
|
||||
{
|
||||
if (TransformationSpellHelper.UnderTransformation(m, typeof(StoneFormSpell)))
|
||||
{
|
||||
return GetDamBonus(m);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static double StatOffsetReduction(Mobile caster, Mobile m)
|
||||
{
|
||||
if (TransformationSpellHelper.UnderTransformation(m, typeof(StoneFormSpell)))
|
||||
{
|
||||
int prim = (int)m.Skills[SkillName.Mysticism].Value;
|
||||
int sec = (int)m.Skills[SkillName.Imbuing].Value;
|
||||
|
||||
if (m.Skills[SkillName.Focus].Value > sec)
|
||||
sec = (int)m.Skills[SkillName.Focus].Value;
|
||||
|
||||
caster.SendLocalizedMessage(1080192); // Your target resists your ability reduction magic.
|
||||
|
||||
return (double)(prim + sec) / 480;
|
||||
}
|
||||
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
private static int GetResBonus(Mobile m)
|
||||
{
|
||||
int prim = (int)m.Skills[SkillName.Mysticism].Value;
|
||||
int sec = (int)m.Skills[SkillName.Imbuing].Value;
|
||||
|
||||
if (m.Skills[SkillName.Focus].Value > sec)
|
||||
sec = (int)m.Skills[SkillName.Focus].Value;
|
||||
|
||||
return Math.Max(2, (prim + sec) / 24);
|
||||
}
|
||||
|
||||
private static int GetMaxResistance(Mobile m)
|
||||
{
|
||||
if (Server.Items.BaseArmor.HasRefinedResist(m))
|
||||
return 0;
|
||||
|
||||
int prim = (int)m.Skills[SkillName.Mysticism].Value;
|
||||
int sec = (int)m.Skills[SkillName.Imbuing].Value;
|
||||
|
||||
if (m.Skills[SkillName.Focus].Value > sec)
|
||||
sec = (int)m.Skills[SkillName.Focus].Value;
|
||||
|
||||
return Math.Max(2, (prim + sec) / 48);
|
||||
}
|
||||
|
||||
private static int GetDamBonus(Mobile m)
|
||||
{
|
||||
int prim = (int)m.Skills[SkillName.Mysticism].Value;
|
||||
int sec = (int)m.Skills[SkillName.Imbuing].Value;
|
||||
|
||||
if (m.Skills[SkillName.Focus].Value > sec)
|
||||
sec = (int)m.Skills[SkillName.Focus].Value;
|
||||
|
||||
return Math.Max(0, (prim + sec) / 12);
|
||||
}
|
||||
|
||||
public static bool CheckImmunity(Mobile from)
|
||||
{
|
||||
if (TransformationSpellHelper.UnderTransformation(from, typeof(StoneFormSpell)))
|
||||
{
|
||||
int prim = (int)from.Skills[SkillName.Mysticism].Value;
|
||||
int sec = (int)from.Skills[SkillName.Imbuing].Value;
|
||||
|
||||
if (from.Skills[SkillName.Focus].Value > sec)
|
||||
sec = (int)from.Skills[SkillName.Focus].Value;
|
||||
|
||||
int immunity = (int)(((double)(prim + sec) / 480) * 100);
|
||||
|
||||
if (Server.Spells.Necromancy.EvilOmenSpell.TryEndEffect(from))
|
||||
immunity -= 30;
|
||||
|
||||
return immunity > Utility.Random(100);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user