Reorganizes Project (#41)

This commit is contained in:
Kamron Batman 2019-08-02 18:13:40 -07:00 committed by GitHub
parent 08bf44af9a
commit 3614a66aee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3499 changed files with 79 additions and 55 deletions

View file

@ -0,0 +1,62 @@
using System;
using Server.Targeting;
namespace Server.Spells.First
{
public class ClumsySpell : MagerySpell, ISpellTargetingMobile
{
private static SpellInfo m_Info = new SpellInfo(
"Clumsy", "Uus Jux",
212,
9031,
Reagent.Bloodmoss,
Reagent.Nightshade
);
public ClumsySpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info)
{
}
public override SpellCircle Circle => SpellCircle.First;
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);
SpellHelper.AddStatCurse(Caster, m, StatType.Dex);
m.Spell?.OnCasterHurt();
m.Paralyzed = false;
m.FixedParticles(0x3779, 10, 15, 5002, EffectLayer.Head);
m.PlaySound(0x1DF);
int percentage = (int)(SpellHelper.GetOffsetScalar(Caster, m, true) * 100);
TimeSpan length = SpellHelper.GetDuration(Caster, m);
BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Clumsy, 1075831, length, m, percentage.ToString()));
HarmfulSpell(m);
}
FinishSequence();
}
}
}

View file

@ -0,0 +1,88 @@
using System;
using Server.Items;
namespace Server.Spells.First
{
public class CreateFoodSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Create Food", "In Mani Ylem",
224,
9011,
Reagent.Garlic,
Reagent.Ginseng,
Reagent.MandrakeRoot
);
private static FoodInfo[] m_Food =
{
new FoodInfo(typeof(Grapes), "a grape bunch"),
new FoodInfo(typeof(Ham), "a ham"),
new FoodInfo(typeof(CheeseWedge), "a wedge of cheese"),
new FoodInfo(typeof(Muffins), "muffins"),
new FoodInfo(typeof(FishSteak), "a fish steak"),
new FoodInfo(typeof(Ribs), "cut of ribs"),
new FoodInfo(typeof(CookedBird), "a cooked bird"),
new FoodInfo(typeof(Sausage), "sausage"),
new FoodInfo(typeof(Apple), "an apple"),
new FoodInfo(typeof(Peach), "a peach")
};
public CreateFoodSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info)
{
}
public override SpellCircle Circle => SpellCircle.First;
public override void OnCast()
{
if (CheckSequence())
{
FoodInfo foodInfo = m_Food[Utility.Random(m_Food.Length)];
Item food = foodInfo.Create();
if (food != null)
{
Caster.AddToBackpack(food);
// You magically create food in your backpack:
Caster.SendLocalizedMessage(1042695, true, " " + foodInfo.Name);
Caster.FixedParticles(0, 10, 5, 2003, EffectLayer.RightHand);
Caster.PlaySound(0x1E2);
}
}
FinishSequence();
}
}
public class FoodInfo
{
public FoodInfo(Type type, string name)
{
Type = type;
Name = name;
}
public Type Type{ get; set; }
public string Name{ get; set; }
public Item Create()
{
Item item;
try
{
item = (Item)Activator.CreateInstance(Type);
}
catch
{
item = null;
}
return item;
}
}
}

View file

@ -0,0 +1,60 @@
using System;
using Server.Targeting;
namespace Server.Spells.First
{
public class FeeblemindSpell : MagerySpell, ISpellTargetingMobile
{
private static SpellInfo m_Info = new SpellInfo(
"Feeblemind", "Rel Wis",
212,
9031,
Reagent.Ginseng,
Reagent.Nightshade
);
public FeeblemindSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info)
{
}
public override SpellCircle Circle => SpellCircle.First;
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);
SpellHelper.AddStatCurse(Caster, m, StatType.Int);
m.Spell?.OnCasterHurt();
m.Paralyzed = false;
m.FixedParticles(0x3779, 10, 15, 5004, EffectLayer.Head);
m.PlaySound(0x1E4);
int percentage = (int)(SpellHelper.GetOffsetScalar(Caster, m, true) * 100);
TimeSpan length = SpellHelper.GetDuration(Caster, m);
BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.FeebleMind, 1075833, length, m, percentage.ToString()));
HarmfulSpell(m);
}
FinishSequence();
}
}
}

View file

@ -0,0 +1,97 @@
using Server.Engines.ConPVP;
using Server.Items;
using Server.Mobiles;
using Server.Network;
using Server.Targeting;
namespace Server.Spells.First
{
public class HealSpell : MagerySpell, ISpellTargetingMobile
{
private static SpellInfo m_Info = new SpellInfo(
"Heal", "In Mani",
224,
9061,
Reagent.Garlic,
Reagent.Ginseng,
Reagent.SpidersSilk
);
public HealSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info)
{
}
public override SpellCircle Circle => SpellCircle.First;
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.IsDeadBondedPet)
{
Caster.SendLocalizedMessage(1060177); // You cannot heal a creature that is already dead!
}
else if (m is BaseCreature creature && creature.IsAnimatedDead)
{
Caster.SendLocalizedMessage(1061654); // You cannot heal that which is not alive.
}
else if (m is Golem)
{
Caster.LocalOverheadMessage(MessageType.Regular, 0x3B2, 500951); // You cannot heal that.
}
else if (m.Poisoned || MortalStrike.IsWounded(m))
{
Caster.LocalOverheadMessage(MessageType.Regular, 0x22, Caster == m ? 1005000 : 1010398);
}
else if (CheckBSequence(m))
{
SpellHelper.Turn(Caster, m);
int toHeal;
if (Core.AOS)
{
toHeal = Caster.Skills.Magery.Fixed / 120;
toHeal += Utility.RandomMinMax(1, 4);
if (Core.SE && Caster != m)
toHeal = (int)(toHeal * 1.5);
}
else
{
toHeal = (int)(Caster.Skills.Magery.Value * 0.1);
toHeal += Utility.Random(1, 5);
}
//m.Heal( toHeal, Caster );
SpellHelper.Heal(toHeal, m, Caster);
m.FixedParticles(0x376A, 9, 32, 5005, EffectLayer.Waist);
m.PlaySound(0x1F2);
}
FinishSequence();
}
}
}

View file

@ -0,0 +1,73 @@
using Server.Targeting;
namespace Server.Spells.First
{
public class MagicArrowSpell : MagerySpell, ISpellTargetingMobile
{
private static SpellInfo m_Info = new SpellInfo(
"Magic Arrow", "In Por Ylem",
212,
9041,
Reagent.SulfurousAsh
);
public MagicArrowSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info)
{
}
public override SpellCircle Circle => SpellCircle.First;
public override bool DelayedDamageStacking => !Core.AOS;
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(source, m);
SpellHelper.CheckReflect((int)Circle, ref source, ref m);
double damage;
if (Core.AOS)
{
damage = GetNewAosDamage(10, 1, 4, m);
}
else
{
damage = Utility.Random(4, 4);
if (CheckResisted(m))
{
damage *= 0.75;
m.SendLocalizedMessage(501783); // You feel yourself resisting magical energy.
}
damage *= GetDamageScalar(m);
}
source.MovingParticles(m, 0x36E4, 5, 0, false, false, 3006, 0, 0);
source.PlaySound(0x1E5);
SpellHelper.Damage(this, m, damage, 0, 100, 0, 0, 0);
}
FinishSequence();
}
}
}

View file

@ -0,0 +1,75 @@
using Server.Targeting;
namespace Server.Spells.First
{
public class NightSightSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Night Sight", "In Lor",
236,
9031,
Reagent.SulfurousAsh,
Reagent.SpidersSilk
);
public NightSightSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info)
{
}
public override SpellCircle Circle => SpellCircle.First;
public override void OnCast()
{
Caster.Target = new NightSightTarget(this);
}
private class NightSightTarget : Target
{
private Spell m_Spell;
public NightSightTarget(Spell spell) : base(12, false, TargetFlags.Beneficial)
{
m_Spell = spell;
}
protected override void OnTarget(Mobile from, object targeted)
{
if (targeted is Mobile targ && m_Spell.CheckBSequence(targ))
{
SpellHelper.Turn(m_Spell.Caster, targ);
if (targ.BeginAction<LightCycle>())
{
new LightCycle.NightSightTimer(targ).Start();
int level = (int)(LightCycle.DungeonLevel *
((Core.AOS
? targ.Skills.Magery.Value
: from.Skills.Magery.Value) / 100));
if (level < 0)
level = 0;
targ.LightLevel = level;
targ.FixedParticles(0x376A, 9, 32, 5007, EffectLayer.Waist);
targ.PlaySound(0x1E3);
BuffInfo.AddBuff(targ,
new BuffInfo(BuffIcon.NightSight, 1075643)); //Night Sight/You ignore lighting effects
}
else
{
from.SendMessage("{0} already have nightsight.", from == targ ? "You" : "They");
}
}
m_Spell.FinishSequence();
}
protected override void OnTargetFinish(Mobile from)
{
m_Spell.FinishSequence();
}
}
}
}

View file

@ -0,0 +1,151 @@
using System.Collections.Generic;
namespace Server.Spells.First
{
public class ReactiveArmorSpell : MagerySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Reactive Armor", "Flam Sanct",
236,
9011,
Reagent.Garlic,
Reagent.SpidersSilk,
Reagent.SulfurousAsh
);
private static Dictionary<Mobile, ResistanceMod[]> m_Table = new Dictionary<Mobile, ResistanceMod[]>();
public ReactiveArmorSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info)
{
}
public override SpellCircle Circle => SpellCircle.First;
public override bool CheckCast()
{
if (Core.AOS)
return true;
if (Caster.MeleeDamageAbsorb > 0)
{
Caster.SendLocalizedMessage(1005559); // This spell is already in effect.
return false;
}
if (!Caster.CanBeginAction<DefensiveSpell>())
{
Caster.SendLocalizedMessage(1005385); // The spell will not adhere to you at this time.
return false;
}
return true;
}
public override void OnCast()
{
if (Core.AOS)
{
/* The reactive armor spell increases the caster's physical resistance, while lowering the caster's elemental resistances.
* 15 + (Inscription/20) Physcial bonus
* -5 Elemental
* The reactive armor spell has an indefinite duration, becoming active when cast, and deactivated when re-cast.
* Reactive Armor, Protection, and Magic Reflection will stay on<EFBFBD>even after logging out, even after dying<EFBFBD>until you <EFBFBD>turn them off<EFBFBD> by casting them again.
* (+20 physical -5 elemental at 100 Inscription)
*/
if (CheckSequence())
{
Mobile targ = Caster;
if (!m_Table.TryGetValue(targ, out ResistanceMod[] mods))
{
targ.PlaySound(0x1E9);
targ.FixedParticles(0x376A, 9, 32, 5008, EffectLayer.Waist);
mods = new []
{
new ResistanceMod(ResistanceType.Physical,
15 + (int)(targ.Skills.Inscribe.Value / 20)),
new ResistanceMod(ResistanceType.Fire, -5),
new ResistanceMod(ResistanceType.Cold, -5),
new ResistanceMod(ResistanceType.Poison, -5),
new ResistanceMod(ResistanceType.Energy, -5)
};
m_Table[targ] = mods;
for (int i = 0; i < mods.Length; ++i)
targ.AddResistanceMod(mods[i]);
int physresist = 15 + (int)(targ.Skills.Inscribe.Value / 20);
string args = $"{physresist}\t{5}\t{5}\t{5}\t{5}";
BuffInfo.AddBuff(Caster, new BuffInfo(BuffIcon.ReactiveArmor, 1075812, 1075813, args));
}
else
{
targ.PlaySound(0x1ED);
targ.FixedParticles(0x376A, 9, 32, 5008, EffectLayer.Waist);
m_Table.Remove(targ);
for (int i = 0; i < mods.Length; ++i)
targ.RemoveResistanceMod(mods[i]);
BuffInfo.RemoveBuff(Caster, BuffIcon.ReactiveArmor);
}
}
FinishSequence();
}
else
{
if (Caster.MeleeDamageAbsorb > 0)
{
Caster.SendLocalizedMessage(1005559); // This spell is already in effect.
}
else if (!Caster.CanBeginAction<DefensiveSpell>())
{
Caster.SendLocalizedMessage(1005385); // The spell will not adhere to you at this time.
}
else if (CheckSequence())
{
if (Caster.BeginAction<DefensiveSpell>())
{
int value = (int)(Caster.Skills.Magery.Value + Caster.Skills.Meditation.Value +
Caster.Skills.Inscribe.Value);
value /= 3;
if (value < 0)
value = 1;
else if (value > 75)
value = 75;
Caster.MeleeDamageAbsorb = value;
Caster.FixedParticles(0x376A, 9, 32, 5008, EffectLayer.Waist);
Caster.PlaySound(0x1F2);
}
else
{
Caster.SendLocalizedMessage(1005385); // The spell will not adhere to you at this time.
}
}
FinishSequence();
}
}
public static void EndArmor(Mobile m)
{
if (!m_Table.TryGetValue(m, out ResistanceMod[] mods))
return;
for (int i = 0; i < mods?.Length; ++i)
m.RemoveResistanceMod(mods[i]);
m_Table.Remove(m);
BuffInfo.RemoveBuff(m, BuffIcon.ReactiveArmor);
}
}
}

View file

@ -0,0 +1,60 @@
using System;
using Server.Targeting;
namespace Server.Spells.First
{
public class WeakenSpell : MagerySpell, ISpellTargetingMobile
{
private static SpellInfo m_Info = new SpellInfo(
"Weaken", "Des Mani",
212,
9031,
Reagent.Garlic,
Reagent.Nightshade
);
public WeakenSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info)
{
}
public override SpellCircle Circle => SpellCircle.First;
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);
SpellHelper.AddStatCurse(Caster, m, StatType.Str);
m.Spell?.OnCasterHurt();
m.Paralyzed = false;
m.FixedParticles(0x3779, 10, 15, 5009, EffectLayer.Waist);
m.PlaySound(0x1E6);
int percentage = (int)(SpellHelper.GetOffsetScalar(Caster, m, true) * 100);
TimeSpan length = SpellHelper.GetDuration(Caster, m);
BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Weaken, 1075837, length, m, percentage.ToString()));
HarmfulSpell(m);
}
FinishSequence();
}
}
}