ServUO Version
Publish 57
Ultima Expansion
Endless Journey
using System;
using Server.Items;
using Server.Mobiles;

namespace Server.SkillHandlers
{
public class Stealth
{
private static readonly int[,] m_ArmorTable = new int[,]
{
// Gorget Gloves Helmet Arms Legs Chest Shield
/* Cloth */ { 0, 0, 0, 0, 0, 0, 0 },
/* Leather */ { 0, 0, 0, 0, 0, 0, 0 },
/* Studded */ { 2, 2, 0, 4, 6, 10, 0 },
/* Bone */ { 0, 5, 10, 10, 15, 25, 0 },
/* Spined */ { 0, 0, 0, 0, 0, 0, 0 },
/* Horned */ { 0, 0, 0, 0, 0, 0, 0 },
/* Barbed */ { 0, 0, 0, 0, 0, 0, 0 },
/* Ring */ { 0, 5, 0, 10, 15, 25, 0 },
/* Chain */ { 0, 0, 10, 0, 15, 25, 0 },
/* Plate */ { 5, 5, 10, 10, 15, 25, 0 },
/* Dragon */ { 0, 5, 10, 10, 15, 25, 0 }
};
public static double HidingRequirement
{
get
{
return (Core.ML ? 30.0 : (Core.SE ? 50.0 : 80.0));
}
}
public static int[,] ArmorTable
{
get
{
return m_ArmorTable;
}
}
public static void Initialize()
{
SkillInfo.Table[(int)SkillName.Stealth].Callback = new SkillUseCallback(OnUse);
}

public static int GetArmorRating(Mobile m)
{
if (!Core.AOS)
return (int)m.ArmorRating;

int ar = 0;

for (int i = 0; i < m.Items.Count; i++)
{
BaseArmor armor = m.Items as BaseArmor;

if (armor == null)
continue;

int materialType = (int)armor.MaterialType;
int bodyPosition = (int)armor.BodyPosition;

if (materialType >= m_ArmorTable.GetLength(0) || bodyPosition >= m_ArmorTable.GetLength(1))
continue;

if (armor.ArmorAttributes.MageArmor == 0)
ar += m_ArmorTable[materialType, bodyPosition];
}

return ar;
}

public static TimeSpan OnUse(Mobile m)
{
if (!m.Hidden)
{
m.SendLocalizedMessage(502725); // You must hide first
}
else if (m.Flying)
{
m.SendLocalizedMessage(1113415); // You cannot use this ability while flying.
m.RevealingAction();
BuffInfo.RemoveBuff(m, BuffIcon.HidingAndOrStealth);
}
else if (m.Skills[SkillName.Hiding].Base < HidingRequirement)
{
m.SendLocalizedMessage(502726); // You are not hidden well enough. Become better at hiding.
m.RevealingAction();
BuffInfo.RemoveBuff(m, BuffIcon.HidingAndOrStealth);
}
else if (!m.CanBeginAction(typeof(Stealth)))
{
m.SendLocalizedMessage(1063086); // You cannot use this skill right now.
m.RevealingAction();
BuffInfo.RemoveBuff(m, BuffIcon.HidingAndOrStealth);
}
else
{
int armorRating = GetArmorRating(m);

if (armorRating >= (Core.AOS ? 42 : 26)) //I have a hunch '42' was chosen cause someone's a fan of DNA
{
m.SendLocalizedMessage(502727); // You could not hope to move quietly wearing this much armor.
m.RevealingAction();
BuffInfo.RemoveBuff(m, BuffIcon.HidingAndOrStealth);
}
else if (m.CheckSkill(SkillName.Stealth, -20.0 + (armorRating * 2), (Core.AOS ? 60.0 : 80.0) + (armorRating * 2)))
{
int steps = (int)(m.Skills[SkillName.Stealth].Value / (Core.AOS ? 5.0 : 10.0));

if (steps < 1)
steps = 1;

m.AllowedStealthSteps = steps;

m.IsStealthing = true;

m.SendLocalizedMessage(502730); // You begin to move quietly.

BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.HidingAndOrStealth, 1044107, 1075655));
return TimeSpan.FromSeconds(10.0);
}
else
{
m.SendLocalizedMessage(502731); // You fail in your attempt to move unnoticed.
m.RevealingAction();
BuffInfo.RemoveBuff(m, BuffIcon.HidingAndOrStealth);
}
}

return TimeSpan.FromSeconds(10.0);
}
}
}


Stealth technology will release the hiding condition if you walk while wearing heavy armor.
using System;
using System.Globalization;

using Server.Items;
using Server.Mobiles;
using Server.Spells.SkillMasteries;

namespace Server.Spells
{
public abstract class MagerySpell : Spell
{
private static readonly int[] m_ManaTable = new int[] { 4, 6, 9, 11, 14, 20, 40, 90 };
private const double ChanceOffset = 20.0, ChanceLength = 100.0 / 7.0;
public MagerySpell(Mobile caster, Item scroll, SpellInfo info)
: base(caster, scroll, info)
{
}
private int m_CastTimeFocusLevel;
public abstract double RequiredSkill { get; }
public abstract SpellCircle Circle { get; }

public override TimeSpan CastDelayBase
{
get
{
return TimeSpan.FromMilliseconds(((4 + (int)Circle) * CastDelaySecondsPerTick) * 1000);
}
}
public override bool ConsumeReagents()
{
if (base.ConsumeReagents())
return true;

if (ArcaneGem.ConsumeCharges(Caster, (Core.SE ? 1 : 1 + (int)Circle)))
return true;

return false;
}

public virtual int FocusLevel { get { return m_CastTimeFocusLevel; } }

public static int GetFocusLevel(Mobile from)
{
ArcaneFocus focus = FindArcaneFocus(from);

if (focus == null || focus.Deleted)
{
if (Core.TOL && from is BaseCreature && from.Skills[SkillName.Magery].Value > 0)
{
return (int)Math.Max(1, Math.Min(6, from.Skills[SkillName.Magery].Value / 20));
}

return Math.Max(GetMasteryFocusLevel(from), 0);
}

return Math.Max(GetMasteryFocusLevel(from), focus.StrengthBonus);
}

public static int GetMasteryFocusLevel(Mobile from)
{
if (!Core.TOL)
{
return 0;
}

if (from.Skills.CurrentMastery == SkillName.Magery)
{
return Math.Max(1, MasteryInfo.GetMasteryLevel(from, SkillName.Magery));
}

return 0;
}

public static ArcaneFocus FindArcaneFocus(Mobile from)
{
if (from == null || from.Backpack == null)
{
return null;
}

if (from.Holding is ArcaneFocus)
{
return (ArcaneFocus)from.Holding;
}

return from.Backpack.FindItemByType<ArcaneFocus>();
}


public override void GetCastSkills(out double min, out double max)
{
min = RequiredSkill - 12.5; //per 5 on friday, 2/16/07
max = RequiredSkill + 37.5;
}
public override bool CheckCast()
{
if (!base.CheckCast())
{
return false;
}
if (Caster.Skills[CastSkill].Value < RequiredSkill)
{
Caster.SendLocalizedMessage(1063013, String.Format("{0}\t{1}", RequiredSkill.ToString("F1"), "#1044114"));
// You need at least ~1_SKILL_REQUIREMENT~ ~2_SKILL_NAME~ skill to use that ability.
return false;
}

return true;
}


public override int GetMana()
{
if (Scroll is BaseWand)
return 0;

return m_ManaTable[(int)Circle];
}

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 maxSkill = (1 + (int)Circle) * 10;
maxSkill += (1 + ((int)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) + (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 virtual void DoEffect(Mobile m)
{
}

public virtual void RemoveEffect(Mobile m)
{
}

public override TimeSpan GetCastDelay()
{
if (!Core.ML && Scroll is BaseWand)
return TimeSpan.Zero;

if (!Core.AOS)
return TimeSpan.FromSeconds(0.5 + (0.25 * (int)Circle));

return base.GetCastDelay();
}
}
}
The above script is MagerySpell.cs . I want to make it impossible to use magic when I wear heavy armor. Is there a way? I need your help.
 
You can try the CheckCast method in Spell.cs

And try this:

C#:
public virtual bool CheckCast()
{
    if (Server.Multis.BaseBoat.IsDriving(m_Caster) && m_Caster.AccessLevel == AccessLevel.Player)
    {
        m_Caster.SendLocalizedMessage(1049616); // You are too busy to do that at the moment.
        return false;
    }
    Type[] plateTypes = new Type[]
    {
        typeof(PlateHelm),
        typeof(PlateChest),
        typeof(PlateArms),
        typeof(PlateGorget),
        typeof(PlateGloves),
        typeof(PlateLegs)
    };
    foreach (Type plateType in plateTypes)
    {
        Item equippedItem = m_Caster.FindItemOnLayer(Layer.Find(plateType));
        if (equippedItem != null && equippedItem.GetType() == plateType)
        {
            return false;
        }
    }
    return true;
}
Not tested,but its a start.
 
You can try the CheckCast method in Spell.cs

And try this:

C#:
public virtual bool CheckCast()
{
    if (Server.Multis.BaseBoat.IsDriving(m_Caster) && m_Caster.AccessLevel == AccessLevel.Player)
    {
        m_Caster.SendLocalizedMessage(1049616); // You are too busy to do that at the moment.
        return false;
    }
    Type[] plateTypes = new Type[]
    {
        typeof(PlateHelm),
        typeof(PlateChest),
        typeof(PlateArms),
        typeof(PlateGorget),
        typeof(PlateGloves),
        typeof(PlateLegs)
    };
    foreach (Type plateType in plateTypes)
    {
        Item equippedItem = m_Caster.FindItemOnLayer(Layer.Find(plateType));
        if (equippedItem != null && equippedItem.GetType() == plateType)
        {
            return false;
        }
    }
    return true;
}
Not tested,but its a start.
CS0117: Line 710: 'Layer' does not contain a definition for 'Find'
Thank you for your answer! I did a test. However, the above error appears.
 
Sorry but now im not testing,try this:

C#:
public virtual bool CheckCast()
{
    if (Server.Multis.BaseBoat.IsDriving(m_Caster) && m_Caster.AccessLevel == AccessLevel.Player)
    {
        m_Caster.SendLocalizedMessage(1049616); // You are too busy to do that at the moment.
        return false;
    }

    Type[] plateTypes = new Type[]
    {
        typeof(PlateHelm),
        typeof(PlateChest),
        typeof(PlateArms),
        typeof(PlateGorget),
        typeof(PlateGloves),
        typeof(PlateLegs)
    };

    foreach (Type plateType in plateTypes)
    {
        foreach (Layer layer in Enum.GetValues(typeof(Layer)))
        {
            Item equippedItem = m_Caster.FindItemOnLayer(layer);
            if (equippedItem != null && equippedItem.GetType() == plateType)
            {
                return false;
            }
        }
    }

    return true;
}
 
Sorry but now im not testing,try this:

C#:
public virtual bool CheckCast()
{
    if (Server.Multis.BaseBoat.IsDriving(m_Caster) && m_Caster.AccessLevel == AccessLevel.Player)
    {
        m_Caster.SendLocalizedMessage(1049616); // You are too busy to do that at the moment.
        return false;
    }

    Type[] plateTypes = new Type[]
    {
        typeof(PlateHelm),
        typeof(PlateChest),
        typeof(PlateArms),
        typeof(PlateGorget),
        typeof(PlateGloves),
        typeof(PlateLegs)
    };

    foreach (Type plateType in plateTypes)
    {
        foreach (Layer layer in Enum.GetValues(typeof(Layer)))
        {
            Item equippedItem = m_Caster.FindItemOnLayer(layer);
            if (equippedItem != null && equippedItem.GetType() == plateType)
            {
                return false;
            }
        }
    }

    return true;
}
public override bool CheckCast()
{
Type[] plateTypes = new Type[]
{
typeof(PlateHelm),
typeof(PlateChest),
typeof(PlateArms),
typeof(PlateGorget),
typeof(PlateGloves),
typeof(PlateLegs)
};

foreach (Type plateType in plateTypes)
{
foreach (Layer layer in Enum.GetValues(typeof(Layer)))
{
Item equippedItem = m_Caster.FindItemOnLayer(layer);
if (equippedItem != null && equippedItem.GetType() == plateType)
{
m_Caster.SendLocalizedMessage("1049616"); // You are too busy to do that at the moment.
return false;
}
}
if (!base.CheckCast())
{
return false;
}
if (Caster.Skills[CastSkill].Value < RequiredSkill)
{
Caster.SendLocalizedMessage(1063013, String.Format("{0}\t{1}", RequiredSkill.ToString("F1"), "#1044114"));
// You need at least ~1_SKILL_REQUIREMENT~ ~2_SKILL_NAME~ skill to use that ability.
return false;
}
return true;
}}
Thank you for your answer! I tested it. Works perfectly! But I don't want to apply it to Spell.cs , I want to apply it to MagerySpell.cs . So I tried the same thing as above, but I get an error like the one below. I'm sorry to keep bothering you.Can I ask for a little more help?
+ Spells/Base/MagerySpell.cs:
CS0122: Line 111: 'Spell.m_Caster' is inaccessible due to its protection level
CS0122: Line 114: 'Spell.m_Caster' is inaccessible due to its protection level
CS1503: Line 114: Argument 1: cannot convert from 'string' to 'int'
CS0161: Line 95: 'MagerySpell.CheckCast()': not all code paths return a value
 
Here we go (in Spell.cs):


C#:
public virtual bool CheckCast()
{
    if (Server.Multis.BaseBoat.IsDriving(m_Caster) && m_Caster.AccessLevel == AccessLevel.Player)
    {
        m_Caster.SendLocalizedMessage(1049616); // You are too busy to do that at the moment.
        return false;
    }

    if (this is MagerySpell)
    {
        Type[] plateTypes = new Type[]
        {
            typeof(PlateHelm),
            typeof(PlateChest),
            typeof(PlateArms),
            typeof(PlateGorget),
            typeof(PlateGloves),
            typeof(PlateLegs)
        };

        foreach (Type plateType in plateTypes)
        {
            foreach (Layer layer in Enum.GetValues(typeof(Layer)))
            {
                Item equippedItem = m_Caster.FindItemOnLayer(layer);
                if (equippedItem != null && equippedItem.GetType() == plateType)
                {
                    m_Caster.SendMessage("You cant cast magery spells with plate armor on you.");
                    return false;
                }
            }
        }
    }

    return true;
}
Take care,i think there is more plate helm types.
 
Here we go (in Spell.cs):


C#:
public virtual bool CheckCast()
{
    if (Server.Multis.BaseBoat.IsDriving(m_Caster) && m_Caster.AccessLevel == AccessLevel.Player)
    {
        m_Caster.SendLocalizedMessage(1049616); // You are too busy to do that at the moment.
        return false;
    }

    if (this is MagerySpell)
    {
        Type[] plateTypes = new Type[]
        {
            typeof(PlateHelm),
            typeof(PlateChest),
            typeof(PlateArms),
            typeof(PlateGorget),
            typeof(PlateGloves),
            typeof(PlateLegs)
        };

        foreach (Type plateType in plateTypes)
        {
            foreach (Layer layer in Enum.GetValues(typeof(Layer)))
            {
                Item equippedItem = m_Caster.FindItemOnLayer(layer);
                if (equippedItem != null && equippedItem.GetType() == plateType)
                {
                    m_Caster.SendMessage("You cant cast magery spells with plate armor on you.");
                    return false;
                }
            }
        }
    }

    return true;
}
Take care,i think there is more plate helm types.
Thank you for your answer! I tested it! There is no problem with the compilation. But there's a problem.Wear armor and the magic in MagerySpell should not be triggered, but the magic is triggered. I don't know what the problem is.
 
If it dont work in Spell.cs,you need to go to individual spells .cs,like Heal.cs,then go to his CheckCast method and apply the code without the if ( is MagerySpell ).
 
If it dont work in Spell.cs,you need to go to individual spells .cs,like Heal.cs,then go to his CheckCast method and apply the code without the if ( is MagerySpell ).
Thank you for your answer! Working with individual orders, it works perfectly. Thank you so much for your kind reply.To me, you are a genius!
 
Back