Bug fix for :

skillcaps and things that exceed it
Possible threading issue
Addition of Generic FindItemsByType  - List<T> findItemsByType<T>()
Change to make polymorph not have a timer and instead a toggle skill
KiAttack no longer works with ranged weapons
Poison strike speed and damage changed
Necro spells now affected by FC
Must have atleast 50 weapon skill if no shield equipped to use Evasion
Stalking bonus capped at 10 + skill/10
Stalking bonus now Clears
Bugfix w/Guilds
Crashguard Exception message moved closer to the top of the file.
Character creation of Pallys and necros using advanced skills now gives skill items 
Honor no longer works on Players
Pre-ML area HitArea attacks nolonger require LoS
Serialization fix for BladeOfTheRighteous
RidingSwipe now has paralyzation immunity as with NerveStrike and ParaBlow
AnkhEast renamed to AnkhNorth
LeggingsOfBane no longer have 510 HP
ElvenWashBasinEastAddon Fixed
AnsellaGryen won't be renamed each time the server Restarts
DiseasedCats are properly named
Localization fixes in DefBlacksmithy
BearMasks/DearMAsks and things that extend from them now can be repaired
This commit is contained in:
asayre 2006-08-19 23:24:47 +00:00
parent c3eb5cebc6
commit ce54fe8635
28 changed files with 1495 additions and 1290 deletions

View file

@ -70,7 +70,7 @@ namespace Server.Commands
private static Type typeofLocalizedStatic = typeof( LocalizedStatic );
private static Type typeofBaseDoor = typeof( BaseDoor );
private static Type typeofAnkhWest = typeof( AnkhWest );
private static Type typeofAnkhEast = typeof( AnkhEast );
private static Type typeofAnkhNorth = typeof( AnkhNorth );
private static Type typeofBeverage = typeof( BaseBeverage );
private static Type typeofLocalizedSign = typeof( LocalizedSign );
private static Type typeofMarkContainer = typeof( MarkContainer );
@ -129,7 +129,7 @@ namespace Server.Commands
item = new LocalizedSign( m_ItemID, labelNumber );
}
else if ( m_Type == typeofAnkhWest || m_Type == typeofAnkhEast )
else if ( m_Type == typeofAnkhWest || m_Type == typeofAnkhNorth )
{
bool bloodied = false;
@ -139,7 +139,7 @@ namespace Server.Commands
if ( m_Type == typeofAnkhWest )
item = new AnkhWest( bloodied );
else
item = new AnkhEast( bloodied );
item = new AnkhNorth( bloodied );
}
else if ( m_Type == typeofMarkContainer )
{

View file

@ -99,6 +99,19 @@ namespace Server.Engines.Craft
return true;
}
private bool IsSpecialClothing( BaseClothing clothing )
{
// Armor repairable but not craftable
if( m_CraftSystem is DefTailoring )
{
return (clothing is BearMask)
|| (clothing is DeerMask);
}
return false;
}
private bool IsSpecialWeapon( BaseWeapon weapon )
{
// Weapons repairable but not craftable
@ -345,7 +358,7 @@ namespace Server.Engines.Craft
toWeaken = 3;
}
if ( m_CraftSystem.CraftItems.SearchForSubclass( clothing.GetType() ) == null )
if ( m_CraftSystem.CraftItems.SearchForSubclass( clothing.GetType() ) == null && !IsSpecialClothing( clothing ))
{
number = (usingDeed) ? 1061136 : 1044277; // That item cannot be repaired. // You cannot repair that item with this type of repair contract.
}

View file

@ -365,10 +365,10 @@ namespace Server.Engines.Craft
index = AddCraft( typeof( ElvenSpellblade ), 1011081, 1031564, 70.0, 120.0, typeof( IronIngot ), 1044036, 14, 1044037 );
SetNeededExpansion( index, Expansion.ML );
index = AddCraft( typeof( AssassinSpike ), 1011081, 1031564, 70.0, 120.0, typeof( IronIngot ), 1044036, 9, 1044037 );
index = AddCraft( typeof( AssassinSpike ), 1011081, 1031565, 70.0, 120.0, typeof( IronIngot ), 1044036, 9, 1044037 );
SetNeededExpansion( index, Expansion.ML );
index = AddCraft( typeof( Leafblade ), 1011081, 1031565, 70.0, 120.0, typeof( IronIngot ), 1044036, 12, 1044037 );
index = AddCraft( typeof( Leafblade ), 1011081, 1031566, 70.0, 120.0, typeof( IronIngot ), 1044036, 12, 1044037 );
SetNeededExpansion( index, Expansion.ML );
index = AddCraft( typeof( RuneBlade ), 1011081, 1031570, 70.0, 120.0, typeof( IronIngot ), 1044036, 15, 1044037 );

View file

@ -111,7 +111,7 @@ namespace Server.Ethics
foreach ( Item item in e.Mobile.GetItemsInRange( 2 ) )
{
if ( item is Items.AnkhEast || item is Items.AnkhWest )
if ( item is Items.AnkhNorth || item is Items.AnkhWest )
{
isNearAnkh = true;
break;

View file

@ -8,7 +8,7 @@ namespace Server.Engines.Quests.Samurai
[Constructable]
public DiseasedCat() : base( AIType.AI_Animal, FightMode.Aggressor, 10, 1, 0.2, 0.4 )
{
Name = "a deseased cat";
Name = "a diseased cat";
Body = 0xC9;
Hue = Utility.RandomAnimalHue();
BaseSoundID = 0x69;
@ -51,6 +51,9 @@ namespace Server.Engines.Quests.Samurai
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
if( Name == "a deseased cat" )
Name = "a diseased cat";
}
}
}

View file

@ -134,5 +134,7 @@ namespace Server.Engines.Quests.Zento
int version = reader.ReadEncodedInt();
}
public override void TurnToTokuno() { }
}
}

View file

@ -149,6 +149,12 @@ namespace Server
return;
}
if( Core.ML && target is PlayerMobile )
{
source.SendLocalizedMessage( 1075614 ); // You cannot honor other players.
return;
}
if ( source.SentHonorContext != null )
source.SentHonorContext.Cancel();

View file

@ -377,7 +377,7 @@ namespace Server.Gumps
int maxLockdowns = house.GetAosMaxLockdowns();
int curLockdowns = house.GetAosCurLockdowns();
int bonusStorage = (int)((house.BonusStorageScalar - 1) * 100);
int bonusStorage = (int)((house.BonusStorageScalar * 100)-100);
if( bonusStorage > 0 )
{

View file

@ -11,7 +11,7 @@ namespace Server.Items
public ElvenWashBasinEastAddon()
{
AddComponent( new AddonComponent( 0x30DF ), 0, 0, 0 );
AddComponent( new AddonComponent( 0x30E0 ), 0, -1, 0 );
AddComponent( new AddonComponent( 0x30E0 ), 0, 1, 0 );
}
public ElvenWashBasinEastAddon( Serial serial ) : base( serial )

View file

@ -18,6 +18,7 @@ namespace Server.Items
{
Hue = 0x4F5;
ArmorAttributes.DurabilityBonus = 100;
this.HitPoints = this.MaxHitPoints = 255; //Cause the Durability bonus and such and the min/max hits as well as all other hits being whole #'s...
Attributes.BonusStam = 8;
Attributes.AttackChance = 20;
}
@ -30,7 +31,7 @@ namespace Server.Items
{
base.Serialize( writer );
writer.Write( (int) 1 );
writer.Write( (int) 2 );
}
public override void Deserialize(GenericReader reader)
@ -39,6 +40,12 @@ namespace Server.Items
int version = reader.ReadInt();
if( version <= 1 )
{
if( this.HitPoints > 255 || this.MaxHitPoints > 255 )
this.HitPoints = this.MaxHitPoints = 255;
}
if ( version < 1 )
{
if ( Hue == 0x559 )

View file

@ -265,24 +265,26 @@ namespace Server.Items
}
}
public class AnkhEast : Item
[TypeAlias( "Server.Items.AnkhEast" )]
public class AnkhNorth : Item
{
private InternalItem m_Item;
[Constructable]
public AnkhEast() : this( false )
public AnkhNorth() : this( false )
{
}
[Constructable]
public AnkhEast( bool bloodied ) : base( bloodied ? 0x1E5D : 0x4 )
public AnkhNorth( bool bloodied ) : base( bloodied ? 0x1E5D : 0x4 )
{
Movable = false;
m_Item = new InternalItem( bloodied, this );
}
public AnkhEast( Serial serial ) : base( serial )
public AnkhNorth( Serial serial )
: base( serial )
{
}
@ -352,9 +354,10 @@ namespace Server.Items
private class InternalItem : Item
{
private AnkhEast m_Item;
private AnkhNorth m_Item;
public InternalItem( bool bloodied, AnkhEast item ) : base( bloodied ? 0x1E5C : 0x5 )
public InternalItem( bool bloodied, AnkhNorth item )
: base( bloodied ? 0x1E5C : 0x5 )
{
Movable = false;
@ -426,7 +429,7 @@ namespace Server.Items
int version = reader.ReadInt();
m_Item = reader.ReadItem() as AnkhEast;
m_Item = reader.ReadItem() as AnkhNorth;
}
}
}

View file

@ -63,9 +63,18 @@ namespace Server.Items
{
int amount = 10 + (int)(10.0 * (attacker.Skills[SkillName.Bushido].Value - 50.0) / 70.0 + 5);
AOS.Damage( defender, attacker, amount, 100, 0, 0, 0, 0 );
AOS.Damage( defender, attacker, amount, 100, 0, 0, 0, 0 );
defender.Paralyze( TimeSpan.FromSeconds( 3.0 ) );
if( Server.Items.ParalyzingBlow.IsImmune( defender ) ) //Does it still do damage?
{
attacker.SendLocalizedMessage( 1070804 ); // Your target resists paralysis.
defender.SendLocalizedMessage( 1070813 ); // You resist paralysis.
}
else
{
defender.Paralyze( TimeSpan.FromSeconds( 3.0 ) );
Server.Items.ParalyzingBlow.BeginImmunity( defender, Server.Items.ParalyzingBlow.FreezeDelayDuration );
}
}
}
}

View file

@ -41,7 +41,7 @@ namespace Server.Items
int version = reader.ReadInt();
if ( Slayer == SlayerName.None )
Slayer = SlayerName.DaemonDismissal;
Slayer = SlayerName.Exorcism;
}
}
}

View file

@ -1389,9 +1389,9 @@ namespace Server.Items
if ( (m_Slayer == SlayerName.Silver || m_Slayer2 == SlayerName.Silver) && context != null && context.Type != typeof( HorrificBeastSpell ) )
factor *= 1.25; // Every necromancer transformation other than horrific beast takes an additional 25% damage
if ( attacker is PlayerMobile )
if ( attacker is PlayerMobile && !(Core.ML && defender is PlayerMobile ))
{
PlayerMobile pmAttacker = (PlayerMobile) attacker;
PlayerMobile pmAttacker = (PlayerMobile) attacker;
if ( pmAttacker.HonorActive && pmAttacker.InRange( defender, 1 ) )
factor *= 1.25;
@ -1797,7 +1797,7 @@ namespace Server.Items
foreach ( Mobile m in from.GetMobilesInRange( 10 ) )
{
if ( from != m && defender != m && SpellHelper.ValidIndirectTarget( from, m ) && from.CanBeHarmful( m, false ) && from.InLOS( m ) )
if ( from != m && defender != m && SpellHelper.ValidIndirectTarget( from, m ) && from.CanBeHarmful( m, false ) && ( !Core.ML || from.InLOS( m ) ) )
list.Add( m );
}

View file

@ -1428,6 +1428,13 @@ namespace Server.Misc
PackItem( new Pitcher( BeverageType.Water ) );
break;
}
case SkillName.Chivalry:
{
if( Core.ML )
PackItem( new BookOfChivalry( (ulong)0x3FF ) );
break;
}
case SkillName.DetectHidden:
{
EquipItem( new Cloak( 0x455 ) );
@ -1570,6 +1577,19 @@ namespace Server.Misc
PackInstrument();
break;
}
case SkillName.Necromancy:
{
if( Core.ML )
{
Container regs = new BagOfNecroReagents( 50 );
PackItem( regs );
regs.LootType = LootType.Regular;
}
break;
}
case SkillName.Ninjitsu:
{
EquipItem( new Hakama( 0x2C3 ) ); //Only ninjas get the hued one.

View file

@ -195,6 +195,10 @@ namespace Server.Misc
try { op.WriteLine( "Items: {0}", World.Items.Count ); }
catch {}
op.WriteLine( "Exception:" );
op.WriteLine( e.Exception );
op.WriteLine();
op.WriteLine( "Clients:" );
try
@ -226,11 +230,6 @@ namespace Server.Misc
{
op.WriteLine( "- Failed" );
}
op.WriteLine();
op.WriteLine( "Exception:" );
op.WriteLine( e.Exception );
}
Console.WriteLine( "done" );

View file

@ -1053,17 +1053,24 @@ namespace Server.Guilds
public bool IsWar( Guild g )
{
if( g == null )
return false;
if( NewGuildSystem )
{
if( FindActiveWar( g ) != null )
return true;
if( Alliance != null && this != Alliance.Leader && Alliance.Leader != null && Alliance.IsMember( this ) )
if( Alliance.Leader.FindActiveWar( g ) != null )
AllianceInfo thisAlliace = this.Alliance;
if( thisAlliace != null && this != thisAlliace.Leader && thisAlliace.Leader != null && thisAlliace.IsMember( this ) )
if( thisAlliace.Leader.FindActiveWar( g ) != null )
return true;
if( g.Alliance != null && g.Alliance.Leader != null && g.Alliance.Leader != g && g.Alliance.IsMember( g ) )
if( FindActiveWar( g.Alliance.Leader ) != null )
AllianceInfo otherAlliance = g.Alliance;
if( otherAlliance != null && otherAlliance.Leader != null && otherAlliance.Leader != g && otherAlliance.IsMember( g ) )
if( FindActiveWar( otherAlliance.Leader ) != null )
return true;
return false;
@ -1206,7 +1213,11 @@ namespace Server.Guilds
}
case 0:
{
Leader = reader.ReadMobile();
m_Leader = reader.ReadMobile();
if( m_Leader is PlayerMobile )
((PlayerMobile)m_Leader).GuildRank = RankDefinition.Leader;
m_Name = reader.ReadString();
m_Abbreviation = reader.ReadString();

View file

@ -16,6 +16,7 @@ namespace Server.Misc
Mobile.DefaultHitsRate = TimeSpan.FromSeconds( 11.0 );
Mobile.DefaultStamRate = TimeSpan.FromSeconds( 7.0 );
Mobile.DefaultManaRate = TimeSpan.FromSeconds( 7.0 );
//TODO: Pub 42 regen limits
Mobile.ManaRegenRateHandler = new RegenRateHandler( Mobile_ManaRegenRate );
@ -65,6 +66,7 @@ namespace Server.Misc
if ( CheckAnimal( from, typeof( Dog ) ) || CheckAnimal( from, typeof( Cat ) ) )
points += from.Skills[SkillName.Ninjitsu].Fixed / 300;
//TODO: What's the new increased rate?
if( Core.ML && from.Race == Race.Human )
points += 2;
@ -82,8 +84,9 @@ namespace Server.Misc
CheckBonusSkill( from, from.Stam, from.StamMax, SkillName.Focus );
int points = AosAttributes.GetValue( from, AosAttribute.RegenStam ) +
(int)(from.Skills[SkillName.Focus].Value * 0.1);
int points =(int)(from.Skills[SkillName.Focus].Value * 0.1);
points += AosAttributes.GetValue( from, AosAttribute.RegenStam );
if ( CheckTransform( from, typeof( VampiricEmbraceSpell ) ) )
points += 15;
@ -124,8 +127,9 @@ namespace Server.Misc
if ( armorPenalty > 0 )
medPoints = 0; // In AOS, wearing any meditation-blocking armor completely removes meditation bonus
double totalPoints = AosAttributes.GetValue( from, AosAttribute.RegenMana ) +
focusPoints + medPoints + (from.Meditating ? (medPoints > 13.0 ? 13.0 : medPoints) : 0.0);
double totalPoints = focusPoints + medPoints + (from.Meditating ? (medPoints > 13.0 ? 13.0 : medPoints) : 0.0);
totalPoints += AosAttributes.GetValue( from, AosAttribute.RegenMana );
if ( CheckTransform( from, typeof( VampiricEmbraceSpell ) ) )
totalPoints += 3;

View file

@ -444,6 +444,7 @@ namespace Server.Multis
public void Refresh()
{
m_DecayTime = DateTime.Now + BoatDecayDelay;
if( m_TillerMan != null )
m_TillerMan.InvalidateProperties();
}
@ -1671,4 +1672,4 @@ namespace Server.Multis
}
}
}
}
}

View file

@ -4,6 +4,7 @@ using Server;
using Server.Gumps;
using Server.Network;
using Server.Spells.Necromancy;
using Server.Spells;
namespace Server.SkillHandlers
{
@ -51,8 +52,6 @@ namespace Server.SkillHandlers
public static double GetStalkingBonus( Mobile tracker, Mobile target )
{
// Note: This is not reset as of publish 35.
TrackingInfo info = null;
m_Table.TryGetValue( tracker, out info );
@ -62,9 +61,17 @@ namespace Server.SkillHandlers
int xDelta = info.m_Location.X - target.X;
int yDelta = info.m_Location.Y - target.Y;
return Math.Sqrt( (xDelta * xDelta) + (yDelta * yDelta) );
double bonus = Math.Sqrt( (xDelta * xDelta) + (yDelta * yDelta) );
m_Table.Remove( tracker ); //Reset as of Pub 40, counting it as bug for Core.SE.
if( Core.ML )
return Math.Min( bonus, 10 + tracker.Skills.Tracking.Value/10 );
return bonus;
}
public static void ClearTrackingInfo( Mobile tracker )
{
m_Table.Remove( tracker );

View file

@ -21,14 +21,28 @@ namespace Server.Spells.Bushido
public override bool CheckCast()
{
if ( Caster.FindItemOnLayer( Layer.TwoHanded ) as BaseShield != null )
if( Caster.FindItemOnLayer( Layer.TwoHanded ) as BaseShield != null )
return base.CheckCast();
if ( Caster.FindItemOnLayer( Layer.OneHanded ) as BaseWeapon != null )
return base.CheckCast();
//Intentional having a Shield check override all.
BaseWeapon weap = Caster.FindItemOnLayer( Layer.OneHanded ) as BaseWeapon;
if( weap == null )
weap = Caster.FindItemOnLayer( Layer.TwoHanded ) as BaseWeapon;
if( weap != null )
{
if( Core.ML && Caster.Skills[weap.Skill].Value < 50 )
{
//Does UBW affect this?
Caster.SendLocalizedMessage( 1076206 ); // Your skill with your equipped weapon must be 50 or higher to use Evasion.
return false;
}
if ( Caster.FindItemOnLayer( Layer.TwoHanded ) as BaseWeapon != null )
return base.CheckCast();
}
Caster.SendLocalizedMessage( 1062944 ); // You must have a weapon or a shield equipped to use this ability!
return false;

View file

@ -13,7 +13,7 @@ namespace Server.Spells.Necromancy
public override bool ClearHandsOnCast{ get{ return false; } }
public override int CastDelayFastScalar{ get{ return 0; } } // Necromancer spells are not effected by fast cast items, though they are by fast cast recovery
public override int CastDelayFastScalar{ get{ return (Core.SE? base.CastDelayFastScalar : 0); } } // Necromancer spells are not effected by fast cast items, though they are by fast cast recovery
public NecromancerSpell( Mobile caster, Item scroll, SpellInfo info ) : base( caster, scroll, info )
{

View file

@ -10,7 +10,8 @@ namespace Server.Spells.Necromancy
{
private static SpellInfo m_Info = new SpellInfo(
"Poison Strike", "In Vas Nox",
SpellCircle.Fourth, // 0.5 + 1.0 = 1.5s base cast delay
(Core.ML ? SpellCircle.Fifth : // 0.5 + 1.25 = 1.75s base cast delay
SpellCircle.Fourth), // 0.5 + 1.0 = 1.5s base cast delay
203,
9031,
Reagent.NoxCrystal
@ -46,7 +47,7 @@ namespace Server.Spells.Necromancy
Effects.SendLocationParticles( EffectItem.Create( m.Location, m.Map, EffectItem.DefaultDuration ), 0x36B0, 1, 14, 63, 7, 9915, 0 );
Effects.PlaySound( m.Location, m.Map, 0x229 );
double damage = Utility.RandomMinMax( 36, 40 ) * ((300 + (GetDamageSkill( Caster ) * 9)) / 1000);
double damage = Utility.RandomMinMax( (Core.ML ? 32 : 36), 40 ) * ((300 + (GetDamageSkill( Caster ) * 9)) / 1000);
Map map = m.Map;

View file

@ -37,6 +37,18 @@ namespace Server.Spells.Ninjitsu
return false;
}
if( Core.ML )
{
BaseRanged ranged = from.Weapon as BaseRanged;
if( ranged != null )
{
from.SendLocalizedMessage( 1075858 ); // You can only use this with melee attacks.
return false;
}
}
return base.Validate( from );
}

View file

@ -61,7 +61,10 @@ namespace Server.Spells.Seventh
}
else if ( !Caster.CanBeginAction( typeof( PolymorphSpell ) ) )
{
Caster.SendLocalizedMessage( 1005559 ); // This spell is already in effect.
if( Core.ML )
EndPolymorph( Caster );
else
Caster.SendLocalizedMessage( 1005559 ); // This spell is already in effect.
return false;
}
else if ( m_NewBody == 0 )
@ -92,7 +95,10 @@ namespace Server.Spells.Seventh
}
else if ( !Caster.CanBeginAction( typeof( PolymorphSpell ) ) )
{
Caster.SendLocalizedMessage( 1005559 ); // This spell is already in effect.
if( Core.ML )
EndPolymorph( Caster );
else
Caster.SendLocalizedMessage( 1005559 ); // This spell is already in effect.
}
else if ( Necromancy.TransformationSpell.UnderTransformation( Caster ) )
{
@ -134,13 +140,16 @@ namespace Server.Spells.Seventh
BaseArmor.ValidateMobile( Caster );
BaseClothing.ValidateMobile( Caster );
StopTimer( Caster );
if( !Core.ML )
{
StopTimer( Caster );
Timer t = new InternalTimer( Caster );
Timer t = new InternalTimer( Caster );
m_Timers[Caster] = t;
m_Timers[Caster] = t;
t.Start();
t.Start();
}
}
}
else
@ -167,6 +176,19 @@ namespace Server.Spells.Seventh
return ( t != null );
}
private static void EndPolymorph( Mobile m )
{
if( !m.CanBeginAction( typeof( PolymorphSpell ) ) )
{
m.BodyMod = 0;
m.HueMod = -1;
m.EndAction( typeof( PolymorphSpell ) );
BaseArmor.ValidateMobile( m );
BaseClothing.ValidateMobile( m );
}
}
private class InternalTimer : Timer
{
private Mobile m_Owner;
@ -186,15 +208,7 @@ namespace Server.Spells.Seventh
protected override void OnTick()
{
if ( !m_Owner.CanBeginAction( typeof( PolymorphSpell ) ) )
{
m_Owner.BodyMod = 0;
m_Owner.HueMod = -1;
m_Owner.EndAction( typeof( PolymorphSpell ) );
BaseArmor.ValidateMobile( m_Owner );
BaseClothing.ValidateMobile( m_Owner );
}
EndPolymorph( m_Owner );
}
}
}