Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
472
Scripts/Spells/Skill Masteries/CombatTraining.cs
Normal file
472
Scripts/Spells/Skill Masteries/CombatTraining.cs
Normal file
@@ -0,0 +1,472 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Spells;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
using Server.Gumps;
|
||||
using Server.Targeting;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Spells.SkillMasteries
|
||||
{
|
||||
public enum TrainingType
|
||||
{
|
||||
Empowerment,
|
||||
Berserk,
|
||||
ConsumeDamage,
|
||||
AsOne
|
||||
}
|
||||
|
||||
public class CombatTrainingSpell : SkillMasterySpell
|
||||
{
|
||||
private static SpellInfo m_Info = new SpellInfo(
|
||||
"Combat Training", "",
|
||||
-1,
|
||||
9002
|
||||
);
|
||||
|
||||
public override double UpKeep
|
||||
{
|
||||
get
|
||||
{
|
||||
double taming = Caster.Skills[CastSkill].Base;
|
||||
double lore = Caster.Skills[SkillName.AnimalLore].Base;
|
||||
bool asone = SpellType == TrainingType.AsOne;
|
||||
|
||||
double skillvalue = (taming + (lore/2));
|
||||
int mastery_base = 12;
|
||||
if (skillvalue < 150) mastery_base = 12;
|
||||
if (skillvalue < 165) mastery_base = 10;
|
||||
if (skillvalue < 180) mastery_base = 8;
|
||||
if (skillvalue >= 180) mastery_base = 6;
|
||||
|
||||
return asone ? mastery_base*2 : mastery_base;
|
||||
}
|
||||
}
|
||||
|
||||
public override double RequiredSkill { get { return 90; } }
|
||||
public override int RequiredMana { get { return 40; } }
|
||||
public override bool PartyEffects { get { return false; } }
|
||||
public override SkillName CastSkill { get { return SkillName.AnimalTaming; } }
|
||||
|
||||
public TrainingType SpellType { get; set; }
|
||||
|
||||
private int _Phase;
|
||||
private int _DamageTaken;
|
||||
private bool _Expired;
|
||||
|
||||
public int Phase { get { return _Phase; } set { _Phase = value; } }
|
||||
public int DamageTaken { get { return _DamageTaken; } set { _DamageTaken = value; } }
|
||||
|
||||
public CombatTrainingSpell(Mobile caster, Item scroll)
|
||||
: base(caster, scroll, m_Info)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool Cast()
|
||||
{
|
||||
CombatTrainingSpell spell = GetSpell(Caster, typeof(CombatTrainingSpell)) as CombatTrainingSpell;
|
||||
|
||||
if (spell != null)
|
||||
{
|
||||
spell.Expire();
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.Cast();
|
||||
}
|
||||
|
||||
public override bool CheckCast()
|
||||
{
|
||||
if (Caster is PlayerMobile && ((PlayerMobile)Caster).AllFollowers == null || ((PlayerMobile)Caster).AllFollowers.Count == 0)
|
||||
{
|
||||
Caster.SendLocalizedMessage(1156112); // This ability requires you to have pets.
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.CheckCast();
|
||||
}
|
||||
|
||||
public override void SendCastEffect()
|
||||
{
|
||||
base.SendCastEffect();
|
||||
|
||||
Caster.PrivateOverheadMessage(MessageType.Regular, 0x35, false, "You ready your pet for combat, increasing its battle effectiveness!", Caster.NetState);
|
||||
}
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
Caster.Target = new InternalTarget(this);
|
||||
}
|
||||
|
||||
public void OnSelected(TrainingType type, Mobile target)
|
||||
{
|
||||
if (!CheckSequence() || (type == TrainingType.AsOne && Caster is PlayerMobile && ((PlayerMobile)Caster).AllFollowers.Where(mob => mob != target).Count() == 0))
|
||||
{
|
||||
FinishSequence();
|
||||
return;
|
||||
}
|
||||
|
||||
SpellType = type;
|
||||
Target = target;
|
||||
|
||||
_Phase = 0;
|
||||
|
||||
BeginTimer();
|
||||
|
||||
Target.FixedParticles(0x373A, 10, 80, 5018, 0, 0, EffectLayer.Waist);
|
||||
|
||||
BuffInfo.AddBuff(Caster, new BuffInfo(BuffIcon.CombatTraining, 1155933, 1156107, String.Format("{0}\t{1}\t{2}", SpellType.ToString(), Target.Name, ((int)ScaleUpkeep()).ToString())));
|
||||
//You train ~2_NAME~ to use ~1_SKILLNAME~.<br>Mana Upkeep: ~3_COST~
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
|
||||
public override void EndEffects()
|
||||
{
|
||||
BuffInfo.RemoveBuff(Caster, BuffIcon.CombatTraining);
|
||||
Caster.SendSound(0x1ED);
|
||||
|
||||
_Expired = true;
|
||||
}
|
||||
|
||||
protected override void DoEffects()
|
||||
{
|
||||
Caster.FixedParticles(0x376A, 10, 30, 5052, 1261, 0, EffectLayer.LeftFoot, 0);
|
||||
Caster.DisruptiveAction();
|
||||
}
|
||||
|
||||
public override bool OnTick()
|
||||
{
|
||||
if (Target == null || Target.IsDeadBondedPet /* || Target.Map != Caster.Map*/)
|
||||
{
|
||||
Expire();
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.OnTick();
|
||||
}
|
||||
|
||||
public double DamageMod
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Target == null || SpellType == TrainingType.AsOne)
|
||||
return 0.0;
|
||||
|
||||
double dam = (double)_DamageTaken / ((double)Target.HitsMax * .66);
|
||||
|
||||
if (dam > 1.0) dam = 1.0;
|
||||
|
||||
return dam;
|
||||
}
|
||||
}
|
||||
|
||||
private void EndPhase1()
|
||||
{
|
||||
if (_Expired)
|
||||
return;
|
||||
|
||||
_Phase = 2;
|
||||
|
||||
Server.Timer.DelayCall(TimeSpan.FromSeconds(SpellType == TrainingType.Berserk ? 8 : 10), EndPhase2);
|
||||
}
|
||||
|
||||
private void EndPhase2()
|
||||
{
|
||||
if (_Expired)
|
||||
return;
|
||||
|
||||
_DamageTaken = 0;
|
||||
_Phase = 0;
|
||||
|
||||
if (SpellType == TrainingType.Berserk)
|
||||
{
|
||||
AddRageCooldown(Target);
|
||||
}
|
||||
}
|
||||
|
||||
public static void CheckDamage(Mobile attacker, Mobile defender, DamageType type, ref int damage)
|
||||
{
|
||||
if (defender is BaseCreature && (((BaseCreature)defender).Controlled || ((BaseCreature)defender).Summoned))
|
||||
{
|
||||
CombatTrainingSpell spell = GetSpell<CombatTrainingSpell>(sp => sp.Target == defender);
|
||||
|
||||
if (spell != null)
|
||||
{
|
||||
int storedDamage = damage;
|
||||
|
||||
switch (spell.SpellType)
|
||||
{
|
||||
case TrainingType.Empowerment:
|
||||
break;
|
||||
case TrainingType.Berserk:
|
||||
if (InRageCooldown(defender))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (spell.Phase > 1)
|
||||
{
|
||||
damage = damage - (int)((double)damage * spell.DamageMod);
|
||||
defender.FixedParticles(0x376A, 10, 30, 5052, 1261, 7, EffectLayer.LeftFoot, 0);
|
||||
}
|
||||
break;
|
||||
case TrainingType.ConsumeDamage:
|
||||
if (spell.Phase < 2)
|
||||
{
|
||||
defender.SendDamagePacket(attacker, damage);
|
||||
damage = 0;
|
||||
}
|
||||
break;
|
||||
case TrainingType.AsOne:
|
||||
if (((BaseCreature)defender).GetMaster() is PlayerMobile)
|
||||
{
|
||||
var pm = ((BaseCreature)defender).GetMaster() as PlayerMobile;
|
||||
var list = pm.AllFollowers.Where(m => (m == defender || m.InRange(defender.Location, 3)) && m.CanBeHarmful(attacker)).ToList();
|
||||
|
||||
if (list.Count > 0)
|
||||
{
|
||||
damage = damage / list.Count;
|
||||
|
||||
foreach (var m in list.Where(mob => mob != defender))
|
||||
{
|
||||
m.Damage(damage, attacker, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
ColUtility.Free(list);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (spell.Phase < 2)
|
||||
{
|
||||
if (spell.Phase != 1)
|
||||
{
|
||||
spell.Phase = 1;
|
||||
|
||||
if (spell.SpellType != TrainingType.AsOne && (spell.SpellType != TrainingType.Berserk || !InRageCooldown(defender)))
|
||||
{
|
||||
Server.Timer.DelayCall(TimeSpan.FromSeconds(5), spell.EndPhase1);
|
||||
}
|
||||
}
|
||||
|
||||
if (spell.DamageTaken == 0)
|
||||
defender.FixedEffect(0x3779, 10, 30, 1743, 0);
|
||||
|
||||
spell.DamageTaken += storedDamage;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (attacker is BaseCreature && (((BaseCreature)attacker).Controlled || ((BaseCreature)attacker).Summoned))
|
||||
{
|
||||
CombatTrainingSpell spell = GetSpell<CombatTrainingSpell>(sp => sp.Target == attacker);
|
||||
|
||||
if (spell != null)
|
||||
{
|
||||
switch (spell.SpellType)
|
||||
{
|
||||
case TrainingType.Empowerment:
|
||||
if (spell.Phase > 1)
|
||||
{
|
||||
damage = damage + (int)((double)damage * spell.DamageMod);
|
||||
attacker.FixedParticles(0x376A, 10, 30, 5052, 1261, 7, EffectLayer.LeftFoot, 0);
|
||||
}
|
||||
break;
|
||||
case TrainingType.Berserk:
|
||||
case TrainingType.ConsumeDamage:
|
||||
case TrainingType.AsOne:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void OnCreatureHit(Mobile attacker, Mobile defender, ref int damage)
|
||||
{
|
||||
if (attacker is BaseCreature && (((BaseCreature)attacker).Controlled || ((BaseCreature)attacker).Summoned))
|
||||
{
|
||||
CombatTrainingSpell spell = GetSpell<CombatTrainingSpell>(sp => sp.Target == attacker);
|
||||
|
||||
if (spell != null)
|
||||
{
|
||||
switch (spell.SpellType)
|
||||
{
|
||||
case TrainingType.Empowerment:
|
||||
break;
|
||||
case TrainingType.Berserk:
|
||||
if (spell.Phase > 1)
|
||||
{
|
||||
damage = damage + (int)((double)damage * spell.DamageMod);
|
||||
attacker.FixedParticles(0x376A, 10, 30, 5052, 1261, 7, EffectLayer.LeftFoot, 0);
|
||||
}
|
||||
break;
|
||||
case TrainingType.ConsumeDamage:
|
||||
case TrainingType.AsOne:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int RegenBonus(Mobile m)
|
||||
{
|
||||
if (m is BaseCreature && (((BaseCreature)m).Controlled || ((BaseCreature)m).Summoned))
|
||||
{
|
||||
CombatTrainingSpell spell = GetSpell<CombatTrainingSpell>(sp => sp.Target == m);
|
||||
|
||||
if (spell != null && spell.SpellType == TrainingType.ConsumeDamage && spell.Phase > 1)
|
||||
{
|
||||
return (int)(30.0 * spell.DamageMod);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int GetHitChanceBonus(Mobile m)
|
||||
{
|
||||
if (m is BaseCreature && (((BaseCreature)m).Controlled || ((BaseCreature)m).Summoned))
|
||||
{
|
||||
CombatTrainingSpell spell = GetSpell<CombatTrainingSpell>(sp => sp.Target == m);
|
||||
|
||||
if (spell != null && spell.SpellType == TrainingType.ConsumeDamage && spell.Phase > 1)
|
||||
{
|
||||
return (int)(45 * spell.DamageMod);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public class InternalTarget : Target
|
||||
{
|
||||
public CombatTrainingSpell Spell { get; set; }
|
||||
|
||||
public InternalTarget(CombatTrainingSpell spell)
|
||||
: base(8, false, TargetFlags.None)
|
||||
{
|
||||
Spell = spell;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (targeted is Server.Engines.Despise.DespiseCreature)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (targeted is BaseCreature && ((BaseCreature)targeted).GetMaster() == from && from.Spell == Spell)
|
||||
{
|
||||
Spell.Caster.FixedEffect(0x3779, 10, 20, 1270, 0);
|
||||
Spell.Caster.SendSound(0x64E);
|
||||
|
||||
int taming = (int)from.Skills[SkillName.AnimalTaming].Value;
|
||||
int lore = (int)from.Skills[SkillName.AnimalLore].Value;
|
||||
|
||||
from.CheckTargetSkill(SkillName.AnimalTaming, (BaseCreature)targeted, taming - 25, taming + 25);
|
||||
from.CheckTargetSkill(SkillName.AnimalLore, (BaseCreature)targeted, lore - 25, lore + 25);
|
||||
|
||||
from.CloseGump(typeof(ChooseTrainingGump));
|
||||
from.SendGump(new ChooseTrainingGump(from, (BaseCreature)targeted, Spell));
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnTargetCancel(Mobile from, TargetCancelType cancelType)
|
||||
{
|
||||
from.SendLocalizedMessage(1156110); // Your ability was canceled.
|
||||
Spell.FinishSequence();
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddRageCooldown(Mobile m)
|
||||
{
|
||||
if (_RageCooldown == null)
|
||||
_RageCooldown = new Dictionary<Mobile, Timer>();
|
||||
|
||||
_RageCooldown[m] = Server.Timer.DelayCall<Mobile>(TimeSpan.FromSeconds(60), EndRageCooldown, m);
|
||||
}
|
||||
|
||||
public static bool InRageCooldown(Mobile m)
|
||||
{
|
||||
return _RageCooldown != null && _RageCooldown.ContainsKey(m);
|
||||
}
|
||||
|
||||
public static void EndRageCooldown(Mobile m)
|
||||
{
|
||||
if (_RageCooldown != null && _RageCooldown.ContainsKey(m))
|
||||
{
|
||||
_RageCooldown.Remove(m);
|
||||
}
|
||||
}
|
||||
|
||||
public static Dictionary<Mobile, Timer> _RageCooldown;
|
||||
}
|
||||
|
||||
public class ChooseTrainingGump : Gump
|
||||
{
|
||||
public CombatTrainingSpell Spell { get; private set; }
|
||||
public Mobile Caster { get; private set; }
|
||||
public BaseCreature Target { get; private set; }
|
||||
|
||||
public const int Hue = 0x07FF;
|
||||
|
||||
public ChooseTrainingGump(Mobile caster, BaseCreature target, CombatTrainingSpell spell) : base(100, 100)
|
||||
{
|
||||
Spell = spell;
|
||||
Caster = caster;
|
||||
Target = target;
|
||||
|
||||
AddBackground(0, 0, 260, 187, 3600);
|
||||
AddAlphaRegion(10, 10, 240, 167);
|
||||
|
||||
AddImageTiled(220, 15, 30, 162, 10464);
|
||||
|
||||
AddHtmlLocalized(20, 20, 150, 16, 1156113, Hue, false, false); // Select Training
|
||||
|
||||
int y = 40;
|
||||
if (MasteryInfo.HasLearned(caster, SkillName.AnimalTaming, 1))
|
||||
{
|
||||
AddButton(20, y, 9762, 9763, 1, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(43, y, 150, 16, 1156109, Hue, false, false); // Empowerment
|
||||
y += 20;
|
||||
}
|
||||
|
||||
if (MasteryInfo.HasLearned(caster, SkillName.AnimalTaming, 2))
|
||||
{
|
||||
AddButton(20, y, 9762, 9763, 2, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(43, y, 150, 16, 1153271, Hue, false, false); // Berserk
|
||||
y += 20;
|
||||
}
|
||||
|
||||
if (MasteryInfo.HasLearned(caster, SkillName.AnimalTaming, 3))
|
||||
{
|
||||
AddButton(20, y, 9762, 9763, 3, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(43, y, 150, 16, 1156108, Hue, false, false); // Consume Damage
|
||||
y += 20;
|
||||
}
|
||||
|
||||
if (MasteryInfo.HasLearned(caster, SkillName.AnimalTaming, 1))
|
||||
{
|
||||
AddButton(20, y, 9762, 9763, 4, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(43, y, 150, 16, 1157544, Hue, false, false); // As One
|
||||
y += 20;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState state, RelayInfo info)
|
||||
{
|
||||
if (info.ButtonID == 0)
|
||||
{
|
||||
Spell.FinishSequence();
|
||||
state.Mobile.SendLocalizedMessage(1156110); // Your ability was canceled.
|
||||
return;
|
||||
}
|
||||
|
||||
Spell.OnSelected((TrainingType)info.ButtonID - 1, Target);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user