Reorganizes Project (#41)
This commit is contained in:
parent
08bf44af9a
commit
3614a66aee
3499 changed files with 79 additions and 55 deletions
111
Projects/Scripts/Spells/Seventh/ChainLightning.cs
Normal file
111
Projects/Scripts/Spells/Seventh/ChainLightning.cs
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Spells.Seventh
|
||||
{
|
||||
public class ChainLightningSpell : MagerySpell, ISpellTargetingPoint3D
|
||||
{
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Chain Lightning", "Vas Ort Grav",
|
||||
209,
|
||||
9022,
|
||||
false,
|
||||
Reagent.BlackPearl,
|
||||
Reagent.Bloodmoss,
|
||||
Reagent.MandrakeRoot,
|
||||
Reagent.SulfurousAsh
|
||||
);
|
||||
|
||||
public ChainLightningSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info)
|
||||
{
|
||||
}
|
||||
|
||||
public override SpellCircle Circle => SpellCircle.Seventh;
|
||||
|
||||
public override bool DelayedDamage => true;
|
||||
|
||||
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);
|
||||
|
||||
if (p is Item item)
|
||||
p = item.GetWorldLocation();
|
||||
|
||||
List<Mobile> targets = new List<Mobile>();
|
||||
|
||||
Map map = Caster.Map;
|
||||
|
||||
bool playerVsPlayer = false;
|
||||
|
||||
if (map != null)
|
||||
{
|
||||
IPooledEnumerable<Mobile> eable = map.GetMobilesInRange(new Point3D(p), 2);
|
||||
|
||||
targets.AddRange(eable.Where(m =>
|
||||
{
|
||||
if (Core.AOS && (m == Caster || !Caster.InLOS(m)) || !SpellHelper.ValidIndirectTarget(Caster, m) ||
|
||||
!Caster.CanBeHarmful(m, false))
|
||||
return false;
|
||||
|
||||
if (m.Player)
|
||||
playerVsPlayer = true;
|
||||
|
||||
return true;
|
||||
}).ToList());
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
double damage;
|
||||
|
||||
damage = Core.AOS ? GetNewAosDamage(51, 1, 5, playerVsPlayer)
|
||||
: Utility.Random(27, 22);
|
||||
|
||||
if (targets.Count > 0)
|
||||
{
|
||||
if (Core.AOS && targets.Count > 2)
|
||||
damage = damage * 2 / targets.Count;
|
||||
else if (!Core.AOS)
|
||||
damage /= targets.Count;
|
||||
|
||||
for (int i = 0; i < targets.Count; ++i)
|
||||
{
|
||||
double toDeal = damage;
|
||||
Mobile m = targets[i];
|
||||
|
||||
if (!Core.AOS && CheckResisted(m))
|
||||
{
|
||||
toDeal *= 0.5;
|
||||
|
||||
m.SendLocalizedMessage(501783); // You feel yourself resisting magical energy.
|
||||
}
|
||||
|
||||
toDeal *= GetDamageScalar(m);
|
||||
Caster.DoHarmful(m);
|
||||
SpellHelper.Damage(this, m, toDeal, 0, 0, 0, 0, 100);
|
||||
|
||||
m.BoltEffect(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Caster.PlaySound(0x29);
|
||||
}
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
}
|
||||
}
|
||||
175
Projects/Scripts/Spells/Seventh/EnergyField.cs
Normal file
175
Projects/Scripts/Spells/Seventh/EnergyField.cs
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
using System;
|
||||
using Server.Items;
|
||||
using Server.Misc;
|
||||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Spells.Seventh
|
||||
{
|
||||
public class EnergyFieldSpell : MagerySpell, ISpellTargetingPoint3D
|
||||
{
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Energy Field", "In Sanct Grav",
|
||||
221,
|
||||
9022,
|
||||
false,
|
||||
Reagent.BlackPearl,
|
||||
Reagent.MandrakeRoot,
|
||||
Reagent.SpidersSilk,
|
||||
Reagent.SulfurousAsh
|
||||
);
|
||||
|
||||
public EnergyFieldSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info)
|
||||
{
|
||||
}
|
||||
|
||||
public override SpellCircle Circle => SpellCircle.Seventh;
|
||||
|
||||
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);
|
||||
|
||||
TimeSpan duration;
|
||||
|
||||
if (Core.AOS)
|
||||
duration = TimeSpan.FromSeconds((15 + Caster.Skills.Magery.Fixed / 5) / 7.0);
|
||||
else
|
||||
duration = TimeSpan.FromSeconds(Caster.Skills.Magery.Value * 0.28 +
|
||||
2.0); // (28% of magery) + 2.0 seconds
|
||||
|
||||
int itemID = eastToWest ? 0x3946 : 0x3956;
|
||||
|
||||
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);
|
||||
bool canFit = SpellHelper.AdjustField(ref loc, Caster.Map, 12, false);
|
||||
|
||||
if (!canFit)
|
||||
continue;
|
||||
|
||||
Item item = new InternalItem(loc, Caster.Map, duration, itemID, Caster);
|
||||
item.ProcessDelta();
|
||||
|
||||
Effects.SendLocationParticles(EffectItem.Create(loc, Caster.Map, EffectItem.DefaultDuration), 0x376A, 9,
|
||||
10, 5051);
|
||||
}
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
|
||||
[DispellableField]
|
||||
private class InternalItem : Item
|
||||
{
|
||||
private Mobile m_Caster;
|
||||
private Timer m_Timer;
|
||||
|
||||
public InternalItem(Point3D loc, Map map, TimeSpan duration, int itemID, Mobile caster) : base(itemID)
|
||||
{
|
||||
Visible = false;
|
||||
Movable = false;
|
||||
Light = LightType.Circle300;
|
||||
|
||||
MoveToWorld(loc, map);
|
||||
|
||||
m_Caster = caster;
|
||||
|
||||
if (caster.InLOS(this))
|
||||
Visible = true;
|
||||
else
|
||||
Delete();
|
||||
|
||||
if (Deleted)
|
||||
return;
|
||||
|
||||
m_Timer = new InternalTimer(this, duration);
|
||||
m_Timer.Start();
|
||||
}
|
||||
|
||||
public InternalItem(Serial serial) : base(serial)
|
||||
{
|
||||
m_Timer = new InternalTimer(this, TimeSpan.FromSeconds(5.0));
|
||||
m_Timer.Start();
|
||||
}
|
||||
|
||||
public override bool BlocksFit => true;
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
|
||||
public override bool OnMoveOver(Mobile m)
|
||||
{
|
||||
if (!(m is PlayerMobile))
|
||||
return base.OnMoveOver(m);
|
||||
|
||||
int noto = Notoriety.Compute(m_Caster, m);
|
||||
return noto != Notoriety.Enemy && noto != Notoriety.Ally && base.OnMoveOver(m);
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
base.OnAfterDelete();
|
||||
|
||||
m_Timer?.Stop();
|
||||
}
|
||||
|
||||
private class InternalTimer : Timer
|
||||
{
|
||||
private InternalItem m_Item;
|
||||
|
||||
public InternalTimer(InternalItem item, TimeSpan duration) : base(duration)
|
||||
{
|
||||
Priority = TimerPriority.OneSecond;
|
||||
m_Item = item;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Item.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
70
Projects/Scripts/Spells/Seventh/FlameStrike.cs
Normal file
70
Projects/Scripts/Spells/Seventh/FlameStrike.cs
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
using Server.Targeting;
|
||||
|
||||
namespace Server.Spells.Seventh
|
||||
{
|
||||
public class FlameStrikeSpell : MagerySpell, ISpellTargetingMobile
|
||||
{
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Flame Strike", "Kal Vas Flam",
|
||||
245,
|
||||
9042,
|
||||
Reagent.SpidersSilk,
|
||||
Reagent.SulfurousAsh
|
||||
);
|
||||
|
||||
public FlameStrikeSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info)
|
||||
{
|
||||
}
|
||||
|
||||
public override SpellCircle Circle => SpellCircle.Seventh;
|
||||
|
||||
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))
|
||||
{
|
||||
SpellHelper.Turn(Caster, m);
|
||||
|
||||
SpellHelper.CheckReflect((int)Circle, Caster, ref m);
|
||||
|
||||
double damage;
|
||||
|
||||
if (Core.AOS)
|
||||
{
|
||||
damage = GetNewAosDamage(48, 1, 5, m);
|
||||
}
|
||||
else
|
||||
{
|
||||
damage = Utility.Random(27, 22);
|
||||
|
||||
if (CheckResisted(m))
|
||||
{
|
||||
damage *= 0.6;
|
||||
|
||||
m.SendLocalizedMessage(501783); // You feel yourself resisting magical energy.
|
||||
}
|
||||
|
||||
damage *= GetDamageScalar(m);
|
||||
}
|
||||
|
||||
m.FixedParticles(0x3709, 10, 30, 5052, EffectLayer.LeftFoot);
|
||||
m.PlaySound(0x208);
|
||||
|
||||
SpellHelper.Damage(this, m, damage, 0, 100, 0, 0, 0);
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
}
|
||||
}
|
||||
184
Projects/Scripts/Spells/Seventh/GateTravel.cs
Normal file
184
Projects/Scripts/Spells/Seventh/GateTravel.cs
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Server.Factions;
|
||||
using Server.Items;
|
||||
using Server.Misc;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Spells.Seventh
|
||||
{
|
||||
public class GateTravelSpell : MagerySpell, IRecallSpell
|
||||
{
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Gate Travel", "Vas Rel Por",
|
||||
263,
|
||||
9032,
|
||||
Reagent.BlackPearl,
|
||||
Reagent.MandrakeRoot,
|
||||
Reagent.SulfurousAsh
|
||||
);
|
||||
|
||||
private RunebookEntry m_Entry;
|
||||
|
||||
public GateTravelSpell(Mobile caster, RunebookEntry entry = null, Item scroll = null) : base(caster, scroll, m_Info)
|
||||
{
|
||||
m_Entry = entry;
|
||||
}
|
||||
|
||||
public override SpellCircle Circle => SpellCircle.Seventh;
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
if (m_Entry == null)
|
||||
Caster.Target = new RecallSpellTarget(this, false);
|
||||
else
|
||||
Effect(m_Entry.Location, m_Entry.Map, true);
|
||||
}
|
||||
|
||||
public override bool CheckCast()
|
||||
{
|
||||
if (Sigil.ExistsOn(Caster))
|
||||
{
|
||||
Caster.SendLocalizedMessage(1061632); // You can't do that while carrying the sigil.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Caster.Criminal)
|
||||
{
|
||||
Caster.SendLocalizedMessage(1005561, "", 0x22); // Thou'rt a criminal and cannot escape so easily.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SpellHelper.CheckCombat(Caster))
|
||||
{
|
||||
Caster.SendLocalizedMessage(1005564, "", 0x22); // Wouldst thou flee during the heat of battle??
|
||||
return false;
|
||||
}
|
||||
|
||||
return SpellHelper.CheckTravel(Caster, TravelCheckType.GateFrom);
|
||||
}
|
||||
|
||||
private bool GateExistsAt(Map map, Point3D loc)
|
||||
{
|
||||
IPooledEnumerable<Item> eable = map.GetItemsInRange(loc, 0);
|
||||
bool gateFound = eable.Any(item => item is Moongate || item is PublicMoongate);
|
||||
eable.Free();
|
||||
|
||||
return gateFound;
|
||||
}
|
||||
|
||||
public void Effect(Point3D loc, Map map, bool checkMulti)
|
||||
{
|
||||
if (Sigil.ExistsOn(Caster))
|
||||
{
|
||||
Caster.SendLocalizedMessage(1061632); // You can't do that while carrying the sigil.
|
||||
}
|
||||
else if (map == null || !Core.AOS && Caster.Map != map)
|
||||
{
|
||||
Caster.SendLocalizedMessage(1005570); // You can not gate to another facet.
|
||||
}
|
||||
else if (!SpellHelper.CheckTravel(Caster, TravelCheckType.GateFrom))
|
||||
{
|
||||
}
|
||||
else if (!SpellHelper.CheckTravel(Caster, map, loc, TravelCheckType.GateTo))
|
||||
{
|
||||
}
|
||||
else if (map == Map.Felucca && Caster is PlayerMobile mobile && mobile.Young)
|
||||
{
|
||||
mobile.SendLocalizedMessage(1049543); // You decide against traveling to Felucca while you are still young.
|
||||
}
|
||||
else if (Caster.Kills >= 5 && map != Map.Felucca)
|
||||
{
|
||||
Caster.SendLocalizedMessage(1019004); // You are not allowed to travel there.
|
||||
}
|
||||
else if (Caster.Criminal)
|
||||
{
|
||||
Caster.SendLocalizedMessage(1005561, "", 0x22); // Thou'rt a criminal and cannot escape so easily.
|
||||
}
|
||||
else if (SpellHelper.CheckCombat(Caster))
|
||||
{
|
||||
Caster.SendLocalizedMessage(1005564, "", 0x22); // Wouldst thou flee during the heat of battle??
|
||||
}
|
||||
else if (!map.CanSpawnMobile(loc.X, loc.Y, loc.Z))
|
||||
{
|
||||
Caster.SendLocalizedMessage(501942); // That location is blocked.
|
||||
}
|
||||
else if (checkMulti && SpellHelper.CheckMulti(loc, map))
|
||||
{
|
||||
Caster.SendLocalizedMessage(501942); // That location is blocked.
|
||||
}
|
||||
else if (Core.SE && (GateExistsAt(map, loc) || GateExistsAt(Caster.Map, Caster.Location))
|
||||
) // SE restricted stacking gates
|
||||
{
|
||||
Caster.SendLocalizedMessage(1071242); // There is already a gate there.
|
||||
}
|
||||
else if (CheckSequence())
|
||||
{
|
||||
Caster.SendLocalizedMessage(501024); // You open a magical gate to another location
|
||||
|
||||
Effects.PlaySound(Caster.Location, Caster.Map, 0x20E);
|
||||
|
||||
InternalItem firstGate = new InternalItem(loc, map);
|
||||
firstGate.MoveToWorld(Caster.Location, Caster.Map);
|
||||
|
||||
Effects.PlaySound(loc, map, 0x20E);
|
||||
|
||||
InternalItem secondGate = new InternalItem(Caster.Location, Caster.Map);
|
||||
secondGate.MoveToWorld(loc, map);
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
|
||||
[DispellableField]
|
||||
private class InternalItem : Moongate
|
||||
{
|
||||
public InternalItem(Point3D target, Map map) : base(target, map)
|
||||
{
|
||||
Map = map;
|
||||
|
||||
if (ShowFeluccaWarning && map == Map.Felucca)
|
||||
ItemID = 0xDDA;
|
||||
|
||||
Dispellable = true;
|
||||
|
||||
InternalTimer t = new InternalTimer(this);
|
||||
t.Start();
|
||||
}
|
||||
|
||||
public InternalItem(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool ShowFeluccaWarning => Core.AOS;
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
Delete();
|
||||
}
|
||||
|
||||
private class InternalTimer : Timer
|
||||
{
|
||||
private Item m_Item;
|
||||
|
||||
public InternalTimer(Item item) : base(TimeSpan.FromSeconds(30.0))
|
||||
{
|
||||
Priority = TimerPriority.OneSecond;
|
||||
m_Item = item;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Item.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
97
Projects/Scripts/Spells/Seventh/ManaVampire.cs
Normal file
97
Projects/Scripts/Spells/Seventh/ManaVampire.cs
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
using Server.Targeting;
|
||||
|
||||
namespace Server.Spells.Seventh
|
||||
{
|
||||
public class ManaVampireSpell : MagerySpell, ISpellTargetingMobile
|
||||
{
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Mana Vampire", "Ort Sanct",
|
||||
221,
|
||||
9032,
|
||||
Reagent.BlackPearl,
|
||||
Reagent.Bloodmoss,
|
||||
Reagent.MandrakeRoot,
|
||||
Reagent.SpidersSilk
|
||||
);
|
||||
|
||||
public ManaVampireSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info)
|
||||
{
|
||||
}
|
||||
|
||||
public override SpellCircle Circle => SpellCircle.Seventh;
|
||||
|
||||
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))
|
||||
{
|
||||
SpellHelper.Turn(Caster, m);
|
||||
|
||||
SpellHelper.CheckReflect((int)Circle, Caster, ref m);
|
||||
|
||||
m.Spell?.OnCasterHurt();
|
||||
|
||||
m.Paralyzed = false;
|
||||
|
||||
int toDrain = 0;
|
||||
|
||||
if (Core.AOS)
|
||||
{
|
||||
toDrain = (int)(GetDamageSkill(Caster) - GetResistSkill(m));
|
||||
|
||||
if (!m.Player)
|
||||
toDrain /= 2;
|
||||
|
||||
if (toDrain < 0)
|
||||
toDrain = 0;
|
||||
else if (toDrain > m.Mana)
|
||||
toDrain = m.Mana;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CheckResisted(m))
|
||||
m.SendLocalizedMessage(501783); // You feel yourself resisting magical energy.
|
||||
else
|
||||
toDrain = m.Mana;
|
||||
}
|
||||
|
||||
if (toDrain > Caster.ManaMax - Caster.Mana)
|
||||
toDrain = Caster.ManaMax - Caster.Mana;
|
||||
|
||||
m.Mana -= toDrain;
|
||||
Caster.Mana += toDrain;
|
||||
|
||||
if (Core.AOS)
|
||||
{
|
||||
m.FixedParticles(0x374A, 1, 15, 5054, 23, 7, EffectLayer.Head);
|
||||
m.PlaySound(0x1F9);
|
||||
|
||||
Caster.FixedParticles(0x0000, 10, 5, 2054, EffectLayer.Head);
|
||||
}
|
||||
else
|
||||
{
|
||||
m.FixedParticles(0x374A, 10, 15, 5054, EffectLayer.Head);
|
||||
m.PlaySound(0x1F9);
|
||||
}
|
||||
|
||||
HarmfulSpell(m);
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
|
||||
public override double GetResistPercent(Mobile target)
|
||||
{
|
||||
return 98.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
79
Projects/Scripts/Spells/Seventh/MassDispel.cs
Normal file
79
Projects/Scripts/Spells/Seventh/MassDispel.cs
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Spells.Seventh
|
||||
{
|
||||
public class MassDispelSpell : MagerySpell, ISpellTargetingPoint3D
|
||||
{
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Mass Dispel", "Vas An Ort",
|
||||
263,
|
||||
9002,
|
||||
Reagent.Garlic,
|
||||
Reagent.MandrakeRoot,
|
||||
Reagent.BlackPearl,
|
||||
Reagent.SulfurousAsh
|
||||
);
|
||||
|
||||
public MassDispelSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info)
|
||||
{
|
||||
}
|
||||
|
||||
public override SpellCircle Circle => SpellCircle.Seventh;
|
||||
|
||||
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<BaseCreature> eable = map.GetMobilesInRange<BaseCreature>(new Point3D(p), 8);
|
||||
|
||||
foreach (BaseCreature bc in eable)
|
||||
{
|
||||
if (!(bc.IsDispellable && Caster.CanBeHarmful(bc, false)))
|
||||
continue;
|
||||
|
||||
double dispelChance =
|
||||
(50.0 + 100 * (Caster.Skills.Magery.Value - bc.DispelDifficulty) / (bc.DispelFocus * 2)) / 100;
|
||||
|
||||
if (dispelChance > Utility.RandomDouble())
|
||||
{
|
||||
Effects.SendLocationParticles(EffectItem.Create(bc.Location, bc.Map, EffectItem.DefaultDuration),
|
||||
0x3728, 8, 20, 5042);
|
||||
Effects.PlaySound(bc, bc.Map, 0x201);
|
||||
|
||||
bc.Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
Caster.DoHarmful(bc);
|
||||
|
||||
bc.FixedEffect(0x3779, 10, 20);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
}
|
||||
}
|
||||
114
Projects/Scripts/Spells/Seventh/MeteorSwarm.cs
Normal file
114
Projects/Scripts/Spells/Seventh/MeteorSwarm.cs
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Spells.Seventh
|
||||
{
|
||||
public class MeteorSwarmSpell : MagerySpell, ISpellTargetingPoint3D
|
||||
{
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Meteor Swarm", "Flam Kal Des Ylem",
|
||||
233,
|
||||
9042,
|
||||
false,
|
||||
Reagent.Bloodmoss,
|
||||
Reagent.MandrakeRoot,
|
||||
Reagent.SulfurousAsh,
|
||||
Reagent.SpidersSilk
|
||||
);
|
||||
|
||||
public MeteorSwarmSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info)
|
||||
{
|
||||
}
|
||||
|
||||
public override SpellCircle Circle => SpellCircle.Seventh;
|
||||
|
||||
public override bool DelayedDamage => true;
|
||||
|
||||
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);
|
||||
|
||||
if (p is Item item)
|
||||
p = item.GetWorldLocation();
|
||||
|
||||
List<Mobile> targets;
|
||||
|
||||
Map map = Caster.Map;
|
||||
|
||||
bool playerVsPlayer = false;
|
||||
|
||||
if (map != null)
|
||||
{
|
||||
IPooledEnumerable<Mobile> eable = map.GetMobilesInRange(new Point3D(p), 2);
|
||||
|
||||
targets = eable.Where(m =>
|
||||
{
|
||||
if (Caster == m || !SpellHelper.ValidIndirectTarget(Caster, m) || !Caster.CanBeHarmful(m, false) ||
|
||||
Core.AOS && !Caster.InLOS(m))
|
||||
return false;
|
||||
|
||||
if (m.Player)
|
||||
playerVsPlayer = true;
|
||||
|
||||
return true;
|
||||
}).ToList();
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
else
|
||||
{
|
||||
targets = new List<Mobile>();
|
||||
}
|
||||
|
||||
double damage;
|
||||
|
||||
damage = Core.AOS ? GetNewAosDamage(51, 1, 5, playerVsPlayer)
|
||||
: Utility.Random(27, 22);
|
||||
|
||||
if (targets.Count > 0)
|
||||
{
|
||||
Effects.PlaySound(p, Caster.Map, 0x160);
|
||||
|
||||
if (Core.AOS && targets.Count > 2)
|
||||
damage = damage * 2 / targets.Count;
|
||||
else if (!Core.AOS)
|
||||
damage /= targets.Count;
|
||||
|
||||
for (int i = 0; i < targets.Count; ++i)
|
||||
{
|
||||
Mobile m = targets[i];
|
||||
|
||||
double toDeal = damage;
|
||||
|
||||
if (!Core.AOS && CheckResisted(m))
|
||||
{
|
||||
damage *= 0.5;
|
||||
|
||||
m.SendLocalizedMessage(501783); // You feel yourself resisting magical energy.
|
||||
}
|
||||
|
||||
toDeal *= GetDamageScalar(m);
|
||||
Caster.DoHarmful(m);
|
||||
SpellHelper.Damage(this, m, toDeal, 0, 100, 0, 0, 0);
|
||||
|
||||
Caster.MovingParticles(m, 0x36D4, 7, 0, false, true, 9501, 1, 0, 0x100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
}
|
||||
}
|
||||
209
Projects/Scripts/Spells/Seventh/Polymorph.cs
Normal file
209
Projects/Scripts/Spells/Seventh/Polymorph.cs
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Factions;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Spells.Fifth;
|
||||
|
||||
namespace Server.Spells.Seventh
|
||||
{
|
||||
public class PolymorphSpell : MagerySpell
|
||||
{
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Polymorph", "Vas Ylem Rel",
|
||||
221,
|
||||
9002,
|
||||
Reagent.Bloodmoss,
|
||||
Reagent.SpidersSilk,
|
||||
Reagent.MandrakeRoot
|
||||
);
|
||||
|
||||
private static Dictionary<Mobile, InternalTimer> m_Timers = new Dictionary<Mobile, InternalTimer>();
|
||||
|
||||
private int m_NewBody;
|
||||
|
||||
public PolymorphSpell(Mobile caster, Item scroll, int body = 0) : base(caster, scroll, m_Info)
|
||||
{
|
||||
m_NewBody = body;
|
||||
}
|
||||
|
||||
public override SpellCircle Circle => SpellCircle.Seventh;
|
||||
|
||||
public override bool CheckCast()
|
||||
{
|
||||
/*if ( Caster.Mounted )
|
||||
{
|
||||
Caster.SendLocalizedMessage( 1042561 ); //Please dismount first.
|
||||
return false;
|
||||
}
|
||||
else */
|
||||
if (Sigil.ExistsOn(Caster))
|
||||
{
|
||||
Caster.SendLocalizedMessage(1010521); // You cannot polymorph while you have a Town Sigil
|
||||
return false;
|
||||
}
|
||||
|
||||
if (TransformationSpellHelper.UnderTransformation(Caster))
|
||||
{
|
||||
Caster.SendLocalizedMessage(1061633); // You cannot polymorph while in that form.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (DisguiseTimers.IsDisguised(Caster))
|
||||
{
|
||||
Caster.SendLocalizedMessage(502167); // You cannot polymorph while disguised.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Caster.BodyMod == 183 || Caster.BodyMod == 184)
|
||||
{
|
||||
Caster.SendLocalizedMessage(1042512); // You cannot polymorph while wearing body paint
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Caster.CanBeginAction<PolymorphSpell>())
|
||||
{
|
||||
if (Core.ML)
|
||||
EndPolymorph(Caster);
|
||||
else
|
||||
Caster.SendLocalizedMessage(1005559); // This spell is already in effect.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_NewBody == 0)
|
||||
{
|
||||
Gump gump = Core.SE ? (Gump)new NewPolymorphGump(Caster, Scroll) : new PolymorphGump(Caster, Scroll);
|
||||
|
||||
Caster.SendGump(gump);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
/*if ( Caster.Mounted )
|
||||
{
|
||||
Caster.SendLocalizedMessage( 1042561 ); //Please dismount first.
|
||||
}
|
||||
else */
|
||||
if (Sigil.ExistsOn(Caster))
|
||||
{
|
||||
Caster.SendLocalizedMessage(1010521); // You cannot polymorph while you have a Town Sigil
|
||||
}
|
||||
else if (!Caster.CanBeginAction<PolymorphSpell>())
|
||||
{
|
||||
if (Core.ML)
|
||||
EndPolymorph(Caster);
|
||||
else
|
||||
Caster.SendLocalizedMessage(1005559); // This spell is already in effect.
|
||||
}
|
||||
else if (TransformationSpellHelper.UnderTransformation(Caster))
|
||||
{
|
||||
Caster.SendLocalizedMessage(1061633); // You cannot polymorph while in that form.
|
||||
}
|
||||
else if (DisguiseTimers.IsDisguised(Caster))
|
||||
{
|
||||
Caster.SendLocalizedMessage(502167); // You cannot polymorph while disguised.
|
||||
}
|
||||
else if (Caster.BodyMod == 183 || Caster.BodyMod == 184)
|
||||
{
|
||||
Caster.SendLocalizedMessage(1042512); // You cannot polymorph while wearing body paint
|
||||
}
|
||||
else if (!Caster.CanBeginAction<IncognitoSpell>() || Caster.IsBodyMod)
|
||||
{
|
||||
DoFizzle();
|
||||
}
|
||||
else if (CheckSequence())
|
||||
{
|
||||
if (Caster.BeginAction<PolymorphSpell>())
|
||||
{
|
||||
if (m_NewBody != 0)
|
||||
{
|
||||
if (!((Body)m_NewBody).IsHuman)
|
||||
{
|
||||
IMount mt = Caster.Mount;
|
||||
|
||||
if (mt != null)
|
||||
mt.Rider = null;
|
||||
}
|
||||
|
||||
Caster.BodyMod = m_NewBody;
|
||||
|
||||
if (m_NewBody == 400 || m_NewBody == 401)
|
||||
Caster.HueMod = Caster.Race.RandomSkinHue();
|
||||
else
|
||||
Caster.HueMod = 0;
|
||||
|
||||
BaseArmor.ValidateMobile(Caster);
|
||||
BaseClothing.ValidateMobile(Caster);
|
||||
|
||||
if (!Core.ML)
|
||||
{
|
||||
StopTimer(Caster);
|
||||
|
||||
InternalTimer timer = new InternalTimer(Caster);
|
||||
|
||||
m_Timers[Caster] = timer;
|
||||
|
||||
timer.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Caster.SendLocalizedMessage(1005559); // This spell is already in effect.
|
||||
}
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
|
||||
public static void StopTimer(Mobile m)
|
||||
{
|
||||
if (!m_Timers.TryGetValue(m, out InternalTimer timer))
|
||||
return;
|
||||
|
||||
timer?.Stop();
|
||||
m_Timers.Remove(m);
|
||||
}
|
||||
|
||||
private static void EndPolymorph(Mobile m)
|
||||
{
|
||||
if (m.CanBeginAction<PolymorphSpell>())
|
||||
return;
|
||||
|
||||
m.BodyMod = 0;
|
||||
m.HueMod = -1;
|
||||
m.EndAction<PolymorphSpell>();
|
||||
|
||||
BaseArmor.ValidateMobile(m);
|
||||
BaseClothing.ValidateMobile(m);
|
||||
}
|
||||
|
||||
private class InternalTimer : Timer
|
||||
{
|
||||
private Mobile m_Owner;
|
||||
|
||||
public InternalTimer(Mobile owner) : base(TimeSpan.FromSeconds(0))
|
||||
{
|
||||
m_Owner = owner;
|
||||
|
||||
int val = (int)owner.Skills.Magery.Value;
|
||||
|
||||
if (val > 120)
|
||||
val = 120;
|
||||
|
||||
Delay = TimeSpan.FromSeconds(val);
|
||||
Priority = TimerPriority.OneSecond;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
EndPolymorph(m_Owner);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue