This commit is contained in:
parent
c63a5f13fa
commit
2204d5fb86
86 changed files with 1077 additions and 257 deletions
|
|
@ -272,7 +272,33 @@ namespace Server.Commands
|
|||
|
||||
public static void GetFollowers_OnTarget( Mobile from, object obj )
|
||||
{
|
||||
if ( obj is Mobile && ((Mobile)obj).Player )
|
||||
if ( obj is PlayerMobile )
|
||||
{
|
||||
PlayerMobile master = (PlayerMobile)obj;
|
||||
List<Mobile> pets = master.AllFollowers;
|
||||
|
||||
if ( pets.Count > 0 )
|
||||
{
|
||||
CommandLogging.WriteLine( from, "{0} {1} getting all followers of {2}", from.AccessLevel, CommandLogging.Format( from ), CommandLogging.Format( master ) );
|
||||
|
||||
from.SendMessage( "That player has {0} pet{1}.", pets.Count, pets.Count != 1 ? "s" : "" );
|
||||
|
||||
for ( int i = 0; i < pets.Count; ++i )
|
||||
{
|
||||
Mobile pet = (Mobile)pets[i];
|
||||
|
||||
if ( pet is IMount )
|
||||
((IMount)pet).Rider = null; // make sure it's dismounted
|
||||
|
||||
pet.MoveToWorld( from.Location, from.Map );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage( "There were no pets found for that player." );
|
||||
}
|
||||
}
|
||||
else if ( obj is Mobile && ((Mobile)obj).Player )
|
||||
{
|
||||
Mobile master = (Mobile)obj;
|
||||
ArrayList pets = new ArrayList();
|
||||
|
|
|
|||
|
|
@ -1096,6 +1096,7 @@ namespace Server.Mobiles
|
|||
|
||||
case OrderType.Stop:
|
||||
m_Mobile.ControlMaster.RevealingAction();
|
||||
m_Mobile.Home = m_Mobile.Location;
|
||||
m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed;
|
||||
m_Mobile.PlaySound( m_Mobile.GetIdleSound() );
|
||||
m_Mobile.Warmode = false;
|
||||
|
|
@ -1476,13 +1477,9 @@ namespace Server.Mobiles
|
|||
Mobile newCombatant = null;
|
||||
double newScore = 0.0;
|
||||
|
||||
List<AggressorInfo> list = m_Mobile.Aggressors;
|
||||
|
||||
for( int i = 0; i < list.Count; ++i )
|
||||
foreach( Mobile aggr in m_Mobile.GetMobilesInRange( m_Mobile.RangePerception ) )
|
||||
{
|
||||
Mobile aggr = list[i].Attacker;
|
||||
|
||||
if( aggr.Map != m_Mobile.Map || !aggr.InRange( m_Mobile.Location, m_Mobile.RangePerception ) || !m_Mobile.CanSee( aggr ) )
|
||||
if( !m_Mobile.CanSee( aggr ) || aggr.Combatant != m_Mobile )
|
||||
continue;
|
||||
|
||||
if( aggr.IsDeadBondedPet || !aggr.Alive )
|
||||
|
|
@ -1571,7 +1568,15 @@ namespace Server.Mobiles
|
|||
m_Mobile.Home = m_Mobile.Location;
|
||||
|
||||
m_Mobile.ControlTarget = null;
|
||||
m_Mobile.ControlOrder = OrderType.None;
|
||||
|
||||
if( Core.ML )
|
||||
{
|
||||
WalkRandomInHome( 3, 2, 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Mobile.ControlOrder = OrderType.None;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,9 +55,10 @@ namespace Server.Mobiles
|
|||
[Flags]
|
||||
public enum FoodType
|
||||
{
|
||||
None = 0x0000,
|
||||
Meat = 0x0001,
|
||||
FruitsAndVegies = 0x0002,
|
||||
GrainsAndHay = 0x0004,
|
||||
FruitsAndVegies = 0x0002,
|
||||
GrainsAndHay = 0x0004,
|
||||
Fish = 0x0008,
|
||||
Eggs = 0x0010,
|
||||
Gold = 0x0020
|
||||
|
|
@ -170,39 +171,39 @@ namespace Server.Mobiles
|
|||
#region Var declarations
|
||||
private BaseAI m_AI; // THE AI
|
||||
|
||||
private AIType m_CurrentAI; // The current AI
|
||||
private AIType m_DefaultAI; // The default AI
|
||||
private AIType m_CurrentAI; // The current AI
|
||||
private AIType m_DefaultAI; // The default AI
|
||||
|
||||
private Mobile m_FocusMob; // Use focus mob instead of combatant, maybe we don't whan to fight
|
||||
private FightMode m_FightMode; // The style the mob uses
|
||||
private FightMode m_FightMode; // The style the mob uses
|
||||
|
||||
private int m_iRangePerception; // The view area
|
||||
private int m_iRangeFight; // The fight distance
|
||||
|
||||
private bool m_bDebugAI; // Show debug AI messages
|
||||
|
||||
private int m_iTeam; // Monster Team
|
||||
private bool m_bDebugAI; // Show debug AI messages
|
||||
|
||||
private double m_dActiveSpeed; // Timer speed when active
|
||||
private double m_dPassiveSpeed; // Timer speed when not active
|
||||
private double m_dCurrentSpeed; // The current speed, lets say it could be changed by something;
|
||||
private int m_iTeam; // Monster Team
|
||||
|
||||
private Point3D m_pHome; // The home position of the creature, used by some AI
|
||||
private double m_dActiveSpeed; // Timer speed when active
|
||||
private double m_dPassiveSpeed; // Timer speed when not active
|
||||
private double m_dCurrentSpeed; // The current speed, lets say it could be changed by something;
|
||||
|
||||
private Point3D m_pHome; // The home position of the creature, used by some AI
|
||||
private int m_iRangeHome = 10; // The home range of the creature
|
||||
|
||||
List<Type> m_arSpellAttack; // List of attack spell/power
|
||||
List<Type> m_arSpellDefense; // List of defensive spell/power
|
||||
|
||||
private bool m_bControlled; // Is controlled
|
||||
private Mobile m_ControlMaster; // My master
|
||||
private Mobile m_ControlTarget; // My target mobile
|
||||
private Point3D m_ControlDest; // My target destination (patrol)
|
||||
private OrderType m_ControlOrder; // My order
|
||||
private bool m_bControlled; // Is controlled
|
||||
private Mobile m_ControlMaster; // My master
|
||||
private Mobile m_ControlTarget; // My target mobile
|
||||
private Point3D m_ControlDest; // My target destination (patrol)
|
||||
private OrderType m_ControlOrder; // My order
|
||||
|
||||
private int m_Loyalty;
|
||||
private int m_Loyalty;
|
||||
|
||||
private double m_dMinTameSkill;
|
||||
private bool m_bTamable;
|
||||
private double m_dMinTameSkill;
|
||||
private bool m_bTamable;
|
||||
|
||||
private bool m_bSummoned = false;
|
||||
private DateTime m_SummonEnd;
|
||||
|
|
@ -218,20 +219,20 @@ namespace Server.Mobiles
|
|||
|
||||
private Mobile m_SummonMaster;
|
||||
|
||||
private int m_HitsMax = -1;
|
||||
private int m_StamMax = -1;
|
||||
private int m_ManaMax = -1;
|
||||
private int m_DamageMin = -1;
|
||||
private int m_DamageMax = -1;
|
||||
private int m_HitsMax = -1;
|
||||
private int m_StamMax = -1;
|
||||
private int m_ManaMax = -1;
|
||||
private int m_DamageMin = -1;
|
||||
private int m_DamageMax = -1;
|
||||
|
||||
private int m_PhysicalResistance, m_PhysicalDamage = 100;
|
||||
private int m_FireResistance, m_FireDamage;
|
||||
private int m_ColdResistance, m_ColdDamage;
|
||||
private int m_PoisonResistance, m_PoisonDamage;
|
||||
private int m_EnergyResistance, m_EnergyDamage;
|
||||
private int m_PhysicalResistance, m_PhysicalDamage = 100;
|
||||
private int m_FireResistance, m_FireDamage;
|
||||
private int m_ColdResistance, m_ColdDamage;
|
||||
private int m_PoisonResistance, m_PoisonDamage;
|
||||
private int m_EnergyResistance, m_EnergyDamage;
|
||||
|
||||
private List<Mobile> m_Owners;
|
||||
private List<Mobile> m_Friends;
|
||||
private List<Mobile> m_Owners;
|
||||
private List<Mobile> m_Friends;
|
||||
|
||||
private bool m_IsStabled;
|
||||
|
||||
|
|
@ -239,6 +240,10 @@ namespace Server.Mobiles
|
|||
|
||||
private bool m_Paragon;
|
||||
|
||||
private bool m_IsPrisoner;
|
||||
|
||||
private Timer m_GhostDeletionTimer;
|
||||
|
||||
#endregion
|
||||
|
||||
public virtual InhumanSpeech SpeechType{ get{ return null; } }
|
||||
|
|
@ -246,9 +251,20 @@ namespace Server.Mobiles
|
|||
public bool IsStabled
|
||||
{
|
||||
get{ return m_IsStabled; }
|
||||
set{ m_IsStabled = value; }
|
||||
set
|
||||
{
|
||||
m_IsStabled = value;
|
||||
SetGhostDeletionTimer( !m_IsStabled );
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public bool IsPrisoner
|
||||
{
|
||||
get{ return m_IsPrisoner; }
|
||||
set{ m_IsPrisoner = value; }
|
||||
}
|
||||
|
||||
protected DateTime SummonEnd
|
||||
{
|
||||
get { return m_SummonEnd; }
|
||||
|
|
@ -402,6 +418,7 @@ namespace Server.Mobiles
|
|||
public virtual bool BardImmune{ get{ return false; } }
|
||||
public virtual bool Unprovokable{ get{ return BardImmune || m_IsDeadPet; } }
|
||||
public virtual bool Uncalmable{ get{ return BardImmune || m_IsDeadPet; } }
|
||||
public virtual bool AreaPeaceImmune { get { return BardImmune || m_IsDeadPet; } }
|
||||
|
||||
public virtual bool BleedImmune{ get{ return false; } }
|
||||
public virtual double BonusPetDamageScalar{ get{ return 1.0; } }
|
||||
|
|
@ -824,16 +841,38 @@ namespace Server.Mobiles
|
|||
|
||||
int taming = (int)((useBaseSkill ? m.Skills[SkillName.AnimalTaming].Base : m.Skills[SkillName.AnimalTaming].Value ) * 10);
|
||||
int lore = (int)((useBaseSkill ? m.Skills[SkillName.AnimalLore].Base : m.Skills[SkillName.AnimalLore].Value )* 10);
|
||||
int bonus = 0, chance = 700;
|
||||
|
||||
int difficulty = (int)(dMinTameSkill * 10);
|
||||
int weighted = ((taming * 4) + lore) / 5;
|
||||
int bonus = weighted - difficulty;
|
||||
int chance;
|
||||
if( Core.ML )
|
||||
{
|
||||
int SkillBonus = taming - (int)(dMinTameSkill * 10);
|
||||
int LoreBonus = lore - (int)(dMinTameSkill * 10);
|
||||
|
||||
if ( bonus <= 0 )
|
||||
chance = 700 + (bonus * 14);
|
||||
int SkillMod = 6, LoreMod = 6;
|
||||
|
||||
if( SkillBonus < 0 )
|
||||
SkillMod = 28;
|
||||
if( LoreBonus < 0 )
|
||||
LoreMod = 14;
|
||||
|
||||
SkillBonus *= SkillMod;
|
||||
LoreBonus *= LoreMod;
|
||||
|
||||
bonus = (SkillBonus + LoreBonus ) / 2;
|
||||
}
|
||||
else
|
||||
chance = 700 + (bonus * 6);
|
||||
{
|
||||
int difficulty = (int)(dMinTameSkill * 10);
|
||||
int weighted = ((taming * 4) + lore) / 5;
|
||||
bonus = weighted - difficulty;
|
||||
|
||||
if ( bonus <= 0 )
|
||||
bonus *= 14;
|
||||
else
|
||||
bonus *= 6;
|
||||
}
|
||||
|
||||
chance += bonus;
|
||||
|
||||
if ( chance >= 0 && chance < 200 )
|
||||
chance = 200;
|
||||
|
|
@ -1693,6 +1732,8 @@ namespace Server.Mobiles
|
|||
|
||||
if ( IsAnimatedDead )
|
||||
Spells.Necromancy.AnimateDeadSpell.Register( m_SummonMaster, this );
|
||||
|
||||
SetGhostDeletionTimer( true );
|
||||
}
|
||||
|
||||
public virtual bool IsHumanInTown()
|
||||
|
|
@ -2215,9 +2256,23 @@ namespace Server.Mobiles
|
|||
public void RemoveFollowers()
|
||||
{
|
||||
if ( m_ControlMaster != null )
|
||||
{
|
||||
m_ControlMaster.Followers -= ControlSlots;
|
||||
if( m_ControlMaster is PlayerMobile )
|
||||
{
|
||||
((PlayerMobile)m_ControlMaster).AllFollowers.Remove( this );
|
||||
if( ((PlayerMobile)m_ControlMaster).AutoStabled.Contains( this ) )
|
||||
((PlayerMobile)m_ControlMaster).AutoStabled.Remove( this );
|
||||
}
|
||||
}
|
||||
else if ( m_SummonMaster != null )
|
||||
{
|
||||
m_SummonMaster.Followers -= ControlSlots;
|
||||
if( m_SummonMaster is PlayerMobile )
|
||||
{
|
||||
((PlayerMobile)m_SummonMaster).AllFollowers.Remove( this );
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_ControlMaster != null && m_ControlMaster.Followers < 0 )
|
||||
m_ControlMaster.Followers = 0;
|
||||
|
|
@ -2229,9 +2284,21 @@ namespace Server.Mobiles
|
|||
public void AddFollowers()
|
||||
{
|
||||
if ( m_ControlMaster != null )
|
||||
{
|
||||
m_ControlMaster.Followers += ControlSlots;
|
||||
if( m_ControlMaster is PlayerMobile )
|
||||
{
|
||||
((PlayerMobile)m_ControlMaster).AllFollowers.Add( this );
|
||||
}
|
||||
}
|
||||
else if ( m_SummonMaster != null )
|
||||
{
|
||||
m_SummonMaster.Followers += ControlSlots;
|
||||
if( m_SummonMaster is PlayerMobile )
|
||||
{
|
||||
((PlayerMobile)m_SummonMaster).AllFollowers.Add( this );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
|
|
@ -2833,8 +2900,22 @@ namespace Server.Mobiles
|
|||
{
|
||||
base.AggressiveAction( aggressor, criminal );
|
||||
|
||||
OrderType ct = m_ControlOrder;
|
||||
|
||||
if ( m_AI != null )
|
||||
m_AI.OnAggressiveAction( aggressor );
|
||||
{
|
||||
if( !Core.ML || ( ct != OrderType.Follow && ct != OrderType.Stop ) )
|
||||
{
|
||||
m_AI.OnAggressiveAction( aggressor );
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugSay( "I'm being attacked but my master told me not to fight." );
|
||||
Warmode = false;
|
||||
Combatant = null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
StopFlee();
|
||||
|
||||
|
|
@ -2848,9 +2929,7 @@ namespace Server.Mobiles
|
|||
pl.FinishShield();
|
||||
}
|
||||
|
||||
OrderType ct = m_ControlOrder;
|
||||
|
||||
if ( aggressor.ChangingCombatant && (m_bControlled || m_bSummoned) && (ct == OrderType.Come || ct == OrderType.Stay || ct == OrderType.Stop || ct == OrderType.None || ct == OrderType.Follow) )
|
||||
if ( aggressor.ChangingCombatant && (m_bControlled || m_bSummoned) && (ct == OrderType.Come || ( !Core.ML && ct == OrderType.Stay ) || ct == OrderType.Stop || ct == OrderType.None || ct == OrderType.Follow) )
|
||||
{
|
||||
ControlTarget = aggressor;
|
||||
ControlOrder = OrderType.Attack;
|
||||
|
|
@ -2874,7 +2953,7 @@ namespace Server.Mobiles
|
|||
{
|
||||
}
|
||||
|
||||
public virtual bool CanDrop { get { return !Summoned; } }
|
||||
public virtual bool CanDrop { get { return IsBonded; } }
|
||||
|
||||
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
|
||||
{
|
||||
|
|
@ -4182,6 +4261,8 @@ namespace Server.Mobiles
|
|||
GiftOfLifeSpell.HandleDeath( this );
|
||||
|
||||
CheckStatTimers();
|
||||
|
||||
SetGhostDeletionTimer( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -4801,8 +4882,26 @@ namespace Server.Mobiles
|
|||
}
|
||||
|
||||
CheckStatTimers();
|
||||
|
||||
SetGhostDeletionTimer( false );
|
||||
}
|
||||
|
||||
private void SetGhostDeletionTimer( bool running )
|
||||
{
|
||||
if( running && ( !IsDeadBondedPet || !Core.ML ) )
|
||||
return;
|
||||
|
||||
if( m_GhostDeletionTimer != null )
|
||||
m_GhostDeletionTimer.Stop();
|
||||
|
||||
if( !running )
|
||||
return;
|
||||
|
||||
m_GhostDeletionTimer = new GhostDeletionTimer( this, TimeSpan.FromMinutes( 120 + Utility.Random( 120 ) ) );
|
||||
m_GhostDeletionTimer.Start();
|
||||
}
|
||||
|
||||
|
||||
public override bool CanBeDamaged()
|
||||
{
|
||||
if ( IsDeadPet )
|
||||
|
|
@ -4839,6 +4938,26 @@ namespace Server.Mobiles
|
|||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int RemoveStep { get { return m_RemoveStep; } set { m_RemoveStep = value; } }
|
||||
|
||||
private class GhostDeletionTimer : Timer
|
||||
{
|
||||
private BaseCreature m_Creature;
|
||||
|
||||
public GhostDeletionTimer( BaseCreature Creature, TimeSpan delay ) : base( delay )
|
||||
{
|
||||
Priority = TimerPriority.FiveSeconds;
|
||||
m_Creature = Creature;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if( Core.ML && m_Creature.IsDeadBondedPet );
|
||||
{
|
||||
m_Creature.Delete();
|
||||
}
|
||||
Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class LoyaltyTimer : Timer
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ namespace Server
|
|||
typeof( SnowElemental ), typeof( WhiteWyrm ), typeof( Wisp ),
|
||||
typeof( DemonKnight ), typeof( GiantBlackWidow ), typeof( SummonedAirElemental ),
|
||||
typeof( LesserHiryu ), typeof( Hiryu ), typeof( LadyOfTheSnow ),
|
||||
typeof( RaiJu ), typeof( Ronin )
|
||||
typeof( RaiJu ), typeof( Ronin ), typeof( RuneBeetle )
|
||||
} ),
|
||||
/* Very Fast */
|
||||
new SpeedInfo( 0.175, 0.350, new Type[]
|
||||
|
|
@ -206,7 +206,7 @@ namespace Server
|
|||
typeof( Kappa ), typeof( KazeKemono ), typeof( DeathwatchBeetle ),
|
||||
typeof( TsukiWolf ), typeof( YomotsuElder ), typeof( YomotsuPriest ),
|
||||
typeof( YomotsuWarrior ), typeof( RevenantLion ), typeof( Oni ),
|
||||
typeof( RuneBeetle ), typeof( Gaman ), typeof( Crane )
|
||||
typeof( Gaman ), typeof( Crane )
|
||||
} )
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ using Server.Multis;
|
|||
using Server.Prompts;
|
||||
using Server.Mobiles;
|
||||
using Server.ContextMenus;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Engines.BulkOrders
|
||||
{
|
||||
|
|
@ -63,6 +64,34 @@ namespace Server.Engines.BulkOrders
|
|||
from.SendGump( new BOBGump( (PlayerMobile)from, this ) );
|
||||
}
|
||||
|
||||
public override void OnDoubleClickSecureTrade( Mobile from )
|
||||
{
|
||||
if ( !from.InRange( GetWorldLocation(), 2 ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 500446 ); // That is too far away.
|
||||
}
|
||||
else if ( m_Entries.Count == 0 )
|
||||
{
|
||||
from.SendLocalizedMessage( 1062381 ); // The book is empty.
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendGump( new BOBGump( (PlayerMobile)from, this ) );
|
||||
|
||||
SecureTradeContainer cont = GetSecureTradeCont();
|
||||
|
||||
if ( cont != null )
|
||||
{
|
||||
SecureTrade trade = cont.Trade;
|
||||
|
||||
if ( trade != null && trade.From.Mobile == from )
|
||||
trade.To.Mobile.SendGump( new BOBGump( (PlayerMobile)(trade.To.Mobile), this ) );
|
||||
else if ( trade != null && trade.To.Mobile == from )
|
||||
trade.From.Mobile.SendGump( new BOBGump( (PlayerMobile)(trade.From.Mobile), this ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnDragDrop( Mobile from, Item dropped )
|
||||
{
|
||||
if ( dropped is LargeBOD )
|
||||
|
|
|
|||
|
|
@ -56,12 +56,10 @@ namespace Server.Engines.Harvest
|
|||
|
||||
if ( m_Definition.RandomizeVeins )
|
||||
{
|
||||
m_Vein = m_Definition.GetVeinFrom( Utility.RandomDouble() );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Vein = m_DefaultVein;
|
||||
m_DefaultVein = m_Definition.GetVeinFrom( Utility.RandomDouble() );
|
||||
}
|
||||
|
||||
m_Vein = m_DefaultVein;
|
||||
}
|
||||
|
||||
public void Consume( int amount, Mobile from )
|
||||
|
|
|
|||
|
|
@ -91,6 +91,15 @@ namespace Server.Engines.Harvest
|
|||
fish.Resources = res;
|
||||
fish.Veins = veins;
|
||||
|
||||
if ( Core.ML )
|
||||
{
|
||||
fish.BonusResources = new BonusHarvestResource[]
|
||||
{
|
||||
new BonusHarvestResource( 0, 99.4, null, null ), //set to same chance as mining ml gems
|
||||
new BonusHarvestResource( 80.0, .6, 1072597, typeof( WhitePearl ) )
|
||||
};
|
||||
}
|
||||
|
||||
m_Definition = fish;
|
||||
Definitions.Add( fish );
|
||||
#endregion
|
||||
|
|
|
|||
|
|
@ -114,13 +114,13 @@ namespace Server.Engines.Harvest
|
|||
{
|
||||
oreAndStone.BonusResources = new BonusHarvestResource[]
|
||||
{
|
||||
new BonusHarvestResource( 0, 99.8998, null, null ), //Nothing //Note: Rounded the below to .0167 instead of 1/6th of a %. Close enough
|
||||
new BonusHarvestResource( 100, .0167, 1072562, typeof( BlueDiamond ) ),
|
||||
new BonusHarvestResource( 100, .0167, 1072567, typeof( DarkSapphire ) ),
|
||||
new BonusHarvestResource( 100, .0167, 1072570, typeof( EcruCitrine ) ),
|
||||
new BonusHarvestResource( 100, .0167, 1072564, typeof( FireRuby ) ),
|
||||
new BonusHarvestResource( 100, .0167, 1072566, typeof( PerfectEmerald ) ),
|
||||
new BonusHarvestResource( 100, .0167, 1072568, typeof( Turquoise ) )
|
||||
new BonusHarvestResource( 0, 99.4, null, null ), //Nothing
|
||||
new BonusHarvestResource( 100, .1, 1072562, typeof( BlueDiamond ) ),
|
||||
new BonusHarvestResource( 100, .1, 1072567, typeof( DarkSapphire ) ),
|
||||
new BonusHarvestResource( 100, .1, 1072570, typeof( EcruCitrine ) ),
|
||||
new BonusHarvestResource( 100, .1, 1072564, typeof( FireRuby ) ),
|
||||
new BonusHarvestResource( 100, .1, 1072566, typeof( PerfectEmerald ) ),
|
||||
new BonusHarvestResource( 100, .1, 1072568, typeof( Turquoise ) )
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -166,13 +166,13 @@ namespace Server.PathAlgorithms.FastAStar
|
|||
int newCost = m_Nodes[bestNode].cost + 1;
|
||||
int newTotal = newCost + Heuristic( newNode % AreaSize, (newNode / AreaSize) % AreaSize, m_Nodes[newNode].z );
|
||||
|
||||
if ( m_Nodes[newNode].total > newTotal )
|
||||
if ( !wasTouched || m_Nodes[newNode].total > newTotal )
|
||||
{
|
||||
m_Nodes[newNode].parent = bestNode;
|
||||
m_Nodes[newNode].cost = newCost;
|
||||
m_Nodes[newNode].total = newTotal;
|
||||
|
||||
if ( !m_OnOpen[newNode] )
|
||||
if ( !wasTouched || !m_OnOpen[newNode] )
|
||||
{
|
||||
AddToChain( newNode );
|
||||
|
||||
|
|
|
|||
|
|
@ -149,8 +149,8 @@ namespace Server
|
|||
{
|
||||
alg = FastAStarAlgorithm.Instance;
|
||||
|
||||
if ( !alg.CheckCondition( m, map, start, goal ) )
|
||||
alg = SlowAStarAlgorithm.Instance;
|
||||
//if ( !alg.CheckCondition( m, map, start, goal ) ) // SlowAstar is still broken
|
||||
// alg = SlowAStarAlgorithm.Instance; // TODO: Fix SlowAstar
|
||||
}
|
||||
|
||||
if ( alg != null && alg.CheckCondition( m, map, start, goal ) )
|
||||
|
|
|
|||
|
|
@ -92,6 +92,8 @@ namespace Server.Gumps
|
|||
if ( m_Mobile.AccessLevel >= AccessLevel.GameMaster )
|
||||
{
|
||||
m_Mobile.SendMessage( "You do not get a refund for your house as you are not a player" );
|
||||
m_House.RemoveKeys(m_Mobile);
|
||||
m_House.Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@ namespace Server.Items
|
|||
|
||||
public class BarrelHoops : Item
|
||||
{
|
||||
public override int LabelNumber { get { return 1011228; } } // Barrel hoops
|
||||
|
||||
[Constructable]
|
||||
public BarrelHoops() : base(0x1DB7)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ namespace Server.Items
|
|||
get {
|
||||
if ( Core.ML ) {
|
||||
Mobile m = ParentEntity as Mobile;
|
||||
if ( m != null && m.Backpack == this ) {
|
||||
if ( m != null && m.Player && m.Backpack == this ) {
|
||||
return 550;
|
||||
} else {
|
||||
return base.DefaultMaxWeight;
|
||||
|
|
|
|||
|
|
@ -106,7 +106,9 @@ namespace Server.Items
|
|||
public void EndPlace( Mobile from, HolidayTreeType type, Point3D loc )
|
||||
{
|
||||
this.Delete();
|
||||
new HolidayTree( from, type, loc );
|
||||
HolidayTree tree = new HolidayTree( from, type, loc );
|
||||
BaseHouse house = BaseHouse.FindHouseAt( tree );
|
||||
house.Addons.Add( tree );
|
||||
}
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ namespace Server.Items
|
|||
[Constructable]
|
||||
public SushiPlatter() : base( 0x2840 )
|
||||
{
|
||||
Stackable = false;
|
||||
Stackable = Core.ML;
|
||||
Weight = 3.0;
|
||||
FillFactor = 2;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ namespace Server.Items
|
|||
[Constructable]
|
||||
public Dough() : base( 0x103d )
|
||||
{
|
||||
Stackable = Core.ML;
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
|
|
@ -124,6 +125,7 @@ namespace Server.Items
|
|||
[Constructable]
|
||||
public SweetDough() : base( 0x103d )
|
||||
{
|
||||
Stackable = Core.ML;
|
||||
Weight = 1.0;
|
||||
Hue = 150;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -688,7 +688,7 @@ namespace Server.Items
|
|||
[Constructable]
|
||||
public Cookies() : base( 0x160b )
|
||||
{
|
||||
Stackable = false;
|
||||
Stackable = Core.ML;
|
||||
this.Weight = 1.0;
|
||||
this.FillFactor = 4;
|
||||
}
|
||||
|
|
@ -997,7 +997,7 @@ namespace Server.Items
|
|||
[Constructable]
|
||||
public Quiche() : base( 0x1041 )
|
||||
{
|
||||
Stackable = false;
|
||||
Stackable = Core.ML;
|
||||
this.Weight = 1.0;
|
||||
this.FillFactor = 5;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ namespace Server.Items
|
|||
[Constructable]
|
||||
public ArcaneGem() : base( 0x1EA7 )
|
||||
{
|
||||
Stackable = Core.ML;
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -929,6 +929,16 @@ namespace Server.Items
|
|||
|
||||
public void Carve( Mobile from, Item item )
|
||||
{
|
||||
if ( IsCriminalAction( from ) && this.Map != null && (this.Map.Rules & MapRules.HarmfulRestrictions) != 0 )
|
||||
{
|
||||
if ( m_Owner == null || !m_Owner.Player )
|
||||
from.SendLocalizedMessage( 1005035 ); // You did not earn the right to loot this creature!
|
||||
else
|
||||
from.SendLocalizedMessage( 1010049 ); // You may not loot this corpse.
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Mobile dead = m_Owner;
|
||||
|
||||
if ( m_Carved || dead == null )
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ namespace Server.Items
|
|||
{
|
||||
Hue = 2101;
|
||||
Weight = 2.0;
|
||||
Stackable = Core.ML;
|
||||
}
|
||||
|
||||
public TribalPaint( Serial serial ) : base( serial )
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ namespace Server.Items
|
|||
public BigFish() : base( 0x09CC )
|
||||
{
|
||||
Weight = Utility.RandomMinMax( 3, 200 ); //TODO: Find correct formula. max on OSI currently 200, OSI dev says it's not 200 as max, and ~ 1/1,000,000 chance to get highest
|
||||
Hue = 0x847;
|
||||
Hue = Utility.RandomBool() ? 0x847 : 0x58C;
|
||||
}
|
||||
|
||||
public override void GetProperties( ObjectPropertyList list )
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ namespace Server.Items
|
|||
else
|
||||
list.Add( CraftResources.GetName( m_Resource ) );
|
||||
}
|
||||
Stackable = Core.ML;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -146,6 +146,8 @@ namespace Server.Items
|
|||
|
||||
public class TrophyAddon : Item, IAddon
|
||||
{
|
||||
public override bool ForceShowProperties { get { return ObjectPropertyList.Enabled; } }
|
||||
|
||||
private int m_WestID;
|
||||
private int m_NorthID;
|
||||
private int m_DeedNumber;
|
||||
|
|
|
|||
|
|
@ -134,12 +134,20 @@ namespace Server.Items
|
|||
m.Animate( 34, 5, 1, true, false, 0 );
|
||||
}
|
||||
|
||||
public static int EnhancePotions( Mobile m )
|
||||
{
|
||||
int EP = AosAttributes.GetValue( m, AosAttribute.EnhancePotions );
|
||||
if ( Core.ML && EP > 50 )
|
||||
EP = 50;
|
||||
return EP;
|
||||
}
|
||||
|
||||
public static TimeSpan Scale( Mobile m, TimeSpan v )
|
||||
{
|
||||
if ( !Core.AOS )
|
||||
return v;
|
||||
|
||||
double scalar = 1.0 + (0.01 * AosAttributes.GetValue( m, AosAttribute.EnhancePotions ));
|
||||
double scalar = 1.0 + ( 0.01 * EnhancePotions( m ) );
|
||||
|
||||
return TimeSpan.FromSeconds( v.TotalSeconds * scalar );
|
||||
}
|
||||
|
|
@ -149,7 +157,7 @@ namespace Server.Items
|
|||
if ( !Core.AOS )
|
||||
return v;
|
||||
|
||||
double scalar = 1.0 + (0.01 * AosAttributes.GetValue( m, AosAttribute.EnhancePotions ));
|
||||
double scalar = 1.0 + ( 0.01 * EnhancePotions( m ) );
|
||||
|
||||
return v * scalar;
|
||||
}
|
||||
|
|
@ -159,7 +167,7 @@ namespace Server.Items
|
|||
if ( !Core.AOS )
|
||||
return v;
|
||||
|
||||
return AOS.Scale( v, 100 + AosAttributes.GetValue( m, AosAttribute.EnhancePotions ) );
|
||||
return AOS.Scale( v, 100 + EnhancePotions( m ) );
|
||||
}
|
||||
|
||||
public override bool StackWith( Mobile from, Item dropped, bool playSound )
|
||||
|
|
|
|||
|
|
@ -276,7 +276,7 @@ namespace Server.Items
|
|||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
if ( from.InRange( GetWorldLocation(), 1 ) )
|
||||
if ( from.InRange( GetWorldLocation(), (Core.ML ? 3 : 1) ) )
|
||||
{
|
||||
if ( DateTime.Now < NextUse )
|
||||
{
|
||||
|
|
@ -294,22 +294,22 @@ namespace Server.Items
|
|||
NextUse = DateTime.Now + UseDelay;
|
||||
}
|
||||
|
||||
public override void OnAfterDuped( Item newItem )
|
||||
{
|
||||
Runebook book = newItem as Runebook;
|
||||
public override void OnAfterDuped( Item newItem )
|
||||
{
|
||||
Runebook book = newItem as Runebook;
|
||||
|
||||
if ( book == null )
|
||||
return;
|
||||
if ( book == null )
|
||||
return;
|
||||
|
||||
book.m_Entries = new List<RunebookEntry>();
|
||||
|
||||
for ( int i = 0; i < m_Entries.Count; i++ )
|
||||
{
|
||||
RunebookEntry entry = m_Entries[i];
|
||||
for ( int i = 0; i < m_Entries.Count; i++ )
|
||||
{
|
||||
RunebookEntry entry = m_Entries[i];
|
||||
|
||||
book.m_Entries.Add( new RunebookEntry( entry.Location, entry.Map, entry.Description, entry.House ) );
|
||||
}
|
||||
}
|
||||
book.m_Entries.Add( new RunebookEntry( entry.Location, entry.Map, entry.Description, entry.House ) );
|
||||
}
|
||||
}
|
||||
|
||||
public bool CheckAccess( Mobile m )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ namespace Server.Items
|
|||
public ArcaneCircleScroll( int amount )
|
||||
: base( 600, 0x2D51, amount )
|
||||
{
|
||||
Hue = 0x8FD;
|
||||
}
|
||||
|
||||
public ArcaneCircleScroll( Serial serial )
|
||||
|
|
@ -50,6 +51,7 @@ namespace Server.Items
|
|||
public GiftOfRenewalScroll( int amount )
|
||||
: base( 601, 0x2D52, amount )
|
||||
{
|
||||
Hue = 0x8FD;
|
||||
}
|
||||
|
||||
public GiftOfRenewalScroll( Serial serial )
|
||||
|
|
@ -84,6 +86,7 @@ namespace Server.Items
|
|||
public ImmolatingWeaponScroll( int amount )
|
||||
: base( 602, 0x2D53, amount )
|
||||
{
|
||||
Hue = 0x8FD;
|
||||
}
|
||||
|
||||
public ImmolatingWeaponScroll( Serial serial )
|
||||
|
|
@ -118,6 +121,7 @@ namespace Server.Items
|
|||
public AttuneWeaponScroll( int amount )
|
||||
: base( 603, 0x2D54, amount )
|
||||
{
|
||||
Hue = 0x8FD;
|
||||
}
|
||||
|
||||
public AttuneWeaponScroll( Serial serial )
|
||||
|
|
@ -152,6 +156,7 @@ namespace Server.Items
|
|||
public ThunderstormScroll( int amount )
|
||||
: base( 604, 0x2D55, amount )
|
||||
{
|
||||
Hue = 0x8FD;
|
||||
}
|
||||
|
||||
public ThunderstormScroll( Serial serial )
|
||||
|
|
@ -186,6 +191,7 @@ namespace Server.Items
|
|||
public NatureFuryScroll( int amount )
|
||||
: base( 605, 0x2D56, amount )
|
||||
{
|
||||
Hue = 0x8FD;
|
||||
}
|
||||
|
||||
public NatureFuryScroll( Serial serial )
|
||||
|
|
@ -220,6 +226,7 @@ namespace Server.Items
|
|||
public SummonFeyScroll( int amount )
|
||||
: base( 606, 0x2D57, amount )
|
||||
{
|
||||
Hue = 0x8FD;
|
||||
}
|
||||
|
||||
public SummonFeyScroll( Serial serial )
|
||||
|
|
@ -254,6 +261,7 @@ namespace Server.Items
|
|||
public SummonFiendScroll( int amount )
|
||||
: base( 607, 0x2D58, amount )
|
||||
{
|
||||
Hue = 0x8FD;
|
||||
}
|
||||
|
||||
public SummonFiendScroll( Serial serial )
|
||||
|
|
@ -288,6 +296,7 @@ namespace Server.Items
|
|||
public ReaperFormScroll( int amount )
|
||||
: base( 608, 0x2D59, amount )
|
||||
{
|
||||
Hue = 0x8FD;
|
||||
}
|
||||
|
||||
public ReaperFormScroll( Serial serial )
|
||||
|
|
@ -322,6 +331,7 @@ namespace Server.Items
|
|||
public WildfireScroll( int amount )
|
||||
: base( 609, 0x2D5A, amount )
|
||||
{
|
||||
Hue = 0x8FD;
|
||||
}
|
||||
|
||||
public WildfireScroll( Serial serial )
|
||||
|
|
@ -356,6 +366,7 @@ namespace Server.Items
|
|||
public EssenceOfWindScroll( int amount )
|
||||
: base( 610, 0x2D5B, amount )
|
||||
{
|
||||
Hue = 0x8FD;
|
||||
}
|
||||
|
||||
public EssenceOfWindScroll( Serial serial )
|
||||
|
|
@ -390,6 +401,7 @@ namespace Server.Items
|
|||
public DryadAllureScroll( int amount )
|
||||
: base( 611, 0x2D5C, amount )
|
||||
{
|
||||
Hue = 0x8FD;
|
||||
}
|
||||
|
||||
public DryadAllureScroll( Serial serial )
|
||||
|
|
@ -424,6 +436,7 @@ namespace Server.Items
|
|||
public EtherealVoyageScroll( int amount )
|
||||
: base( 612, 0x2D5D, amount )
|
||||
{
|
||||
Hue = 0x8FD;
|
||||
}
|
||||
|
||||
public EtherealVoyageScroll( Serial serial )
|
||||
|
|
@ -458,6 +471,7 @@ namespace Server.Items
|
|||
public WordOfDeathScroll( int amount )
|
||||
: base( 613, 0x2D5E, amount )
|
||||
{
|
||||
Hue = 0x8FD;
|
||||
}
|
||||
|
||||
public WordOfDeathScroll( Serial serial )
|
||||
|
|
@ -492,6 +506,7 @@ namespace Server.Items
|
|||
public GiftOfLifeScroll( int amount )
|
||||
: base( 614, 0x2D5F, amount )
|
||||
{
|
||||
Hue = 0x8FD;
|
||||
}
|
||||
|
||||
public GiftOfLifeScroll( Serial serial )
|
||||
|
|
@ -526,6 +541,7 @@ namespace Server.Items
|
|||
public ArcaneEmpowermentScroll( int amount )
|
||||
: base( 615, 0x2D60, amount )
|
||||
{
|
||||
Hue = 0x8FD;
|
||||
}
|
||||
|
||||
public ArcaneEmpowermentScroll( Serial serial )
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ namespace Server.Items
|
|||
[Constructable]
|
||||
public EggBomb() : base( 0x2809 )
|
||||
{
|
||||
Stackable = Core.ML;
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ namespace Server.Items
|
|||
[Constructable]
|
||||
public SmokeBomb() : base( 0x2808 )
|
||||
{
|
||||
Stackable = Core.ML;
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ namespace Server.Items
|
|||
[Constructable]
|
||||
public Sand( int amount ) : base( 0x11EA )
|
||||
{
|
||||
Stackable = false;
|
||||
Stackable = Core.ML;
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -492,7 +492,13 @@ namespace Server.Items
|
|||
/* Begin Sheilds */
|
||||
case 0: ApplyAttribute( primary, min, max, AosAttribute.SpellChanneling, 1, 1 ); break;
|
||||
case 1: ApplyAttribute( primary, min, max, AosAttribute.DefendChance, 1, 15 ); break;
|
||||
case 2: ApplyAttribute( primary, min, max, AosAttribute.AttackChance, 1, 15 ); break;
|
||||
case 2:
|
||||
if (Core.ML) {
|
||||
ApplyAttribute( primary, min, max, AosAttribute.ReflectPhysical, 1, 15 );
|
||||
} else {
|
||||
ApplyAttribute( primary, min, max, AosAttribute.AttackChance, 1, 15 );
|
||||
}
|
||||
break;
|
||||
case 3: ApplyAttribute( primary, min, max, AosAttribute.CastSpeed, 1, 1 ); break;
|
||||
/* Begin Armor */
|
||||
case 4: ApplyAttribute( secondary, min, max, AosArmorAttribute.LowerStatReq, 10, 100, 10 ); break;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Collections;
|
||||
using Server.Network;
|
||||
using Server.Items;
|
||||
using Server.Multis;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
|
|
@ -11,7 +12,7 @@ namespace Server.Items
|
|||
Modern
|
||||
}
|
||||
|
||||
public class HolidayTree : Item
|
||||
public class HolidayTree : Item, IAddon
|
||||
{
|
||||
private ArrayList m_Components;
|
||||
private Mobile m_Placer;
|
||||
|
|
@ -208,6 +209,16 @@ namespace Server.Items
|
|||
{
|
||||
}
|
||||
|
||||
public bool CouldFit( IPoint3D p, Map map )
|
||||
{
|
||||
return map.CanFit( (Point3D)p, 20 );
|
||||
}
|
||||
|
||||
Item IAddon.Deed
|
||||
{
|
||||
get{ return new HolidayTreeDeed(); }
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
|
@ -253,8 +264,22 @@ namespace Server.Items
|
|||
break;
|
||||
}
|
||||
}
|
||||
ValidatePlacement();
|
||||
}
|
||||
|
||||
public void ValidatePlacement()
|
||||
{
|
||||
BaseHouse house = BaseHouse.FindHouseAt( this );
|
||||
|
||||
if ( house == null )
|
||||
{
|
||||
HolidayTreeDeed deed = new HolidayTreeDeed();
|
||||
deed.MoveToWorld( Location, Map );
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
if ( from.InRange( this.GetWorldLocation(), 1 ) )
|
||||
|
|
@ -265,6 +290,13 @@ namespace Server.Items
|
|||
|
||||
this.Delete();
|
||||
|
||||
BaseHouse house = BaseHouse.FindHouseAt( this );
|
||||
|
||||
if ( house != null && house.Addons.Contains( this ) )
|
||||
{
|
||||
house.Addons.Remove( this );
|
||||
}
|
||||
|
||||
from.SendLocalizedMessage( 503393 ); // A deed for the tree has been placed in your backpack.
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ using Server.Targeting;
|
|||
using Server.ContextMenus;
|
||||
using Server.Network;
|
||||
using Server.Regions;
|
||||
using Server.Spells;
|
||||
using Server.Spells.Ninjitsu;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
|
|
@ -144,20 +146,27 @@ namespace Server.Items
|
|||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
if ( this.RootParent == from ) // TODO: Previous implementation allowed use on ground, without house protection checks. What is the correct behavior?
|
||||
if ( this.RootParent != from ) // TODO: Previous implementation allowed use on ground, without house protection checks. What is the correct behavior?
|
||||
{
|
||||
if ( Pet == null )
|
||||
{
|
||||
LinkPet( from );
|
||||
}
|
||||
else
|
||||
{
|
||||
SummonPet( from );
|
||||
}
|
||||
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1042001 ); // That must be in your pack for you to use it.
|
||||
return;
|
||||
}
|
||||
|
||||
AnimalFormContext animalContext = AnimalForm.GetContext( from );
|
||||
|
||||
if( Core.ML && animalContext != null )
|
||||
{
|
||||
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1080073 ); // You cannot use a Crystal Ball of Pet Summoning while in animal form.
|
||||
return;
|
||||
}
|
||||
|
||||
if ( Pet == null )
|
||||
{
|
||||
LinkPet( from );
|
||||
}
|
||||
else
|
||||
{
|
||||
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1042001 ); // That must be in your pack for you to use it.
|
||||
CastSummonPet( from );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -220,7 +229,7 @@ namespace Server.Items
|
|||
}
|
||||
}
|
||||
|
||||
public void SummonPet( Mobile from )
|
||||
public void CastSummonPet( Mobile from )
|
||||
{
|
||||
BaseCreature pet = this.Pet;
|
||||
|
||||
|
|
@ -251,27 +260,48 @@ namespace Server.Items
|
|||
{
|
||||
from.Send( new AsciiMessage( this.Serial, this.ItemID, MessageType.Regular, 0x22, 3, "", "You cannot summon your pet to this location." ) );
|
||||
}
|
||||
else if ( Core.ML && from is PlayerMobile && DateTime.Now < ((PlayerMobile)from).LastPetBallTime.AddSeconds( 15.0 ) )
|
||||
{
|
||||
MessageHelper.SendLocalizedMessageTo( this, from, 1080072, 0x22 ); // You must wait a few seconds before you can summon your pet.
|
||||
}
|
||||
else
|
||||
{
|
||||
Charges--;
|
||||
if( Core.ML )
|
||||
new PetSummoningSpell( this, from ).Cast();
|
||||
else
|
||||
SummonPet( from );
|
||||
}
|
||||
|
||||
if ( pet.IsStabled )
|
||||
{
|
||||
pet.SetControlMaster( from );
|
||||
}
|
||||
|
||||
if ( pet.Summoned )
|
||||
pet.SummonMaster = from;
|
||||
|
||||
public void SummonPet( Mobile from )
|
||||
{
|
||||
BaseCreature pet = this.Pet;
|
||||
|
||||
pet.ControlTarget = from;
|
||||
pet.ControlOrder = OrderType.Follow;
|
||||
Charges--;
|
||||
|
||||
pet.IsStabled = false;
|
||||
from.Stabled.Remove( pet );
|
||||
}
|
||||
if ( pet.IsStabled )
|
||||
{
|
||||
pet.SetControlMaster( from );
|
||||
|
||||
pet.MoveToWorld( from.Location, from.Map );
|
||||
if ( pet.Summoned )
|
||||
pet.SummonMaster = from;
|
||||
|
||||
MessageHelper.SendLocalizedMessageTo( this, from, 1054128, 0x43 ); // The Crystal Ball fills with a green mist. Your pet has been summoned.
|
||||
pet.ControlTarget = from;
|
||||
pet.ControlOrder = OrderType.Follow;
|
||||
|
||||
pet.IsStabled = false;
|
||||
from.Stabled.Remove( pet );
|
||||
}
|
||||
|
||||
pet.MoveToWorld( from.Location, from.Map );
|
||||
|
||||
MessageHelper.SendLocalizedMessageTo( this, from, 1054128, 0x43 ); // The Crystal Ball fills with a green mist. Your pet has been summoned.
|
||||
|
||||
if ( from is PlayerMobile )
|
||||
{
|
||||
((PlayerMobile)from).LastPetBallTime = DateTime.Now;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -341,5 +371,94 @@ namespace Server.Items
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class PetSummoningSpell : Spell
|
||||
{
|
||||
private static SpellInfo m_Info = new SpellInfo( "Ball Of Summoning", "", 230 );
|
||||
|
||||
private BallOfSummoning m_Ball;
|
||||
private Mobile m_Caster;
|
||||
|
||||
public PetSummoningSpell( BallOfSummoning ball, Mobile caster )
|
||||
: base( caster, null, m_Info )
|
||||
{
|
||||
m_Caster = caster;
|
||||
m_Ball = ball;
|
||||
}
|
||||
|
||||
public override bool ClearHandsOnCast { get { return false; } }
|
||||
public override bool RevealOnCast { get { return true; } }
|
||||
|
||||
public override TimeSpan GetCastRecovery()
|
||||
{
|
||||
return TimeSpan.Zero;
|
||||
}
|
||||
|
||||
public override double CastDelayFastScalar { get { return 0; } }
|
||||
|
||||
public override TimeSpan CastDelayBase
|
||||
{
|
||||
get
|
||||
{
|
||||
return TimeSpan.FromSeconds( 2.0 );
|
||||
}
|
||||
}
|
||||
|
||||
public override int GetMana()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override bool ConsumeReagents()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool CheckFizzle()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool m_Stop;
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
m_Stop = true;
|
||||
Disturb( DisturbType.Hurt, false, false );
|
||||
}
|
||||
|
||||
public override bool CheckDisturb( DisturbType type, bool checkFirst, bool resistable )
|
||||
{
|
||||
if( type == DisturbType.EquipRequest || type == DisturbType.UseRequest/* || type == DisturbType.Hurt*/ )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void DoHurtFizzle()
|
||||
{
|
||||
if( !m_Stop )
|
||||
base.DoHurtFizzle();
|
||||
}
|
||||
|
||||
public override void DoFizzle()
|
||||
{
|
||||
if( !m_Stop )
|
||||
base.DoFizzle();
|
||||
}
|
||||
|
||||
public override void OnDisturb( DisturbType type, bool message )
|
||||
{
|
||||
if( message && !m_Stop )
|
||||
Caster.SendLocalizedMessage( 1080074 ); // You have been disrupted while attempting to summon your pet!
|
||||
}
|
||||
|
||||
public override void OnCast()
|
||||
{
|
||||
m_Ball.SummonPet( m_Caster );
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ namespace Server.Items
|
|||
|
||||
public abstract class BaseWand : BaseBashing
|
||||
{
|
||||
public override WeaponAbility PrimaryAbility { get { return WeaponAbility.Dismount; } }
|
||||
public override WeaponAbility SecondaryAbility { get { return WeaponAbility.Disarm; } }
|
||||
|
||||
public override int AosStrengthReq { get { return 5; } }
|
||||
public override int AosMinDamage { get { return 9; } }
|
||||
public override int AosMaxDamage { get { return 11; } }
|
||||
public override int AosSpeed { get { return 40; } }
|
||||
|
||||
public override int OldStrengthReq { get { return 0; } }
|
||||
public override int OldMinDamage { get { return 2; } }
|
||||
public override int OldMaxDamage { get { return 6; } }
|
||||
public override int OldSpeed { get { return 35; } }
|
||||
|
||||
public override int InitMinHits { get { return 31; } }
|
||||
public override int InitMaxHits { get { return 110; } }
|
||||
|
||||
private WandEffect m_WandEffect;
|
||||
private int m_Charges;
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,16 @@ namespace Server.Items
|
|||
return false;
|
||||
}*/
|
||||
|
||||
public override bool RequiresTactics( Mobile from )
|
||||
{
|
||||
BaseWeapon weapon = from.Weapon as BaseWeapon;
|
||||
|
||||
if ( weapon == null )
|
||||
return false;
|
||||
|
||||
return weapon.Skill != SkillName.Wrestling;
|
||||
}
|
||||
|
||||
public static readonly TimeSpan BlockEquipDuration = TimeSpan.FromSeconds( 5.0 );
|
||||
|
||||
public override void OnHit( Mobile attacker, Mobile defender, int damage )
|
||||
|
|
@ -53,7 +63,7 @@ namespace Server.Items
|
|||
{
|
||||
attacker.SendLocalizedMessage( 1004001 ); // You cannot disarm your opponent.
|
||||
}
|
||||
else if ( toDisarm == null || toDisarm is BaseShield || toDisarm is Spellbook )
|
||||
else if (toDisarm == null || toDisarm is BaseShield || toDisarm is Spellbook && !Core.ML )
|
||||
{
|
||||
attacker.SendLocalizedMessage( 1060849 ); // Your target is already unarmed!
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,6 +58,11 @@ namespace Server.Items
|
|||
if ( !CheckMana( attacker, true ) )
|
||||
return;
|
||||
|
||||
if ( Core.ML && attacker is LesserHiryu && 0.8 >= Utility.RandomDouble() )
|
||||
{
|
||||
return; //Lesser Hiryu have an 80% chance of missing this attack
|
||||
}
|
||||
|
||||
attacker.SendLocalizedMessage( 1060082 ); // The force of your attack has dislodged them from their mount!
|
||||
|
||||
if ( attacker.Mounted )
|
||||
|
|
@ -71,8 +76,15 @@ namespace Server.Items
|
|||
mount.Rider = null;
|
||||
|
||||
BaseMount.SetMountPrevention( defender, BlockMountType.Dazed, DefenderRemountDelay );
|
||||
BaseMount.SetMountPrevention( attacker, BlockMountType.DismountRecovery, AttackerRemountDelay );
|
||||
|
||||
if( Core.ML && attacker is BaseCreature && ((BaseCreature)attacker).ControlMaster != null )
|
||||
{
|
||||
BaseMount.SetMountPrevention( ((BaseCreature)attacker).ControlMaster, BlockMountType.DismountRecovery, AttackerRemountDelay );
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseMount.SetMountPrevention( attacker, BlockMountType.DismountRecovery, AttackerRemountDelay );
|
||||
}
|
||||
|
||||
if ( !attacker.Mounted )
|
||||
AOS.Damage( defender, attacker, Utility.RandomMinMax( 15, 25 ), 100, 0, 0, 0, 0 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,11 @@ namespace Server.Items
|
|||
|
||||
public override int BaseMana{ get{ return 15; } }
|
||||
|
||||
public override bool RequiresTactics( Mobile from )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnHit( Mobile attacker, Mobile defender, int damage )
|
||||
{
|
||||
if ( !Validate( attacker ) )
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ namespace Server.Items
|
|||
}
|
||||
|
||||
public override int BaseMana{ get{ return 15; } }
|
||||
public override double AccuracyScalar{ get{ return 0.75; } }
|
||||
public override int AccuracyBonus{ get{ return -25; } }
|
||||
|
||||
public override bool OnBeforeSwing( Mobile attacker, Mobile defender )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -38,6 +38,16 @@ namespace Server.Items
|
|||
return false;
|
||||
}*/
|
||||
|
||||
public override bool RequiresTactics( Mobile from )
|
||||
{
|
||||
BaseWeapon weapon = from.Weapon as BaseWeapon;
|
||||
|
||||
if ( weapon == null )
|
||||
return true;
|
||||
|
||||
return weapon.Skill != SkillName.Wrestling;
|
||||
}
|
||||
|
||||
public override bool OnBeforeSwing( Mobile attacker, Mobile defender )
|
||||
{
|
||||
if( defender.Paralyzed )
|
||||
|
|
|
|||
|
|
@ -16,6 +16,11 @@ namespace Server.Items
|
|||
public override int BaseMana{ get{ return 20; } }
|
||||
public override double DamageScalar{ get{ return 1.25; } }
|
||||
|
||||
public override bool RequiresTactics( Mobile from )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool CheckSkills( Mobile from )
|
||||
{
|
||||
if ( !base.CheckSkills( from ) )
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ namespace Server.Items
|
|||
{
|
||||
public virtual int BaseMana{ get{ return 0; } }
|
||||
|
||||
public virtual double AccuracyScalar{ get{ return 1.0; } }
|
||||
public virtual int AccuracyBonus{ get{ return 0; } }
|
||||
public virtual double DamageScalar{ get{ return 1.0; } }
|
||||
|
||||
public virtual bool RequiresSE { get { return false; } }
|
||||
|
|
@ -35,6 +35,11 @@ namespace Server.Items
|
|||
return true;
|
||||
}
|
||||
|
||||
public virtual bool RequiresTactics( Mobile from )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual double GetRequiredSkill( Mobile from )
|
||||
{
|
||||
BaseWeapon weapon = from.Weapon as BaseWeapon;
|
||||
|
|
@ -87,6 +92,13 @@ namespace Server.Items
|
|||
|
||||
Skill skill = from.Skills[weapon.Skill];
|
||||
double reqSkill = GetRequiredSkill( from );
|
||||
bool reqTactics = Core.ML && RequiresTactics( from );
|
||||
|
||||
if ( Core.ML && reqTactics && from.Skills[SkillName.Tactics].Base < reqSkill )
|
||||
{
|
||||
from.SendLocalizedMessage( 1079308, reqSkill.ToString() ); // You need ~1_SKILL_REQUIREMENT~ weapon and tactics skill to perform that attack
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( skill != null && skill.Base >= reqSkill )
|
||||
return true;
|
||||
|
|
@ -96,7 +108,14 @@ namespace Server.Items
|
|||
return true;
|
||||
/* </UBWS> */
|
||||
|
||||
from.SendLocalizedMessage( 1060182, reqSkill.ToString() ); // You need ~1_SKILL_REQUIREMENT~ weapon skill to perform that attack
|
||||
if ( reqTactics )
|
||||
{
|
||||
from.SendLocalizedMessage( 1079308, reqSkill.ToString() ); // You need ~1_SKILL_REQUIREMENT~ weapon and tactics skill to perform that attack
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage( 1060182, reqSkill.ToString() ); // You need ~1_SKILL_REQUIREMENT~ weapon skill to perform that attack
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -160,6 +179,11 @@ namespace Server.Items
|
|||
from.SendLocalizedMessage( 1063024 ); // You cannot perform this special move right now.
|
||||
return false;
|
||||
}
|
||||
if ( Core.ML && from.Spell != null )
|
||||
{
|
||||
from.SendLocalizedMessage( 1063024 ); // You cannot perform this special move right now.
|
||||
return false;
|
||||
}
|
||||
|
||||
return CheckSkills( from ) && CheckMana( from, false );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -750,9 +750,6 @@ namespace Server.Items
|
|||
double atkValue = atkWeapon.GetAttackSkillValue( attacker, defender );
|
||||
double defValue = defWeapon.GetDefendSkillValue( attacker, defender );
|
||||
|
||||
//attacker.CheckSkill( atkSkill.SkillName, defValue - 20.0, 120.0 );
|
||||
//defender.CheckSkill( defSkill.SkillName, atkValue - 20.0, 120.0 );
|
||||
|
||||
double ourValue, theirValue;
|
||||
|
||||
int bonus = GetHitChanceBonus();
|
||||
|
|
@ -765,12 +762,7 @@ namespace Server.Items
|
|||
if ( defValue <= -20.0 )
|
||||
defValue = -19.9;
|
||||
|
||||
// Hit Chance Increase = 45%
|
||||
int atkChance = AosAttributes.GetValue( attacker, AosAttribute.AttackChance );
|
||||
if ( atkChance > 45 )
|
||||
atkChance = 45;
|
||||
|
||||
bonus += atkChance;
|
||||
bonus += AosAttributes.GetValue( attacker, AosAttribute.AttackChance );
|
||||
|
||||
if ( Spells.Chivalry.DivineFurySpell.UnderEffect( attacker ) )
|
||||
bonus += 10; // attacker gets 10% bonus when they're under divine fury
|
||||
|
|
@ -781,13 +773,24 @@ namespace Server.Items
|
|||
if ( HitLower.IsUnderAttackEffect( attacker ) )
|
||||
bonus -= 25; // Under Hit Lower Attack effect -> 25% malus
|
||||
|
||||
ourValue = (atkValue + 20.0) * (100 + bonus);
|
||||
WeaponAbility ability = WeaponAbility.GetCurrentAbility( attacker );
|
||||
|
||||
// Defense Chance Increase = 45%
|
||||
bonus = AosAttributes.GetValue( defender, AosAttribute.DefendChance );
|
||||
if ( ability != null )
|
||||
bonus += ability.AccuracyBonus;
|
||||
|
||||
SpecialMove move = SpecialMove.GetCurrentMove( attacker );
|
||||
|
||||
if ( move != null )
|
||||
bonus += move.GetAccuracyBonus( attacker );
|
||||
|
||||
// Max Hit Chance Increase = 45%
|
||||
if ( bonus > 45 )
|
||||
bonus = 45;
|
||||
|
||||
ourValue = (atkValue + 20.0) * (100 + bonus);
|
||||
|
||||
bonus = AosAttributes.GetValue( defender, AosAttribute.DefendChance );
|
||||
|
||||
if ( Spells.Chivalry.DivineFurySpell.UnderEffect( defender ) )
|
||||
bonus -= 20; // defender loses 20% bonus when they're under divine fury
|
||||
|
||||
|
|
@ -810,6 +813,10 @@ namespace Server.Items
|
|||
if ( SkillHandlers.Discordance.GetEffect( attacker, ref discordanceEffect ) )
|
||||
bonus -= discordanceEffect;
|
||||
|
||||
// Defense Chance Increase = 45%
|
||||
if ( bonus > 45 )
|
||||
bonus = 45;
|
||||
|
||||
theirValue = (defValue + 20.0) * (100 + bonus);
|
||||
|
||||
bonus = 0;
|
||||
|
|
@ -833,19 +840,7 @@ namespace Server.Items
|
|||
if ( Core.AOS && chance < 0.02 )
|
||||
chance = 0.02;
|
||||
|
||||
WeaponAbility ability = WeaponAbility.GetCurrentAbility( attacker );
|
||||
|
||||
if ( ability != null )
|
||||
chance *= ability.AccuracyScalar;
|
||||
|
||||
SpecialMove move = SpecialMove.GetCurrentMove( attacker );
|
||||
|
||||
if ( move != null )
|
||||
chance *= move.GetAccuracyScalar( attacker );
|
||||
|
||||
return attacker.CheckSkill( atkSkill.SkillName, chance );
|
||||
|
||||
//return ( chance >= Utility.RandomDouble() );
|
||||
}
|
||||
|
||||
public virtual TimeSpan GetDelay( Mobile m )
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@ namespace Server.Items
|
|||
{
|
||||
public class MagicWand : BaseBashing
|
||||
{
|
||||
public override WeaponAbility PrimaryAbility { get { return WeaponAbility.Dismount; } }
|
||||
public override WeaponAbility SecondaryAbility { get { return WeaponAbility.Disarm; } }
|
||||
|
||||
public override int AosStrengthReq{ get{ return 5; } }
|
||||
public override int AosMinDamage{ get{ return 9; } }
|
||||
public override int AosMaxDamage{ get{ return 11; } }
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ namespace Server
|
|||
}
|
||||
|
||||
#region Dragon Barding
|
||||
if( (!Core.AOS || from == null || !from.Player) && m.Player && m.Mount is SwampDragon )
|
||||
if( (from == null || !from.Player) && m.Player && m.Mount is SwampDragon )
|
||||
{
|
||||
SwampDragon pet = m.Mount as SwampDragon;
|
||||
|
||||
|
|
|
|||
|
|
@ -281,6 +281,16 @@ namespace Server.Misc
|
|||
if ( master != null && master.AccessLevel > AccessLevel.Player )
|
||||
return Notoriety.CanBeAttacked;
|
||||
|
||||
master = bc.ControlMaster;
|
||||
|
||||
if ( Core.ML && master != null )
|
||||
{
|
||||
if( source == master && CheckAggressor( target.Aggressors, source ) )
|
||||
return Notoriety.CanBeAttacked;
|
||||
else
|
||||
return MobileNotoriety( source, master );
|
||||
}
|
||||
|
||||
if( !bc.Summoned && !bc.Controlled && ((PlayerMobile)source).EnemyOfOneType == target.GetType() )
|
||||
return Notoriety.Enemy;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ namespace Server.Misc
|
|||
|
||||
CheckBonusSkill( from, from.Mana, from.ManaMax, SkillName.Focus );
|
||||
|
||||
double focusPoints = (int)(from.Skills[SkillName.Focus].Value * 0.05);
|
||||
double focusPoints = (from.Skills[SkillName.Focus].Value * 0.05);
|
||||
|
||||
if ( armorPenalty > 0 )
|
||||
medPoints = 0; // In AOS, wearing any meditation-blocking armor completely removes meditation bonus
|
||||
|
|
@ -154,7 +154,10 @@ namespace Server.Misc
|
|||
if ( totalPoints < -1 )
|
||||
totalPoints = -1;
|
||||
|
||||
rate = 1.0 / (0.1 * (2 + (int)totalPoints));
|
||||
if ( Core.ML )
|
||||
totalPoints = Math.Floor( totalPoints );
|
||||
|
||||
rate = 1.0 / (0.1 * (2 + totalPoints));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ namespace Server.Mobiles
|
|||
Timer.DelayCall( TimeSpan.Zero, delegate { Hue = GetHue(); } );
|
||||
|
||||
if( version <= 1 )
|
||||
Timer.DelayCall( TimeSpan.Zero, delegate { InternalItem.Hue = this.Hue; } );
|
||||
Timer.DelayCall( TimeSpan.Zero, delegate { if( InternalItem != null ) { InternalItem.Hue = this.Hue; } } );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,12 +118,26 @@ namespace Server.Mobiles
|
|||
|
||||
public override double GetControlChance( Mobile m, bool useBaseSkill )
|
||||
{
|
||||
double tamingChance = base.GetControlChance( m, useBaseSkill );
|
||||
|
||||
if( tamingChance >= 0.95 )
|
||||
{
|
||||
return tamingChance;
|
||||
}
|
||||
|
||||
double skill = (useBaseSkill? m.Skills.Bushido.Base : m.Skills.Bushido.Value);
|
||||
|
||||
if( skill >= 90.0 )
|
||||
return 1.0;
|
||||
if( skill < 90.0 )
|
||||
{
|
||||
return tamingChance;
|
||||
}
|
||||
|
||||
return base.GetControlChance( m, useBaseSkill );
|
||||
double bushidoChance = ( skill - 30.0 ) / 100;
|
||||
|
||||
if( m.Skills.Bushido.Base >= 120 )
|
||||
bushidoChance += 0.05;
|
||||
|
||||
return bushidoChance > tamingChance ? bushidoChance : tamingChance;
|
||||
}
|
||||
|
||||
public override int TreasureMapLevel { get { return 3; } }
|
||||
|
|
@ -217,7 +231,7 @@ namespace Server.Mobiles
|
|||
Timer.DelayCall( TimeSpan.Zero, delegate { Hue = GetHue(); } );
|
||||
|
||||
if( version <= 1 )
|
||||
Timer.DelayCall( TimeSpan.Zero, delegate { InternalItem.Hue = this.Hue; } );
|
||||
Timer.DelayCall( TimeSpan.Zero, delegate { if( InternalItem != null ) { InternalItem.Hue = this.Hue; } } );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ namespace Server.Mobiles
|
|||
if ( pack != null )
|
||||
pack.Delete();
|
||||
|
||||
pack = new StrongBackpack();
|
||||
pack = new Backpack();
|
||||
pack.Movable = false;
|
||||
|
||||
AddItem( pack );
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ namespace Server.Mobiles
|
|||
|
||||
public override bool BardImmune{ get{ return !Core.SE; } }
|
||||
public override bool Unprovokable{ get{ return Core.SE; } }
|
||||
public override bool Uncalmable{ get{ return Core.SE; } }
|
||||
public override bool AreaPeaceImmune { get { return Core.SE; } }
|
||||
public override Poison PoisonImmune{ get{ return Poison.Lethal; } }
|
||||
public override int TreasureMapLevel{ get{ return 1; } }
|
||||
|
||||
|
|
|
|||
|
|
@ -50,8 +50,9 @@ namespace Server.Mobiles
|
|||
AddLoot( LootPack.FilthyRich, 8 );
|
||||
}
|
||||
|
||||
public override bool Unprovokable{ get{ return true; } }
|
||||
public override bool Uncalmable{ get{ return true; } }
|
||||
public override bool BardImmune { get { return !Core.SE; } }
|
||||
public override bool Unprovokable { get { return Core.SE; } }
|
||||
public override bool AreaPeaceImmune { get { return Core.SE; } }
|
||||
public override Poison PoisonImmune{ get{ return Poison.Lethal; } }
|
||||
public override int TreasureMapLevel{ get{ return 1; } }
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ namespace Server.Mobiles
|
|||
|
||||
public override bool BardImmune{ get{ return !Core.SE; } }
|
||||
public override bool Unprovokable{ get{ return Core.SE; } }
|
||||
public override bool Uncalmable{ get{ return Core.SE; } }
|
||||
public override bool AreaPeaceImmune { get { return Core.SE; } }
|
||||
public override bool BleedImmune{ get{ return true; } }
|
||||
public override Poison PoisonImmune{ get{ return Poison.Lethal; } }
|
||||
public override Poison HitPoison{ get{ return Poison.Lethal; } }
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ namespace Server.Mobiles
|
|||
|
||||
public override bool BardImmune{ get{ return !Core.SE; } }
|
||||
public override bool Unprovokable{ get{ return Core.SE; } }
|
||||
public override bool Uncalmable{ get{ return Core.SE; } }
|
||||
public override bool AreaPeaceImmune { get { return Core.SE; } }
|
||||
public override Poison PoisonImmune{ get{ return Poison.Lethal; } }
|
||||
|
||||
public override int TreasureMapLevel{ get{ return 1; } }
|
||||
|
|
|
|||
|
|
@ -63,8 +63,9 @@ namespace Server.Mobiles
|
|||
}
|
||||
|
||||
public override bool AutoDispel{ get{ return true; } }
|
||||
public override bool Unprovokable{ get{ return true; } }
|
||||
public override bool Uncalmable{ get{ return true; } }
|
||||
public override bool BardImmune { get { return !Core.SE; } }
|
||||
public override bool Unprovokable { get { return Core.SE; } }
|
||||
public override bool AreaPeaceImmune { get { return Core.SE; } }
|
||||
public override Poison PoisonImmune{ get{ return Poison.Lethal; } }
|
||||
|
||||
public override int TreasureMapLevel{ get{ return 1; } }
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ namespace Server.Mobiles
|
|||
public override bool AutoDispel{ get{ return true; } }
|
||||
public override bool BardImmune{ get{ return !Core.SE; } }
|
||||
public override bool Unprovokable{ get{ return Core.SE; } }
|
||||
public override bool Uncalmable{ get{ return Core.SE; } }
|
||||
public override bool AreaPeaceImmune { get { return Core.SE; } }
|
||||
public override Poison PoisonImmune{ get{ return Poison.Lethal; } }
|
||||
public override Poison HitPoison{ get{ return (0.8 >= Utility.RandomDouble() ? Poison.Greater : Poison.Deadly); } }
|
||||
|
||||
|
|
|
|||
|
|
@ -167,7 +167,9 @@ namespace Server.Mobiles
|
|||
base.OnThink();
|
||||
}
|
||||
|
||||
public override bool BardImmune{ get{ return true; } }
|
||||
public override bool BardImmune{ get{ return !Core.SE; } }
|
||||
public override bool Unprovokable{ get{ return Core.SE; } }
|
||||
public override bool AreaPeaceImmune{ get{ return Core.SE; } }
|
||||
public override Poison PoisonImmune{ get{ return Poison.Lethal; } }
|
||||
|
||||
public override int TreasureMapLevel{ get{ return 1; } }
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ namespace Server.Mobiles
|
|||
|
||||
public override bool IsBondable{ get{ return false; } }
|
||||
|
||||
public override FoodType FavoriteFood { get { return FoodType.None; } }
|
||||
|
||||
[Constructable]
|
||||
public Golem() : this( false, 1.0 )
|
||||
{
|
||||
|
|
@ -81,7 +83,7 @@ namespace Server.Mobiles
|
|||
PackItem( new Gears() );
|
||||
}
|
||||
|
||||
ControlSlots = 4;
|
||||
ControlSlots = 3;
|
||||
}
|
||||
|
||||
public override bool DeleteOnRelease{ get{ return true; } }
|
||||
|
|
|
|||
|
|
@ -131,20 +131,40 @@ namespace Server.Mobiles
|
|||
|
||||
List<ResistanceMod> mods = new List<ResistanceMod>();
|
||||
|
||||
if ( defender.PhysicalResistance > 0 )
|
||||
mods.Add( new ResistanceMod( ResistanceType.Physical, (defender.PhysicalResistance > 70) ? -70 : -defender.PhysicalResistance ) );
|
||||
if ( Core.ML )
|
||||
{
|
||||
if ( defender.PhysicalResistance > 0 )
|
||||
mods.Add( new ResistanceMod( ResistanceType.Physical, defender.PhysicalResistance / 2 ) );
|
||||
|
||||
if ( defender.FireResistance > 0 )
|
||||
mods.Add( new ResistanceMod( ResistanceType.Fire, (defender.FireResistance > 70) ? -70 : -defender.FireResistance ) );
|
||||
if ( defender.FireResistance > 0 )
|
||||
mods.Add( new ResistanceMod( ResistanceType.Fire, defender.FireResistance / 2 ) );
|
||||
|
||||
if ( defender.ColdResistance > 0 )
|
||||
mods.Add( new ResistanceMod( ResistanceType.Cold, (defender.ColdResistance > 70) ? -70 : -defender.ColdResistance ) );
|
||||
if ( defender.ColdResistance > 0 )
|
||||
mods.Add( new ResistanceMod( ResistanceType.Cold, defender.ColdResistance / 2 ) );
|
||||
|
||||
if ( defender.PoisonResistance > 0 )
|
||||
mods.Add( new ResistanceMod( ResistanceType.Poison, (defender.PoisonResistance > 70) ? -70 : -defender.PoisonResistance ) );
|
||||
if ( defender.PoisonResistance > 0 )
|
||||
mods.Add( new ResistanceMod( ResistanceType.Poison, defender.PoisonResistance / 2 ) );
|
||||
|
||||
if ( defender.EnergyResistance > 0 )
|
||||
mods.Add( new ResistanceMod( ResistanceType.Energy, (defender.EnergyResistance > 70) ? -70 : -defender.EnergyResistance ) );
|
||||
if ( defender.EnergyResistance > 0 )
|
||||
mods.Add( new ResistanceMod( ResistanceType.Energy, defender.EnergyResistance / 2 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( defender.PhysicalResistance > 0 )
|
||||
mods.Add( new ResistanceMod( ResistanceType.Physical, (defender.PhysicalResistance > 70) ? -70 : -defender.PhysicalResistance ) );
|
||||
|
||||
if ( defender.FireResistance > 0 )
|
||||
mods.Add( new ResistanceMod( ResistanceType.Fire, (defender.FireResistance > 70) ? -70 : -defender.FireResistance ) );
|
||||
|
||||
if ( defender.ColdResistance > 0 )
|
||||
mods.Add( new ResistanceMod( ResistanceType.Cold, (defender.ColdResistance > 70) ? -70 : -defender.ColdResistance ) );
|
||||
|
||||
if ( defender.PoisonResistance > 0 )
|
||||
mods.Add( new ResistanceMod( ResistanceType.Poison, (defender.PoisonResistance > 70) ? -70 : -defender.PoisonResistance ) );
|
||||
|
||||
if ( defender.EnergyResistance > 0 )
|
||||
mods.Add( new ResistanceMod( ResistanceType.Energy, (defender.EnergyResistance > 70) ? -70 : -defender.EnergyResistance ) );
|
||||
}
|
||||
|
||||
for ( int i = 0; i < mods.Count; ++i )
|
||||
defender.AddResistanceMod( mods[i] );
|
||||
|
|
|
|||
|
|
@ -105,7 +105,22 @@ namespace Server.Mobiles
|
|||
|
||||
private int m_GuildMessageHue, m_AllianceMessageHue;
|
||||
|
||||
private List<Mobile> m_AutoStabled;
|
||||
private List<Mobile> m_AllFollowers;
|
||||
|
||||
#region Getters & Setters
|
||||
public List<Mobile> AutoStabled { get { return m_AutoStabled; } }
|
||||
|
||||
public List<Mobile> AllFollowers
|
||||
{
|
||||
get
|
||||
{
|
||||
if( m_AllFollowers == null )
|
||||
m_AllFollowers = new List<Mobile>();;
|
||||
return m_AllFollowers;
|
||||
}
|
||||
}
|
||||
|
||||
public Server.Guilds.RankDefinition GuildRank
|
||||
{
|
||||
get
|
||||
|
|
@ -516,7 +531,11 @@ namespace Server.Mobiles
|
|||
}
|
||||
|
||||
from.SendGump( new NoticeGump( 1060637, 30720, notice, 0xFFC000, 300, 140, null, null ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if( from is PlayerMobile )
|
||||
((PlayerMobile)from).ClaimAutoStabledPets();
|
||||
}
|
||||
|
||||
private bool m_NoDeltaRecursion;
|
||||
|
|
@ -768,6 +787,8 @@ namespace Server.Mobiles
|
|||
|
||||
private static void OnLogout( LogoutEventArgs e )
|
||||
{
|
||||
if( e.Mobile is PlayerMobile )
|
||||
((PlayerMobile)e.Mobile).AutoStablePets();
|
||||
}
|
||||
|
||||
private static void EventSink_Connected( ConnectedEventArgs e )
|
||||
|
|
@ -989,6 +1010,9 @@ namespace Server.Mobiles
|
|||
strBase = this.Str; //this.Str already includes GetStatOffset/str
|
||||
strOffs = AosAttributes.GetValue( this, AosAttribute.BonusHits );
|
||||
|
||||
if ( Core.ML && strOffs > 25 )
|
||||
strOffs = 25;
|
||||
|
||||
if ( AnimalForm.UnderTransformation( this, typeof( BakeKitsune ) ) || AnimalForm.UnderTransformation( this, typeof( GreyWolf ) ) )
|
||||
strOffs += 20;
|
||||
}
|
||||
|
|
@ -1998,6 +2022,7 @@ namespace Server.Mobiles
|
|||
private TimeSpan m_LongTermElapse;
|
||||
private DateTime m_SessionStart;
|
||||
private DateTime m_LastEscortTime;
|
||||
private DateTime m_LastPetBallTime;
|
||||
private DateTime m_NextSmithBulkOrder;
|
||||
private DateTime m_NextTailorBulkOrder;
|
||||
private DateTime m_SavagePaintExpiration;
|
||||
|
|
@ -2072,8 +2097,17 @@ namespace Server.Mobiles
|
|||
set{ m_LastEscortTime = value; }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public DateTime LastPetBallTime
|
||||
{
|
||||
get{ return m_LastPetBallTime; }
|
||||
set{ m_LastPetBallTime = value; }
|
||||
}
|
||||
|
||||
public PlayerMobile()
|
||||
{
|
||||
m_AutoStabled = new List<Mobile>();
|
||||
|
||||
m_VisList = new List<Mobile>();
|
||||
m_PermaFlags = new List<Mobile>();
|
||||
m_AntiMacroTable = new Hashtable();
|
||||
|
|
@ -2260,6 +2294,9 @@ namespace Server.Mobiles
|
|||
if ( target is BaseCreature && ((BaseCreature)target).InitialInnocent && !((BaseCreature)target).Controlled )
|
||||
return false;
|
||||
|
||||
if ( Core.ML && target is BaseCreature && ((BaseCreature)target).Controlled && this == ((BaseCreature)target).ControlMaster )
|
||||
return false;
|
||||
|
||||
return base.IsHarmfulCriminal( target );
|
||||
}
|
||||
|
||||
|
|
@ -2319,6 +2356,11 @@ namespace Server.Mobiles
|
|||
|
||||
switch ( version )
|
||||
{
|
||||
case 26:
|
||||
{
|
||||
m_AutoStabled = reader.ReadStrongMobileList();
|
||||
goto case 25;
|
||||
}
|
||||
case 25:
|
||||
{
|
||||
int recipeCount = reader.ReadInt();
|
||||
|
|
@ -2520,6 +2562,8 @@ namespace Server.Mobiles
|
|||
}
|
||||
case 0:
|
||||
{
|
||||
if( version < 26 )
|
||||
m_AutoStabled = new List<Mobile>();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -2598,7 +2642,9 @@ namespace Server.Mobiles
|
|||
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 25 ); // version
|
||||
writer.Write( (int) 26 ); // version
|
||||
|
||||
writer.Write( m_AutoStabled, true );
|
||||
|
||||
if( m_AcquiredRecipes == null )
|
||||
{
|
||||
|
|
@ -3855,5 +3901,99 @@ namespace Server.Mobiles
|
|||
m_BuffTable = null;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public void AutoStablePets()
|
||||
{
|
||||
if ( Core.SE && AllFollowers.Count > 0 )
|
||||
{
|
||||
for ( int i = 0; i < m_AllFollowers.Count; ++i )
|
||||
{
|
||||
BaseCreature pet = AllFollowers[i] as BaseCreature;
|
||||
|
||||
if ( pet == null || pet.ControlMaster == null || ( pet.Summoned && !Core.ML ) )
|
||||
continue;
|
||||
|
||||
if ( pet is IMount && ((IMount)pet).Rider != null )
|
||||
continue;
|
||||
|
||||
if ( (pet is PackLlama || pet is PackHorse || pet is Beetle || pet is HordeMinionFamiliar) && (pet.Backpack != null && pet.Backpack.Items.Count > 0) )
|
||||
continue;
|
||||
|
||||
if ( !pet.Summoned && !pet.IsBonded )
|
||||
continue;
|
||||
|
||||
pet.ControlTarget = null;
|
||||
pet.ControlOrder = OrderType.Stay;
|
||||
pet.Internalize();
|
||||
|
||||
pet.SetControlMaster( null );
|
||||
pet.SummonMaster = null;
|
||||
|
||||
pet.IsStabled = true;
|
||||
|
||||
pet.Loyalty = BaseCreature.MaxLoyalty; // Wonderfully happy
|
||||
|
||||
Stabled.Add( pet );
|
||||
m_AutoStabled.Add( pet );
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ClaimAutoStabledPets()
|
||||
{
|
||||
if( !Core.SE || m_AutoStabled.Count <= 0 )
|
||||
return;
|
||||
|
||||
if( !Alive )
|
||||
{
|
||||
SendLocalizedMessage( 1076251 ); // Your pet was unable to join you while you are a ghost. Please re-login once you have ressurected to claim your pets.
|
||||
return;
|
||||
}
|
||||
|
||||
for ( int i = 0; i < m_AutoStabled.Count; ++i )
|
||||
{
|
||||
BaseCreature pet = m_AutoStabled[i] as BaseCreature;
|
||||
|
||||
if ( pet == null || pet.Deleted )
|
||||
{
|
||||
pet.IsStabled = false;
|
||||
m_AutoStabled.RemoveAt( i );
|
||||
if( Stabled.Contains( pet ) )
|
||||
Stabled.Remove( pet );
|
||||
--i;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( (Followers + pet.ControlSlots) <= FollowersMax )
|
||||
{
|
||||
m_AutoStabled.RemoveAt( i );
|
||||
--i;
|
||||
|
||||
pet.SetControlMaster( this );
|
||||
|
||||
if ( pet.Summoned )
|
||||
pet.SummonMaster = this;
|
||||
|
||||
pet.ControlTarget = this;
|
||||
pet.ControlOrder = OrderType.Follow;
|
||||
|
||||
pet.MoveToWorld( Location, Map );
|
||||
|
||||
pet.IsStabled = false;
|
||||
|
||||
pet.Loyalty = BaseCreature.MaxLoyalty; // Wonderfully Happy
|
||||
|
||||
if( Stabled.Contains( pet ) )
|
||||
Stabled.Remove( pet );
|
||||
}
|
||||
else
|
||||
{
|
||||
SendMessage( 1049612, pet.Name ); // ~1_NAME~ remained in the stables because you have too many followers.
|
||||
}
|
||||
}
|
||||
|
||||
m_AutoStabled.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -332,7 +332,7 @@ namespace Server.Mobiles
|
|||
{
|
||||
pm.SendLocalizedMessage( 1053004 ); // You must wait about a day before you can gain in compassion again.
|
||||
}
|
||||
else if ( VirtueHelper.Award( pm, VirtueName.Compassion, 200, ref gainedPath ) )
|
||||
else if ( VirtueHelper.Award( pm, VirtueName.Compassion, this.IsPrisoner ? 400 : 200, ref gainedPath ) )
|
||||
{
|
||||
if ( gainedPath )
|
||||
pm.SendLocalizedMessage( 1053005 ); // You have achieved a path in compassion!
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ namespace Server.Multis
|
|||
|
||||
public override void AddComponents()
|
||||
{
|
||||
BaseCreature bc;
|
||||
|
||||
IronGate gate = new IronGate( DoorFacing.EastCCW );
|
||||
m_Gate = gate;
|
||||
|
||||
|
|
@ -46,6 +48,8 @@ namespace Server.Multis
|
|||
case 1: m_Prisoner = new SeekerOfAdventure(); break;
|
||||
}
|
||||
|
||||
bc = (BaseCreature)m_Prisoner;
|
||||
bc.IsPrisoner = true;
|
||||
m_Prisoner.YellHue = Utility.RandomList( 0x57, 0x67, 0x77, 0x87, 0x117 );
|
||||
|
||||
AddMobile( m_Prisoner, 2, -2, 0, 0 );
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ namespace Server.Multis
|
|||
|
||||
public override void AddComponents()
|
||||
{
|
||||
BaseCreature bc;
|
||||
|
||||
IronGate gate = new IronGate( DoorFacing.EastCCW );
|
||||
m_Gate = gate;
|
||||
|
||||
|
|
@ -46,6 +48,8 @@ namespace Server.Multis
|
|||
case 1: m_Prisoner = new SeekerOfAdventure(); break;
|
||||
}
|
||||
|
||||
bc = (BaseCreature)m_Prisoner;
|
||||
bc.IsPrisoner = true;
|
||||
m_Prisoner.YellHue = Utility.RandomList( 0x57, 0x67, 0x77, 0x87, 0x117 );
|
||||
|
||||
AddMobile( m_Prisoner, 2, -2, 0, 0 );
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ namespace Server.SkillHandlers
|
|||
|
||||
public static void ScaleSkills( BaseCreature bc, double scalar )
|
||||
{
|
||||
int totalCapIncrease = 0;
|
||||
int totalCapIncrease = Core.SE ? 2000 : 0; // 2000 points for GM Anatomy and Meditation
|
||||
|
||||
for ( int i = 0; i < bc.Skills.Length; ++i )
|
||||
{
|
||||
|
|
@ -246,7 +246,7 @@ namespace Server.SkillHandlers
|
|||
m_Creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 502796, m_Tamer.NetState ); // You are dead, and cannot continue taming.
|
||||
Stop();
|
||||
}
|
||||
else if ( !m_Tamer.CanSee( m_Creature ) || !m_Tamer.InLOS( m_Creature ) )
|
||||
else if ( !m_Tamer.CanSee( m_Creature ) || !m_Tamer.InLOS( m_Creature ) || !CanPath() )
|
||||
{
|
||||
m_BeingTamed.Remove( m_Creature );
|
||||
m_Tamer.NextSkillTime = DateTime.Now;
|
||||
|
|
@ -356,6 +356,21 @@ namespace Server.SkillHandlers
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool CanPath()
|
||||
{
|
||||
IPoint3D p = m_Tamer as IPoint3D;
|
||||
|
||||
if ( p == null )
|
||||
return false;
|
||||
|
||||
if( m_Creature.InRange( new Point3D( p ), 1 ) )
|
||||
return true;
|
||||
|
||||
MovementPath path = new MovementPath( m_Creature, new Point3D( p ) );
|
||||
|
||||
return path.Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,12 +23,17 @@ namespace Server.SkillHandlers
|
|||
|
||||
public static TimeSpan OnUse( Mobile m )
|
||||
{
|
||||
if ( m.Target != null || m.Spell != null )
|
||||
if ( m.Spell != null )
|
||||
{
|
||||
m.SendLocalizedMessage( 501238 ); // You are busy doing something else and cannot hide.
|
||||
return TimeSpan.FromSeconds( 1.0 );
|
||||
}
|
||||
|
||||
if ( Core.ML && m.Target != null )
|
||||
{
|
||||
Targeting.Target.Cancel( m );
|
||||
}
|
||||
|
||||
double bonus = 0.0;
|
||||
|
||||
BaseHouse house = BaseHouse.FindHouseAt( m );
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ namespace Server.SkillHandlers
|
|||
|
||||
foreach ( Mobile m in from.GetMobilesInRange( range ) )
|
||||
{
|
||||
if ( (m is BaseCreature && ((BaseCreature)m).Uncalmable) || m == from || !from.CanBeHarmful( m, false ) )
|
||||
if ((m is BaseCreature && ((BaseCreature)m).Uncalmable) || (m is BaseCreature && ((BaseCreature)m).AreaPeaceImmune) || m == from || !from.CanBeHarmful ( m, false ))
|
||||
continue;
|
||||
|
||||
calmed = true;
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ namespace Server.Spells
|
|||
public virtual bool BlockedByAnimalForm{ get{ return true; } }
|
||||
public virtual bool DelayedContext{ get{ return false; } }
|
||||
|
||||
public virtual double GetAccuracyScalar( Mobile attacker )
|
||||
public virtual int GetAccuracyBonus( Mobile attacker )
|
||||
{
|
||||
return 1.0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public virtual double GetDamageScalar( Mobile attacker, Mobile defender )
|
||||
|
|
|
|||
|
|
@ -532,6 +532,9 @@ namespace Server.Spells
|
|||
if ( ClearHandsOnCast )
|
||||
m_Caster.ClearHands();
|
||||
|
||||
if ( Core.ML )
|
||||
WeaponAbility.ClearCurrentAbility( m_Caster );
|
||||
|
||||
m_CastTimer = new CastTimer( this, castDelay );
|
||||
m_CastTimer.Start();
|
||||
|
||||
|
|
|
|||
|
|
@ -18,14 +18,6 @@ namespace Server.Spells.Bushido
|
|||
|
||||
public override TextDefinition AbilityMessage{ get{ return new TextDefinition( 1063122 ); } } // You better kill your enemy with your next hit or you'll be rather sorry...
|
||||
|
||||
public override double GetAccuracyScalar( Mobile attacker )
|
||||
{
|
||||
double bushido = attacker.Skills[SkillName.Bushido].Value;
|
||||
|
||||
// TODO: 4 -> Perfection / 5
|
||||
return 1.0 + ( bushido / 10.0 + 4 ) / 100.0;
|
||||
}
|
||||
|
||||
public override double GetDamageScalar( Mobile attacker, Mobile defender )
|
||||
{
|
||||
double bushido = attacker.Skills[SkillName.Bushido].Value;
|
||||
|
|
|
|||
|
|
@ -20,12 +20,9 @@ namespace Server.Spells.Bushido
|
|||
|
||||
public override bool DelayedContext{ get{ return true; } }
|
||||
|
||||
public override double GetAccuracyScalar( Mobile attacker )
|
||||
public override int GetAccuracyBonus( Mobile attacker )
|
||||
{
|
||||
if ( GetContext( attacker, typeof( Bushido.LightningStrike ) ) )
|
||||
return 1.1;
|
||||
|
||||
return 1.5;
|
||||
return 50;
|
||||
}
|
||||
|
||||
public override bool IgnoreArmor( Mobile attacker )
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ namespace Server.Spells.Bushido
|
|||
|
||||
public override bool CheckCast()
|
||||
{
|
||||
int mana = ScaleMana ( RequiredMana );
|
||||
|
||||
if ( !base.CheckCast() )
|
||||
return false;
|
||||
|
||||
|
|
@ -56,9 +58,9 @@ namespace Server.Spells.Bushido
|
|||
Caster.SendLocalizedMessage( 1063013, args ); // You need at least ~1_SKILL_REQUIREMENT~ ~2_SKILL_NAME~ skill to use that ability.
|
||||
return false;
|
||||
}
|
||||
else if ( Caster.Mana < ScaleMana( RequiredMana ) )
|
||||
else if ( Caster.Mana < mana )
|
||||
{
|
||||
Caster.SendLocalizedMessage( 1060174, RequiredMana.ToString() ); // You must have at least ~1_MANA_REQUIREMENT~ Mana to use this ability.
|
||||
Caster.SendLocalizedMessage( 1060174, mana.ToString() ); // You must have at least ~1_MANA_REQUIREMENT~ Mana to use this ability.
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ namespace Server.Spells.Chivalry
|
|||
|
||||
m_Table[Caster] = t = Timer.DelayCall( TimeSpan.FromSeconds( delay ), new TimerStateCallback( Expire_Callback ), Caster );
|
||||
Caster.Delta( MobileDelta.WeaponDamage );
|
||||
|
||||
BuffInfo.AddBuff(Caster, new BuffInfo(BuffIcon.DivineFury, 1060589, 1075634, TimeSpan.FromSeconds(delay), Caster));
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
|
|
|
|||
|
|
@ -56,6 +56,8 @@ namespace Server.Spells.Chivalry
|
|||
{
|
||||
((PlayerMobile)Caster).EnemyOfOneType = null;
|
||||
((PlayerMobile)Caster).WaitingForEnemy = true;
|
||||
|
||||
BuffInfo.AddBuff ( Caster, new BuffInfo ( BuffIcon.EnemyOfOne, 1075653, 1044111, TimeSpan.FromMinutes ( delay ), Caster ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ namespace Server.Spells.Chivalry
|
|||
|
||||
public override bool CheckCast()
|
||||
{
|
||||
int mana = ScaleMana( RequiredMana );
|
||||
|
||||
if ( !base.CheckCast() )
|
||||
return false;
|
||||
|
||||
|
|
@ -39,9 +41,9 @@ namespace Server.Spells.Chivalry
|
|||
Caster.SendLocalizedMessage( 1060173, RequiredTithing.ToString() ); // You must have at least ~1_TITHE_REQUIREMENT~ Tithing Points to use this ability,
|
||||
return false;
|
||||
}
|
||||
else if ( Caster.Mana < ScaleMana( RequiredMana ) )
|
||||
else if ( Caster.Mana < mana )
|
||||
{
|
||||
Caster.SendLocalizedMessage( 1060174, RequiredMana.ToString() ); // You must have at least ~1_MANA_REQUIREMENT~ Mana to use this ability.
|
||||
Caster.SendLocalizedMessage( 1060174, mana.ToString() ); // You must have at least ~1_MANA_REQUIREMENT~ Mana to use this ability.
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -69,7 +71,7 @@ namespace Server.Spells.Chivalry
|
|||
}
|
||||
else if ( Caster.Mana < mana )
|
||||
{
|
||||
Caster.SendLocalizedMessage( 1060174, RequiredMana.ToString() ); // You must have at least ~1_MANA_REQUIREMENT~ Mana to use this ability.
|
||||
Caster.SendLocalizedMessage( 1060174, mana.ToString() ); // You must have at least ~1_MANA_REQUIREMENT~ Mana to use this ability.
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -86,12 +86,16 @@ namespace Server.Spells.Chivalry
|
|||
CorpseSkinSpell.RemoveCurse( m );
|
||||
CurseSpell.RemoveEffect( m );
|
||||
MortalStrike.EndWound( m );
|
||||
if (Core.ML) { BloodOathSpell.RemoveCurse ( m ); }
|
||||
MindRotSpell.ClearMindRotScalar ( m );
|
||||
|
||||
BuffInfo.RemoveBuff( m, BuffIcon.Clumsy );
|
||||
BuffInfo.RemoveBuff( m, BuffIcon.FeebleMind );
|
||||
BuffInfo.RemoveBuff( m, BuffIcon.Weaken );
|
||||
BuffInfo.RemoveBuff ( m, BuffIcon.Curse );
|
||||
BuffInfo.RemoveBuff( m, BuffIcon.MassCurse );
|
||||
BuffInfo.RemoveBuff( m, BuffIcon.MortalStrike );
|
||||
BuffInfo.RemoveBuff ( m, BuffIcon.Mindrot );
|
||||
|
||||
// TODO: Should this remove blood oath? Pain spike?
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,6 +79,11 @@ namespace Server.Spells.First
|
|||
|
||||
for ( int i = 0; i < mods.Length; ++i )
|
||||
targ.AddResistanceMod( mods[i] );
|
||||
|
||||
int physresist = 15 + (int)(targ.Skills[SkillName.Inscribe].Value / 20);
|
||||
string args = String.Format("{0}\t{1}\t{2}\t{3}\t{4}", physresist, 5, 5, 5, 5);
|
||||
|
||||
BuffInfo.AddBuff(Caster, new BuffInfo(BuffIcon.ReactiveArmor, 1075812, 1075813, args.ToString()));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -89,6 +94,8 @@ namespace Server.Spells.First
|
|||
|
||||
for ( int i = 0; i < mods.Length; ++i )
|
||||
targ.RemoveResistanceMod( mods[i] );
|
||||
|
||||
BuffInfo.RemoveBuff(Caster, BuffIcon.ReactiveArmor);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -75,6 +75,13 @@ namespace Server.Spells.Fourth
|
|||
|
||||
m.FixedParticles( 0x374A, 10, 15, 5028, EffectLayer.Waist );
|
||||
m.PlaySound( 0x1EA );
|
||||
|
||||
int percentage = (int)(SpellHelper.GetOffsetScalar(Caster, m, true) * 100);
|
||||
TimeSpan length = SpellHelper.GetDuration(Caster, m);
|
||||
|
||||
string args = String.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}", percentage, percentage, percentage, 10, 10, 10, 10);
|
||||
|
||||
BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Curse, 1075835, 1075836, length, m, args.ToString()));
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
|
|
|
|||
|
|
@ -58,6 +58,10 @@ namespace Server.Spells.Necromancy
|
|||
* ((ss-rm)/8)+8
|
||||
*/
|
||||
|
||||
ExpireTimer timer = (ExpireTimer)m_Table[m];
|
||||
if ( timer != null )
|
||||
timer.DoExpire();
|
||||
|
||||
m_OathTable[Caster] = Caster;
|
||||
m_OathTable[m] = Caster;
|
||||
|
||||
|
|
@ -72,13 +76,32 @@ namespace Server.Spells.Necromancy
|
|||
TimeSpan duration = TimeSpan.FromSeconds( ((GetDamageSkill( Caster ) - GetResistSkill( m )) / 8) + 8 );
|
||||
m.CheckSkill( SkillName.MagicResist, 0.0, 120.0 ); //Skill check for gain
|
||||
|
||||
new ExpireTimer( Caster, m, duration ).Start();
|
||||
timer = new ExpireTimer ( Caster, m, duration );
|
||||
timer.Start ();
|
||||
|
||||
BuffInfo.AddBuff ( Caster, new BuffInfo ( BuffIcon.BloodOathCaster, 1075659, duration, Caster, m.Name.ToString () ) );
|
||||
BuffInfo.AddBuff ( m, new BuffInfo ( BuffIcon.BloodOathCurse, 1075661, duration, m, Caster.Name.ToString () ) );
|
||||
|
||||
m_Table[m] = timer;
|
||||
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
}
|
||||
|
||||
public static bool RemoveCurse( Mobile m )
|
||||
{
|
||||
ExpireTimer t = (ExpireTimer)m_Table[m];
|
||||
|
||||
if ( t == null )
|
||||
return false;
|
||||
|
||||
t.DoExpire();
|
||||
return true;
|
||||
}
|
||||
|
||||
private static Hashtable m_OathTable = new Hashtable();
|
||||
private static Hashtable m_Table = new Hashtable ();
|
||||
|
||||
public static Mobile GetBloodOath( Mobile m )
|
||||
{
|
||||
|
|
@ -112,15 +135,24 @@ namespace Server.Spells.Necromancy
|
|||
{
|
||||
if ( m_Caster.Deleted || m_Target.Deleted || !m_Caster.Alive || !m_Target.Alive || DateTime.Now >= m_End )
|
||||
{
|
||||
m_Caster.SendLocalizedMessage( 1061620 ); // Your Blood Oath has been broken.
|
||||
m_Target.SendLocalizedMessage( 1061620 ); // Your Blood Oath has been broken.
|
||||
|
||||
m_OathTable.Remove( m_Caster );
|
||||
m_OathTable.Remove( m_Target );
|
||||
|
||||
Stop();
|
||||
DoExpire ();
|
||||
}
|
||||
}
|
||||
public void DoExpire()
|
||||
{
|
||||
m_Caster.SendLocalizedMessage( 1061620 ); // Your Blood Oath has been broken.
|
||||
m_Target.SendLocalizedMessage( 1061620 ); // Your Blood Oath has been broken.
|
||||
|
||||
m_OathTable.Remove ( m_Caster );
|
||||
m_OathTable.Remove ( m_Target );
|
||||
|
||||
Stop ();
|
||||
|
||||
BuffInfo.RemoveBuff ( m_Caster, BuffIcon.BloodOathCaster );
|
||||
BuffInfo.RemoveBuff ( m_Target, BuffIcon.BloodOathCurse );
|
||||
|
||||
m_Table.Remove ( m_Caster );
|
||||
}
|
||||
}
|
||||
|
||||
private class InternalTarget : Target
|
||||
|
|
|
|||
|
|
@ -66,56 +66,42 @@ namespace Server.Spells.Necromancy
|
|||
|
||||
public static void ClearMindRotScalar( Mobile m )
|
||||
{
|
||||
m_Table.Remove( m );
|
||||
if (!m_Table.ContainsKey(m))
|
||||
return;
|
||||
|
||||
BuffInfo.RemoveBuff( m, BuffIcon.Mindrot );
|
||||
MRBucket tmpB = (MRBucket)m_Table[m];
|
||||
MRExpireTimer tmpT = (MRExpireTimer)tmpB.m_MRExpireTimer;
|
||||
tmpT.Stop();
|
||||
m_Table.Remove(m);
|
||||
m.SendLocalizedMessage(1060872); // Your mind feels normal again.
|
||||
}
|
||||
|
||||
public static bool HasMindRotScalar( Mobile m )
|
||||
{
|
||||
return m_Table.Contains( m );
|
||||
return m_Table.ContainsKey(m);
|
||||
}
|
||||
|
||||
public static bool GetMindRotScalar( Mobile m, ref double scalar )
|
||||
{
|
||||
object obj = m_Table[m];
|
||||
|
||||
if ( obj == null )
|
||||
if (!m_Table.ContainsKey(m))
|
||||
return false;
|
||||
|
||||
scalar = (double)obj;
|
||||
MRBucket tmpB = (MRBucket)m_Table[m];
|
||||
scalar = tmpB.m_Scalar;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void SetMindRotScalar( Mobile caster, Mobile target, double scalar, TimeSpan duration )
|
||||
{
|
||||
m_Table[target] = scalar;
|
||||
BuffInfo.AddBuff( target, new BuffInfo( BuffIcon.Mindrot, 1075665, duration, target ) );
|
||||
new ExpireTimer( caster, target, duration ).Start();
|
||||
}
|
||||
|
||||
private class ExpireTimer : Timer
|
||||
{
|
||||
private Mobile m_Caster;
|
||||
private Mobile m_Target;
|
||||
private DateTime m_End;
|
||||
|
||||
public ExpireTimer( Mobile caster, Mobile target, TimeSpan delay ) : base( TimeSpan.FromSeconds( 1.0 ), TimeSpan.FromSeconds( 1.0 ) )
|
||||
if (!m_Table.ContainsKey(target))
|
||||
{
|
||||
m_Caster = caster;
|
||||
m_Target = target;
|
||||
m_End = DateTime.Now + delay;
|
||||
|
||||
Priority = TimerPriority.TwoFiftyMS;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if ( m_Target.Deleted || !m_Target.Alive || DateTime.Now >= m_End )
|
||||
{
|
||||
m_Target.SendLocalizedMessage( 1060872 ); // Your mind feels normal again.
|
||||
ClearMindRotScalar( m_Target );
|
||||
Stop();
|
||||
}
|
||||
m_Table.Add(target, new MRBucket(scalar, new MRExpireTimer(caster, target, duration)));
|
||||
BuffInfo.AddBuff(target, new BuffInfo(BuffIcon.Mindrot, 1075665, duration, target));
|
||||
MRBucket tmpB = (MRBucket)m_Table[target];
|
||||
MRExpireTimer tmpT = (MRExpireTimer)tmpB.m_MRExpireTimer;
|
||||
tmpT.Start();
|
||||
target.SendLocalizedMessage(1074384);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -142,4 +128,50 @@ namespace Server.Spells.Necromancy
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class MRExpireTimer : Timer
|
||||
{
|
||||
private Mobile m_Caster;
|
||||
private Mobile m_Target;
|
||||
private DateTime m_End;
|
||||
|
||||
public MRExpireTimer( Mobile caster, Mobile target, TimeSpan delay ) : base( TimeSpan.FromSeconds( 1.0 ), TimeSpan.FromSeconds( 1.0 ) )
|
||||
{
|
||||
m_Caster = caster;
|
||||
m_Target = target;
|
||||
m_End = DateTime.Now + delay;
|
||||
Priority = TimerPriority.TwoFiftyMS;
|
||||
}
|
||||
|
||||
public void RenewDelay(TimeSpan delay)
|
||||
{
|
||||
m_End = DateTime.Now + delay;
|
||||
}
|
||||
|
||||
public void Halt()
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if ( m_Target.Deleted || !m_Target.Alive || DateTime.Now >= m_End )
|
||||
{
|
||||
MindRotSpell.ClearMindRotScalar( m_Target );
|
||||
Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class MRBucket
|
||||
{
|
||||
public MRBucket(double theScalar, MRExpireTimer theTimer)
|
||||
{
|
||||
m_Scalar = theScalar;
|
||||
m_MRExpireTimer = theTimer;
|
||||
}
|
||||
|
||||
public double m_Scalar;
|
||||
public MRExpireTimer m_MRExpireTimer;
|
||||
}
|
||||
}
|
||||
|
|
@ -74,9 +74,7 @@ namespace Server.Spells.Necromancy
|
|||
new InternalTimer( m, damage ).Start();
|
||||
}
|
||||
|
||||
BuffInfo.AddBuff( m, new BuffInfo( BuffIcon.PainSpike, 1075667, buffTime, m, (int)damage ) );
|
||||
|
||||
|
||||
BuffInfo.AddBuff( m, new BuffInfo( BuffIcon.PainSpike, 1075667, buffTime, m, Convert.ToString( (int)damage ) ) );
|
||||
|
||||
Misc.WeightOverloading.DFA = Misc.DFAlgorithm.PainSpike;
|
||||
m.Damage( (int) damage, Caster );
|
||||
|
|
|
|||
|
|
@ -49,6 +49,13 @@ namespace Server.Spells.Necromancy
|
|||
Effects.PlaySound( m.Location, m.Map, 0x229 );
|
||||
|
||||
double damage = Utility.RandomMinMax( (Core.ML ? 32 : 36), 40 ) * ((300 + (GetDamageSkill( Caster ) * 9)) / 1000);
|
||||
|
||||
double sdiBonus = (double)AosAttributes.GetValue( Caster, AosAttribute.SpellDamage )/100;
|
||||
double pvmDamage = damage * (1 + sdiBonus);
|
||||
|
||||
if ( Core.ML && sdiBonus > 0.15 )
|
||||
sdiBonus = 0.15;
|
||||
double pvpDamage = damage * (1 + sdiBonus);
|
||||
|
||||
Map map = m.Map;
|
||||
|
||||
|
|
@ -57,7 +64,7 @@ namespace Server.Spells.Necromancy
|
|||
List<Mobile> targets = new List<Mobile>();
|
||||
|
||||
foreach( Mobile targ in m.GetMobilesInRange( 2 ) )
|
||||
if( (Caster == targ || SpellHelper.ValidIndirectTarget( Caster, targ )) && Caster.CanBeHarmful( targ, false ) )
|
||||
if( (Caster == targ || m == targ || SpellHelper.ValidIndirectTarget( Caster, targ )) && Caster.CanBeHarmful( targ, false ) )
|
||||
targets.Add( targ );
|
||||
|
||||
for( int i = 0; i < targets.Count; ++i )
|
||||
|
|
@ -74,7 +81,7 @@ namespace Server.Spells.Necromancy
|
|||
num = 3;
|
||||
|
||||
Caster.DoHarmful( targ );
|
||||
SpellHelper.Damage( this, targ, damage / num, 0, 0, 0, 100, 0 );
|
||||
SpellHelper.Damage( this, targ, ((m.Player && Caster.Player) ? pvpDamage : pvmDamage) / num, 0, 0, 0, 100, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -135,6 +135,9 @@ namespace Server.Spells.Ninjitsu
|
|||
// This bonus is 8 at most. That brings the cap up to 70/30.
|
||||
damage += info.m_DamageBonus;
|
||||
|
||||
if ( info.m_Attacker.Weapon is BaseWeapon && ((BaseWeapon)info.m_Attacker.Weapon).MaxRange > 1 )
|
||||
damage /= 2;
|
||||
|
||||
// Damage is direct.
|
||||
//info.m_Target.Damage( damage, info.m_Attacker );
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@ namespace Server.Spells.Ninjitsu
|
|||
|
||||
public override bool CheckCast()
|
||||
{
|
||||
int mana = ScaleMana( RequiredMana );
|
||||
|
||||
if ( !base.CheckCast() )
|
||||
return false;
|
||||
|
||||
|
|
@ -58,9 +60,9 @@ namespace Server.Spells.Ninjitsu
|
|||
Caster.SendLocalizedMessage( 1063013, args ); // You need at least ~1_SKILL_REQUIREMENT~ ~2_SKILL_NAME~ skill to use that ability.
|
||||
return false;
|
||||
}
|
||||
else if ( Caster.Mana < ScaleMana( RequiredMana ) )
|
||||
else if ( Caster.Mana < mana )
|
||||
{
|
||||
Caster.SendLocalizedMessage( 1060174, RequiredMana.ToString() ); // You must have at least ~1_MANA_REQUIREMENT~ Mana to use this ability.
|
||||
Caster.SendLocalizedMessage( 1060174, mana.ToString() ); // You must have at least ~1_MANA_REQUIREMENT~ Mana to use this ability.
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,8 +49,8 @@ namespace Server.Spells.Second
|
|||
public static void Toggle( Mobile caster, Mobile target )
|
||||
{
|
||||
/* Players under the protection spell effect can no longer have their spells "disrupted" when hit.
|
||||
* Players under the protection spell have decreased physical resistance stat value,
|
||||
* a decreased "resisting spells" skill value by -35,
|
||||
* Players under the protection spell have decreased physical resistance stat value (-15 + (Inscription/20),
|
||||
* a decreased "resisting spells" skill value by -35 + (Inscription/20),
|
||||
* and a slower casting speed modifier (technically, a negative "faster cast speed") of 2 points.
|
||||
* The protection spell has an indefinite duration, becoming active when cast, and deactivated when re-cast.
|
||||
* Reactive Armor, Protection, and Magic Reflection will stay on—even after logging out,
|
||||
|
|
@ -75,6 +75,11 @@ namespace Server.Spells.Second
|
|||
|
||||
target.AddResistanceMod( (ResistanceMod)mods[0] );
|
||||
target.AddSkillMod( (SkillMod)mods[1] );
|
||||
|
||||
int physloss = -15 + (int) (caster.Skills[SkillName.Inscribe].Value / 20);
|
||||
int resistloss = -35 + (int) (caster.Skills[SkillName.Inscribe].Value / 20);
|
||||
string args = String.Format("{0}\t{1}", physloss, resistloss);
|
||||
BuffInfo.AddBuff(target, new BuffInfo(BuffIcon.Protection, 1075814, 1075815, args.ToString()));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -86,6 +91,8 @@ namespace Server.Spells.Second
|
|||
|
||||
target.RemoveResistanceMod( (ResistanceMod)mods[0] );
|
||||
target.RemoveSkillMod( (SkillMod)mods[1] );
|
||||
|
||||
BuffInfo.RemoveBuff(target, BuffIcon.Protection);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ namespace Server.Spells.Spellweaving
|
|||
|
||||
public virtual bool CheckResisted( Mobile m )
|
||||
{
|
||||
double percent = (50 + 2*(GetResistSkill( m ) - GetDamageSkill( m )))/100; //TODO: According to the guide this is it.. but.. is it correct per OSI?
|
||||
double percent = (50 + 2*(GetResistSkill( m ) - GetDamageSkill( Caster )))/100; //TODO: According to the guide this is it.. but.. is it correct per OSI?
|
||||
|
||||
if( percent <= 0 )
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -70,6 +70,13 @@ namespace Server.Spells.Spellweaving
|
|||
{
|
||||
Caster.SendLocalizedMessage( 501942 ); // That location is blocked.
|
||||
}
|
||||
|
||||
//say "Target can not be seen" if you target directly a mobile, like in OSI
|
||||
if (m != null)
|
||||
{
|
||||
Caster.SendLocalizedMessage(500237); // Target can not be seen.
|
||||
}
|
||||
|
||||
else if( SpellHelper.CheckTown( p, Caster ) && (m_MobileTarg ? CheckHSequence( m ) : CheckSequence()) )
|
||||
{
|
||||
TimeSpan duration = TimeSpan.FromSeconds( Caster.Skills.Spellweaving.Value/24 + 25 + FocusLevel*2 );
|
||||
|
|
|
|||
|
|
@ -27,8 +27,22 @@ namespace Server.Spells.Spellweaving
|
|||
{
|
||||
Caster.PlaySound( 0x5CE );
|
||||
|
||||
double skill = Caster.Skills[SkillName.Spellweaving].Value;
|
||||
|
||||
int damage = Math.Max( 11, 10 + (int)(skill / 24) ) + FocusLevel;
|
||||
|
||||
int sdiBonus = AosAttributes.GetValue( Caster, AosAttribute.SpellDamage );
|
||||
|
||||
int pvmDamage = damage * ( 100 + sdiBonus );
|
||||
pvmDamage /= 100;
|
||||
|
||||
if ( sdiBonus > 15 )
|
||||
sdiBonus = 15;
|
||||
|
||||
int pvpDamage = damage * ( 100 + sdiBonus );
|
||||
pvpDamage /= 100;
|
||||
|
||||
int range = 2 + FocusLevel;
|
||||
int damage = 15 + FocusLevel;
|
||||
TimeSpan duration = TimeSpan.FromSeconds( 5 + FocusLevel );
|
||||
|
||||
List<Mobile> targets = new List<Mobile>();
|
||||
|
|
@ -47,7 +61,7 @@ namespace Server.Spells.Spellweaving
|
|||
|
||||
Spell oldSpell = m.Spell as Spell;
|
||||
|
||||
SpellHelper.Damage( this, m, damage, 0, 0, 0, 0, 100 );
|
||||
SpellHelper.Damage( this, m, ( m.Player && Caster.Player ) ? pvpDamage : pvmDamage, 0, 0, 0, 0, 100 );
|
||||
|
||||
if( oldSpell != null && oldSpell != m.Spell )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -41,6 +41,13 @@ namespace Server.Spells.Third
|
|||
|
||||
m.FixedParticles( 0x373A, 10, 15, 5018, EffectLayer.Waist );
|
||||
m.PlaySound( 0x1EA );
|
||||
|
||||
int percentage = (int)(SpellHelper.GetOffsetScalar(Caster, m, true) * 100);
|
||||
TimeSpan length = SpellHelper.GetDuration(Caster, m);
|
||||
|
||||
string args = String.Format("{0}\t{1}\t{2}", percentage, percentage, percentage);
|
||||
|
||||
BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Bless, 1075847, 1075848, length, m, args.ToString()));
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue