Files
abysmal-isle/Scripts/Spells/Skill Masteries/BodyGuard.cs
Unstable Kitsune b918192e4e Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
2023-11-28 23:20:26 -05:00

323 lines
10 KiB
C#

using System;
using Server;
using Server.Spells;
using Server.Network;
using Server.Mobiles;
using Server.Gumps;
using System.Collections.Generic;
using Server.Items;
namespace Server.Spells.SkillMasteries
{
public class BodyGuardSpell : SkillMasterySpell
{
private static SpellInfo m_Info = new SpellInfo(
"Body Guard", "",
-1,
9002
);
public override int RequiredMana { get { return 40; } }
public override int DisruptMessage { get { return 1156103; } } // Bodyguard has expired.
public override bool BlocksMovement { get { return false; } }
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds(1.0); } }
public override SkillName CastSkill { get { return SkillName.Parry; } }
private double _Block;
public BodyGuardSpell(Mobile caster, Item scroll)
: base(caster, scroll, m_Info)
{
}
public override bool CheckCast()
{
if (_Table != null && _Table.ContainsKey(Caster))
{
RemoveGumpTimer(_Table[Caster], Caster);
return false;
}
BodyGuardSpell spell = GetSpell(Caster, this.GetType()) as BodyGuardSpell;
if(spell != null)
{
spell.Expire(true);
return false;
}
if (!HasShield())
return false;
return base.CheckCast();
}
public override void OnCast()
{
if (Caster is BaseCreature && ((BaseCreature)Caster).ControlMaster != null)
{
var master = ((BaseCreature)Caster).ControlMaster;
if (Caster.CanSee(master) && Caster.InRange(master.Location, 8))
{
SpellHelper.Turn(Caster, master);
OnTarget(master);
}
}
else
{
Caster.BeginTarget(8, false, Server.Targeting.TargetFlags.None, (m, o) =>
{
if (!Caster.CanSee(o))
{
Caster.SendLocalizedMessage(500237); // Target can not be seen.
}
else
{
SpellHelper.Turn(Caster, o);
OnTarget(o);
}
});
}
}
protected override void OnTarget(object o)
{
if (!HasShield())
return;
Mobile protectee = o as Mobile;
Mobile master = null;
if (protectee is BaseCreature && !((BaseCreature)protectee).Summoned && ((BaseCreature)protectee).GetMaster() is PlayerMobile)
master = ((BaseCreature)protectee).GetMaster();
if (protectee != null)
{
BodyGuardSpell spell = GetSpell(s => s.GetType() == typeof(BodyGuardSpell) && s.Target == protectee) as BodyGuardSpell;
if(spell != null)
{
Caster.SendLocalizedMessage(1156094); // Your target is already under the effect of this ability.
}
if (!protectee.Alive)
{
Caster.SendLocalizedMessage( 501857 ); // This spell won't work on that!
}
else if ( !Caster.CanBeBeneficial( protectee, true ))
{
Caster.SendLocalizedMessage(1001017); // You cannot perform beneficial acts on your target.
}
else if (protectee != Caster)
{
Mobile responsible = master != null ? master : protectee;
Caster.FixedParticles( 0x376A, 9, 32, 5030, 1168, 0, EffectLayer.Waist, 0 );
if (Caster.Player)
{
Caster.PlaySound(Caster.Female ? 0x338 : 0x44A);
}
else if (Caster is BaseCreature)
{
Caster.PlaySound(((BaseCreature)Caster).GetAngerSound());
}
if (Caster is PlayerMobile)
{
protectee.SendGump(new AcceptBodyguardGump(Caster, protectee, this));
AddGumpTimer(responsible, Caster);
}
else
{
AcceptBodyGuard(responsible);
}
}
}
}
public void AcceptBodyGuard(Mobile toGuard)
{
RemoveGumpTimer(toGuard, Caster);
if(CheckBSequence(toGuard))
{
_Block = ((Caster.Skills[CastSkill].Value + GetWeaponSkill() + (GetMasteryLevel() * 40)) / 3) / 2.4;
Target = toGuard;
Expires = DateTime.UtcNow + TimeSpan.FromSeconds(90);
BeginTimer();
Caster.SendLocalizedMessage(1049452, "\t" + toGuard.Name); // You are now protecting ~2_NAME~.
toGuard.SendLocalizedMessage(1049451, Caster.Name); // You are now being protected by ~1_NAME~.
BuffInfo.AddBuff(Caster, new BuffInfo(BuffIcon.Bodyguard, 1155924, 1156061, TimeSpan.FromSeconds(90), Caster, String.Format("{0}\t{1}\t{2}\t{3}", Caster.Name, ((int)(_Block + 5)).ToString(), toGuard.Name, ((int)_Block).ToString())));
BuffInfo.AddBuff(toGuard, new BuffInfo(BuffIcon.Bodyguard, 1155924, 1156061, TimeSpan.FromSeconds(90), toGuard, String.Format("{0}\t{1}\t{2}\t{3}", Caster.Name, ((int)(_Block + 5)).ToString(), toGuard.Name, ((int)_Block).ToString())));
//~1_NAME~ receives ~2_DAMAGE~% of all damage dealt to ~3_NAME~. All damage dealt to ~3_NAME~ will be reduced by ~4_DAMAGE~%. Body guard must be within 2 tiles.
}
FinishSequence();
}
private bool HasShield()
{
if (!Caster.Player)
return true;
BaseShield shield = Caster.FindItemOnLayer(Layer.TwoHanded) as BaseShield;
if (shield == null)
{
Caster.SendLocalizedMessage(1156096); // You must be wielding a shield to use this ability!
return false;
}
return true;
}
public override bool OnTick()
{
if (!HasShield())
{
Expire();
return false;
}
return base.OnTick();
}
public override void EndEffects()
{
if (Target != null)
{
Target.SendLocalizedMessage(1156103); // Bodyguard has expired.
BuffInfo.RemoveBuff(Target, BuffIcon.Bodyguard);
}
Caster.SendLocalizedMessage(1156103); // Bodyguard has expired.
BuffInfo.RemoveBuff(Caster, BuffIcon.Bodyguard);
}
public void DeclineBodyGuard(Mobile protectee)
{
Caster.SendLocalizedMessage(1049454, "\t" + protectee.Name); // ~2_NAME~ has declined your protection.
protectee.SendLocalizedMessage(1049453, Caster.Name); // You have declined protection from ~1_NAME~.
RemoveGumpTimer(protectee, Caster);
FinishSequence();
}
public override void OnTargetDamaged(Mobile attacker, Mobile defender, DamageType type, ref int damage)
{
if (defender == Target && Caster.InRange(defender, 2))
{
double mod = (double)PropertyBonus() / 100.0;
damage = damage - (int)((double)damage * mod);
int casterDamage = damage - (int)((double)damage * (mod - .05));
if (type >= DamageType.Spell)
casterDamage /= 2;
Caster.Damage(casterDamage, attacker);
}
}
public static void RemoveGumpTimer(Mobile m, Mobile caster)
{
if (_Table != null && _Table.ContainsKey(caster))
_Table.Remove(caster);
if (m.HasGump(typeof(AcceptBodyguardGump)))
{
m.CloseGump(typeof(AcceptBodyguardGump));
m.SendLocalizedMessage(1156103); // Bodyguard has expired.
caster.SendLocalizedMessage(1156103); // Bodyguard has expired.
}
}
public static void AddGumpTimer(Mobile m, Mobile caster)
{
if (_Table == null)
_Table = new Dictionary<Mobile, Mobile>();
_Table[caster] = m;
Server.Timer.DelayCall(TimeSpan.FromSeconds(10), () =>
{
RemoveGumpTimer(m, caster);
});
}
private static Dictionary<Mobile, Mobile> _Table;
public override int PropertyBonus()
{
return (int)_Block;
}
}
public class AcceptBodyguardGump : Gump
{
private Mobile m_Protector;
private Mobile m_Protectee;
private BodyGuardSpell m_Spell;
public AcceptBodyguardGump( Mobile protector, Mobile protectee, BodyGuardSpell spell ) : base( 150, 50 )
{
m_Protector = protector;
m_Protectee = protectee;
m_Spell = spell;
Closable = false;
AddPage( 0 );
AddBackground( 0, 0, 396, 218, 3600 );
AddImageTiled( 15, 15, 365, 190, 2624 );
AddAlphaRegion( 15, 15, 365, 190 );
AddHtmlLocalized( 30, 20, 360, 25, 1156099, 0x7FFF, false, false ); // Another player is offering to bodyguard you:
AddLabel( 90, 55, 1153, String.Format("{0} will body guard {1}", protector.Name, protectee.Name));
AddImage( 50, 45, 9005 );
AddImageTiled( 80, 80, 200, 1, 9107 );
AddImageTiled( 95, 82, 200, 1, 9157 );
AddRadio( 30, 110, 9727, 9730, true, 1 );
AddHtmlLocalized( 65, 115, 300, 25, 1049444, 0x7FFF, false, false ); // Yes, I would like their protection.
AddRadio( 30, 145, 9727, 9730, false, 0 );
AddHtmlLocalized( 65, 148, 300, 25, 1049445, 0x7FFF, false, false ); // No thanks, I can take care of myself.
AddButton( 160, 175, 247, 248, 2, GumpButtonType.Reply, 0 );
AddImage( 215, 0, 50581 );
AddImageTiled( 15, 14, 365, 1, 9107 );
AddImageTiled( 380, 14, 1, 190, 9105 );
AddImageTiled( 15, 205, 365, 1, 9107 );
AddImageTiled( 15, 14, 1, 190, 9105 );
AddImageTiled( 0, 0, 395, 1, 9157 );
AddImageTiled( 394, 0, 1, 217, 9155 );
AddImageTiled( 0, 216, 395, 1, 9157 );
AddImageTiled( 0, 0, 1, 217, 9155 );
}
public override void OnResponse( Server.Network.NetState sender, RelayInfo info )
{
if ( info.ButtonID == 2 )
{
bool okay = info.IsSwitched( 1 );
if(okay)
m_Spell.AcceptBodyGuard(m_Protectee);
else
m_Spell.DeclineBodyGuard(m_Protectee);
}
}
}
}