- Hit Life Leech now works in PvP

(http://www.uodemise.com/discussion/showthread.php?t=121298)

- Summoned Daemon now has the proper bodyvalue (AoS+) and effect
(http://www.uodemise.com/discussion/showthread.php?t=127404)

- Two new house signs are added
(http://www.uodemise.com/discussion/showthread.php?t=125409)

- Changes to Satyrs and Dryads:
--> Dryads:
----> they do area peace
----> can partially undress males
----> have chance to drop peculiar or fragrant (not yet implemented) seeds
--> Satyrs:
----> their karma is neutral
----> can peace combatants
----> can provoke nearby creatures to the combatant
----> can undress females
----> can discord combatants
--> Both: can drop spellweaving scrolls
(http://www.uodemise.com/discussion/showthread.php?t=125444)

- Added Auto Arrow Recovery feature (SE+)
(http://www.uodemise.com/discussion/showthread.php?t=114807)
This commit is contained in:
daedalus 2009-12-14 19:01:59 +00:00
parent 37043076e0
commit cd7c2becf7
14 changed files with 511 additions and 98 deletions

View file

@ -190,6 +190,8 @@ namespace Server.Gumps
660, 666, 672, 898, 970,
974, 982
};
private static List<int> _HouseSigns = new List<int>();
public HouseGumpAOS( HouseGumpPageAOS page, Mobile from, BaseHouse house ) : base( 50, 40 )
{
@ -486,20 +488,37 @@ namespace Server.Gumps
case HouseGumpPageAOS.ChangeSign:
{
int index = 0;
if ( _HouseSigns.Count == 0 )
{
// Add standard signs
for ( int i = 0; i < 54; ++i )
{
_HouseSigns.Add( 2980 + ( i * 2 ) );
}
// Add library and beekeeper signs ( ML )
_HouseSigns.Add( 2966 );
_HouseSigns.Add( 3140 );
}
int signsPerPage = Core.ML ? 24 : 18;
int totalSigns = Core.ML ? 56 : 54;
int pages = (int) Math.Ceiling( (double) totalSigns / signsPerPage );
for ( int i = 0; i < 3; ++i )
for ( int i = 0; i < pages; ++i )
{
AddPage( i + 1 );
AddButton( 10, 360, 4005, 4007, 0, GumpButtonType.Page, ((i + 1) % 3) + 1 );
AddButton( 10, 360, 4005, 4007, 0, GumpButtonType.Page, ((i + 1) % pages ) + 1 );
for ( int j = 0; j < 18; ++j )
for ( int j = 0; j < signsPerPage && totalSigns - ( signsPerPage * i ) - j > 0; ++j )
{
int x = 30 + ((j % 6) * 60);
int y = 130 + ((j / 6) * 60);
AddButton( x, y, 4005, 4007, GetButtonID( 9, index ), GumpButtonType.Reply, 0 );
AddItem( x + 20, y, 2980 + (index++ * 2) );
AddItem( x + 20, y, _HouseSigns[index++] );
}
}
@ -1305,9 +1324,9 @@ namespace Server.Gumps
}
case 9:
{
if ( isOwner && m_House.Public && index >= 0 && index < 54 )
if ( isOwner && m_House.Public && index >= 0 && index < _HouseSigns.Count )
{
m_House.ChangeSignType( 2980 + (index * 2) );
m_House.ChangeSignType( _HouseSigns[index] );
from.SendGump( new HouseGumpAOS( HouseGumpPageAOS.Customize, from, m_House ) );
}

View file

@ -1011,6 +1011,13 @@ namespace Server.Items
canSwing = ( sp == null || !sp.IsCasting || !sp.BlocksMovement );
}
if ( canSwing )
{
PlayerMobile p = attacker as PlayerMobile;
canSwing = ( p == null || p.PeacedUntil <= DateTime.Now );
}
}
if ( canSwing && attacker.HarmfulCheck( defender ) )

View file

@ -21,6 +21,7 @@ namespace Server.Items
public override SkillName AccuracySkill{ get{ return SkillName.Archery; } }
private Timer m_RecoveryTimer; // so we don't start too many timers
private bool m_Balanced;
private int m_Velocity;
@ -120,7 +121,33 @@ namespace Server.Items
public override void OnMiss( Mobile attacker, Mobile defender )
{
if ( attacker.Player && 0.4 >= Utility.RandomDouble() )
{
if ( Core.SE )
{
PlayerMobile p = attacker as PlayerMobile;
if ( p != null )
{
Type ammo = AmmoType;
if ( p.RecoverableAmmo.ContainsKey( ammo ) )
p.RecoverableAmmo[ ammo ]++;
else
p.RecoverableAmmo.Add( ammo, 1 );
if ( !p.Warmode )
{
if ( m_RecoveryTimer == null )
m_RecoveryTimer = Timer.DelayCall( TimeSpan.FromSeconds( 10 ), new TimerCallback( p.RecoverAmmo ) );
if ( !m_RecoveryTimer.Running )
m_RecoveryTimer.Start();
}
}
}
else
Ammo.MoveToWorld( new Point3D( defender.X + Utility.RandomMinMax( -1, 1 ), defender.Y + Utility.RandomMinMax( -1, 1 ), defender.Z ), defender.Map );
}
base.OnMiss( attacker, defender );
}

View file

@ -224,10 +224,19 @@ namespace Server
private static Type[] m_PaladinScrollTypes = new Type[0];
private static Type[] m_ArcaneScrollTypes = new Type[]
{
typeof( ArcaneCircleScroll ), typeof ( GiftOfRenewalScroll ), typeof( ImmolatingWeaponScroll ), typeof( AttuneWeaponScroll ),
typeof( ThunderstormScroll ), typeof( NatureFuryScroll ), typeof( ReaperFormScroll ), typeof( WildfireScroll ),
typeof( EssenceOfWindScroll ), typeof( DryadAllureScroll ), typeof( EtherealVoyageScroll ), typeof( WordOfDeathScroll ),
typeof( GiftOfLifeScroll ), typeof( ArcaneEmpowermentScroll )
};
public static Type[] RegularScrollTypes{ get{ return m_RegularScrollTypes; } }
public static Type[] NecromancyScrollTypes{ get{ return m_NecromancyScrollTypes; } }
public static Type[] SENecromancyScrollTypes{ get{ return m_SENecromancyScrollTypes; } }
public static Type[] PaladinScrollTypes{ get{ return m_PaladinScrollTypes; } }
public static Type[] ArcaneScrollTypes{ get{ return m_ArcaneScrollTypes; } }
private static Type[] m_GrimmochJournalTypes = new Type[]
{
@ -589,6 +598,7 @@ namespace Server
case SpellbookType.Regular: types = m_RegularScrollTypes; break;
case SpellbookType.Necromancer: types = (Core.SE ? m_SENecromancyScrollTypes : m_NecromancyScrollTypes ); break;
case SpellbookType.Paladin: types = m_PaladinScrollTypes; break;
case SpellbookType.Arcanist: types = m_ArcaneScrollTypes; break;
}
return Construct( types, Utility.RandomMinMax( minIndex, maxIndex ) ) as SpellScroll;

View file

@ -239,6 +239,17 @@ namespace Server
};
#endregion
#region ML definitions
public static readonly LootPack MlRich = new LootPack( new LootPackEntry[]
{
new LootPackEntry( true, Gold, 100.00, "4d50+450" ),
new LootPackEntry( false, AosMagicItemsRichType1, 100.00, 1, 3, 0, 75 ),
new LootPackEntry( false, AosMagicItemsRichType1, 80.00, 1, 3, 0, 75 ),
new LootPackEntry( false, AosMagicItemsRichType1, 60.00, 1, 5, 0, 100 ),
new LootPackEntry( false, Instruments, 1.00, 1 )
} );
#endregion
#region SE definitions
public static readonly LootPack SePoor = new LootPack( new LootPackEntry[]
{

View file

@ -1222,6 +1222,9 @@ namespace Server.Mobiles
if ( m_ReceivedHonorContext != null )
m_ReceivedHonorContext.OnTargetDamaged( from, amount );
if ( willKill && from is PlayerMobile )
Timer.DelayCall( TimeSpan.FromSeconds( 10 ), new TimerCallback( ((PlayerMobile) from).RecoverAmmo ) );
base.OnDamage( amount, from, willKill );
}
@ -3507,6 +3510,14 @@ namespace Server.Mobiles
PackItem( Loot.RandomPotion() );
}
public void PackArcanceScroll( double chance )
{
if ( !Core.ML || chance <= Utility.RandomDouble() )
return;
PackItem( Loot.Construct( Loot.ArcaneScrollTypes ) );
}
public void PackNecroScroll( int index )
{
if ( !Core.AOS || 0.05 <= Utility.RandomDouble() )

View file

@ -106,7 +106,8 @@ namespace Server
typeof( Silvani ),
typeof( Unicorn ),
typeof( Wisp ),
typeof( Treefellow )
typeof( Treefellow ),
typeof( MLDryad )
},
new Type[]
{

View file

@ -1,86 +1,160 @@
using System;
using System.Collections;
using Server.Items;
using Server.Targeting;
using Server.Misc;
using Server.Engines.Plants;
namespace Server.Mobiles
{
[CorpseName("a dryad corpse")]
[CorpseName( "a dryad's corpse" )]
public class MLDryad : BaseCreature
{
public override bool InitialInnocent { get { return true; } }
/* VULNERABLE TO FEY SLAYER!
* These creatures should be able to cast Area Peace as
* well as cause Players' armor to drop into their backpack*/
public override WeaponAbility GetWeaponAbility()
public override OppositionGroup OppositionGroup
{
return WeaponAbility.Disrobe;
get { return OppositionGroup.FeyAndUndead; }
}
[Constructable]
public MLDryad()
: base(AIType.AI_Mage, FightMode.Aggressor, 10, 1, 0.2, 0.4) // NEED TO CHECK
public MLDryad() : base( AIType.AI_Mage, FightMode.Evil, 10, 1, 0.2, 0.4 )
{
Name = "a dryad";
Body = 266;
BaseSoundID = 0x57B;
SetStr(132, 149);
SetDex(152, 168);
SetInt(251, 280);
SetStr( 132, 149 );
SetDex( 152, 168 );
SetInt( 251, 280 );
SetHits(304, 321);
SetHits( 304, 321 );
SetDamage(11, 20);
SetDamage( 11, 20 );
SetDamageType(ResistanceType.Physical, 100);
SetDamageType( ResistanceType.Physical, 100 );
SetResistance(ResistanceType.Physical, 40, 50);
SetResistance(ResistanceType.Fire, 15, 25);
SetResistance(ResistanceType.Cold, 40, 45);
SetResistance(ResistanceType.Poison, 30, 40);
SetResistance(ResistanceType.Energy, 25, 35);
SetResistance( ResistanceType.Physical, 40, 50 );
SetResistance( ResistanceType.Fire, 15, 25 );
SetResistance( ResistanceType.Cold, 40, 45 );
SetResistance( ResistanceType.Poison, 30, 40 );
SetResistance( ResistanceType.Energy, 25, 35 );
SetSkill(SkillName.Meditation, 80.9, 89.9);
SetSkill(SkillName.EvalInt, 70.3, 78.7);
SetSkill(SkillName.Magery, 70.7, 75.7);
SetSkill(SkillName.Anatomy, 0);
SetSkill(SkillName.MagicResist, 101.7, 117.1);
SetSkill(SkillName.Tactics, 71.7, 79.8);
SetSkill(SkillName.Wrestling, 72.5, 79.5);
SetSkill( SkillName.Meditation, 80.0, 90.0 );
SetSkill( SkillName.EvalInt, 70.0, 80.0 );
SetSkill( SkillName.Magery, 70.0, 80.0 );
SetSkill( SkillName.Anatomy, 0 );
SetSkill( SkillName.MagicResist, 100.0, 120.0 );
SetSkill( SkillName.Tactics, 70.0, 80.0 );
SetSkill( SkillName.Wrestling, 70.0, 80.0 );
Fame = 5000;
Karma = 5000;
VirtualArmor = 28; // Don't know what it should be
if ( Core.ML && Utility.RandomDouble() < .33 )
PackItem( Engines.Plants.Seed.RandomPeculiarSeed(1) );
if ( Core.ML && Utility.RandomDouble() < .60 )
PackItem( Seed.RandomPeculiarSeed( 1 ) );
PackArcanceScroll( 0.05 );
}
public override void GenerateLoot()
{
AddLoot(LootPack.Rich); // Need to verify
AddLoot( LootPack.MlRich );
}
public override int Meat { get { return 1; } }
public MLDryad(Serial serial) : base(serial)
public override void OnThink()
{
base.OnThink();
AreaPeace();
AreaUndress();
}
#region Area Peace
private DateTime m_NextPeace;
public void AreaPeace()
{
if ( Combatant == null || Deleted || !Alive || m_NextPeace > DateTime.Now || 0.1 < Utility.RandomDouble() )
return;
TimeSpan duration = TimeSpan.FromSeconds( Utility.RandomMinMax( 20, 80 ) );
foreach ( Mobile m in GetMobilesInRange( RangePerception ) )
{
PlayerMobile p = m as PlayerMobile;
if ( IsValidTarget( p ) )
{
p.PeacedUntil = DateTime.Now + duration;
p.SendLocalizedMessage( 1072065 ); // You gaze upon the dryad's beauty, and forget to continue battling!
p.FixedParticles( 0x376A, 1, 20, 0x7F5, EffectLayer.Waist );
p.Combatant = null;
}
}
m_NextPeace = DateTime.Now + TimeSpan.FromSeconds( 10 );
PlaySound( 0x1D3 );
}
public bool IsValidTarget( PlayerMobile m )
{
if ( m != null && m.PeacedUntil < DateTime.Now && !m.Hidden && m.AccessLevel == AccessLevel.Player && CanBeHarmful( m ) )
return true;
return false;
}
#endregion
#region Undress
private DateTime m_NextUndress;
public void AreaUndress()
{
if ( Combatant == null || Deleted || !Alive || m_NextUndress > DateTime.Now || 0.005 < Utility.RandomDouble() )
return;
foreach ( Mobile m in GetMobilesInRange( RangePerception ) )
{
if ( m != null && m.Player && !m.Female && !m.Hidden && m.AccessLevel == AccessLevel.Player && CanBeHarmful( m ) )
{
UndressItem( m, Layer.OuterTorso );
UndressItem( m, Layer.InnerTorso );
UndressItem( m, Layer.MiddleTorso );
UndressItem( m, Layer.Pants );
UndressItem( m, Layer.Shirt );
m.SendLocalizedMessage( 1072197 ); // The dryad's beauty makes your blood race. Your clothing is too confining.
}
}
m_NextUndress = DateTime.Now + TimeSpan.FromMinutes( 1 );
}
public void UndressItem( Mobile m, Layer layer )
{
Item item = m.FindItemOnLayer( layer );
if ( item != null && item.Movable )
m.PlaceInBackpack( item );
}
#endregion
public MLDryad( Serial serial ) : base( serial )
{
}
public override void Serialize(GenericWriter writer)
public override void Serialize( GenericWriter writer )
{
base.Serialize(writer);
writer.Write((int)0);
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize(GenericReader reader)
public override void Deserialize( GenericReader reader )
{
base.Deserialize(reader);
base.Deserialize( reader );
int version = reader.ReadInt();
}
}

View file

@ -1,83 +1,233 @@
using System;
using System.Collections;
using Server.Items;
using Server.Targeting;
using Server.Misc;
using System.Collections.Generic;
namespace Server.Mobiles
{
[CorpseName("a satyr corpse")]
[CorpseName( "a satyr's corpse" )]
public class Satyr : BaseCreature
{
/* These creatures should be able to cast Area Peace as
* well as cause Players' armor to drop into their backpack
*/
public override WeaponAbility GetWeaponAbility()
{
return WeaponAbility.Disrobe;
}
[Constructable]
public Satyr()
: base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4) // NEED TO CHECK
public Satyr() : base( AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4 )
{
Name = "a satyr";
Body = 271;
BaseSoundID = 0x586;
BaseSoundID = 0x586;
SetStr(177, 195);
SetDex(251, 269);
SetInt(153, 170);
SetStr( 177, 195 );
SetDex( 251, 269 );
SetInt( 153, 170 );
SetHits(353, 399);
SetHits( 350, 400 );
SetDamage(13, 24);
SetDamage( 13, 24 );
SetDamageType(ResistanceType.Physical, 100);
SetDamageType( ResistanceType.Physical, 100 );
SetResistance(ResistanceType.Physical, 55, 60);
SetResistance(ResistanceType.Fire, 26, 35);
SetResistance(ResistanceType.Cold, 30, 40);
SetResistance(ResistanceType.Poison, 30, 40);
SetResistance(ResistanceType.Energy, 30, 40);
SetResistance( ResistanceType.Physical, 55, 60 );
SetResistance( ResistanceType.Fire, 25, 35 );
SetResistance( ResistanceType.Cold, 30, 40 );
SetResistance( ResistanceType.Poison, 30, 40 );
SetResistance( ResistanceType.Energy, 30, 40 );
SetSkill(SkillName.Poisoning, 0);
SetSkill(SkillName.Meditation, 0);
SetSkill(SkillName.EvalInt, 0);
SetSkill(SkillName.Magery, 0);
SetSkill(SkillName.Anatomy, 0);
SetSkill(SkillName.MagicResist, 55.3, 64.3);
SetSkill(SkillName.Tactics, 80.1, 99.3);
SetSkill(SkillName.Wrestling, 80.6, 100.0);
SetSkill( SkillName.MagicResist, 55.0, 65.0 );
SetSkill( SkillName.Tactics, 80.0, 100.0 );
SetSkill( SkillName.Wrestling, 80.0, 100.0 );
Fame = 5000;
Karma = -5000;
Karma = 0;
VirtualArmor = 28; // Don't know what it should be
}
PackArcanceScroll( 0.05 );
}
public override void GenerateLoot()
{
AddLoot(LootPack.Rich); // Need to verify
AddLoot( LootPack.MlRich );
}
public override void OnThink()
{
base.OnThink();
Peace( Combatant );
Undress( Combatant );
Suppress( Combatant );
Provoke( Combatant );
}
#region Peace
private DateTime m_NextPeace;
public void Peace( Mobile target )
{
if ( target == null || Deleted || !Alive || m_NextPeace > DateTime.Now || 0.1 < Utility.RandomDouble() )
return;
PlayerMobile p = target as PlayerMobile;
if ( p != null && p.PeacedUntil < DateTime.Now && !p.Hidden && CanBeHarmful( p ) )
{
p.PeacedUntil = DateTime.Now + TimeSpan.FromMinutes( 1 );
p.SendLocalizedMessage( 500616 ); // You hear lovely music, and forget to continue battling!
p.FixedParticles( 0x376A, 1, 32, 0x15BD, EffectLayer.Waist );
p.Combatant = null;
PlaySound( 0x58D );
}
m_NextPeace = DateTime.Now + TimeSpan.FromSeconds( 10 );
}
#endregion
#region Suppress
private static Dictionary<Mobile, Timer> m_Suppressed = new Dictionary<Mobile, Timer>();
private DateTime m_NextSuppress;
public void Suppress( Mobile target )
{
if ( target == null || m_Suppressed.ContainsKey( target ) || Deleted || !Alive || m_NextSuppress > DateTime.Now || 0.1 < Utility.RandomDouble() )
return;
TimeSpan delay = TimeSpan.FromSeconds( Utility.RandomMinMax( 20, 80 ) );
if ( !target.Hidden && CanBeHarmful( target ) )
{
target.SendLocalizedMessage( 1072061 ); // You hear jarring music, suppressing your strength.
for ( int i = 0; i < target.Skills.Length; i++ )
{
Skill s = target.Skills[ i ];
target.AddSkillMod( new TimedSkillMod( s.SkillName, true, s.Base * -0.28, delay ) );
}
int count = (int) Math.Round( delay.TotalSeconds / 1.25 );
Timer timer = new AnimateTimer( target, count );
m_Suppressed.Add( target, timer );
timer.Start();
PlaySound( 0x58C );
}
m_NextSuppress = DateTime.Now + TimeSpan.FromSeconds( 10 );
}
public static void SuppressRemove( Mobile target )
{
if ( target != null && m_Suppressed.ContainsKey( target ) )
{
Timer timer = m_Suppressed[ target ];
if ( timer != null || timer.Running )
timer.Stop();
m_Suppressed.Remove( target );
}
}
private class AnimateTimer : Timer
{
private Mobile m_Owner;
private int m_Count;
public AnimateTimer( Mobile owner, int count ) : base( TimeSpan.Zero, TimeSpan.FromSeconds( 1.25 ) )
{
m_Owner = owner;
m_Count = count;
}
protected override void OnTick()
{
if ( m_Owner.Deleted || !m_Owner.Alive || m_Count-- < 0 )
{
SuppressRemove( m_Owner );
}
else
m_Owner.FixedParticles( 0x376A, 1, 32, 0x15BD, EffectLayer.Waist );
}
}
#endregion
#region Undress
private DateTime m_NextUndress;
public void Undress( Mobile target )
{
if ( target == null || Deleted || !Alive || m_NextUndress > DateTime.Now || 0.005 < Utility.RandomDouble() )
return;
if ( target.Player && target.Female && !target.Hidden && CanBeHarmful( target ) )
{
UndressItem( target, Layer.OuterTorso );
UndressItem( target, Layer.InnerTorso );
UndressItem( target, Layer.MiddleTorso );
UndressItem( target, Layer.Pants );
UndressItem( target, Layer.Shirt );
target.SendLocalizedMessage( 1072196 ); // The satyr's music makes your blood race. Your clothing is too confining.
}
m_NextUndress = DateTime.Now + TimeSpan.FromMinutes( 1 );
}
public void UndressItem( Mobile m, Layer layer )
{
Item item = m.FindItemOnLayer( layer );
if ( item != null && item.Movable )
m.PlaceInBackpack( item );
}
#endregion
#region Provoke
private DateTime m_NextProvoke;
public void Provoke( Mobile target )
{
if ( target == null || Deleted || !Alive || m_NextProvoke > DateTime.Now || 0.05 < Utility.RandomDouble() )
return;
foreach ( Mobile m in GetMobilesInRange( RangePerception ) )
{
if ( m is BaseCreature )
{
BaseCreature c = (BaseCreature) m;
if ( c == this || c == target || c.Unprovokable || c.IsParagon || c.BardProvoked || c.AccessLevel != AccessLevel.Player || !c.CanBeHarmful( target ) )
continue;
c.Provoke( this, target, true );
if ( target.Player )
target.SendLocalizedMessage( 1072062 ); // You hear angry music, and start to fight.
PlaySound( 0x58A );
break;
}
}
m_NextProvoke = DateTime.Now + TimeSpan.FromSeconds( 10 );
}
#endregion
public override int Meat { get { return 1; } }
public Satyr(Serial serial) : base(serial)
public Satyr( Serial serial ) : base( serial )
{
}
public override void Serialize(GenericWriter writer)
public override void Serialize( GenericWriter writer )
{
base.Serialize(writer);
writer.Write((int)0);
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize(GenericReader reader)
public override void Deserialize( GenericReader reader )
{
base.Deserialize(reader);
base.Deserialize( reader );
int version = reader.ReadInt();
}
}

View file

@ -14,7 +14,7 @@ namespace Server.Mobiles
public SummonedDaemon () : base( AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4 )
{
Name = NameList.RandomName( "daemon" );
Body = 9;
Body = Core.AOS ? 10 : 9;
BaseSoundID = 357;
SetStr( 200 );

View file

@ -313,6 +313,62 @@ namespace Server.Mobiles
}
#endregion
#region Auto Arrow Recovery
private Dictionary<Type, int> m_RecoverableAmmo = new Dictionary<Type,int>();
public Dictionary<Type, int> RecoverableAmmo
{
get { return m_RecoverableAmmo; }
}
public void RecoverAmmo()
{
if ( Core.SE && Alive )
{
foreach ( KeyValuePair<Type, int> kvp in m_RecoverableAmmo )
{
if ( kvp.Value > 0 )
{
Item ammo = null;
try
{
ammo = Activator.CreateInstance( kvp.Key ) as Item;
}
catch
{
}
if ( ammo != null )
{
string name = ammo.Name;
ammo.Amount = kvp.Value;
if ( name == null )
{
if ( ammo is Arrow )
name = "arrow";
else if ( ammo is Bolt )
name = "bolt";
}
if ( name != null && ammo.Amount > 1 )
name = String.Format( "{0}s", name );
if ( name == null )
name = String.Format( "#{0}", ammo.LabelNumber );
PlaceInBackpack( ammo );
SendLocalizedMessage( 1073504, String.Format( "{0}\t{1}", ammo.Amount, name ) ); // You recover ~1_NUM~ ~2_AMMO~.
}
}
}
m_RecoverableAmmo.Clear();
}
}
#endregion
private DateTime m_AnkhNextUse;
[CommandProperty( AccessLevel.GameMaster )]
@ -322,6 +378,15 @@ namespace Server.Mobiles
set{ m_AnkhNextUse = value; }
}
private DateTime m_PeacedUntil;
[CommandProperty( AccessLevel.GameMaster )]
public DateTime PeacedUntil
{
get { return m_PeacedUntil; }
set { m_PeacedUntil = value; }
}
#region Scroll of Alacrity
private DateTime m_AcceleratedStart;
@ -342,7 +407,6 @@ namespace Server.Mobiles
}
#endregion
public static Direction GetDirection4( Point3D from, Point3D to )
{
int dx = from.X - to.X;
@ -1833,6 +1897,9 @@ namespace Server.Mobiles
if ( m_SentHonorContext != null )
m_SentHonorContext.OnSourceDamaged( from, amount );
if ( willKill && from is PlayerMobile )
Timer.DelayCall( TimeSpan.FromSeconds( 10 ), new TimerCallback( ((PlayerMobile) from).RecoverAmmo ) );
base.OnDamage( amount, from, willKill );
}
@ -1862,6 +1929,12 @@ namespace Server.Mobiles
}
}
public override void OnWarmodeChanged()
{
if ( !Warmode )
Timer.DelayCall( TimeSpan.FromSeconds( 10 ), new TimerCallback( RecoverAmmo ) );
}
private Mobile m_InsuranceAward;
private int m_InsuranceCost;
private int m_InsuranceBonus;
@ -1890,6 +1963,8 @@ namespace Server.Mobiles
if ( m_SentHonorContext != null )
m_SentHonorContext.OnSourceKilled();
RecoverAmmo();
return base.OnBeforeDeath();
}
@ -2417,6 +2492,12 @@ namespace Server.Mobiles
switch ( version )
{
case 28:
{
m_PeacedUntil = reader.ReadDateTime();
goto case 27;
}
case 27:
{
m_AnkhNextUse = reader.ReadDateTime();
@ -2710,8 +2791,9 @@ namespace Server.Mobiles
base.Serialize( writer );
writer.Write( (int) 27 ); // version
writer.Write( (int) 28 ); // version
writer.Write( (DateTime) m_PeacedUntil );
writer.Write( (DateTime) m_AnkhNextUse );
writer.Write( m_AutoStabled, true );

View file

@ -498,6 +498,10 @@ namespace Server.Spells
{
m_Caster.SendLocalizedMessage( 502644 ); // You have not yet recovered from casting a spell.
}
else if ( m_Caster is PlayerMobile && ( (PlayerMobile) m_Caster ).PeacedUntil > DateTime.Now )
{
m_Caster.SendLocalizedMessage( 1072060 ); // You cannot cast a spell while calmed.
}
else if ( m_Caster.Mana >= ScaleMana( GetMana() ) )
{
if ( m_Caster.Spell == null && m_Caster.CheckSpellCast( this ) && CheckCast() && m_Caster.Region.OnBeginSpellCast( m_Caster, this ) )
@ -727,6 +731,11 @@ namespace Server.Spells
m_Caster.SendLocalizedMessage( 502646 ); // You cannot cast a spell while frozen.
DoFizzle();
}
else if ( m_Caster is PlayerMobile && ((PlayerMobile) m_Caster).PeacedUntil > DateTime.Now )
{
m_Caster.SendLocalizedMessage( 1072060 ); // You cannot cast a spell while calmed.
DoFizzle();
}
else if ( CheckFizzle() )
{
m_Caster.Mana -= mana;

View file

@ -987,6 +987,11 @@ namespace Server.Spells
//from.SendMessage(String.Format("You Leeched {0} Mana", manaLeech));
}
}
if ( context != null && context.Type == typeof( VampiricEmbraceSpell ) )
{
from.Hits += AOS.Scale( damageGiven, 20 );
from.PlaySound( 0x44D );
}
}
public static void Heal( int amount, Mobile target, Mobile from )

View file

@ -1,4 +1,6 @@
using System;
using Server.Misc;
using Server.Items;
using Server.Mobiles;
using Server.Network;
using Server.Targeting;
@ -7,6 +9,8 @@ namespace Server.Spells.Eighth
{
public class SummonDaemonSpell : MagerySpell
{
private BaseCreature m_Daemon = new SummonedDaemon();
private static SpellInfo m_Info = new SpellInfo(
"Summon Daemon", "Kal Vas Xen Corp",
269,
@ -41,11 +45,14 @@ namespace Server.Spells.Eighth
public override void OnCast()
{
if ( CheckSequence() )
{
{
TimeSpan duration = TimeSpan.FromSeconds( (2 * Caster.Skills.Magery.Fixed) / 5 );
if ( Core.AOS )
SpellHelper.Summon( new SummonedDaemon(), Caster, 0x216, duration, false, false );
{
SpellHelper.Summon( m_Daemon, Caster, 0x216, duration, false, false );
m_Daemon.FixedParticles(0x3728, 8, 20, 5042, EffectLayer.Head );
}
else
SpellHelper.Summon( new Daemon(), Caster, 0x216, duration, false, false );
}