#W# Source and Scripts added. Added Scripts/Settings.cs to expose some basic tweak able settings.
This commit is contained in:
parent
b51c58f514
commit
3045c83799
3512 changed files with 627673 additions and 0 deletions
362
Scripts/Spells/Base/SpecialMove.cs
Normal file
362
Scripts/Spells/Base/SpecialMove.cs
Normal file
|
|
@ -0,0 +1,362 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
using Server.Spells.Ninjitsu;
|
||||
using Server.Spells.Bushido;
|
||||
|
||||
namespace Server.Spells
|
||||
{
|
||||
public abstract class SpecialMove
|
||||
{
|
||||
public virtual int BaseMana{ get{ return 0; } }
|
||||
|
||||
public virtual SkillName MoveSkill{ get{ return SkillName.Bushido; } }
|
||||
public virtual double RequiredSkill{ get{ return 0.0; } }
|
||||
|
||||
public virtual TextDefinition AbilityMessage{ get{ return 0; } }
|
||||
|
||||
public virtual bool BlockedByAnimalForm{ get{ return true; } }
|
||||
public virtual bool DelayedContext{ get{ return false; } }
|
||||
|
||||
public virtual int GetAccuracyBonus( Mobile attacker )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public virtual double GetDamageScalar( Mobile attacker, Mobile defender )
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
// Called before swinging, to make sure the accuracy scalar is to be computed.
|
||||
public virtual bool OnBeforeSwing( Mobile attacker, Mobile defender )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Called when a hit connects, but before damage is calculated.
|
||||
public virtual bool OnBeforeDamage( Mobile attacker, Mobile defender )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Called as soon as the ability is used.
|
||||
public virtual void OnUse( Mobile from )
|
||||
{
|
||||
}
|
||||
|
||||
// Called when a hit connects, at the end of the weapon.OnHit() method.
|
||||
public virtual void OnHit( Mobile attacker, Mobile defender, int damage )
|
||||
{
|
||||
}
|
||||
|
||||
// Called when a hit misses.
|
||||
public virtual void OnMiss( Mobile attacker, Mobile defender )
|
||||
{
|
||||
}
|
||||
|
||||
// Called when the move is cleared.
|
||||
public virtual void OnClearMove( Mobile from )
|
||||
{
|
||||
}
|
||||
|
||||
public virtual bool IgnoreArmor( Mobile attacker )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual double GetPropertyBonus( Mobile attacker )
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
public virtual bool CheckSkills( Mobile m )
|
||||
{
|
||||
if ( m.Skills[MoveSkill].Value < RequiredSkill )
|
||||
{
|
||||
string args = String.Format( "{0}\t{1}\t ", RequiredSkill.ToString( "F1" ), MoveSkill.ToString() );
|
||||
m.SendLocalizedMessage( 1063013, args ); // You need at least ~1_SKILL_REQUIREMENT~ ~2_SKILL_NAME~ skill to use that ability.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual int ScaleMana( Mobile m, int mana )
|
||||
{
|
||||
double scalar = 1.0;
|
||||
|
||||
if ( !Server.Spells.Necromancy.MindRotSpell.GetMindRotScalar( m, ref scalar ) )
|
||||
scalar = 1.0;
|
||||
|
||||
// Lower Mana Cost = 40%
|
||||
int lmc = Math.Min( AosAttributes.GetValue( m, AosAttribute.LowerManaCost ), 40 );
|
||||
|
||||
scalar -= (double)lmc / 100;
|
||||
|
||||
int total = (int)(mana * scalar);
|
||||
|
||||
if ( m.Skills[MoveSkill].Value < 50.0 && GetContext( m ) != null )
|
||||
total *= 2;
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
public virtual bool CheckMana( Mobile from, bool consume )
|
||||
{
|
||||
int mana = ScaleMana( from, BaseMana );
|
||||
|
||||
if ( from.Mana < mana )
|
||||
{
|
||||
from.SendLocalizedMessage( 1060181, mana.ToString() ); // You need ~1_MANA_REQUIREMENT~ mana to perform that attack
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( consume )
|
||||
{
|
||||
if ( !DelayedContext )
|
||||
SetContext( from );
|
||||
|
||||
from.Mana -= mana;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void SetContext( Mobile from )
|
||||
{
|
||||
if ( GetContext( from ) == null )
|
||||
{
|
||||
if ( DelayedContext || from.Skills[MoveSkill].Value < 50.0 )
|
||||
{
|
||||
Timer timer = new SpecialMoveTimer( from );
|
||||
timer.Start();
|
||||
|
||||
AddContext( from, new SpecialMoveContext( timer, this.GetType() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool Validate( Mobile from )
|
||||
{
|
||||
if ( !from.Player )
|
||||
return true;
|
||||
|
||||
if ( Bushido.HonorableExecution.IsUnderPenalty( from ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1063024 ); // You cannot perform this special move right now.
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( Ninjitsu.AnimalForm.UnderTransformation( from ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1063024 ); // You cannot perform this special move right now.
|
||||
return false;
|
||||
}
|
||||
|
||||
#region Dueling
|
||||
string option = null;
|
||||
|
||||
if ( this is Backstab )
|
||||
option = "Backstab";
|
||||
else if ( this is DeathStrike )
|
||||
option = "Death Strike";
|
||||
else if ( this is FocusAttack )
|
||||
option = "Focus Attack";
|
||||
else if ( this is KiAttack )
|
||||
option = "Ki Attack";
|
||||
else if ( this is SurpriseAttack )
|
||||
option = "Surprise Attack";
|
||||
else if ( this is HonorableExecution )
|
||||
option = "Honorable Execution";
|
||||
else if ( this is LightningStrike )
|
||||
option = "Lightning Strike";
|
||||
else if ( this is MomentumStrike )
|
||||
option = "Momentum Strike";
|
||||
|
||||
if ( option != null && !Engines.ConPVP.DuelContext.AllowSpecialMove( from, option, this ) )
|
||||
return false;
|
||||
#endregion
|
||||
|
||||
return CheckSkills( from ) && CheckMana( from, false );
|
||||
}
|
||||
|
||||
public virtual void CheckGain( Mobile m )
|
||||
{
|
||||
m.CheckSkill( MoveSkill, RequiredSkill, RequiredSkill + 37.5 );
|
||||
}
|
||||
|
||||
private static Dictionary<Mobile, SpecialMove> m_Table = new Dictionary<Mobile, SpecialMove>();
|
||||
|
||||
public static Dictionary<Mobile, SpecialMove> Table{ get{ return m_Table; } }
|
||||
|
||||
public static void ClearAllMoves( Mobile m )
|
||||
{
|
||||
foreach ( KeyValuePair<Int32, SpecialMove> kvp in SpellRegistry.SpecialMoves )
|
||||
{
|
||||
int moveID = kvp.Key;
|
||||
|
||||
if ( moveID != -1 )
|
||||
m.Send( new ToggleSpecialAbility( moveID + 1, false ) );
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool ValidatesDuringHit{ get { return true; } }
|
||||
|
||||
public static SpecialMove GetCurrentMove( Mobile m )
|
||||
{
|
||||
if ( m == null )
|
||||
return null;
|
||||
|
||||
if ( !Core.SE )
|
||||
{
|
||||
ClearCurrentMove( m );
|
||||
return null;
|
||||
}
|
||||
|
||||
SpecialMove move = null;
|
||||
m_Table.TryGetValue( m, out move );
|
||||
|
||||
if ( move != null && move.ValidatesDuringHit && !move.Validate( m ) )
|
||||
{
|
||||
ClearCurrentMove( m );
|
||||
return null;
|
||||
}
|
||||
|
||||
return move;
|
||||
}
|
||||
|
||||
public static bool SetCurrentMove( Mobile m, SpecialMove move )
|
||||
{
|
||||
if ( !Core.SE )
|
||||
{
|
||||
ClearCurrentMove( m );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( move != null && !move.Validate( m ) )
|
||||
{
|
||||
ClearCurrentMove( m );
|
||||
return false;
|
||||
}
|
||||
|
||||
bool sameMove = ( move == GetCurrentMove( m ) );
|
||||
|
||||
ClearCurrentMove( m );
|
||||
|
||||
if ( sameMove )
|
||||
return true;
|
||||
|
||||
if ( move != null )
|
||||
{
|
||||
WeaponAbility.ClearCurrentAbility( m );
|
||||
|
||||
m_Table[m] = move;
|
||||
|
||||
move.OnUse( m );
|
||||
|
||||
int moveID = SpellRegistry.GetRegistryNumber( move );
|
||||
|
||||
if ( moveID > 0 )
|
||||
m.Send( new ToggleSpecialAbility( moveID + 1, true ) );
|
||||
|
||||
TextDefinition.SendMessageTo( m, move.AbilityMessage );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void ClearCurrentMove( Mobile m )
|
||||
{
|
||||
SpecialMove move = null;
|
||||
m_Table.TryGetValue( m, out move );
|
||||
|
||||
if ( move != null )
|
||||
{
|
||||
move.OnClearMove( m );
|
||||
|
||||
int moveID = SpellRegistry.GetRegistryNumber( move );
|
||||
|
||||
if ( moveID > 0 )
|
||||
m.Send( new ToggleSpecialAbility( moveID + 1, false ) );
|
||||
}
|
||||
|
||||
m_Table.Remove( m );
|
||||
}
|
||||
|
||||
public SpecialMove()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
private static Dictionary<Mobile, SpecialMoveContext> m_PlayersTable = new Dictionary<Mobile, SpecialMoveContext>();
|
||||
|
||||
private static void AddContext( Mobile m, SpecialMoveContext context )
|
||||
{
|
||||
m_PlayersTable[m] = context;
|
||||
}
|
||||
|
||||
private static void RemoveContext( Mobile m )
|
||||
{
|
||||
SpecialMoveContext context = GetContext( m );
|
||||
|
||||
if ( context != null )
|
||||
{
|
||||
m_PlayersTable.Remove( m );
|
||||
|
||||
context.Timer.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
private static SpecialMoveContext GetContext( Mobile m )
|
||||
{
|
||||
return ( m_PlayersTable.ContainsKey( m ) ? m_PlayersTable[m] : null );
|
||||
}
|
||||
|
||||
public static bool GetContext( Mobile m, Type type )
|
||||
{
|
||||
SpecialMoveContext context = null;
|
||||
m_PlayersTable.TryGetValue( m, out context );
|
||||
|
||||
if ( context == null )
|
||||
return false;
|
||||
|
||||
return ( context.Type == type );
|
||||
}
|
||||
|
||||
private class SpecialMoveTimer : Timer
|
||||
{
|
||||
private Mobile m_Mobile;
|
||||
|
||||
public SpecialMoveTimer( Mobile from ) : base ( TimeSpan.FromSeconds( 3.0 ) )
|
||||
{
|
||||
m_Mobile = from;
|
||||
|
||||
Priority = TimerPriority.TwentyFiveMS;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
RemoveContext( m_Mobile );
|
||||
}
|
||||
}
|
||||
|
||||
public class SpecialMoveContext
|
||||
{
|
||||
private Timer m_Timer;
|
||||
private Type m_Type;
|
||||
|
||||
public Timer Timer{ get{ return m_Timer; } }
|
||||
public Type Type{ get{ return m_Type; } }
|
||||
|
||||
public SpecialMoveContext( Timer timer, Type type )
|
||||
{
|
||||
m_Timer = timer;
|
||||
m_Type = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue