Reorganizes Project (#41)
This commit is contained in:
parent
08bf44af9a
commit
3614a66aee
3499 changed files with 79 additions and 55 deletions
63
Projects/Scripts/Spells/Sixth/Dispel.cs
Normal file
63
Projects/Scripts/Spells/Sixth/Dispel.cs
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Spells.Sixth
|
||||
{
|
||||
public class DispelSpell : MagerySpell, ISpellTargetingMobile
|
||||
{
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Dispel", "An Ort",
|
||||
218,
|
||||
9002,
|
||||
Reagent.Garlic,
|
||||
Reagent.MandrakeRoot,
|
||||
Reagent.SulfurousAsh
|
||||
);
|
||||
|
||||
public DispelSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info)
|
||||
{
|
||||
}
|
||||
|
||||
public override SpellCircle Circle => SpellCircle.Sixth;
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
Caster.Target = new SpellTargetMobile(this, TargetFlags.Harmful, Core.ML ? 10 : 12);
|
||||
}
|
||||
|
||||
public void Target(Mobile m)
|
||||
{
|
||||
if (m == null)
|
||||
return;
|
||||
|
||||
if (!Caster.CanSee(m))
|
||||
Caster.SendLocalizedMessage(500237); // Target can not be seen.
|
||||
else if (!(m is BaseCreature bc && bc.IsDispellable))
|
||||
Caster.SendLocalizedMessage(1005049); // That cannot be dispelled.
|
||||
else if (CheckHSequence(m))
|
||||
{
|
||||
SpellHelper.Turn(Caster, m);
|
||||
|
||||
double dispelChance =
|
||||
(50.0 + 100 * (Caster.Skills.Magery.Value - bc.DispelDifficulty) / (bc.DispelFocus * 2)) / 100;
|
||||
|
||||
if (dispelChance > Utility.RandomDouble())
|
||||
{
|
||||
Effects.SendLocationParticles(EffectItem.Create(m.Location, m.Map, EffectItem.DefaultDuration),
|
||||
0x3728, 8, 20, 5042);
|
||||
Effects.PlaySound(m, m.Map, 0x201);
|
||||
|
||||
m.Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
m.FixedEffect(0x3779, 10, 20);
|
||||
Caster.SendLocalizedMessage(1010084); // The creature resisted the attempt to dispel it!
|
||||
}
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
}
|
||||
}
|
||||
75
Projects/Scripts/Spells/Sixth/EnergyBolt.cs
Normal file
75
Projects/Scripts/Spells/Sixth/EnergyBolt.cs
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
using Server.Targeting;
|
||||
|
||||
namespace Server.Spells.Sixth
|
||||
{
|
||||
public class EnergyBoltSpell : MagerySpell, ISpellTargetingMobile
|
||||
{
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Energy Bolt", "Corp Por",
|
||||
230,
|
||||
9022,
|
||||
Reagent.BlackPearl,
|
||||
Reagent.Nightshade
|
||||
);
|
||||
|
||||
public EnergyBoltSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info)
|
||||
{
|
||||
}
|
||||
|
||||
public override SpellCircle Circle => SpellCircle.Sixth;
|
||||
|
||||
public override bool DelayedDamage => true;
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
Caster.Target = new SpellTargetMobile(this, TargetFlags.Harmful, Core.ML ? 10 : 12);
|
||||
}
|
||||
|
||||
public void Target(Mobile m)
|
||||
{
|
||||
if (m == null)
|
||||
return;
|
||||
|
||||
if (!Caster.CanSee(m))
|
||||
Caster.SendLocalizedMessage(500237); // Target can not be seen.
|
||||
else if (CheckHSequence(m))
|
||||
{
|
||||
Mobile source = Caster;
|
||||
|
||||
SpellHelper.Turn(Caster, m);
|
||||
|
||||
SpellHelper.CheckReflect((int)Circle, ref source, ref m);
|
||||
|
||||
double damage;
|
||||
|
||||
if (Core.AOS)
|
||||
{
|
||||
damage = GetNewAosDamage(40, 1, 5, m);
|
||||
}
|
||||
else
|
||||
{
|
||||
damage = Utility.Random(24, 18);
|
||||
|
||||
if (CheckResisted(m))
|
||||
{
|
||||
damage *= 0.75;
|
||||
|
||||
m.SendLocalizedMessage(501783); // You feel yourself resisting magical energy.
|
||||
}
|
||||
|
||||
// Scale damage based on evalint and resist
|
||||
damage *= GetDamageScalar(m);
|
||||
}
|
||||
|
||||
// Do the effects
|
||||
source.MovingParticles(m, 0x379F, 7, 0, false, true, 3043, 4043, 0x211);
|
||||
source.PlaySound(0x20A);
|
||||
|
||||
// Deal the damage
|
||||
SpellHelper.Damage(this, m, damage, 0, 0, 0, 0, 100);
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
}
|
||||
}
|
||||
109
Projects/Scripts/Spells/Sixth/Explosion.cs
Normal file
109
Projects/Scripts/Spells/Sixth/Explosion.cs
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
using System;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Spells.Sixth
|
||||
{
|
||||
public class ExplosionSpell : MagerySpell, ISpellTargetingMobile
|
||||
{
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Explosion", "Vas Ort Flam",
|
||||
230,
|
||||
9041,
|
||||
Reagent.Bloodmoss,
|
||||
Reagent.MandrakeRoot
|
||||
);
|
||||
|
||||
public ExplosionSpell(Mobile caster, Item scroll = null)
|
||||
: base(caster, scroll, m_Info)
|
||||
{
|
||||
}
|
||||
|
||||
public override SpellCircle Circle => SpellCircle.Sixth;
|
||||
|
||||
public override bool DelayedDamageStacking => !Core.AOS;
|
||||
|
||||
public override bool DelayedDamage => false;
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
Caster.Target = new SpellTargetMobile(this, TargetFlags.Harmful, Core.ML ? 10 : 12);
|
||||
}
|
||||
|
||||
public void Target(Mobile m)
|
||||
{
|
||||
if (m == null)
|
||||
return;
|
||||
|
||||
if (!Caster.CanSee(m))
|
||||
{
|
||||
Caster.SendLocalizedMessage(500237); // Target can not be seen.
|
||||
}
|
||||
else if (Caster.CanBeHarmful(m) && CheckSequence())
|
||||
{
|
||||
Mobile attacker = Caster, defender = m;
|
||||
|
||||
SpellHelper.Turn(Caster, m);
|
||||
|
||||
SpellHelper.CheckReflect((int)Circle, Caster, ref m);
|
||||
|
||||
InternalTimer t = new InternalTimer(this, attacker, defender, m);
|
||||
t.Start();
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
|
||||
private class InternalTimer : Timer
|
||||
{
|
||||
private Mobile m_Attacker, m_Defender;
|
||||
private MagerySpell m_Spell;
|
||||
private Mobile m_Target;
|
||||
|
||||
public InternalTimer(MagerySpell spell, Mobile attacker, Mobile defender, Mobile target)
|
||||
: base(TimeSpan.FromSeconds(Core.AOS ? 3.0 : 2.5))
|
||||
{
|
||||
m_Spell = spell;
|
||||
m_Attacker = attacker;
|
||||
m_Defender = defender;
|
||||
m_Target = target;
|
||||
|
||||
m_Spell?.StartDelayedDamageContext(attacker, this);
|
||||
|
||||
Priority = TimerPriority.FiftyMS;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if (m_Attacker.HarmfulCheck(m_Defender))
|
||||
{
|
||||
double damage;
|
||||
|
||||
if (Core.AOS)
|
||||
{
|
||||
damage = m_Spell.GetNewAosDamage(40, 1, 5, m_Defender);
|
||||
}
|
||||
else
|
||||
{
|
||||
damage = Utility.Random(23, 22);
|
||||
|
||||
if (m_Spell.CheckResisted(m_Target))
|
||||
{
|
||||
damage *= 0.75;
|
||||
|
||||
m_Target.SendLocalizedMessage(501783); // You feel yourself resisting magical energy.
|
||||
}
|
||||
|
||||
damage *= m_Spell.GetDamageScalar(m_Target);
|
||||
}
|
||||
|
||||
m_Target.FixedParticles(0x36BD, 20, 10, 5044, EffectLayer.Head);
|
||||
m_Target.PlaySound(0x307);
|
||||
|
||||
SpellHelper.Damage(m_Spell, m_Target, damage, 0, 100, 0, 0, 0);
|
||||
|
||||
m_Spell?.RemoveDelayedDamageContext(m_Attacker);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
118
Projects/Scripts/Spells/Sixth/Invisibility.cs
Normal file
118
Projects/Scripts/Spells/Sixth/Invisibility.cs
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Engines.ConPVP;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Spells.Sixth
|
||||
{
|
||||
public class InvisibilitySpell : MagerySpell, ISpellTargetingMobile
|
||||
{
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Invisibility", "An Lor Xen",
|
||||
206,
|
||||
9002,
|
||||
Reagent.Bloodmoss,
|
||||
Reagent.Nightshade
|
||||
);
|
||||
|
||||
private static Dictionary<Mobile, Timer> m_Table = new Dictionary<Mobile, Timer>();
|
||||
|
||||
public InvisibilitySpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info)
|
||||
{
|
||||
}
|
||||
|
||||
public override SpellCircle Circle => SpellCircle.Sixth;
|
||||
|
||||
public override bool CheckCast()
|
||||
{
|
||||
if (DuelContext.CheckSuddenDeath(Caster))
|
||||
{
|
||||
Caster.SendMessage(0x22, "You cannot cast this spell when in sudden death.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.CheckCast();
|
||||
}
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
Caster.Target = new SpellTargetMobile(this, TargetFlags.Beneficial, Core.ML ? 10 : 12);
|
||||
}
|
||||
|
||||
public void Target(Mobile m)
|
||||
{
|
||||
if (m == null)
|
||||
return;
|
||||
|
||||
if (!Caster.CanSee(m))
|
||||
{
|
||||
Caster.SendLocalizedMessage(500237); // Target can not be seen.
|
||||
}
|
||||
else if (m is BaseVendor || m is PlayerVendor || m.AccessLevel > Caster.AccessLevel)
|
||||
{
|
||||
Caster.SendLocalizedMessage(501857); // This spell won't work on that!
|
||||
}
|
||||
else if (CheckBSequence(m))
|
||||
{
|
||||
SpellHelper.Turn(Caster, m);
|
||||
|
||||
Effects.SendLocationParticles(
|
||||
EffectItem.Create(new Point3D(m.X, m.Y, m.Z + 16), Caster.Map, EffectItem.DefaultDuration), 0x376A, 10,
|
||||
15, 5045);
|
||||
m.PlaySound(0x3C4);
|
||||
|
||||
m.Hidden = true;
|
||||
m.Combatant = null;
|
||||
m.Warmode = false;
|
||||
|
||||
RemoveTimer(m);
|
||||
|
||||
TimeSpan duration = TimeSpan.FromSeconds(1.2 * Caster.Skills.Magery.Fixed / 10);
|
||||
|
||||
Timer t = new InternalTimer(m, duration);
|
||||
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.HidingAndOrStealth);
|
||||
BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Invisibility, 1075825, duration, m)); //Invisibility/Invisible
|
||||
|
||||
m_Table[m] = t;
|
||||
|
||||
t.Start();
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
|
||||
public static bool HasTimer(Mobile m)
|
||||
{
|
||||
return m_Table.ContainsKey(m);
|
||||
}
|
||||
|
||||
public static void RemoveTimer(Mobile m)
|
||||
{
|
||||
if (!m_Table.TryGetValue(m, out Timer t))
|
||||
return;
|
||||
|
||||
t.Stop();
|
||||
m_Table.Remove(m);
|
||||
}
|
||||
|
||||
private class InternalTimer : Timer
|
||||
{
|
||||
private Mobile m_Mobile;
|
||||
|
||||
public InternalTimer(Mobile m, TimeSpan duration) : base(duration)
|
||||
{
|
||||
Priority = TimerPriority.OneSecond;
|
||||
m_Mobile = m;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Mobile.RevealingAction();
|
||||
RemoveTimer(m_Mobile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
60
Projects/Scripts/Spells/Sixth/Mark.cs
Normal file
60
Projects/Scripts/Spells/Sixth/Mark.cs
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Spells.Sixth
|
||||
{
|
||||
public class MarkSpell : MagerySpell, ISpellTargetingItem
|
||||
{
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Mark", "Kal Por Ylem",
|
||||
218,
|
||||
9002,
|
||||
Reagent.BlackPearl,
|
||||
Reagent.Bloodmoss,
|
||||
Reagent.MandrakeRoot
|
||||
);
|
||||
|
||||
public MarkSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info)
|
||||
{
|
||||
}
|
||||
|
||||
public override SpellCircle Circle => SpellCircle.Sixth;
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
Caster.Target = new SpellTargetItem(this, TargetFlags.None, Core.ML ? 10 : 12);
|
||||
}
|
||||
|
||||
public override bool CheckCast()
|
||||
{
|
||||
return base.CheckCast() && SpellHelper.CheckTravel(Caster, TravelCheckType.Mark);
|
||||
}
|
||||
|
||||
public void Target(Item item)
|
||||
{
|
||||
if (!(item is RecallRune rune))
|
||||
Caster.Send(new MessageLocalized(Caster.Serial, Caster.Body, MessageType.Regular, 0x3B2, 3, 501797, Caster.Name,
|
||||
"")); // I cannot mark that object.
|
||||
else if (!Caster.CanSee(rune))
|
||||
Caster.SendLocalizedMessage(500237); // Target can not be seen.
|
||||
else if (!SpellHelper.CheckTravel(Caster, TravelCheckType.Mark))
|
||||
{
|
||||
}
|
||||
else if (SpellHelper.CheckMulti(Caster.Location, Caster.Map, !Core.AOS))
|
||||
Caster.SendLocalizedMessage(501942); // That location is blocked.
|
||||
else if (!rune.IsChildOf(Caster.Backpack))
|
||||
Caster.LocalOverheadMessage(MessageType.Regular, 0x3B2,
|
||||
1062422); // You must have this rune in your backpack in order to mark it.
|
||||
else if (CheckSequence())
|
||||
{
|
||||
rune.Mark(Caster);
|
||||
|
||||
Caster.PlaySound(0x1FA);
|
||||
Effects.SendLocationEffect(Caster, Caster.Map, 14201, 16);
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
}
|
||||
}
|
||||
74
Projects/Scripts/Spells/Sixth/MassCurse.cs
Normal file
74
Projects/Scripts/Spells/Sixth/MassCurse.cs
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
using Server.Targeting;
|
||||
|
||||
namespace Server.Spells.Sixth
|
||||
{
|
||||
public class MassCurseSpell : MagerySpell, ISpellTargetingPoint3D
|
||||
{
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Mass Curse", "Vas Des Sanct",
|
||||
218,
|
||||
9031,
|
||||
false,
|
||||
Reagent.Garlic,
|
||||
Reagent.Nightshade,
|
||||
Reagent.MandrakeRoot,
|
||||
Reagent.SulfurousAsh
|
||||
);
|
||||
|
||||
public MassCurseSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info)
|
||||
{
|
||||
}
|
||||
|
||||
public override SpellCircle Circle => SpellCircle.Sixth;
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
Caster.Target = new SpellTargetPoint3D(this, TargetFlags.None, Core.ML ? 10 : 12);
|
||||
}
|
||||
|
||||
public void Target(IPoint3D p)
|
||||
{
|
||||
if (!Caster.CanSee(p))
|
||||
{
|
||||
Caster.SendLocalizedMessage(500237); // Target can not be seen.
|
||||
}
|
||||
else if (SpellHelper.CheckTown(p, Caster) && CheckSequence())
|
||||
{
|
||||
SpellHelper.Turn(Caster, p);
|
||||
|
||||
SpellHelper.GetSurfaceTop(ref p);
|
||||
|
||||
Map map = Caster.Map;
|
||||
|
||||
if (map != null)
|
||||
{
|
||||
IPooledEnumerable<Mobile> eable = map.GetMobilesInRange(new Point3D(p), 2);
|
||||
|
||||
foreach (Mobile m in eable)
|
||||
{
|
||||
if (Core.AOS && (m == Caster || !SpellHelper.ValidIndirectTarget(Caster, m) || !Caster.CanSee(m) ||
|
||||
!Caster.CanBeHarmful(m, false)))
|
||||
continue;
|
||||
|
||||
Caster.DoHarmful(m);
|
||||
|
||||
SpellHelper.AddStatCurse(Caster, m, StatType.Str);
|
||||
SpellHelper.DisableSkillCheck = true;
|
||||
SpellHelper.AddStatCurse(Caster, m, StatType.Dex);
|
||||
SpellHelper.AddStatCurse(Caster, m, StatType.Int);
|
||||
SpellHelper.DisableSkillCheck = false;
|
||||
|
||||
m.FixedParticles(0x374A, 10, 15, 5028, EffectLayer.Waist);
|
||||
m.PlaySound(0x1FB);
|
||||
|
||||
HarmfulSpell(m);
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
}
|
||||
}
|
||||
215
Projects/Scripts/Spells/Sixth/ParalyzeField.cs
Normal file
215
Projects/Scripts/Spells/Sixth/ParalyzeField.cs
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
using System;
|
||||
using Server.Items;
|
||||
using Server.Misc;
|
||||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Spells.Sixth
|
||||
{
|
||||
public class ParalyzeFieldSpell : MagerySpell, ISpellTargetingPoint3D
|
||||
{
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Paralyze Field", "In Ex Grav",
|
||||
230,
|
||||
9012,
|
||||
false,
|
||||
Reagent.BlackPearl,
|
||||
Reagent.Ginseng,
|
||||
Reagent.SpidersSilk
|
||||
);
|
||||
|
||||
public ParalyzeFieldSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info)
|
||||
{
|
||||
}
|
||||
|
||||
public override SpellCircle Circle => SpellCircle.Sixth;
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
Caster.Target = new SpellTargetPoint3D(this, TargetFlags.None, Core.ML ? 10 : 12);
|
||||
}
|
||||
|
||||
public void Target(IPoint3D p)
|
||||
{
|
||||
if (!Caster.CanSee(p))
|
||||
{
|
||||
Caster.SendLocalizedMessage(500237); // Target can not be seen.
|
||||
}
|
||||
else if (SpellHelper.CheckTown(p, Caster) && CheckSequence())
|
||||
{
|
||||
SpellHelper.Turn(Caster, p);
|
||||
|
||||
SpellHelper.GetSurfaceTop(ref p);
|
||||
|
||||
int dx = Caster.Location.X - p.X;
|
||||
int dy = Caster.Location.Y - p.Y;
|
||||
int rx = (dx - dy) * 44;
|
||||
int ry = (dx + dy) * 44;
|
||||
|
||||
bool eastToWest;
|
||||
|
||||
if (rx >= 0 && ry >= 0)
|
||||
eastToWest = false;
|
||||
else if (rx >= 0)
|
||||
eastToWest = true;
|
||||
else if (ry >= 0)
|
||||
eastToWest = true;
|
||||
else
|
||||
eastToWest = false;
|
||||
|
||||
Effects.PlaySound(p, Caster.Map, 0x20B);
|
||||
|
||||
int itemID = eastToWest ? 0x3967 : 0x3979;
|
||||
|
||||
TimeSpan duration = TimeSpan.FromSeconds(3.0 + Caster.Skills.Magery.Value / 3.0);
|
||||
|
||||
for (int i = -2; i <= 2; ++i)
|
||||
{
|
||||
Point3D loc = new Point3D(eastToWest ? p.X + i : p.X, eastToWest ? p.Y : p.Y + i, p.Z);
|
||||
|
||||
if (!SpellHelper.AdjustField(ref loc, Caster.Map, 12, false))
|
||||
continue;
|
||||
|
||||
Item item = new InternalItem(Caster, itemID, loc, Caster.Map, duration);
|
||||
item.ProcessDelta();
|
||||
|
||||
Effects.SendLocationParticles(EffectItem.Create(loc, Caster.Map, EffectItem.DefaultDuration), 0x376A, 9,
|
||||
10, 5048);
|
||||
}
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
|
||||
[DispellableField]
|
||||
public class InternalItem : Item
|
||||
{
|
||||
private Mobile m_Caster;
|
||||
private DateTime m_End;
|
||||
private Timer m_Timer;
|
||||
|
||||
public InternalItem(Mobile caster, int itemID, Point3D loc, Map map, TimeSpan duration) : base(itemID)
|
||||
{
|
||||
Visible = false;
|
||||
Movable = false;
|
||||
Light = LightType.Circle300;
|
||||
|
||||
MoveToWorld(loc, map);
|
||||
|
||||
if (caster.InLOS(this))
|
||||
Visible = true;
|
||||
else
|
||||
Delete();
|
||||
|
||||
if (Deleted)
|
||||
return;
|
||||
|
||||
m_Caster = caster;
|
||||
|
||||
m_Timer = new InternalTimer(this, duration);
|
||||
m_Timer.Start();
|
||||
|
||||
m_End = DateTime.UtcNow + duration;
|
||||
}
|
||||
|
||||
public InternalItem(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool BlocksFit => true;
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
base.OnAfterDelete();
|
||||
|
||||
m_Timer?.Stop();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write(m_Caster);
|
||||
writer.WriteDeltaTime(m_End);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_Caster = reader.ReadMobile();
|
||||
m_End = reader.ReadDeltaTime();
|
||||
|
||||
m_Timer = new InternalTimer(this, m_End - DateTime.UtcNow);
|
||||
m_Timer.Start();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnMoveOver(Mobile m)
|
||||
{
|
||||
if (Visible && m_Caster != null && (!Core.AOS || m != m_Caster) &&
|
||||
SpellHelper.ValidIndirectTarget(m_Caster, m) && m_Caster.CanBeHarmful(m, false))
|
||||
{
|
||||
if (SpellHelper.CanRevealCaster(m))
|
||||
m_Caster.RevealingAction();
|
||||
|
||||
m_Caster.DoHarmful(m);
|
||||
|
||||
double duration;
|
||||
|
||||
if (Core.AOS)
|
||||
{
|
||||
duration = 2.0 + ((int)(m_Caster.Skills.EvalInt.Value / 10) -
|
||||
(int)(m.Skills.MagicResist.Value / 10));
|
||||
|
||||
if (!m.Player)
|
||||
duration *= 3.0;
|
||||
|
||||
if (duration < 0.0)
|
||||
duration = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
duration = 7.0 + m_Caster.Skills.Magery.Value * 0.2;
|
||||
}
|
||||
|
||||
m.Paralyze(TimeSpan.FromSeconds(duration));
|
||||
|
||||
m.PlaySound(0x204);
|
||||
m.FixedEffect(0x376A, 10, 16);
|
||||
|
||||
(m as BaseCreature)?.OnHarmfulSpell(m_Caster);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private class InternalTimer : Timer
|
||||
{
|
||||
private Item m_Item;
|
||||
|
||||
public InternalTimer(Item item, TimeSpan duration) : base(duration)
|
||||
{
|
||||
Priority = TimerPriority.OneSecond;
|
||||
m_Item = item;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Item.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
88
Projects/Scripts/Spells/Sixth/Reveal.cs
Normal file
88
Projects/Scripts/Spells/Sixth/Reveal.cs
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Spells.Sixth
|
||||
{
|
||||
public class RevealSpell : MagerySpell, ISpellTargetingPoint3D
|
||||
{
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Reveal", "Wis Quas",
|
||||
206,
|
||||
9002,
|
||||
Reagent.Bloodmoss,
|
||||
Reagent.SulfurousAsh
|
||||
);
|
||||
|
||||
public RevealSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info)
|
||||
{
|
||||
}
|
||||
|
||||
public override SpellCircle Circle => SpellCircle.Sixth;
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
Caster.Target = new SpellTargetPoint3D(this, TargetFlags.None, Core.ML ? 10 : 12);
|
||||
}
|
||||
|
||||
public void Target(IPoint3D p)
|
||||
{
|
||||
if (!Caster.CanSee(p))
|
||||
{
|
||||
Caster.SendLocalizedMessage(500237); // Target can not be seen.
|
||||
}
|
||||
else if (CheckSequence())
|
||||
{
|
||||
SpellHelper.Turn(Caster, p);
|
||||
SpellHelper.GetSurfaceTop(ref p);
|
||||
Map map = Caster.Map;
|
||||
|
||||
if (map != null)
|
||||
{
|
||||
IPooledEnumerable<Mobile> eable = map.GetMobilesInRange(new Point3D(p),
|
||||
1 + (int)(Caster.Skills.Magery.Value / 20.0));
|
||||
|
||||
foreach (Mobile m in eable)
|
||||
{
|
||||
if (m is ShadowKnight &&
|
||||
(m.X != p.X || m.Y != p.Y || !m.Hidden || m.AccessLevel != AccessLevel.Player &&
|
||||
Caster.AccessLevel <= m.AccessLevel ||
|
||||
!CheckDifficulty(Caster, m)))
|
||||
continue;
|
||||
|
||||
m.RevealingAction();
|
||||
|
||||
m.FixedParticles(0x375A, 9, 20, 5049, EffectLayer.Head);
|
||||
m.PlaySound(0x1FD);
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
|
||||
// Reveal uses magery and detect hidden vs. hide and stealth
|
||||
private static bool CheckDifficulty(Mobile from, Mobile m)
|
||||
{
|
||||
// Reveal always reveals vs. invisibility spell
|
||||
if (!Core.AOS || InvisibilitySpell.HasTimer(m))
|
||||
return true;
|
||||
|
||||
int magery = from.Skills.Magery.Fixed;
|
||||
int detectHidden = from.Skills.DetectHidden.Fixed;
|
||||
|
||||
int hiding = m.Skills.Hiding.Fixed;
|
||||
int stealth = m.Skills.Stealth.Fixed;
|
||||
int divisor = hiding + stealth;
|
||||
|
||||
int chance;
|
||||
if (divisor > 0)
|
||||
chance = 50 * (magery + detectHidden) / divisor;
|
||||
else
|
||||
chance = 100;
|
||||
|
||||
return chance > Utility.Random(100);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue