public static void Gain(Mobile from, Skill skill, int toGain)
{
if (from.Region.IsPartOf<Jail>())
return;
if (from is BaseCreature && ((BaseCreature)from).IsDeadPet)
return;
if (skill.SkillName == SkillName.Focus && from is BaseCreature &&
(!PetTrainingHelper.Enabled || !((BaseCreature)from).Controlled))
return;
if (skill.Base < skill.Cap && skill.Lock == SkillLock.Up)
{
var skills = from.Skills;
// Define excluded skills (must match BaseFixedPoint)
HashSet<SkillName> excludedSkills = new HashSet<SkillName>
{
SkillName.ArmsLore, SkillName.Begging, SkillName.Camping,
SkillName.DetectHidden, SkillName.Herding, SkillName.Forensics,
SkillName.ItemID, SkillName.Stealing, SkillName.TasteID,
SkillName.RemoveTrap, SkillName.Tracking
};
// We calculate the sum of only non-excluded skills
int nonExcludedTotal = 0;
foreach (var s in skills)
{
if (s != null && !excludedSkills.Contains(s.SkillName))
nonExcludedTotal += s.BaseFixedPoint;
}
// Check the limit only for non-excluded skills
if (from is PlayerMobile && Siege.SiegeShard)
{
var minsPerGain = Siege.MinutesPerGain(from, skill);
if (minsPerGain > 0)
{
if (Siege.CheckSkillGain((PlayerMobile)from, minsPerGain, skill))
{
CheckReduceSkill(skills, toGain, skill);
if (nonExcludedTotal + toGain <= skills.Cap)
{
skill.BaseFixedPoint += toGain;
}
}
return;
}
}
if (toGain == 1 && skill.Base <= 10.0)
toGain = Utility.Random(4) + 1;
#region Mondain's Legacy
if (from is PlayerMobile && QuestHelper.EnhancedSkill((PlayerMobile)from, skill))
{
toGain *= Utility.RandomMinMax(2, 4);
}
#endregion
#region Scroll of Alacrity
if (from is PlayerMobile && skill.SkillName == ((PlayerMobile)from).AcceleratedSkill &&
((PlayerMobile)from).AcceleratedStart > DateTime.UtcNow)
{
((PlayerMobile)from).SendLocalizedMessage(1077956);
toGain = Utility.RandomMinMax(2, 5);
}
#endregion
#region Skill Masteries
else if (from is BaseCreature && !(from is Server.Engines.Despise.DespiseCreature) && (((BaseCreature)from).Controlled || ((BaseCreature)from).Summoned))
{
var master = ((BaseCreature)from).GetMaster();
if (master != null)
{
var spell = SkillMasterySpell.GetSpell(master, typeof(WhisperingSpell)) as WhisperingSpell;
if (spell != null && master.InRange(from.Location, spell.PartyRange) && master.Map == from.Map &&
spell.EnhancedGainChance >= Utility.Random(100))
{
toGain = Utility.RandomMinMax(2, 5);
}
}
}
#endregion
if (from is PlayerMobile)
{
CheckReduceSkill(skills, toGain, skill);
}
// Apply the increase only if the non-excluded skills do not exceed the limit
if (!from.Player || (nonExcludedTotal + toGain <= skills.Cap))
{
skill.BaseFixedPoint = Math.Min(skill.CapFixedPoint, skill.BaseFixedPoint + toGain);
EventSink.InvokeSkillGain(new SkillGainEventArgs(from, skill, toGain));
if (from is PlayerMobile)
UpdateGGS(from, skill);
}
}
#region Mondain's Legacy
if (from is PlayerMobile)
QuestHelper.CheckSkill((PlayerMobile)from, skill);
#endregion
if (skill.Lock == SkillLock.Up &&
(!Siege.SiegeShard || !(from is PlayerMobile) || Siege.CanGainStat((PlayerMobile)from)))
{
var info = skill.Info;
if (!Core.ML)
{
var scalar = 1.0;
if (from.StrLock == StatLockType.Up && (info.StrGain / 33.3) * scalar > Utility.RandomDouble())
GainStat(from, Stat.Str);
else if (from.DexLock == StatLockType.Up && (info.DexGain / 33.3) * scalar > Utility.RandomDouble())
GainStat(from, Stat.Dex);
else if (from.IntLock == StatLockType.Up && (info.IntGain / 33.3) * scalar > Utility.RandomDouble())
GainStat(from, Stat.Int);
}
else
{
TryStatGain(info, from);
}
}
}