Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
651
Scripts/Spells/Skill Masteries/Core/MasteryInfo.cs
Normal file
651
Scripts/Spells/Skill Masteries/Core/MasteryInfo.cs
Normal file
@@ -0,0 +1,651 @@
|
||||
using Server;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using System.Linq;
|
||||
|
||||
namespace Server.Spells.SkillMasteries
|
||||
{
|
||||
public enum Volume
|
||||
{
|
||||
None,
|
||||
One,
|
||||
Two,
|
||||
Three
|
||||
}
|
||||
|
||||
public enum PassiveSpell
|
||||
{
|
||||
None,
|
||||
EnchantedSummoning,
|
||||
Intuition,
|
||||
SavingThrow,
|
||||
Potency,
|
||||
Knockout,
|
||||
Boarding,
|
||||
AnticipateHit
|
||||
}
|
||||
|
||||
public class MasteryInfo
|
||||
{
|
||||
public static readonly int MinSkillRequirement = 90;
|
||||
|
||||
public static void Configure()
|
||||
{
|
||||
Infos = new List<MasteryInfo>();
|
||||
|
||||
EventSink.Login += new LoginEventHandler(OnLogin);
|
||||
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.InspireSpell), 700, SkillName.Provocation));
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.InvigorateSpell), 701, SkillName.Provocation));
|
||||
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.ResilienceSpell), 702, SkillName.Peacemaking));
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.PerseveranceSpell), 703, SkillName.Peacemaking));
|
||||
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.TribulationSpell), 704, SkillName.Discordance));
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.DespairSpell), 705, SkillName.Discordance));
|
||||
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.DeathRaySpell), 706, SkillName.Magery));
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.EtherealBurstSpell), 707, SkillName.Magery));
|
||||
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.NetherBlastSpell), 708, SkillName.Mysticism));
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.MysticWeaponSpell), 709, SkillName.Mysticism));
|
||||
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.CommandUndeadSpell), 710, SkillName.Necromancy));
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.ConduitSpell), 711, SkillName.Necromancy));
|
||||
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.ManaShieldSpell), 712, SkillName.Spellweaving));
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.SummonReaperSpell), 713, SkillName.Spellweaving));
|
||||
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.WarcrySpell), 716, SkillName.Bushido));
|
||||
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.RejuvinateSpell), 718, SkillName.Chivalry));
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.HolyFistSpell), 719, SkillName.Chivalry));
|
||||
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.ShadowSpell), 720, SkillName.Ninjitsu));
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.WhiteTigerFormSpell), 721, SkillName.Ninjitsu));
|
||||
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.FlamingShotSpell), 722, SkillName.Archery));
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.PlayingTheOddsSpell), 723, SkillName.Archery));
|
||||
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.ThrustSpell), 724, SkillName.Fencing));
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.PierceSpell), 725, SkillName.Fencing));
|
||||
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.StaggerSpell), 726, SkillName.Macing));
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.ToughnessSpell), 727, SkillName.Macing));
|
||||
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.OnslaughtSpell), 728, SkillName.Swords));
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.FocusedEyeSpell), 729, SkillName.Swords));
|
||||
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.ElementalFurySpell), 730, SkillName.Throwing));
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.CalledShotSpell), 731, SkillName.Throwing));
|
||||
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.ShieldBashSpell), 733, SkillName.Parry));
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.BodyGuardSpell), 734, SkillName.Parry));
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.HeightenedSensesSpell), 735, SkillName.Parry));
|
||||
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.ToleranceSpell), 736, SkillName.Poisoning));
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.InjectedStrikeSpell), 737, SkillName.Poisoning));
|
||||
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.RampageSpell), 739, SkillName.Wrestling));
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.FistsOfFurySpell), 740, SkillName.Wrestling));
|
||||
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.WhisperingSpell), 742, SkillName.AnimalTaming));
|
||||
Infos.Add(new MasteryInfo(typeof(SkillMasteries.CombatTrainingSpell), 743, SkillName.AnimalTaming));
|
||||
|
||||
//Passive Masteries
|
||||
Infos.Add(new MasteryInfo(null, 714, SkillName.Magery, PassiveSpell.EnchantedSummoning)); // Enchanted Summoning
|
||||
Infos.Add(new MasteryInfo(null, 714, SkillName.Necromancy, PassiveSpell.EnchantedSummoning)); // Enchanted Summoning
|
||||
Infos.Add(new MasteryInfo(null, 714, SkillName.Spellweaving, PassiveSpell.EnchantedSummoning)); // Enchanted Summoning
|
||||
Infos.Add(new MasteryInfo(null, 714, SkillName.Mysticism, PassiveSpell.EnchantedSummoning)); // Enchanted Summoning
|
||||
|
||||
Infos.Add(new MasteryInfo(null, 715, SkillName.Bushido, PassiveSpell.AnticipateHit)); // Anticipate Hit
|
||||
|
||||
Infos.Add(new MasteryInfo(null, 717, SkillName.Bushido, PassiveSpell.Intuition)); // Intuition
|
||||
Infos.Add(new MasteryInfo(null, 717, SkillName.Ninjitsu, PassiveSpell.Intuition)); // Intuition
|
||||
Infos.Add(new MasteryInfo(null, 717, SkillName.Chivalry, PassiveSpell.Intuition)); // Intuition
|
||||
|
||||
Infos.Add(new MasteryInfo(null, 732, SkillName.Archery, PassiveSpell.SavingThrow)); // Saving Throw
|
||||
Infos.Add(new MasteryInfo(null, 732, SkillName.Fencing, PassiveSpell.SavingThrow)); // Saving Throw
|
||||
Infos.Add(new MasteryInfo(null, 732, SkillName.Swords, PassiveSpell.SavingThrow)); // Saving Throw
|
||||
Infos.Add(new MasteryInfo(null, 732, SkillName.Macing, PassiveSpell.SavingThrow)); // Saving Throw
|
||||
Infos.Add(new MasteryInfo(null, 732, SkillName.Throwing, PassiveSpell.SavingThrow)); // Saving Throw
|
||||
|
||||
Infos.Add(new MasteryInfo(null, 738, SkillName.Poisoning, PassiveSpell.Potency)); // Potency
|
||||
Infos.Add(new MasteryInfo(null, 741, SkillName.Wrestling, PassiveSpell.Knockout)); // Knockout
|
||||
Infos.Add(new MasteryInfo(null, 744, SkillName.AnimalTaming, PassiveSpell.Boarding)); // Boarding
|
||||
}
|
||||
|
||||
public static List<MasteryInfo> Infos { get; set; }
|
||||
|
||||
public Type SpellType { get; set; }
|
||||
public int SpellID { get; set; }
|
||||
public SkillName MasterySkill { get; set; }
|
||||
public int NameLocalization { get; set; }
|
||||
|
||||
public bool Passive { get { return PassiveSpell != PassiveSpell.None; } }
|
||||
public PassiveSpell PassiveSpell { get; set; }
|
||||
|
||||
public MasteryInfo(Type skillType, int spellID, SkillName masterySkill, PassiveSpell passive = PassiveSpell.None)
|
||||
{
|
||||
SpellType = skillType;
|
||||
SpellID = spellID;
|
||||
|
||||
MasterySkill = masterySkill;
|
||||
PassiveSpell = passive;
|
||||
|
||||
NameLocalization = GetLocalization(masterySkill);
|
||||
}
|
||||
|
||||
public static MasteryInfo GetInfo(Type spell, SkillName skill)
|
||||
{
|
||||
return Infos.FirstOrDefault(info => info.SpellType == spell && info.MasterySkill == skill);
|
||||
}
|
||||
|
||||
public static MasteryInfo GetInfo(int spellID)
|
||||
{
|
||||
return Infos.FirstOrDefault(info => info.SpellID == spellID);
|
||||
}
|
||||
|
||||
public static MasteryInfo GetInfo(int spellID, SkillName name)
|
||||
{
|
||||
return Infos.FirstOrDefault(info => info.SpellID == spellID && info.MasterySkill == name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Obsolete, used to serialize old types
|
||||
/// </summary>
|
||||
/// <param name="spellID"></param>
|
||||
/// <param name="skill"></param>
|
||||
/// <returns></returns>
|
||||
public static int GetVolume(int spellID, SkillName skill)
|
||||
{
|
||||
if (IsPassiveMastery(spellID) || spellID == 733)
|
||||
return 1;
|
||||
else if (spellID <= 715)
|
||||
{
|
||||
if (spellID % 2 == 0)
|
||||
return 3;
|
||||
|
||||
return 2;
|
||||
}
|
||||
else if (spellID <= 731 || (spellID >= 736 && spellID <= 743))
|
||||
{
|
||||
if (spellID % 2 == 0)
|
||||
return 2;
|
||||
|
||||
return 3;
|
||||
}
|
||||
else if (spellID == 734)
|
||||
return 2;
|
||||
else if (spellID == 735)
|
||||
return 3;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
public static SkillName GetSkillForID(int spellID)
|
||||
{
|
||||
MasteryInfo info = GetInfo(spellID);
|
||||
|
||||
if (info != null)
|
||||
return info.MasterySkill;
|
||||
|
||||
return SkillName.Archery;
|
||||
}
|
||||
|
||||
public static bool HasLearned(Mobile m, SkillName skill)
|
||||
{
|
||||
return m.Skills[skill].HasLearnedMastery();
|
||||
}
|
||||
|
||||
public static bool HasLearned(Mobile m, SkillName skill, int volume)
|
||||
{
|
||||
return m.Skills[skill].HasLearnedVolume(volume);
|
||||
}
|
||||
|
||||
public static bool HasLearned(Mobile m, Type spell, SkillName skill)
|
||||
{
|
||||
MasteryInfo info = GetInfo(spell, skill);
|
||||
|
||||
return info != null && m.Skills[info.MasterySkill].HasLearnedMastery();
|
||||
}
|
||||
|
||||
public static int GetMasteryLevel(Mobile m, SkillName name)
|
||||
{
|
||||
return m.Skills[name].VolumeLearned;
|
||||
}
|
||||
|
||||
public static bool CanLearn(Mobile m, int spellID, SkillName skill)
|
||||
{
|
||||
MasteryInfo info = GetInfo(spellID, skill);
|
||||
|
||||
if (info != null)
|
||||
{
|
||||
return m.Skills[info.MasterySkill].Base >= MinSkillRequirement;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool LearnMastery(Mobile m, SkillName skill, int volume)
|
||||
{
|
||||
if (GetMasteryLevel(m, skill) < volume)
|
||||
{
|
||||
m.Skills[skill].LearnMastery((int)volume);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool IsPassiveMastery(int spellID)
|
||||
{
|
||||
return spellID == 714 || spellID == 715 || spellID == 716 || spellID == 732 || spellID == 738 || spellID == 741 || spellID == 744;
|
||||
}
|
||||
|
||||
public static void OnMasteryChanged(Mobile m, SkillName oldMastery)
|
||||
{
|
||||
PassiveSpell passive = GetActivePassive(m);
|
||||
SkillName newMastery = m.Skills.CurrentMastery;
|
||||
|
||||
if (oldMastery != newMastery)
|
||||
{
|
||||
List<SkillMasterySpell> list = SkillMasterySpell.GetSpells(m);
|
||||
|
||||
if (list != null)
|
||||
{
|
||||
list.ForEach(spell =>
|
||||
{
|
||||
spell.Expire();
|
||||
});
|
||||
|
||||
ColUtility.Free(list);
|
||||
}
|
||||
|
||||
if (m is PlayerMobile && oldMastery == SkillName.Necromancy)
|
||||
{
|
||||
((PlayerMobile)m).AllFollowers.IterateReverse(mob =>
|
||||
{
|
||||
if (mob is BaseCreature && CommandUndeadSpell.ValidateTarget((BaseCreature)mob))
|
||||
{
|
||||
((BaseCreature)mob).SetControlMaster(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
SpecialMove move = SpecialMove.GetCurrentMove(m);
|
||||
|
||||
if(move is SkillMasteryMove)
|
||||
SpecialMove.ClearCurrentMove(m);
|
||||
|
||||
m.RemoveStatMod("SavingThrow_Str");
|
||||
|
||||
ColUtility.Free(list);
|
||||
RemovePassiveBuffs(m);
|
||||
}
|
||||
|
||||
if (passive != PassiveSpell.None && passive != PassiveSpell.AnticipateHit)
|
||||
{
|
||||
switch (passive)
|
||||
{
|
||||
case PassiveSpell.EnchantedSummoning:
|
||||
BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.EnchantedSummoning, 1155904, 1156090, String.Format("{0}\t{0}", EnchantedSummoningBonus(m).ToString()), true)); // +~1_STAMINA~ Stamina Regeneration and +~2_HP~% Hit Points for summoned pets.<br>Increased difficulty for summoned pets to be dispelled.
|
||||
break;
|
||||
case PassiveSpell.Intuition:
|
||||
BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Intuition, 1155907, 1156089, IntuitionBonus(m).ToString(), true)); // Mana Increase ~1_VAL~
|
||||
break;
|
||||
case PassiveSpell.SavingThrow:
|
||||
{
|
||||
string args = null;
|
||||
|
||||
switch (GetMasteryLevel(m, newMastery))
|
||||
{
|
||||
default: args = "5\t0\t0\t0"; break;
|
||||
case 2: args = "5\t5\t0\t0"; break;
|
||||
case 3: args = "5\t5\t5\t5"; break;
|
||||
}
|
||||
|
||||
m.AddStatMod(new StatMod(StatType.Str, "SavingThrow_Str", 5, TimeSpan.Zero));
|
||||
BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.SavingThrow, 1156031, 1156032, args, true)); // Provides a chance to block disarm attempts based on Mastery level, weapon skill level and tactics skill level.
|
||||
}
|
||||
break;
|
||||
case PassiveSpell.Potency:
|
||||
BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Potency, 1155928, 1156195, NonPoisonConsumeChance(m).ToString(), true)); // ~1_VAL~% chance to not consume poison charges when using infecting strike or injected strike.
|
||||
break;
|
||||
case PassiveSpell.Knockout:
|
||||
BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Knockout, 1155931, 1156030, String.Format("{0}\t{1}", GetKnockoutModifier(m).ToString(), GetKnockoutModifier(m, true).ToString(), true))); // Wrestling Damage Bonus:<br>+~1_VAL~% PvM<br>+~2_VAL~% PvP
|
||||
break;
|
||||
case PassiveSpell.Boarding:
|
||||
BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Boarding, 1155934, 1156194, BoardingSlotIncrease(m).ToString(), true)); // Your number of stable slots has been increased by ~1_VAL~.
|
||||
break;
|
||||
}
|
||||
|
||||
m.Delta(MobileDelta.WeaponDamage);
|
||||
m.UpdateResistances();
|
||||
|
||||
if (m.Mana > m.ManaMax)
|
||||
m.Mana = m.ManaMax;
|
||||
}
|
||||
|
||||
if (m.Backpack != null)
|
||||
{
|
||||
foreach (Item item in m.Backpack.FindItemsByType(typeof(BookOfMasteries)))
|
||||
{
|
||||
BookOfMasteries book = item as BookOfMasteries;
|
||||
|
||||
if (book != null)
|
||||
book.InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Item item in m.Items.Where(i => i is BookOfMasteries))
|
||||
{
|
||||
BookOfMasteries book = item as BookOfMasteries;
|
||||
|
||||
if (book != null)
|
||||
book.InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public static PassiveSpell GetActivePassive(Mobile m)
|
||||
{
|
||||
if (m == null || m.Skills == null || Infos == null)
|
||||
return PassiveSpell.None;
|
||||
|
||||
SkillName mastery = m.Skills.CurrentMastery;
|
||||
|
||||
MasteryInfo info = Infos.FirstOrDefault(i => i.Passive && i.MasterySkill == mastery && i.PassiveSpell != PassiveSpell.AnticipateHit);
|
||||
|
||||
if (info != null)
|
||||
return info.PassiveSpell;
|
||||
|
||||
return PassiveSpell.None;
|
||||
}
|
||||
|
||||
public static bool IsActivePassive(Mobile m, PassiveSpell spell)
|
||||
{
|
||||
if (spell == PassiveSpell.AnticipateHit)
|
||||
return m.Skills.CurrentMastery == SkillName.Bushido;
|
||||
|
||||
return GetActivePassive(m) == spell;
|
||||
}
|
||||
|
||||
public static void RemovePassiveBuffs(Mobile m)
|
||||
{
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.EnchantedSummoning);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.AnticipateHit);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.Intuition);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.SavingThrow);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.Potency);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.Knockout);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.Boarding);
|
||||
}
|
||||
|
||||
public static void OnLogin(LoginEventArgs e)
|
||||
{
|
||||
Mobile m = e.Mobile;
|
||||
|
||||
if ((int)m.Skills.CurrentMastery > 0)
|
||||
OnMasteryChanged(m, m.Skills.CurrentMastery);
|
||||
}
|
||||
|
||||
public static int GetSpellID(PassiveSpell spell)
|
||||
{
|
||||
switch (spell)
|
||||
{
|
||||
case PassiveSpell.EnchantedSummoning: return 714;
|
||||
case PassiveSpell.AnticipateHit: return 715;
|
||||
case PassiveSpell.Intuition: return 717;
|
||||
case PassiveSpell.SavingThrow: return 732;
|
||||
case PassiveSpell.Potency: return 738;
|
||||
case PassiveSpell.Knockout: return 741;
|
||||
case PassiveSpell.Boarding: return 744;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static int GetSpellID(SkillName name)
|
||||
{
|
||||
MasteryInfo info = Infos.FirstOrDefault(i => i.MasterySkill == name && i.Passive);
|
||||
|
||||
if (info == null)
|
||||
return -1;
|
||||
|
||||
return info.SpellID;
|
||||
}
|
||||
|
||||
public static int GetLocalization(SkillName name)
|
||||
{
|
||||
switch (name)
|
||||
{
|
||||
default:
|
||||
case SkillName.Discordance: return 1151945;
|
||||
case SkillName.Provocation: return 1151946;
|
||||
case SkillName.Peacemaking: return 1151947;
|
||||
case SkillName.Magery: return 1155771;
|
||||
case SkillName.Mysticism: return 1155772;
|
||||
case SkillName.Necromancy: return 1155773;
|
||||
case SkillName.Spellweaving: return 1155774;
|
||||
case SkillName.Bushido: return 1155775;
|
||||
case SkillName.Chivalry: return 1155776;
|
||||
case SkillName.Ninjitsu: return 1155777;
|
||||
case SkillName.Archery: return 1155786;
|
||||
case SkillName.Fencing: return 1155778;
|
||||
case SkillName.Macing: return 1155779;
|
||||
case SkillName.Swords: return 1155780;
|
||||
case SkillName.Throwing: return 1155781;
|
||||
case SkillName.Parry: return 1155782;
|
||||
case SkillName.Poisoning: return 1155783;
|
||||
case SkillName.Wrestling: return 1155784;
|
||||
case SkillName.AnimalTaming: return 1155785;
|
||||
}
|
||||
}
|
||||
|
||||
#region Passive Bonuses/Maluses
|
||||
public static int EnchantedSummoningBonus(BaseCreature bc)
|
||||
{
|
||||
if (bc.Summoned)
|
||||
return EnchantedSummoningBonus(bc.SummonMaster);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int EnchantedSummoningBonus(Mobile m)
|
||||
{
|
||||
if (IsActivePassive(m, PassiveSpell.EnchantedSummoning))
|
||||
{
|
||||
SkillName sk = m.Skills.CurrentMastery;
|
||||
|
||||
return (int)((m.Skills[sk].Value + (GetMasteryLevel(m, sk) * 40)) / 16);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int AnticipateHitBonus(Mobile m)
|
||||
{
|
||||
if (IsActivePassive(m, PassiveSpell.AnticipateHit))
|
||||
{
|
||||
return (int)(m.Skills[SkillName.Bushido].Value * .67);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int IntuitionBonus(Mobile m)
|
||||
{
|
||||
if (IsActivePassive(m, PassiveSpell.Intuition))
|
||||
{
|
||||
SkillName sk = m.Skills.CurrentMastery;
|
||||
|
||||
return (int)((GetMasteryLevel(m, sk) * 40) / 8);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int NonPoisonConsumeChance(Mobile m)
|
||||
{
|
||||
if (IsActivePassive(m, PassiveSpell.Potency))
|
||||
{
|
||||
double skill = m.Skills[SkillName.Poisoning].Value + m.Skills[SkillName.Anatomy].Value;
|
||||
skill += GetMasteryLevel(m, SkillName.Poisoning) * 20;
|
||||
|
||||
return (int)(skill / 4.375);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int GetKnockoutModifier(Mobile m, bool pvp = false)
|
||||
{
|
||||
if (IsActivePassive(m, PassiveSpell.Knockout))
|
||||
{
|
||||
switch (GetMasteryLevel(m, SkillName.Wrestling))
|
||||
{
|
||||
default: return 0;
|
||||
case 3: return pvp ? 50 : 100;
|
||||
case 2: return pvp ? 25 : 50;
|
||||
case 1: return pvp ? 10 : 25;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int BoardingSlotIncrease(Mobile m)
|
||||
{
|
||||
if (IsActivePassive(m, PassiveSpell.Boarding))
|
||||
{
|
||||
return GetMasteryLevel(m, SkillName.AnimalTaming);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int SavingThrowChance(Mobile m, AosAttribute attr)
|
||||
{
|
||||
if (IsActivePassive(m, PassiveSpell.SavingThrow))
|
||||
{
|
||||
int level = GetMasteryLevel(m, m.Skills.CurrentMastery);
|
||||
|
||||
if (level <= 0)
|
||||
return 0;
|
||||
|
||||
switch (attr)
|
||||
{
|
||||
case AosAttribute.AttackChance: return 5;
|
||||
case AosAttribute.DefendChance: return level > 1 ? 5 : 0;
|
||||
case AosAttribute.BonusStr: return level > 2 ? 5 : 0;
|
||||
case AosAttribute.WeaponDamage: return level > 2 ? 5 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Mastery Skills
|
||||
public static SkillName[] Skills { get { return _Skills; } }
|
||||
|
||||
private static SkillName[] _Skills =
|
||||
{
|
||||
SkillName.Peacemaking,
|
||||
SkillName.Provocation,
|
||||
SkillName.Discordance,
|
||||
SkillName.Magery,
|
||||
SkillName.Mysticism,
|
||||
SkillName.Necromancy,
|
||||
SkillName.Spellweaving,
|
||||
SkillName.Bushido,
|
||||
SkillName.Chivalry,
|
||||
SkillName.Ninjitsu,
|
||||
SkillName.Fencing,
|
||||
SkillName.Macing,
|
||||
SkillName.Swords,
|
||||
SkillName.Throwing,
|
||||
SkillName.Parry,
|
||||
SkillName.Poisoning,
|
||||
SkillName.Wrestling,
|
||||
SkillName.AnimalTaming,
|
||||
SkillName.Archery
|
||||
};
|
||||
|
||||
private static int[] _Descriptions =
|
||||
{
|
||||
1115707,
|
||||
1115706,
|
||||
1115708,
|
||||
1156303,
|
||||
1156316,
|
||||
1156311,
|
||||
1156315,
|
||||
1156313,
|
||||
1156312,
|
||||
1156314,
|
||||
1156309,
|
||||
1156308,
|
||||
1156307,
|
||||
1156317,
|
||||
1156302,
|
||||
1156304,
|
||||
1156310,
|
||||
1156306,
|
||||
1156305
|
||||
};
|
||||
|
||||
private static string[] _Titles =
|
||||
{
|
||||
"the Galvanizer",
|
||||
"the Exhilarator",
|
||||
"the Desponder",
|
||||
"the Marvelous",
|
||||
"the Enigmatic",
|
||||
"the Undying",
|
||||
"the Mysterious",
|
||||
"the Disciplined",
|
||||
"the Courageous",
|
||||
"the Unseen",
|
||||
"the Needle",
|
||||
"the Crushing",
|
||||
"the Blade",
|
||||
"the Precise",
|
||||
"the Deflector",
|
||||
"the Lethal",
|
||||
"the Champion",
|
||||
"the Beastmaster",
|
||||
"the Exact"
|
||||
};
|
||||
|
||||
public static int GetDescription(Mobile m)
|
||||
{
|
||||
SkillName sk = m.Skills.CurrentMastery;
|
||||
|
||||
for (int i = 0; i < _Skills.Length; i++)
|
||||
{
|
||||
if (_Skills[i] == sk)
|
||||
return _Descriptions[i];
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static string GetTitle(Mobile m)
|
||||
{
|
||||
SkillName sk = m.Skills.CurrentMastery;
|
||||
|
||||
for(int i = 0; i < _Skills.Length; i++)
|
||||
{
|
||||
if (_Skills[i] == sk)
|
||||
return _Titles[i];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
78
Scripts/Spells/Skill Masteries/Core/SelectMasteryGump.cs
Normal file
78
Scripts/Spells/Skill Masteries/Core/SelectMasteryGump.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
using Server;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Spells.SkillMasteries;
|
||||
using System.Linq;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Gumps
|
||||
{
|
||||
public class MasterySelectionGump : BaseGump
|
||||
{
|
||||
//public const int Red = 0x4800;
|
||||
//public const int Blue = 0x000F;
|
||||
public const int Red = 0x8e2525;
|
||||
public const int Blue = 0x000066;
|
||||
|
||||
public BookOfMasteries Book { get; private set; }
|
||||
|
||||
public MasterySelectionGump(PlayerMobile user, BookOfMasteries book)
|
||||
: base(user, 75, 25)
|
||||
{
|
||||
Book = book;
|
||||
}
|
||||
|
||||
public override void AddGumpLayout()
|
||||
{
|
||||
AddBackground(0, 0, 404, 550, 9380);
|
||||
|
||||
AddHtmlLocalized(0, 40, 404, 16, CenterLoc, "#1151948", 0, false, false); // Switch Mastery
|
||||
|
||||
int y = 58;
|
||||
SkillName current = User.Skills.CurrentMastery;
|
||||
|
||||
foreach (SkillName skName in MasteryInfo.Skills)
|
||||
{
|
||||
Skill sk = User.Skills[skName];
|
||||
|
||||
if (sk != null && sk.IsMastery && sk.VolumeLearned > 0)
|
||||
{
|
||||
AddButton(30, y, 4005, 4007, (int)skName + 1, GumpButtonType.Reply, 0);
|
||||
|
||||
AddHtmlLocalized(72, y, 200, 16, MasteryInfo.GetLocalization(skName), skName == current ? C32216(Red) : C32216(Blue), false, false);
|
||||
AddHtmlLocalized(265, y, 100, 16, 1156052, MasteryInfo.GetMasteryLevel(User, skName).ToString(), 0, false, false);
|
||||
|
||||
y += 24;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResponse(RelayInfo info)
|
||||
{
|
||||
if (info.ButtonID == 0)
|
||||
return;
|
||||
|
||||
SkillName n = (SkillName)info.ButtonID - 1;
|
||||
SkillName current = User.Skills.CurrentMastery;
|
||||
|
||||
if (n == current)
|
||||
{
|
||||
User.Skills.CurrentMastery = SkillName.Alchemy;
|
||||
MasteryInfo.OnMasteryChanged(User, current);
|
||||
}
|
||||
else if (User.Skills[n].Base >= MasteryInfo.MinSkillRequirement)
|
||||
{
|
||||
User.SendLocalizedMessage(1155886, User.Skills[n].Info.Name); // Your active skill mastery is now set to ~1_MasterySkill~!
|
||||
User.Skills.CurrentMastery = n;
|
||||
|
||||
MasteryInfo.OnMasteryChanged(User, current);
|
||||
|
||||
BookOfMasteries.AddToCooldown(User);
|
||||
}
|
||||
else
|
||||
User.SendLocalizedMessage(1156236, String.Format("{0}\t{1}", MasteryInfo.MinSkillRequirement.ToString(), User.Skills[n].Info.Name)); // You need at least ~1_SKILL_REQUIREMENT~ ~2_SKILL_NAME~ skill to use that mastery.
|
||||
}
|
||||
}
|
||||
}
|
||||
110
Scripts/Spells/Skill Masteries/Core/SkillMasteryMove.cs
Normal file
110
Scripts/Spells/Skill Masteries/Core/SkillMasteryMove.cs
Normal file
@@ -0,0 +1,110 @@
|
||||
using System;
|
||||
using Server;
|
||||
using System.Globalization;
|
||||
using Server.Spells;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
using System.Collections.Generic;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Spells.SkillMasteries
|
||||
{
|
||||
public class SkillMasteryMove : SpecialMove
|
||||
{
|
||||
public Dictionary<Mobile, DateTime> Cooldown { get; set; }
|
||||
|
||||
public virtual TimeSpan CooldownPeriod { get { return TimeSpan.MinValue; } }
|
||||
public override bool ValidatesDuringHit { get { return false; } }
|
||||
|
||||
public SkillMasteryMove()
|
||||
{
|
||||
}
|
||||
|
||||
public override void SendAbilityMessage(Mobile m)
|
||||
{
|
||||
if(AbilityMessage.Number > 0)
|
||||
m.PrivateOverheadMessage(MessageType.Regular, 1150, AbilityMessage.Number, m.NetState);
|
||||
else
|
||||
m.PrivateOverheadMessage(MessageType.Regular, 1150, false, AbilityMessage.String, m.NetState);
|
||||
}
|
||||
|
||||
public override bool Validate(Mobile from)
|
||||
{
|
||||
SkillMasteryMove move = SpecialMove.GetCurrentMove(from) as SkillMasteryMove;
|
||||
|
||||
if ((move == null || move.GetType() != this.GetType()) && !CheckCooldown(from))
|
||||
return false;
|
||||
|
||||
if (from.Player && from.Skills.CurrentMastery != MoveSkill)
|
||||
{
|
||||
from.SendLocalizedMessage(1115664); // You are not on the correct path for using this mastery ability.
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.Validate(from);
|
||||
}
|
||||
|
||||
public bool CheckCooldown(Mobile from)
|
||||
{
|
||||
if (CooldownPeriod > TimeSpan.MinValue && IsInCooldown(from))
|
||||
{
|
||||
double left = (Cooldown[from] - DateTime.UtcNow).TotalMinutes;
|
||||
|
||||
if (left > 1)
|
||||
{
|
||||
from.SendLocalizedMessage(1155787, ((int)left).ToString()); // You must wait ~1_minutes~ minutes before you can use this ability.
|
||||
}
|
||||
else
|
||||
{
|
||||
left = (Cooldown[from] - DateTime.UtcNow).TotalSeconds;
|
||||
from.SendLocalizedMessage(1079335, left.ToString("F", CultureInfo.InvariantCulture)); // You must wait ~1_seconds~ seconds before you can use this ability again.
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool CheckWeapon(Mobile from)
|
||||
{
|
||||
if (!from.Player)
|
||||
return true;
|
||||
|
||||
BaseWeapon wep = from.Weapon as BaseWeapon;
|
||||
|
||||
return wep != null && wep.DefSkill == MoveSkill;
|
||||
}
|
||||
|
||||
public virtual bool IsInCooldown(Mobile m)
|
||||
{
|
||||
return Cooldown != null && Cooldown.ContainsKey(m);
|
||||
}
|
||||
|
||||
public virtual void AddToCooldown(Mobile m)
|
||||
{
|
||||
if (CooldownPeriod > TimeSpan.MinValue)
|
||||
{
|
||||
if (Cooldown == null)
|
||||
Cooldown = new Dictionary<Mobile, DateTime>();
|
||||
|
||||
Cooldown[m] = DateTime.UtcNow + CooldownPeriod;
|
||||
Timer.DelayCall(CooldownPeriod, () => RemoveCooldown(m));
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void RemoveCooldown(Mobile m)
|
||||
{
|
||||
if (Cooldown.ContainsKey(m))
|
||||
Cooldown.Remove(m);
|
||||
}
|
||||
|
||||
public virtual void OnGotHit(Mobile attacker, Mobile defender, ref int damage)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void OnDamaged(Mobile attacker, Mobile defender, DamageType type, ref int damage)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
159
Scripts/Spells/Skill Masteries/Core/SkillMasteryPrimer.cs
Normal file
159
Scripts/Spells/Skill Masteries/Core/SkillMasteryPrimer.cs
Normal file
@@ -0,0 +1,159 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Spells.SkillMasteries;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Server.ContextMenus;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class SkillMasteryPrimer : Item
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public SkillName Skill { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Volume { get; set; }
|
||||
|
||||
public override bool ForceShowProperties { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public SkillMasteryPrimer(SkillName skill, int volume) : base(7714)
|
||||
{
|
||||
Skill = skill;
|
||||
LootType = LootType.Cursed;
|
||||
|
||||
Volume = volume;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (IsChildOf(from.Backpack))
|
||||
{
|
||||
if (MasteryInfo.HasLearned(from, Skill, Volume))
|
||||
{
|
||||
from.SendLocalizedMessage(1155884, String.Format("#{0}", MasteryInfo.GetLocalization(Skill))); // You are already proficient in this level of ~1_MasterySkill~
|
||||
}
|
||||
else if (MasteryInfo.LearnMastery(from, Skill, Volume))
|
||||
{
|
||||
from.SendLocalizedMessage(1155885, String.Format("#{0}", MasteryInfo.GetLocalization(Skill))); // You have increased your proficiency in ~1_SkillMastery~!
|
||||
|
||||
Effects.SendLocationParticles(EffectItem.Create(from.Location, from.Map, EffectItem.DefaultDuration), 0, 0, 0, 0, 0, 5060, 0);
|
||||
Effects.PlaySound(from.Location, from.Map, 0x243);
|
||||
|
||||
Effects.SendMovingParticles(new Entity(Serial.Zero, new Point3D(from.X - 6, from.Y - 6, from.Z + 15), from.Map), from, 0x36D4, 7, 0, false, true, 0xAA8, 0, 9502, 1, 0, (EffectLayer)255, 0x100);
|
||||
Effects.SendMovingParticles(new Entity(Serial.Zero, new Point3D(from.X - 4, from.Y - 6, from.Z + 15), from.Map), from, 0x36D4, 7, 0, false, true, 0xAA8, 0, 9502, 1, 0, (EffectLayer)255, 0x100);
|
||||
Effects.SendMovingParticles(new Entity(Serial.Zero, new Point3D(from.X - 6, from.Y - 4, from.Z + 15), from.Map), from, 0x36D4, 7, 0, false, true, 0xAA8, 0, 9502, 1, 0, (EffectLayer)255, 0x100);
|
||||
|
||||
Effects.SendTargetParticles(from, 0x375A, 35, 90, 0x00, 0x00, 9502, (EffectLayer)255, 0x100);
|
||||
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void AddNameProperty(ObjectPropertyList list)
|
||||
{
|
||||
list.Add(1155882, String.Format("#{0}", MasteryInfo.GetLocalization(Skill))); // Primer on ~1_Skill~
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
list.Add(1155883, String.Format("{0}", GetVolume(Volume))); // Volume ~1_Level~
|
||||
}
|
||||
|
||||
private string GetVolume(int volume)
|
||||
{
|
||||
if (volume == 1)
|
||||
return "I";
|
||||
|
||||
if (volume == 2)
|
||||
return "II";
|
||||
|
||||
return "III";
|
||||
}
|
||||
|
||||
public static void CheckPrimerDrop(BaseCreature killed)
|
||||
{
|
||||
List<DamageStore> rights = killed.GetLootingRights();
|
||||
|
||||
rights.ForEach(ds =>
|
||||
{
|
||||
if (ds.m_HasRight)
|
||||
{
|
||||
Mobile m = ds.m_Mobile;
|
||||
|
||||
if (Utility.RandomDouble() < 0.10)
|
||||
{
|
||||
SkillMasteryPrimer primer = GetRandom();
|
||||
|
||||
if (primer != null)
|
||||
{
|
||||
if (m.Backpack == null || !m.Backpack.TryDropItem(m, primer, false))
|
||||
m.BankBox.DropItem(primer);
|
||||
}
|
||||
|
||||
m.SendLocalizedMessage(1156209); // You have received a mastery primer!
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static SkillMasteryPrimer GetRandom()
|
||||
{
|
||||
SkillName skill = MasteryInfo.Skills[Utility.RandomMinMax(3, 18)];
|
||||
int volume = 1;
|
||||
|
||||
double random = Utility.RandomDouble();
|
||||
|
||||
if (0.2 >= random)
|
||||
volume = 3;
|
||||
else if (0.5 >= random)
|
||||
volume = 2;
|
||||
|
||||
SkillMasteryPrimer primer = new SkillMasteryPrimer(skill, volume);
|
||||
|
||||
return primer;
|
||||
}
|
||||
|
||||
public SkillMasteryPrimer(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 1 ); // version
|
||||
|
||||
writer.Write(Volume);
|
||||
writer.Write((int)Skill);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
Volume = reader.ReadInt();
|
||||
Skill = (SkillName)reader.ReadInt();
|
||||
break;
|
||||
case 0:
|
||||
|
||||
Skill = (SkillName)reader.ReadInt();
|
||||
int id = reader.ReadInt();
|
||||
|
||||
Volume = MasteryInfo.GetVolume(id, Skill);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1299
Scripts/Spells/Skill Masteries/Core/SkillMasterySpell.cs
Normal file
1299
Scripts/Spells/Skill Masteries/Core/SkillMasterySpell.cs
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user