|
||
|
|||||||
| Script Support Get support for modifying RunUO Scripts, or writing your own! |
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 (permalink) |
|
Forum Novice
Join Date: May 2007
Posts: 142
|
I am using a custom Resource package however once i went Pre AOS, i was forced to tweak it accordingly.
Currently when a smith creates a shield it retains the ore's resource type however weapons do not! any idea how i can fix this?! this is my BaseWeapon.cs: Code:
using System;
using System.Text;
using System.Collections;
using Server.Network;
using Server.Targeting;
using Server.Mobiles;
using Server.Spells;
using Server.Spells.Necromancy;
using Server.Spells.Bushido;
using Server.Spells.Ninjitsu;
using Server.Factions;
using Server.Engines.Craft;
using System.Collections.Generic;
using Server.Spells.Spellweaving;
namespace Server.Items
{
public interface ISlayer
{
SlayerName Slayer { get; set; }
SlayerName Slayer2 { get; set; }
}
public abstract class BaseWeapon : Item, IWeapon, IFactionItem, ICraftable, ISlayer, IDurability
{
#region Factions
private FactionItem m_FactionState;
public FactionItem FactionItemState
{
get{ return m_FactionState; }
set
{
m_FactionState = value;
if ( m_FactionState == null )
Hue = CraftResources.GetHue( Resource );
LootType = ( m_FactionState == null ? LootType.Regular : LootType.Blessed );
}
}
#endregion
/* Weapon internals work differently now (Mar 13 2003)
*
* The attributes defined below default to -1.
* If the value is -1, the corresponding virtual 'Aos/Old' property is used.
* If not, the attribute value itself is used. Here's the list:
* - MinDamage
* - MaxDamage
* - Speed
* - HitSound
* - MissSound
* - StrRequirement, DexRequirement, IntRequirement
* - WeaponType
* - WeaponAnimation
* - MaxRange
*/
#region Var declarations
// Instance values. These values are unique to each weapon.
private WeaponDamageLevel m_DamageLevel;
private WeaponAccuracyLevel m_AccuracyLevel;
private WeaponDurabilityLevel m_DurabilityLevel;
private WeaponQuality m_Quality;
private Mobile m_Crafter;
private Poison m_Poison;
private int m_PoisonCharges;
private bool m_Identified;
private int m_Hits;
private int m_MaxHits;
private SlayerName m_Slayer;
private SlayerName m_Slayer2;
private SkillMod m_SkillMod, m_MageMod;
private CraftResource m_Resource;
private bool m_PlayerConstructed;
private bool m_Cursed; // Is this weapon cursed via Curse Weapon necromancer spell? Temporary; not serialized.
private bool m_Consecrated; // Is this weapon blessed via Consecrate Weapon paladin ability? Temporary; not serialized.
private AosAttributes m_AosAttributes;
private AosWeaponAttributes m_AosWeaponAttributes;
private AosSkillBonuses m_AosSkillBonuses;
private AosElementAttributes m_AosElementDamages;
// Overridable values. These values are provided to override the defaults which get defined in the individual weapon scripts.
private int m_StrReq, m_DexReq, m_IntReq;
private int m_MinDamage, m_MaxDamage;
private int m_HitSound, m_MissSound;
private int m_Speed;
private int m_MaxRange;
private SkillName m_Skill;
private WeaponType m_Type;
private WeaponAnimation m_Animation;
#endregion
#region Virtual Properties
public virtual WeaponAbility PrimaryAbility{ get{ return null; } }
public virtual WeaponAbility SecondaryAbility{ get{ return null; } }
public virtual int DefMaxRange{ get{ return 1; } }
public virtual int DefHitSound{ get{ return 0; } }
public virtual int DefMissSound{ get{ return 0; } }
public virtual SkillName DefSkill{ get{ return SkillName.Swords; } }
public virtual WeaponType DefType{ get{ return WeaponType.Slashing; } }
public virtual WeaponAnimation DefAnimation{ get{ return WeaponAnimation.Slash1H; } }
public virtual int AosStrengthReq{ get{ return 0; } }
public virtual int AosDexterityReq{ get{ return 0; } }
public virtual int AosIntelligenceReq{ get{ return 0; } }
public virtual int AosMinDamage{ get{ return 0; } }
public virtual int AosMaxDamage{ get{ return 0; } }
public virtual int AosSpeed{ get{ return 0; } }
public virtual int AosMaxRange{ get{ return DefMaxRange; } }
public virtual int AosHitSound{ get{ return DefHitSound; } }
public virtual int AosMissSound{ get{ return DefMissSound; } }
public virtual SkillName AosSkill{ get{ return DefSkill; } }
public virtual WeaponType AosType{ get{ return DefType; } }
public virtual WeaponAnimation AosAnimation{ get{ return DefAnimation; } }
public virtual int OldStrengthReq{ get{ return 0; } }
public virtual int OldDexterityReq{ get{ return 0; } }
public virtual int OldIntelligenceReq{ get{ return 0; } }
public virtual int OldMinDamage{ get{ return 0; } }
public virtual int OldMaxDamage{ get{ return 0; } }
public virtual int OldSpeed{ get{ return 0; } }
public virtual int OldMaxRange{ get{ return DefMaxRange; } }
public virtual int OldHitSound{ get{ return DefHitSound; } }
public virtual int OldMissSound{ get{ return DefMissSound; } }
public virtual SkillName OldSkill{ get{ return DefSkill; } }
public virtual WeaponType OldType{ get{ return DefType; } }
public virtual WeaponAnimation OldAnimation{ get{ return DefAnimation; } }
public virtual int InitMinHits{ get{ return 0; } }
public virtual int InitMaxHits{ get{ return 0; } }
public override int PhysicalResistance{ get{ return m_AosWeaponAttributes.ResistPhysicalBonus; } }
public override int FireResistance{ get{ return m_AosWeaponAttributes.ResistFireBonus; } }
public override int ColdResistance{ get{ return m_AosWeaponAttributes.ResistColdBonus; } }
public override int PoisonResistance{ get{ return m_AosWeaponAttributes.ResistPoisonBonus; } }
public override int EnergyResistance{ get{ return m_AosWeaponAttributes.ResistEnergyBonus; } }
public virtual SkillName AccuracySkill { get { return SkillName.Tactics; } }
#endregion
#region Getters & Setters
[CommandProperty( AccessLevel.GameMaster )]
public AosAttributes Attributes
{
get{ return m_AosAttributes; }
set{}
}
[CommandProperty( AccessLevel.GameMaster )]
public AosWeaponAttributes WeaponAttributes
{
get{ return m_AosWeaponAttributes; }
set{}
}
[CommandProperty( AccessLevel.GameMaster )]
public AosSkillBonuses SkillBonuses
{
get{ return m_AosSkillBonuses; }
set{}
}
[CommandProperty( AccessLevel.GameMaster )]
public AosElementAttributes AosElementDamages
{
get { return m_AosElementDamages; }
set { }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool Cursed
{
get{ return m_Cursed; }
set{ m_Cursed = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool Consecrated
{
get{ return m_Consecrated; }
set{ m_Consecrated = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool Identified
{
get{ return m_Identified; }
set{ m_Identified = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int HitPoints
{
get{ return m_Hits; }
set
{
if ( m_Hits == value )
return;
if ( value > m_MaxHits )
value = m_MaxHits;
m_Hits = value;
InvalidateProperties();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int MaxHitPoints
{
get{ return m_MaxHits; }
set{ m_MaxHits = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int PoisonCharges
{
get{ return m_PoisonCharges; }
set{ m_PoisonCharges = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public Poison Poison
{
get{ return m_Poison; }
set{ m_Poison = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public WeaponQuality Quality
{
get{ return m_Quality; }
set{ UnscaleDurability(); m_Quality = value; ScaleDurability(); InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public Mobile Crafter
{
get{ return m_Crafter; }
set{ m_Crafter = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public SlayerName Slayer
{
get{ return m_Slayer; }
set{ m_Slayer = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public SlayerName Slayer2
{
get { return m_Slayer2; }
set { m_Slayer2 = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public CraftResource Resource
{
get{ return m_Resource; }
set{ UnscaleDurability(); m_Resource = value; Hue = CraftResources.GetHue( m_Resource ); InvalidateProperties(); ScaleDurability(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public WeaponDamageLevel DamageLevel
{
get{ return m_DamageLevel; }
set{ m_DamageLevel = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public WeaponDurabilityLevel DurabilityLevel
{
get{ return m_DurabilityLevel; }
set{ UnscaleDurability(); m_DurabilityLevel = value; InvalidateProperties(); ScaleDurability(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool PlayerConstructed
{
get{ return m_PlayerConstructed; }
set{ m_PlayerConstructed = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public int MaxRange
{
get{ return ( m_MaxRange == -1 ? Core.AOS ? AosMaxRange : OldMaxRange : m_MaxRange ); }
set{ m_MaxRange = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public WeaponAnimation Animation
{
get{ return ( m_Animation == (WeaponAnimation)(-1) ? Core.AOS ? AosAnimation : OldAnimation : m_Animation ); }
set{ m_Animation = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public WeaponType Type
{
get{ return ( m_Type == (WeaponType)(-1) ? Core.AOS ? AosType : OldType : m_Type ); }
set{ m_Type = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public SkillName Skill
{
get{ return ( m_Skill == (SkillName)(-1) ? Core.AOS ? AosSkill : OldSkill : m_Skill ); }
set{ m_Skill = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int HitSound
{
get{ return ( m_HitSound == -1 ? Core.AOS ? AosHitSound : OldHitSound : m_HitSound ); }
set{ m_HitSound = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public int MissSound
{
get{ return ( m_MissSound == -1 ? Core.AOS ? AosMissSound : OldMissSound : m_MissSound ); }
set{ m_MissSound = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public int MinDamage
{
get{ return ( m_MinDamage == -1 ? Core.AOS ? AosMinDamage : OldMinDamage : m_MinDamage ); }
set{ m_MinDamage = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int MaxDamage
{
get{ return ( m_MaxDamage == -1 ? Core.AOS ? AosMaxDamage : OldMaxDamage : m_MaxDamage ); }
set{ m_MaxDamage = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int Speed
{
get{ return ( m_Speed == -1 ? Core.AOS ? AosSpeed : OldSpeed : m_Speed ); }
set{ m_Speed = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int StrRequirement
{
get{ return ( m_StrReq == -1 ? Core.AOS ? AosStrengthReq : OldStrengthReq : m_StrReq ); }
set{ m_StrReq = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int DexRequirement
{
get{ return ( m_DexReq == -1 ? Core.AOS ? AosDexterityReq : OldDexterityReq : m_DexReq ); }
set{ m_DexReq = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public int IntRequirement
{
get{ return ( m_IntReq == -1 ? Core.AOS ? AosIntelligenceReq : OldIntelligenceReq : m_IntReq ); }
set{ m_IntReq = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public WeaponAccuracyLevel AccuracyLevel
{
get
{
return m_AccuracyLevel;
}
set
{
if ( m_AccuracyLevel != value )
{
m_AccuracyLevel = value;
if ( UseSkillMod )
{
if ( m_AccuracyLevel == WeaponAccuracyLevel.Regular )
{
if ( m_SkillMod != null )
m_SkillMod.Remove();
m_SkillMod = null;
}
else if ( m_SkillMod == null && Parent is Mobile )
{
m_SkillMod = new DefaultSkillMod( AccuracySkill, true, (int)m_AccuracyLevel * 5 );
((Mobile)Parent).AddSkillMod( m_SkillMod );
}
else if ( m_SkillMod != null )
{
m_SkillMod.Value = (int)m_AccuracyLevel * 5;
}
}
InvalidateProperties();
}
}
}
#endregion
public virtual void UnscaleDurability()
{
int scale = 100 + GetDurabilityBonus();
m_Hits = ((m_Hits * 100) + (scale - 1)) / scale;
m_MaxHits = ((m_MaxHits * 100) + (scale - 1)) / scale;
InvalidateProperties();
}
public virtual void ScaleDurability()
{
int scale = 100 + GetDurabilityBonus();
m_Hits = ((m_Hits * scale) + 99) / 100;
m_MaxHits = ((m_MaxHits * scale) + 99) / 100;
InvalidateProperties();
}
public int GetDurabilityBonus()
{
int bonus = 0;
if ( m_Quality == WeaponQuality.Exceptional )
bonus += 20;
switch ( m_DurabilityLevel )
{
case WeaponDurabilityLevel.Durable: bonus += 20; break;
case WeaponDurabilityLevel.Substantial: bonus += 50; break;
case WeaponDurabilityLevel.Massive: bonus += 70; break;
case WeaponDurabilityLevel.Fortified: bonus += 100; break;
case WeaponDurabilityLevel.Indestructible: bonus += 120; break;
}
if ( Core.AOS )
{
bonus += m_AosWeaponAttributes.DurabilityBonus;
CraftResourceInfo resInfo = CraftResources.GetInfo( m_Resource );
CraftAttributeInfo attrInfo = null;
if ( resInfo != null )
attrInfo = resInfo.AttributeInfo;
if ( attrInfo != null )
bonus += attrInfo.WeaponDurability;
}
return bonus;
}
public int GetLowerStatReq()
{
if ( !Core.AOS )
return 0;
int v = m_AosWeaponAttributes.LowerStatReq;
CraftResourceInfo info = CraftResources.GetInfo( m_Resource );
if ( info != null )
{
CraftAttributeInfo attrInfo = info.AttributeInfo;
if ( attrInfo != null )
v += attrInfo.WeaponLowerRequirements;
}
if ( v > 100 )
v = 100;
return v;
}
public static void BlockEquip( Mobile m, TimeSpan duration )
{
if ( m.BeginAction( typeof( BaseWeapon ) ) )
new ResetEquipTimer( m, duration ).Start();
}
private class ResetEquipTimer : Timer
{
private Mobile m_Mobile;
public ResetEquipTimer( Mobile m, TimeSpan duration ) : base( duration )
{
m_Mobile = m;
}
protected override void OnTick()
{
m_Mobile.EndAction( typeof( BaseWeapon ) );
}
}
public override bool CheckConflictingLayer( Mobile m, Item item, Layer layer )
{
if ( base.CheckConflictingLayer( m, item, layer ) )
return true;
if ( this.Layer == Layer.TwoHanded && layer == Layer.OneHanded )
{
m.SendLocalizedMessage( 500214 ); // You already have something in both hands.
return true;
}
else if ( this.Layer == Layer.OneHanded && layer == Layer.TwoHanded && !(item is BaseShield) && !(item is BaseEquipableLight) )
{
m.SendLocalizedMessage( 500215 ); // You can only wield one weapon at a time.
return true;
}
return false;
}
public override bool AllowSecureTrade( Mobile from, Mobile to, Mobile newOwner, bool accepted )
{
if ( !Ethics.Ethic.CheckTrade( from, to, newOwner, this ) )
return false;
return base.AllowSecureTrade( from, to, newOwner, accepted );
}
public virtual Race RequiredRace { get { return null; } } //On OSI, there are no weapons with race requirements, this is for custom stuff
public override bool CanEquip( Mobile from )
{
if ( !Ethics.Ethic.CheckEquip( from, this ) )
return false;
if( RequiredRace != null && from.Race != RequiredRace )
{
if( RequiredRace == Race.Elf )
from.SendLocalizedMessage( 1072203 ); // Only Elves may use this.
else
from.SendMessage( "Only {0} may use this.", RequiredRace.PluralName );
return false;
}
else if ( from.Dex < DexRequirement )
{
from.SendMessage( "You are not nimble enough to equip that." );
return false;
}
else if ( from.Str < AOS.Scale( StrRequirement, 100 - GetLowerStatReq() ) )
{
from.SendLocalizedMessage( 500213 ); // You are not strong enough to equip that.
return false;
}
else if ( from.Int < IntRequirement )
{
from.SendMessage( "You are not smart enough to equip that." );
return false;
}
else if ( !from.CanBeginAction( typeof( BaseWeapon ) ) )
{
return false;
}
else
{
return base.CanEquip( from );
}
}
public virtual bool UseSkillMod{ get{ return !Core.AOS; } }
public override bool OnEquip( Mobile from )
{
int strBonus = m_AosAttributes.BonusStr;
int dexBonus = m_AosAttributes.BonusDex;
int intBonus = m_AosAttributes.BonusInt;
if ( (strBonus != 0 || dexBonus != 0 || intBonus != 0) )
{
Mobile m = from;
string modName = this.Serial.ToString();
if ( strBonus != 0 )
m.AddStatMod( new StatMod( StatType.Str, modName + "Str", strBonus, TimeSpan.Zero ) );
if ( dexBonus != 0 )
m.AddStatMod( new StatMod( StatType.Dex, modName + "Dex", dexBonus, TimeSpan.Zero ) );
if ( intBonus != 0 )
m.AddStatMod( new StatMod( StatType.Int, modName + "Int", intBonus, TimeSpan.Zero ) );
}
from.NextCombatTime = DateTime.Now + GetDelay( from );
if ( UseSkillMod && m_AccuracyLevel != WeaponAccuracyLevel.Regular )
{
if ( m_SkillMod != null )
m_SkillMod.Remove();
m_SkillMod = new DefaultSkillMod( AccuracySkill, true, (int)m_AccuracyLevel * 5 );
from.AddSkillMod( m_SkillMod );
}
if ( Core.AOS && m_AosWeaponAttributes.MageWeapon != 0 && m_AosWeaponAttributes.MageWeapon != 30 )
{
if ( m_MageMod != null )
m_MageMod.Remove();
m_MageMod = new DefaultSkillMod( SkillName.Magery, true, -30 + m_AosWeaponAttributes.MageWeapon );
from.AddSkillMod( m_MageMod );
}
return true;
}
public override void OnAdded( object parent )
{
base.OnAdded( parent );
if ( parent is Mobile )
{
Mobile from = (Mobile)parent;
if ( Core.AOS )
m_AosSkillBonuses.AddTo( from );
from.CheckStatTimers();
from.Delta( MobileDelta.WeaponDamage );
}
}
public override void OnRemoved( object parent )
{
if ( parent is Mobile )
{
Mobile m = (Mobile)parent;
BaseWeapon weapon = m.Weapon as BaseWeapon;
string modName = this.Serial.ToString();
m.RemoveStatMod( modName + "Str" );
m.RemoveStatMod( modName + "Dex" );
m.RemoveStatMod( modName + "Int" );
if ( weapon != null )
m.NextCombatTime = DateTime.Now + weapon.GetDelay( m );
if ( UseSkillMod && m_SkillMod != null )
{
m_SkillMod.Remove();
m_SkillMod = null;
}
if ( m_MageMod != null )
{
m_MageMod.Remove();
m_MageMod = null;
}
if ( Core.AOS )
m_AosSkillBonuses.Remove();
m.CheckStatTimers();
m.Delta( MobileDelta.WeaponDamage );
}
}
public virtual SkillName GetUsedSkill( Mobile m, bool checkSkillAttrs )
{
SkillName sk;
if ( checkSkillAttrs && m_AosWeaponAttributes.UseBestSkill != 0 )
{
double swrd = m.Skills[SkillName.Swords].Value;
double fenc = m.Skills[SkillName.Fencing].Value;
double mcng = m.Skills[SkillName.Macing].Value;
double val;
sk = SkillName.Swords;
val = swrd;
if ( fenc > val ){ sk = SkillName.Fencing; val = fenc; }
if ( mcng > val ){ sk = SkillName.Macing; val = mcng; }
}
else if ( m_AosWeaponAttributes.MageWeapon != 0 )
{
if ( m.Skills[SkillName.Magery].Value > m.Skills[Skill].Value )
sk = SkillName.Magery;
else
sk = Skill;
}
else
{
sk = Skill;
if ( sk != SkillName.Wrestling && !m.Player && !m.Body.IsHuman && m.Skills[SkillName.Wrestling].Value > m.Skills[sk].Value )
sk = SkillName.Wrestling;
}
return sk;
}
public virtual double GetAttackSkillValue( Mobile attacker, Mobile defender )
{
return attacker.Skills[GetUsedSkill( attacker, true )].Value;
}
public virtual double GetDefendSkillValue( Mobile attacker, Mobile defender )
{
return defender.Skills[GetUsedSkill( defender, true )].Value;
}
private static bool CheckAnimal( Mobile m, Type type )
{
return AnimalForm.UnderTransformation( m, type );
}
public virtual bool CheckHit( Mobile attacker, Mobile defender )
{
BaseWeapon atkWeapon = attacker.Weapon as BaseWeapon;
BaseWeapon defWeapon = defender.Weapon as BaseWeapon;
Skill atkSkill = attacker.Skills[atkWeapon.Skill];
Skill defSkill = defender.Skills[defWeapon.Skill];
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();
if ( Core.AOS )
{
if ( atkValue <= -20.0 )
atkValue = -19.9;
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;
if ( Spells.Chivalry.DivineFurySpell.UnderEffect( attacker ) )
bonus += 10; // attacker gets 10% bonus when they're under divine fury
if ( CheckAnimal( attacker, typeof( GreyWolf ) ) || CheckAnimal( attacker, typeof( BakeKitsune ) ) )
bonus += 20; // attacker gets 20% bonus when under Wolf or Bake Kitsune form
if ( HitLower.IsUnderAttackEffect( attacker ) )
bonus -= 25; // Under Hit Lower Attack effect -> 25% malus
ourValue = (atkValue + 20.0) * (100 + bonus);
// Defense Chance Increase = 45%
bonus = AosAttributes.GetValue( defender, AosAttribute.DefendChance );
if ( bonus > 45 )
bonus = 45;
if ( Spells.Chivalry.DivineFurySpell.UnderEffect( defender ) )
bonus -= 20; // defender loses 20% bonus when they're under divine fury
if ( HitLower.IsUnderDefenseEffect( defender ) )
bonus -= 25; // Under Hit Lower Defense effect -> 25% malus
int blockBonus = 0;
if ( Block.GetBonus( defender, ref blockBonus ) )
bonus += blockBonus;
int surpriseMalus = 0;
if ( SurpriseAttack.GetMalus( defender, ref surpriseMalus ) )
bonus -= surpriseMalus;
int discordanceEffect = 0;
// Defender loses -0/-28% if under the effect of Discordance.
if ( SkillHandlers.Discordance.GetEffect( attacker, ref discordanceEffect ) )
bonus -= discordanceEffect;
theirValue = (defValue + 20.0) * (100 + bonus);
bonus = 0;
}
else
{
if ( atkValue <= -50.0 )
atkValue = -49.9;
if ( defValue <= -50.0 )
defValue = -49.9;
ourValue = (atkValue + 50.0);
theirValue = (defValue + 50.0);
}
double chance = ourValue / (theirValue * 2.0);
chance *= 1.0 + ((double)bonus / 100);
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 )
{
int speed = this.Speed;
if ( speed == 0 )
return TimeSpan.FromHours( 1.0 );
double delayInSeconds;
if ( Core.SE )
{
/*
* This is likely true for Core.AOS as well... both guides report the same
* formula, and both are wrong.
* The old formula left in for AOS for legacy & because we aren't quite 100%
* Sure that AOS has THIS formula
*/
int bonus = AosAttributes.GetValue( m, AosAttribute.WeaponSpeed );
if ( Spells.Chivalry.DivineFurySpell.UnderEffect( m ) )
bonus += 10;
// Bonus granted by successful use of Honorable Execution.
bonus += HonorableExecution.GetSwingBonus( m );
if( DualWield.Registry.Contains( m ) )
bonus += ((DualWield.DualWieldTimer)DualWield.Registry[m]).BonusSwingSpeed;
if( Feint.Registry.Contains( m ) )
bonus -= ((Feint.FeintTimer)Feint.Registry[m]).SwingSpeedReduction;
TransformContext context = TransformationSpellHelper.GetContext( m );
if( context != null && context.Spell is ReaperFormSpell )
bonus += ((ReaperFormSpell)context.Spell).SwingSpeedBonus;
int discordanceEffect = 0;
// Discordance gives a malus of -0/-28% to swing speed.
if ( SkillHandlers.Discordance.GetEffect( m, ref discordanceEffect ) )
bonus -= discordanceEffect;
if( EssenceOfWindSpell.IsDebuffed( m ) )
bonus -= EssenceOfWindSpell.GetSSIMalus( m );
if ( bonus > 60 )
bonus = 60;
speed = (int)Math.Floor( speed * (bonus + 100.0) / 100.0 );
if ( speed <= 0 )
speed = 1;
int ticks = (int)Math.Floor( (80000.0 / ((m.Stam + 100) * speed)) - 2 );
// Swing speed currently capped at one swing every 1.25 seconds (5 ticks).
if ( ticks < 5 )
ticks = 5;
delayInSeconds = ticks * 0.25;
}
else if ( Core.AOS )
{
int v = (m.Stam + 100) * speed;
int bonus = AosAttributes.GetValue( m, AosAttribute.WeaponSpeed );
if ( Spells.Chivalry.DivineFurySpell.UnderEffect( m ) )
bonus += 10;
int discordanceEffect = 0;
// Discordance gives a malus of -0/-28% to swing speed.
if ( SkillHandlers.Discordance.GetEffect( m, ref discordanceEffect ) )
bonus -= discordanceEffect;
v += AOS.Scale( v, bonus );
if ( v <= 0 )
v = 1;
delayInSeconds = Math.Floor( 40000.0 / v ) * 0.5;
// Maximum swing rate capped at one swing per second
// OSI dev said that it has and is supposed to be 1.25
if ( delayInSeconds < 0.55 )
delayInSeconds = 0.55;
}
else
{
int v = (m.Stam + 100) * speed;
if ( v <= 0 )
v = 1;
delayInSeconds = 15000.0 / v;
}
return TimeSpan.FromSeconds( delayInSeconds );
}
public virtual void OnBeforeSwing( Mobile attacker, Mobile defender )
{
WeaponAbility a = WeaponAbility.GetCurrentAbility( attacker );
if( a != null && !a.OnBeforeSwing( attacker, defender ) )
WeaponAbility.ClearCurrentAbility( attacker );
SpecialMove move = SpecialMove.GetCurrentMove( attacker );
if( move != null && !move.OnBeforeSwing( attacker, defender ) )
SpecialMove.ClearCurrentMove( attacker );
}
public virtual TimeSpan OnSwing( Mobile attacker, Mobile defender )
{
return OnSwing( attacker, defender, 1.0 );
}
public virtual TimeSpan OnSwing( Mobile attacker, Mobile defender, double damageBonus )
{
bool canSwing = true;
if ( Core.AOS )
{
canSwing = ( !attacker.Paralyzed && !attacker.Frozen );
if ( canSwing )
{
Spell sp = attacker.Spell as Spell;
canSwing = ( sp == null || !sp.IsCasting || !sp.BlocksMovement );
}
}
if ( canSwing && attacker.HarmfulCheck( defender ) )
{
attacker.DisruptiveAction();
if ( attacker.NetState != null )
attacker.Send( new Swing( 0, attacker, defender ) );
if ( attacker is BaseCreature )
{
BaseCreature bc = (BaseCreature)attacker;
WeaponAbility ab = bc.GetWeaponAbility();
if ( ab != null )
{
if ( bc.WeaponAbilityChance > Utility.RandomDouble() )
WeaponAbility.SetCurrentAbility( bc, ab );
else
WeaponAbility.ClearCurrentAbility( bc );
}
}
if ( CheckHit( attacker, defender ) )
OnHit( attacker, defender, damageBonus );
else
OnMiss( attacker, defender );
}
return GetDelay( attacker );
}
#region Sounds
public virtual int GetHitAttackSound( Mobile attacker, Mobile defender )
{
int sound = attacker.GetAttackSound();
if ( sound == -1 )
sound = HitSound;
return sound;
}
public virtual int GetHitDefendSound( Mobile attacker, Mobile defender )
{
return defender.GetHurtSound();
}
public virtual int GetMissAttackSound( Mobile attacker, Mobile defender )
{
if ( attacker.GetAttackSound() == -1 )
return MissSound;
else
return -1;
}
public virtual int GetMissDefendSound( Mobile attacker, Mobile defender )
{
return -1;
}
#endregion
public static bool CheckParry( Mobile defender )
{
if ( defender == null )
return false;
BaseShield shield = defender.FindItemOnLayer( Layer.TwoHanded ) as BaseShield;
double parry = defender.Skills[SkillName.Parry].Value;
double bushidoNonRacial = defender.Skills[SkillName.Bushido].NonRacialValue;
double bushido = defender.Skills[SkillName.Bushido].Value;
if ( shield != null )
{
double chance = (parry - bushidoNonRacial) / 400.0; //As per OSI, no negitive effect from the Racial stuffs, ie, 120 parry and '0' bushido with humans
// Parry over 100 grants a 5% bonus.
if ( parry >= 100.0 )
chance += 0.05;
// Evasion grants a variable bonus post ML. 50% prior.
if ( Evasion.IsEvading( defender ) )
chance *= Evasion.GetParryScalar( defender );
// Low dexterity lowers the chance.
if ( defender.Dex < 80 )
chance = chance * (20 + defender.Dex) / 100;
return defender.CheckSkill( SkillName.Parry, chance );
}
else if ( !(defender.Weapon is Fists) && !(defender.Weapon is BaseRanged) )
{
BaseWeapon weapon = defender.Weapon as BaseWeapon;
double divisor = (weapon.Layer == Layer.OneHanded) ? 48000.0 : 41140.0;
double chance = (parry * bushido) / divisor;
double aosChance = parry / 800.0;
// Parry or Bushido over 100 grant a 5% bonus.
if( parry >= 100.0 )
{
chance += 0.05;
aosChance += 0.05;
}
else if( bushido >= 100.0 )
{
chance += 0.05;
}
// Evasion grants a variable bonus post ML. 50% prior.
if( Evasion.IsEvading( defender ) )
chance *= Evasion.GetParryScalar( defender );
// Low dexterity lowers the chance.
if( defender.Dex < 80 )
chance = chance * (20 + defender.Dex) / 100;
if ( chance > aosChance )
return defender.CheckSkill( SkillName.Parry, chance );
else
return (aosChance > Utility.RandomDouble()); // Only skillcheck if wielding a shield & there's no effect from Bushido
}
return false;
}
public virtual int AbsorbDamageAOS( Mobile attacker, Mobile defender, int damage )
{
bool blocked = false;
if ( defender.Player || defender.Body.IsHuman )
{
blocked = CheckParry( defender );
if ( blocked )
{
defender.FixedEffect( 0x37B9, 10, 16 );
damage = 0;
// Successful block removes the Honorable Execution penalty.
HonorableExecution.RemovePenalty( defender );
if ( CounterAttack.IsCountering( defender ) )
{
BaseWeapon weapon = defender.Weapon as BaseWeapon;
if ( weapon != null )
weapon.OnSwing( defender, attacker );
CounterAttack.StopCountering( defender );
}
if ( Confidence.IsConfident( defender ) )
{
defender.SendLocalizedMessage( 1063117 ); // Your confidence reassures you as you successfully block your opponent's blow.
double bushido = defender.Skills.Bushido.Value;
defender.Hits += Utility.RandomMinMax( 1, (int)(bushido / 12) );
defender.Stam += Utility.RandomMinMax( 1, (int)(bushido / 5) );
}
BaseShield shield = defender.FindItemOnLayer( Layer.TwoHanded ) as BaseShield;
if ( shield != null )
{
shield.OnHit( this, damage );
}
}
}
if ( !blocked )
{
double positionChance = Utility.RandomDouble();
Item armorItem;
if( positionChance < 0.07 )
armorItem = defender.NeckArmor;
else if( positionChance < 0.14 )
armorItem = defender.HandArmor;
else if( positionChance < 0.28 )
armorItem = defender.ArmsArmor;
else if( positionChance < 0.43 )
armorItem = defender.HeadArmor;
else if( positionChance < 0.65 )
armorItem = defender.LegsArmor;
else
armorItem = defender.ChestArmor;
IWearableDurability armor = armorItem as IWearableDurability;
if ( armor != null )
armor.OnHit( this, damage ); // call OnHit to lose durability
}
return damage;
}
public virtual int AbsorbDamage( Mobile attacker, Mobile defender, int damage )
{
if ( Core.AOS )
return AbsorbDamageAOS( attacker, defender, damage );
double chance = Utility.RandomDouble();
Item armorItem;
if( chance < 0.07 )
armorItem = defender.NeckArmor;
else if( chance < 0.14 )
armorItem = defender.HandArmor;
else if( chance < 0.28 )
armorItem = defender.ArmsArmor;
else if( chance < 0.43 )
armorItem = defender.HeadArmor;
else if( chance < 0.65 )
armorItem = defender.LegsArmor;
else
armorItem = defender.ChestArmor;
IWearableDurability armor = armorItem as IWearableDurability;
if ( armor != null )
damage = armor.OnHit( this, damage );
BaseShield shield = defender.FindItemOnLayer( Layer.TwoHanded ) as BaseShield;
if ( shield != null )
damage = shield.OnHit( this, damage );
int virtualArmor = defender.VirtualArmor + defender.VirtualArmorMod;
if ( virtualArmor > 0 )
{
double scalar;
if ( chance < 0.14 )
scalar = 0.07;
else if ( chance < 0.28 )
scalar = 0.14;
else if ( chance < 0.43 )
scalar = 0.15;
else if ( chance < 0.65 )
scalar = 0.22;
else
scalar = 0.35;
int from = (int)(virtualArmor * scalar) / 2;
int to = (int)(virtualArmor * scalar);
damage -= Utility.Random( from, (to - from) + 1 );
}
return damage;
}
public virtual int GetPackInstinctBonus( Mobile attacker, Mobile defender )
{
if ( attacker.Player || defender.Player )
return 0;
BaseCreature bc = attacker as BaseCreature;
if ( bc == null || bc.PackInstinct == PackInstinct.None || (!bc.Controlled && !bc.Summoned) )
return 0;
Mobile master = bc.ControlMaster;
if ( master == null )
master = bc.SummonMaster;
if ( master == null )
return 0;
int inPack = 1;
foreach ( Mobile m in defender.GetMobilesInRange( 1 ) )
{
if ( m != attacker && m is BaseCreature )
{
BaseCreature tc = (BaseCreature)m;
if ( (tc.PackInstinct & bc.PackInstinct) == 0 || (!tc.Controlled && !tc.Summoned) )
continue;
Mobile theirMaster = tc.ControlMaster;
if ( theirMaster == null )
theirMaster = tc.SummonMaster;
if ( master == theirMaster && tc.Combatant == defender )
++inPack;
}
}
if ( inPack >= 5 )
return 100;
else if ( inPack >= 4 )
return 75;
else if ( inPack >= 3 )
return 50;
else if ( inPack >= 2 )
return 25;
return 0;
}
private static bool m_InDoubleStrike;
public static bool InDoubleStrike
{
get{ return m_InDoubleStrike; }
set{ m_InDoubleStrike = value; }
}
public void OnHit( Mobile attacker, Mobile defender )
{
OnHit( attacker, defender, 1.0 );
}
public virtual void OnHit( Mobile attacker, Mobile defender, double damageBonus )
{
if ( MirrorImage.HasClone( defender ) && (defender.Skills.Ninjitsu.Value / 150.0) > Utility.RandomDouble() )
{
Clone bc;
foreach ( Mobile m in defender.GetMobilesInRange( 4 ) )
{
bc = m as Clone;
if ( bc != null && bc.Summoned && bc.SummonMaster == defender )
{
attacker.SendLocalizedMessage( 1063141 ); // Your attack has been diverted to a nearby mirror image of your target!
defender.SendLocalizedMessage( 1063140 ); // You manage to divert the attack onto one of your nearby mirror images.
/*
* TODO: What happens if the Clone parries a blow?
* And what about if the attacker is using Honorable Execution
* and kills it?
*/
defender = m;
break;
}
}
}
PlaySwingAnimation( attacker );
PlayHurtAnimation( defender );
attacker.PlaySound( GetHitAttackSound( attacker, defender ) );
defender.PlaySound( GetHitDefendSound( attacker, defender ) );
int damage = ComputeDamage( attacker, defender );
#region Damage Multipliers
/*
* The following damage bonuses multiply damage by a factor.
* Capped at x3 (300%).
*/
//double factor = 1.0;
int percentageBonus = 0;
WeaponAbility a = WeaponAbility.GetCurrentAbility( attacker );
SpecialMove move = SpecialMove.GetCurrentMove( attacker );
if( a != null )
{
//factor *= a.DamageScalar;
percentageBonus += (int)(a.DamageScalar * 100) - 100;
}
if( move != null )
{
//factor *= move.GetDamageScalar( attacker, defender );
percentageBonus += (int)(move.GetDamageScalar( attacker, defender ) * 100) - 100;
}
//factor *= damageBonus;
percentageBonus += (int)(damageBonus * 100) - 100;
CheckSlayerResult cs = CheckSlayers( attacker, defender );
if ( cs != CheckSlayerResult.None )
{
if ( cs == CheckSlayerResult.Slayer )
defender.FixedEffect( 0x37B9, 10, 5 );
//factor *= 2.0;
percentageBonus += 100;
}
if ( !attacker.Player )
{
if ( defender is PlayerMobile )
{
PlayerMobile pm = (PlayerMobile)defender;
if( pm.EnemyOfOneType != null && pm.EnemyOfOneType != attacker.GetType() )
{
//factor *= 2.0;
percentageBonus += 100;
}
}
}
else if ( !defender.Player )
{
if ( attacker is PlayerMobile )
{
PlayerMobile pm = (PlayerMobile)attacker;
if ( pm.WaitingForEnemy )
{
pm.EnemyOfOneType = defender.GetType();
pm.WaitingForEnemy = false;
}
if ( pm.EnemyOfOneType == defender.GetType() )
{
defender.FixedEffect( 0x37B9, 10, 5, 1160, 0 );
//factor *= 1.5;
percentageBonus += 50;
}
}
}
int packInstinctBonus = GetPackInstinctBonus( attacker, defender );
if( packInstinctBonus != 0 )
{
//factor *= 1.0 + (double)packInstinctBonus / 100.0;
percentageBonus += packInstinctBonus;
}
if( m_InDoubleStrike )
{
//factor *= 0.9; // 10% loss when attacking with double-strike
percentageBonus -= 10;
}
TransformContext context = TransformationSpellHelper.GetContext( defender );
if( (m_Slayer == SlayerName.Silver || m_Slayer2 == SlayerName.Silver) && context != null && context.Spell is NecromancerSpell && context.Type != typeof( HorrificBeastSpell ) )
{
//factor *= 1.25; // Every necromancer transformation other than horrific beast takes an additional 25% damage
percentageBonus += 25;
}
if ( attacker is PlayerMobile && !(Core.ML && defender is PlayerMobile ))
{
PlayerMobile pmAttacker = (PlayerMobile) attacker;
if( pmAttacker.HonorActive && pmAttacker.InRange( defender, 1 ) )
{
//factor *= 1.25;
percentageBonus += 25;
}
if( pmAttacker.SentHonorContext != null && pmAttacker.SentHonorContext.Target == defender )
{
//pmAttacker.SentHonorContext.ApplyPerfectionDamageBonus( ref factor );
percentageBonus += pmAttacker.SentHonorContext.PerfectionDamageBonus;
}
}
//if ( factor > 3.0 )
// factor = 3.0;
percentageBonus = Math.Min( percentageBonus, 300 );
//damage = (int)(damage * factor);
damage = AOS.Scale( damage, 100 + percentageBonus );
#endregion
if ( attacker is BaseCreature )
((BaseCreature)attacker).AlterMeleeDamageTo( defender, ref damage );
if ( defender is BaseCreature )
((BaseCreature)defender).AlterMeleeDamageFrom( attacker, ref damage );
damage = AbsorbDamage( attacker, defender, damage );
if ( !Core.AOS && damage < 1 )
damage = 1;
else if ( Core.AOS && damage == 0 ) // parried
{
if ( a != null && a.Validate( attacker ) /*&& a.CheckMana( attacker, true )*/ ) // Parried special moves have no mana cost
{
a = null;
WeaponAbility.ClearCurrentAbility( attacker );
attacker.SendLocalizedMessage( 1061140 ); // Your attack was parried!
}
}
AddBlood( attacker, defender, damage );
int phys, fire, cold, pois, nrgy;
GetDamageTypes( attacker, out phys, out fire, out cold, out pois, out nrgy );
if ( m_Consecrated )
{
phys = defender.PhysicalResistance;
fire = defender.FireResistance;
cold = defender.ColdResistance;
pois = defender.PoisonResistance;
nrgy = defender.EnergyResistance;
int low = phys, type = 0;
if ( fire < low ){ low = fire; type = 1; }
if ( cold < low ){ low = cold; type = 2; }
if ( pois < low ){ low = pois; type = 3; }
if ( nrgy < low ){ low = nrgy; type = 4; }
phys = fire = cold = pois = nrgy = 0;
if ( type == 0 ) phys = 100;
else if ( type == 1 ) fire = 100;
else if ( type == 2 ) cold = 100;
else if ( type == 3 ) pois = 100;
else if ( type == 4 ) nrgy = 100;
}
int damageGiven = damage;
if ( a != null && !a.OnBeforeDamage( attacker, defender ) )
{
WeaponAbility.ClearCurrentAbility( attacker );
a = null;
}
if ( move != null && !move.OnBeforeDamage( attacker, defender ) )
{
SpecialMove.ClearCurrentMove( attacker );
move = null;
}
bool ignoreArmor = ( a is ArmorIgnore || (move != null && move.IgnoreArmor( attacker )) );
damageGiven = AOS.Damage( defender, attacker, damage, ignoreArmor, phys, fire, cold, pois, nrgy );
double propertyBonus = ( move == null ) ? 1.0 : move.GetPropertyBonus( attacker );
if ( Core.AOS )
{
int lifeLeech = 0;
int stamLeech = 0;
int manaLeech = 0;
int wraithLeech = 0;
if ( (int)(m_AosWeaponAttributes.HitLeechHits * propertyBonus) > Utility.Random( 100 ) )
lifeLeech += 30; // HitLeechHits% chance to leech 30% of damage as hit points
if ( (int)(m_AosWeaponAttributes.HitLeechStam * propertyBonus) > Utility.Random( 100 ) )
stamLeech += 100; // HitLeechStam% chance to leech 100% of damage as stamina
if ( (int)(m_AosWeaponAttributes.HitLeechMana * propertyBonus) > Utility.Random( 100 ) )
manaLeech += 40; // HitLeechMana% chance to leech 40% of damage as mana
if ( m_Cursed )
lifeLeech += 50; // Additional 50% life leech for cursed weapons (necro spell)
context = TransformationSpellHelper.GetContext( attacker );
if ( context != null && context.Type == typeof( VampiricEmbraceSpell ) )
lifeLeech += 20; // Vampiric embrace gives an additional 20% life leech
if ( context != null && context.Type == typeof( WraithFormSpell ) )
{
wraithLeech = (5 + (int)((15 * attacker.Skills.SpiritSpeak.Value) / 100)); // Wraith form gives an additional 5-20% mana leech
// Mana leeched by the Wraith Form spell is actually stolen, not just leeched.
defender.Mana -= AOS.Scale( damageGiven, wraithLeech );
manaLeech += wraithLeech;
}
if ( lifeLeech != 0 )
attacker.Hits += AOS.Scale( damageGiven, lifeLeech );
if ( stamLeech != 0 )
attacker.Stam += AOS.Scale( damageGiven, stamLeech );
if ( manaLeech != 0 )
attacker.Mana += AOS.Scale( damageGiven, manaLeech );
if ( lifeLeech != 0 || stamLeech != 0 || manaLeech != 0 )
attacker.PlaySound( 0x44D );
}
if ( m_MaxHits > 0 && ((MaxRange <= 1 && (defender is Slime || defender is ToxicElemental)) || Utility.Random( 25 ) == 0) ) // Stratics says 50% chance, seems more like 4%..
{
if ( MaxRange <= 1 && (defender is Slime || defender is ToxicElemental) )
attacker.LocalOverheadMessage( MessageType.Regular, 0x3B2, 500263 ); // *Acid blood scars your weapon!*
if ( Core.AOS && m_AosWeaponAttributes.SelfRepair > Utility.Random( 10 ) )
{
HitPoints += 2;
}
else
{
if ( m_Hits > 0 )
{
--HitPoints;
}
else if ( m_MaxHits > 1 )
{
--MaxHitPoints;
if ( Parent is Mobile )
((Mobile)Parent).LocalOverheadMessage( MessageType.Regular, 0x3B2, 1061121 ); // Your equipment is severely damaged.
}
else
{
Delete();
}
}
}
if ( attacker is VampireBatFamiliar )
{
BaseCreature bc = (BaseCreature)attacker;
Mobile caster = bc.ControlMaster;
if ( caster == null )
caster = bc.SummonMaster;
if ( caster != null && caster.Map == bc.Map && caster.InRange( bc, 2 ) )
caster.Hits += damage;
else
bc.Hits += damage;
}
if ( Core.AOS )
{
int physChance = (int)(m_AosWeaponAttributes.HitPhysicalArea * propertyBonus);
int fireChance = (int)(m_AosWeaponAttributes.HitFireArea * propertyBonus);
int coldChance = (int)(m_AosWeaponAttributes.HitColdArea * propertyBonus);
int poisChance = (int)(m_AosWeaponAttributes.HitPoisonArea * propertyBonus);
int nrgyChance = (int)(m_AosWeaponAttributes.HitEnergyArea * propertyBonus);
if ( physChance != 0 && physChance > Utility.Random( 100 ) )
DoAreaAttack( attacker, defender, 0x10E, 50, 100, 0, 0, 0, 0 );
if ( fireChance != 0 && fireChance > Utility.Random( 100 ) )
DoAreaAttack( attacker, defender, 0x11D, 1160, 0, 100, 0, 0, 0 );
if ( coldChance != 0 && coldChance > Utility.Random( 100 ) )
DoAreaAttack( attacker, defender, 0x0FC, 2100, 0, 0, 100, 0, 0 );
if ( poisChance != 0 && poisChance > Utility.Random( 100 ) )
DoAreaAttack( attacker, defender, 0x205, 1166, 0, 0, 0, 100, 0 );
if ( nrgyChance != 0 && nrgyChance > Utility.Random( 100 ) )
DoAreaAttack( attacker, defender, 0x1F1, 120, 0, 0, 0, 0, 100 );
int maChance = (int)(m_AosWeaponAttributes.HitMagicArrow * propertyBonus);
int harmChance = (int)(m_AosWeaponAttributes.HitHarm * propertyBonus);
int fireballChance = (int)(m_AosWeaponAttributes.HitFireball * propertyBonus);
int lightningChance = (int)(m_AosWeaponAttributes.HitLightning * propertyBonus);
int dispelChance = (int)(m_AosWeaponAttributes.HitDispel * propertyBonus);
if ( maChance != 0 && maChance > Utility.Random( 100 ) )
DoMagicArrow( attacker, defender );
if ( harmChance != 0 && harmChance > Utility.Random( 100 ) )
DoHarm( attacker, defender );
if ( fireballChance != 0 && fireballChance > Utility.Random( 100 ) )
DoFireball( attacker, defender );
if ( lightningChance != 0 && lightningChance > Utility.Random( 100 ) )
DoLightning( attacker, defender );
if ( dispelChance != 0 && dispelChance > Utility.Random( 100 ) )
DoDispel( attacker, defender );
int laChance = (int)(m_AosWeaponAttributes.HitLowerAttack * propertyBonus);
int ldChance = (int)(m_AosWeaponAttributes.HitLowerDefend * propertyBonus);
if ( laChance != 0 && laChance > Utility.Random( 100 ) )
DoLowerAttack( attacker, defender );
if ( ldChance != 0 && ldChance > Utility.Random( 100 ) )
DoLowerDefense( attacker, defender );
}
if ( attacker is BaseCreature )
((BaseCreature)attacker).OnGaveMeleeAttack( defender );
if ( defender is BaseCreature )
((BaseCreature)defender).OnGotMeleeAttack( attacker );
if ( a != null )
a.OnHit( attacker, defender, damage );
if ( move != null )
move.OnHit( attacker, defender, damage );
if ( defender is IHonorTarget && ((IHonorTarget)defender).ReceivedHonorContext != null )
((IHonorTarget)defender).ReceivedHonorContext.OnTargetHit( attacker );
if ( !(this is BaseRanged) )
{
if ( AnimalForm.UnderTransformation( attacker, typeof( GiantSerpent ) ) )
defender.ApplyPoison( attacker, Poison.Lesser );
if ( AnimalForm.UnderTransformation( defender, typeof( BullFrog ) ) )
attacker.ApplyPoison( defender, Poison.Regular );
}
}
public virtual double GetAosDamage( Mobile attacker, int bonus, int dice, int sides )
{
int damage = Utility.Dice( dice, sides, bonus ) * 100;
int damageBonus = 0;
// Inscription bonus
int inscribeSkill = attacker.Skills[SkillName.Inscribe].Fixed;
damageBonus += inscribeSkill / 200;
if ( inscribeSkill >= 1000 )
damageBonus += 5;
if ( attacker.Player )
{
// Int bonus
damageBonus += (attacker.Int / 10);
// SDI bonus
damageBonus += AosAttributes.GetValue( attacker, AosAttribute.SpellDamage );
TransformContext context = TransformationSpellHelper.GetContext( attacker );
if( context != null && context.Spell is ReaperFormSpell )
damageBonus += ((ReaperFormSpell)context.Spell).SpellDamageBonus;
}
damage = AOS.Scale( damage, 100 + damageBonus );
return damage / 100;
}
#region Do<AoSEffect>
public virtual void DoMagicArrow( Mobile attacker, Mobile defender )
{
if ( !attacker.CanBeHarmful( defender, false ) )
return;
attacker.DoHarmful( defender );
double damage = GetAosDamage( attacker, 10, 1, 4 );
attacker.MovingParticles( defender, 0x36E4, 5, 0, false, true, 3006, 4006, 0 );
attacker.PlaySound( 0x1E5 );
SpellHelper.Damage( TimeSpan.FromSeconds( 1.0 ), defender, attacker, damage, 0, 100, 0, 0, 0 );
}
public virtual void DoHarm( Mobile attacker, Mobile defender )
{
if ( !attacker.CanBeHarmful( defender, false ) )
return;
attacker.DoHarmful( defender );
double damage = GetAosDamage( attacker, 17, 1, 5 );
if ( !defender.InRange( attacker, 2 ) )
damage *= 0.25; // 1/4 damage at > 2 tile range
else if ( !defender.InRange( attacker, 1 ) )
damage *= 0.50; // 1/2 damage at 2 tile range
defender.FixedParticles( 0x374A, 10, 30, 5013, 1153, 2, EffectLayer.Waist );
defender.PlaySound( 0x0FC );
SpellHelper.Damage( TimeSpan.Zero, defender, attacker, damage, 0, 0, 100, 0, 0 );
}
public virtual void DoFireball( Mobile attacker, Mobile defender )
{
if ( !attacker.CanBeHarmful( defender, false ) )
return;
attacker.DoHarmful( defender );
double damage = GetAosDamage( attacker, 19, 1, 5 );
attacker.MovingParticles( defender, 0x36D4, 7, 0, false, true, 9502, 4019, 0x160 );
attacker.PlaySound( 0x15E );
SpellHelper.Damage( TimeSpan.FromSeconds( 1.0 ), defender, attacker, damage, 0, 100, 0, 0, 0 );
}
public virtual void DoLightning( Mobile attacker, Mobile defender )
{
if ( !attacker.CanBeHarmful( defender, false ) )
return;
attacker.DoHarmful( defender );
double damage = GetAosDamage( attacker, 23, 1, 4 );
defender.BoltEffect( 0 );
SpellHelper.Damage( TimeSpan.Zero, defender, attacker, damage, 0, 0, 0, 0, 100 );
}
public virtual void DoDispel( Mobile attacker, Mobile defender )
{
bool dispellable = false;
if ( defender is BaseCreature )
dispellable = ((BaseCreature)defender).Summoned && !((BaseCreature)defender).IsAnimatedDead;
if ( !dispellable )
return;
if ( !attacker.CanBeHarmful( defender, false ) )
return;
attacker.DoHarmful( defender );
Spells.MagerySpell sp = new Spells.Sixth.DispelSpell( attacker, null );
if ( sp.CheckResisted( defender ) )
{
defender.FixedEffect( 0x3779, 10, 20 );
}
else
{
Effects.SendLocationParticles( EffectItem.Create( defender.Location, defender.Map, EffectItem.DefaultDuration ), 0x3728, 8, 20, 5042 );
Effects.PlaySound( defender, defender.Map, 0x201 );
defender.Delete();
}
}
public virtual void DoLowerAttack( Mobile from, Mobile defender )
{
if ( HitLower.ApplyAttack( defender ) )
{
defender.PlaySound( 0x28E );
Effects.SendTargetEffect( defender, 0x37BE, 1, 4, 0xA, 3 );
}
}
public virtual void DoLowerDefense( Mobile from, Mobile defender )
{
if ( HitLower.ApplyDefense( defender ) )
{
defender.PlaySound( 0x28E );
Effects.SendTargetEffect( defender, 0x37BE, 1, 4, 0x23, 3 );
}
}
public virtual void DoAreaAttack( Mobile from, Mobile defender, int sound, int hue, int phys, int fire, int cold, int pois, int nrgy )
{
Map map = from.Map;
if ( map == null )
return;
List<Mobile> list = new List<Mobile>();
foreach ( Mobile m in from.GetMobilesInRange( 10 ) )
{
if ( from != m && defender != m && SpellHelper.ValidIndirectTarget( from, m ) && from.CanBeHarmful( m, false ) && ( !Core.ML || from.InLOS( m ) ) )
list.Add( m );
}
if ( list.Count == 0 )
return;
Effects.PlaySound( from.Location, map, sound );
// TODO: What is the damage calculation?
for ( int i = 0; i < list.Count; ++i )
{
Mobile m = list[i];
double scalar = (11 - from.GetDistanceToSqrt( m )) / 10;
if ( scalar > 1.0 )
scalar = 1.0;
else if ( scalar < 0.0 )
continue;
from.DoHarmful( m, true );
m.FixedEffect( 0x3779, 1, 15, hue, 0 );
AOS.Damage( m, from, (int)(GetBaseDamage( from ) * scalar), phys, fire, cold, pois, nrgy );
}
}
#endregion
public virtual CheckSlayerResult CheckSlayers( Mobile attacker, Mobile defender )
{
BaseWeapon atkWeapon = attacker.Weapon as BaseWeapon;
SlayerEntry atkSlayer = SlayerGroup.GetEntryByName( atkWeapon.Slayer );
SlayerEntry atkSlayer2 = SlayerGroup.GetEntryByName( atkWeapon.Slayer2 );
if ( atkSlayer != null && atkSlayer.Slays( defender ) || atkSlayer2 != null && atkSlayer2.Slays( defender ) )
return CheckSlayerResult.Slayer;
if ( !Core.SE )
{
ISlayer defISlayer = Spellbook.FindEquippedSpellbook( defender );
if( defISlayer == null )
defISlayer = defender.Weapon as ISlayer;
if( defISlayer != null )
{
SlayerEntry defSlayer = SlayerGroup.GetEntryByName( defISlayer.Slayer );
SlayerEntry defSlayer2 = SlayerGroup.GetEntryByName( defISlayer.Slayer2 );
if( defSlayer != null && defSlayer.Group.OppositionSuperSlays( attacker ) || defSlayer2 != null && defSlayer2.Group.OppositionSuperSlays( attacker ) )
return CheckSlayerResult.Opposition;
}
}
return CheckSlayerResult.None;
}
public virtual void AddBlood( Mobile attacker, Mobile defender, int damage )
{
if ( damage > 0 )
{
new Blood().MoveToWorld( defender.Location, defender.Map );
int extraBlood = (Core.SE ? Utility.RandomMinMax( 3, 4 ) : Utility.RandomMinMax( 0, 1 ) );
for( int i = 0; i < extraBlood; i++ )
{
new Blood().MoveToWorld( new Point3D(
defender.X + Utility.RandomMinMax( -1, 1 ),
defender.Y + Utility.RandomMinMax( -1, 1 ),
defender.Z ), defender.Map );
}
}
}
public virtual void GetDamageTypes( Mobile wielder, out int phys, out int fire, out int cold, out int pois, out int nrgy )
{
if( wielder is BaseCreature )
{
BaseCreature bc = (BaseCreature)wielder;
phys = bc.PhysicalDamage;
fire = bc.FireDamage;
cold = bc.ColdDamage;
pois = bc.PoisonDamage;
nrgy = bc.EnergyDamage;
}
else
{
fire = m_AosElementDamages.Fire;
cold = m_AosElementDamages.Cold;
pois = m_AosElementDamages.Poison;
nrgy = m_AosElementDamages.Energy;
phys = 100 - fire - cold - pois - nrgy;
CraftResourceInfo resInfo = CraftResources.GetInfo( m_Resource );
if( resInfo != null )
{
CraftAttributeInfo attrInfo = resInfo.AttributeInfo;
if( attrInfo != null )
{
int left = phys;
left = ApplyCraftAttributeElementDamage( attrInfo.WeaponColdDamage, ref cold, left );
left = ApplyCraftAttributeElementDamage( attrInfo.WeaponEnergyDamage, ref nrgy, left );
left = ApplyCraftAttributeElementDamage( attrInfo.WeaponFireDamage, ref fire, left );
left = ApplyCraftAttributeElementDamage( attrInfo.WeaponPoisonDamage, ref pois, left );
phys = left;
}
}
}
}
private int ApplyCraftAttributeElementDamage( int attrDamage, ref int element, int totalRemaining )
{
if( totalRemaining <= 0 )
return 0;
if ( attrDamage <= 0 )
return totalRemaining;
int appliedDamage = attrDamage;
if ( (appliedDamage + element) > 100 )
appliedDamage = 100 - element;
if( appliedDamage > totalRemaining )
appliedDamage = totalRemaining;
element += appliedDamage;
return totalRemaining - appliedDamage;
}
public virtual void OnMiss( Mobile attacker, Mobile defender )
{
PlaySwingAnimation( attacker );
attacker.PlaySound( GetMissAttackSound( attacker, defender ) );
defender.PlaySound( GetMissDefendSound( attacker, defender ) );
WeaponAbility ability = WeaponAbility.GetCurrentAbility( attacker );
if ( ability != null )
ability.OnMiss( attacker, defender );
SpecialMove move = SpecialMove.GetCurrentMove( attacker );
if ( move != null )
move.OnMiss( attacker, defender );
if ( defender is IHonorTarget && ((IHonorTarget)defender).ReceivedHonorContext != null )
((IHonorTarget)defender).ReceivedHonorContext.OnTargetMissed( attacker );
}
public virtual void GetBaseDamageRange( Mobile attacker, out int min, out int max )
{
if ( attacker is BaseCreature )
{
BaseCreature c = (BaseCreature)attacker;
if ( c.DamageMin >= 0 )
{
min = c.DamageMin;
max = c.DamageMax;
return;
}
if ( this is Fists && !attacker.Body.IsHuman )
{
min = attacker.Str / 28;
max = attacker.Str / 28;
return;
}
}
min = MinDamage;
max = MaxDamage;
}
public virtual double GetBaseDamage( Mobile attacker )
{
int min, max;
GetBaseDamageRange( attacker, out min, out max );
return Utility.RandomMinMax( min, max );
}
public virtual double GetBonus( double value, double scalar, double threshold, double offset )
{
double bonus = value * scalar;
if ( value >= threshold )
bonus += offset;
return bonus / 100;
}
public virtual int GetHitChanceBonus()
{
if ( !Core.AOS )
return 0;
int bonus = 0;
switch ( m_AccuracyLevel )
{
case WeaponAccuracyLevel.Accurate: bonus += 02; break;
case WeaponAccuracyLevel.Surpassingly: bonus += 04; break;
case WeaponAccuracyLevel.Eminently: bonus += 06; break;
case WeaponAccuracyLevel.Exceedingly: bonus += 08; break;
case WeaponAccuracyLevel.Supremely: bonus += 10; break;
}
return bonus;
}
public virtual int GetDamageBonus()
{
int bonus = VirtualDamageBonus;
switch ( m_Quality )
{
case WeaponQuality.Low: bonus -= 20; break;
case WeaponQuality.Exceptional: bonus += 20; break;
}
switch ( m_DamageLevel )
{
case WeaponDamageLevel.Ruin: bonus += 15; break;
case WeaponDamageLevel.Might: bonus += 20; break;
case WeaponDamageLevel.Force: bonus += 25; break;
case WeaponDamageLevel.Power: bonus += 30; break;
case WeaponDamageLevel.Vanq: bonus += 35; break;
}
return bonus;
}
public virtual void GetStatusDamage( Mobile from, out int min, out int max )
{
int baseMin, baseMax;
GetBaseDamageRange( from, out baseMin, out baseMax );
if ( Core.AOS )
{
min = Math.Max( (int)ScaleDamageAOS( from, baseMin, false ), 1 );
max = Math.Max( (int)ScaleDamageAOS( from, baseMax, false ), 1 );
}
else
{
min = Math.Max( (int)ScaleDamageOld( from, baseMin, false ), 1 );
max = Math.Max( (int)ScaleDamageOld( from, baseMax, false ), 1 );
}
}
public virtual double ScaleDamageAOS( Mobile attacker, double damage, bool checkSkills )
{
if ( checkSkills )
{
attacker.CheckSkill( SkillName.Tactics, 0.0, 120.0 ); // Passively check tactics for gain
attacker.CheckSkill( SkillName.Anatomy, 0.0, 120.0 ); // Passively check Anatomy for gain
if ( Type == WeaponType.Axe )
attacker.CheckSkill( SkillName.Lumberjacking, 0.0, 100.0 ); // Passively check Lumberjacking for gain
}
#region Physical bonuses
/*
* These are the bonuses given by the physical characteristics of the mobile.
* No caps apply.
*/
double strengthBonus = GetBonus( attacker.Str, 0.300, 100.0, 5.00 );
double anatomyBonus = GetBonus( attacker.Skills[SkillName.Anatomy].Value, 0.500, 100.0, 5.00 );
double tacticsBonus = GetBonus( attacker.Skills[SkillName.Tactics].Value, 0.625, 100.0, 6.25 );
double lumberBonus = GetBonus( attacker.Skills[SkillName.Lumberjacking].Value, 0.200, 100.0, 10.00 );
if ( Type != WeaponType.Axe )
lumberBonus = 0.0;
#endregion
#region Modifiers
/*
* The following are damage modifiers whose effect shows on the status bar.
* Capped at 100% total.
*/
int damageBonus = AosAttributes.GetValue( attacker, AosAttribute.WeaponDamage );
// Horrific Beast transformation gives a +25% bonus to damage.
if( TransformationSpellHelper.UnderTransformation( attacker, typeof( HorrificBeastSpell ) ) )
damageBonus += 25;
// Divine Fury gives a +10% bonus to damage.
if ( Spells.Chivalry.DivineFurySpell.UnderEffect( attacker ) )
damageBonus += 10;
int defenseMasteryMalus = 0;
// Defense Mastery gives a -50%/-80% malus to damage.
if ( Server.Items.DefenseMastery.GetMalus( attacker, ref defenseMasteryMalus ) )
damageBonus -= defenseMasteryMalus;
int discordanceEffect = 0;
// Discordance gives a -2%/-48% malus to damage.
if ( SkillHandlers.Discordance.GetEffect( attacker, ref discordanceEffect ) )
damageBonus -= discordanceEffect * 2;
if ( damageBonus > 100 )
damageBonus = 100;
#endregion
double totalBonus = strengthBonus + anatomyBonus + tacticsBonus + lumberBonus + ((double)(GetDamageBonus() + damageBonus) / 100.0);
return damage + (int)(damage * totalBonus);
}
public virtual int VirtualDamageBonus{ get{ return 0; } }
public virtual int ComputeDamageAOS( Mobile attacker, Mobile defender )
{
return (int)ScaleDamageAOS( attacker, GetBaseDamage( attacker ), true );
}
public virtual double ScaleDamageOld( Mobile attacker, double damage, bool checkSkills )
{
if ( checkSkills )
{
attacker.CheckSkill( SkillName.Tactics, 0.0, 120.0 ); // Passively check tactics for gain
attacker.CheckSkill( SkillName.Anatomy, 0.0, 120.0 ); // Passively check Anatomy for gain
if ( Type == WeaponType.Axe )
attacker.CheckSkill( SkillName.Lumberjacking, 0.0, 100.0 ); // Passively check Lumberjacking for gain
}
/* Compute tactics modifier
* : 0.0 = 50% loss
* : 50.0 = unchanged
* : 100.0 = 50% bonus
*/
double tacticsBonus = (attacker.Skills[SkillName.Tactics].Value - 50.0) / 100.0;
/* Compute strength modifier
* : 1% bonus for every 5 strength
*/
double strBonus = (attacker.Str / 5.0) / 100.0;
/* Compute anatomy modifier
* : 1% bonus for every 5 points of anatomy
* : +10% bonus at Grandmaster or higher
*/
double anatomyValue = attacker.Skills[SkillName.Anatomy].Value;
double anatomyBonus = (anatomyValue / 5.0) / 100.0;
if ( anatomyValue >= 100.0 )
anatomyBonus += 0.1;
/* Compute lumberjacking bonus
* : 1% bonus for every 5 points of lumberjacking
* : +10% bonus at Grandmaster or higher
*/
double lumberBonus;
if ( Type == WeaponType.Axe )
{
double lumberValue = attacker.Skills[SkillName.Lumberjacking].Value;
lumberBonus = (lumberValue / 5.0) / 100.0;
if ( lumberValue >= 100.0 )
lumberBonus += 0.1;
}
else
{
lumberBonus = 0.0;
}
// New quality bonus:
double qualityBonus = ((int)m_Quality - 1) * 0.2;
// Apply bonuses
damage += (damage * tacticsBonus) + (damage * strBonus) + (damage * anatomyBonus) + (damage * lumberBonus) + (damage * qualityBonus) + ((damage * VirtualDamageBonus) / 100);
// Old quality bonus:
#if false
/* Apply quality offset
* : Low : -4
* : Regular : 0
* : Exceptional : +4
*/
damage += ((int)m_Quality - 1) * 4.0;
#endif
/* Apply damage level offset
* : Regular : 0
* : Ruin : 1
* : Might : 3
* : Force : 5
* : Power : 7
* : Vanq : 9
*/
if ( m_DamageLevel != WeaponDamageLevel.Regular )
damage += (2.0 * (int)m_DamageLevel) - 1.0;
// Halve the computed damage and return
damage /= 2.0;
return ScaleDamageByDurability( (int)damage );
}
public virtual int ScaleDamageByDurability( int damage )
{
int scale = 100;
if ( m_MaxHits > 0 && m_Hits < m_MaxHits )
scale = 50 + ((50 * m_Hits) / m_MaxHits);
return AOS.Scale( damage, scale );
}
public virtual int ComputeDamage( Mobile attacker, Mobile defender )
{
if ( Core.AOS )
return ComputeDamageAOS( attacker, defender );
return (int)ScaleDamageOld( attacker, GetBaseDamage( attacker ), true );
}
public virtual void PlayHurtAnimation( Mobile from )
{
int action;
int frames;
switch ( from.Body.Type )
{
case BodyType.Sea:
case BodyType.Animal:
{
action = 7;
frames = 5;
break;
}
case BodyType.Monster:
{
action = 10;
frames = 4;
break;
}
case BodyType.Human:
{
action = 20;
frames = 5;
break;
}
default: return;
}
if ( from.Mounted )
return;
from.Animate( action, frames, 1, true, false, 0 );
}
public virtual void PlaySwingAnimation( Mobile from )
{
int action;
switch ( from.Body.Type )
{
case BodyType.Sea:
case BodyType.Animal:
{
action = Utility.Random( 5, 2 );
break;
}
case BodyType.Monster:
{
switch ( Animation )
{
default:
case WeaponAnimation.Wrestle:
case WeaponAnimation.Bash1H:
case WeaponAnimation.Pierce1H:
case WeaponAnimation.Slash1H:
case WeaponAnimation.Bash2H:
case WeaponAnimation.Pierce2H:
case WeaponAnimation.Slash2H: action = Utility.Random( 4, 3 ); break;
case WeaponAnimation.ShootBow: return; // 7
case WeaponAnimation.ShootXBow: return; // 8
}
break;
}
case BodyType.Human:
{
if ( !from.Mounted )
{
action = (int)Animation;
}
else
{
switch ( Animation )
{
default:
case WeaponAnimation.Wrestle:
case WeaponAnimation.Bash1H:
case WeaponAnimation.Pierce1H:
case WeaponAnimation.Slash1H: action = 26; break;
case WeaponAnimation.Bash2H:
case WeaponAnimation.Pierce2H:
case WeaponAnimation.Slash2H: action = 29; break;
case WeaponAnimation.ShootBow: action = 27; break;
case WeaponAnimation.ShootXBow: action = 28; break;
}
}
break;
}
default: return;
}
from.Animate( action, 7, 1, true, false, 0 );
}
#region Serialization/Deserialization
private static void SetSaveFlag( ref SaveFlag flags, SaveFlag toSet, bool setIf )
{
if ( setIf )
flags |= toSet;
}
private static bool GetSaveFlag( SaveFlag flags, SaveFlag toGet )
{
return ( (flags & toGet) != 0 );
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 8 ); // version
SaveFlag flags = SaveFlag.None;
SetSaveFlag( ref flags, SaveFlag.DamageLevel, m_DamageLevel != WeaponDamageLevel.Regular );
SetSaveFlag( ref flags, SaveFlag.AccuracyLevel, m_AccuracyLevel != WeaponAccuracyLevel.Regular );
SetSaveFlag( ref flags, SaveFlag.DurabilityLevel, m_DurabilityLevel != WeaponDurabilityLevel.Regular );
SetSaveFlag( ref flags, SaveFlag.Quality, m_Quality != WeaponQuality.Regular );
SetSaveFlag( ref flags, SaveFlag.Hits, m_Hits != 0 );
SetSaveFlag( ref flags, SaveFlag.MaxHits, m_MaxHits != 0 );
SetSaveFlag( ref flags, SaveFlag.Slayer, m_Slayer != SlayerName.None );
SetSaveFlag( ref flags, SaveFlag.Poison, m_Poison != null );
SetSaveFlag( ref flags, SaveFlag.PoisonCharges, m_PoisonCharges != 0 );
SetSaveFlag( ref flags, SaveFlag.Crafter, m_Crafter != null );
SetSaveFlag( ref flags, SaveFlag.Identified, m_Identified != false );
SetSaveFlag( ref flags, SaveFlag.StrReq, m_StrReq != -1 );
SetSaveFlag( ref flags, SaveFlag.DexReq, m_DexReq != -1 );
SetSaveFlag( ref flags, SaveFlag.IntReq, m_IntReq != -1 );
SetSaveFlag( ref flags, SaveFlag.MinDamage, m_MinDamage != -1 );
SetSaveFlag( ref flags, SaveFlag.MaxDamage, m_MaxDamage != -1 );
SetSaveFlag( ref flags, SaveFlag.HitSound, m_HitSound != -1 );
SetSaveFlag( ref flags, SaveFlag.MissSound, m_MissSound != -1 );
SetSaveFlag( ref flags, SaveFlag.Speed, m_Speed != -1 );
SetSaveFlag( ref flags, SaveFlag.MaxRange, m_MaxRange != -1 );
SetSaveFlag( ref flags, SaveFlag.Skill, m_Skill != (SkillName)(-1) );
SetSaveFlag( ref flags, SaveFlag.Type, m_Type != (WeaponType)(-1) );
SetSaveFlag( ref flags, SaveFlag.Animation, m_Animation != (WeaponAnimation)(-1) );
SetSaveFlag( ref flags, SaveFlag.Resource, m_Resource != CraftResource.Iron );
SetSaveFlag( ref flags, SaveFlag.xAttributes, !m_AosAttributes.IsEmpty );
SetSaveFlag( ref flags, SaveFlag.xWeaponAttributes, !m_AosWeaponAttributes.IsEmpty );
SetSaveFlag( ref flags, SaveFlag.PlayerConstructed, m_PlayerConstructed );
SetSaveFlag( ref flags, SaveFlag.SkillBonuses, !m_AosSkillBonuses.IsEmpty );
SetSaveFlag( ref flags, SaveFlag.Slayer2, m_Slayer2 != SlayerName.None );
SetSaveFlag( ref flags, SaveFlag.ElementalDamages, !m_AosElementDamages.IsEmpty );
writer.Write( (int) flags );
if ( GetSaveFlag( flags, SaveFlag.DamageLevel ) )
writer.Write( (int) m_DamageLevel );
if ( GetSaveFlag( flags, SaveFlag.AccuracyLevel ) )
writer.Write( (int) m_AccuracyLevel );
if ( GetSaveFlag( flags, SaveFlag.DurabilityLevel ) )
writer.Write( (int) m_DurabilityLevel );
if ( GetSaveFlag( flags, SaveFlag.Quality ) )
writer.Write( (int) m_Quality );
if ( GetSaveFlag( flags, SaveFlag.Hits ) )
writer.Write( (int) m_Hits );
if ( GetSaveFlag( flags, SaveFlag.MaxHits ) )
writer.Write( (int) m_MaxHits );
if ( GetSaveFlag( flags, SaveFlag.Slayer ) )
writer.Write( (int) m_Slayer );
if ( GetSaveFlag( flags, SaveFlag.Poison ) )
Poison.Serialize( m_Poison, writer );
if ( GetSaveFlag( flags, SaveFlag.PoisonCharges ) )
writer.Write( (int) m_PoisonCharges );
if ( GetSaveFlag( flags, SaveFlag.Crafter ) )
writer.Write( (Mobile) m_Crafter );
if ( GetSaveFlag( flags, SaveFlag.StrReq ) )
writer.Write( (int) m_StrReq );
if ( GetSaveFlag( flags, SaveFlag.DexReq ) )
writer.Write( (int) m_DexReq );
if ( GetSaveFlag( flags, SaveFlag.IntReq ) )
writer.Write( (int) m_IntReq );
if ( GetSaveFlag( flags, SaveFlag.MinDamage ) )
writer.Write( (int) m_MinDamage );
if ( GetSaveFlag( flags, SaveFlag.MaxDamage ) )
writer.Write( (int) m_MaxDamage );
if ( GetSaveFlag( flags, SaveFlag.HitSound ) )
writer.Write( (int) m_HitSound );
if ( GetSaveFlag( flags, SaveFlag.MissSound ) )
writer.Write( (int) m_MissSound );
if ( GetSaveFlag( flags, SaveFlag.Speed ) )
writer.Write( (int) m_Speed );
if ( GetSaveFlag( flags, SaveFlag.MaxRange ) )
writer.Write( (int) m_MaxRange );
if ( GetSaveFlag( flags, SaveFlag.Skill ) )
writer.Write( (int) m_Skill );
if ( GetSaveFlag( flags, SaveFlag.Type ) )
writer.Write( (int) m_Type );
if ( GetSaveFlag( flags, SaveFlag.Animation ) )
writer.Write( (int) m_Animation );
if ( GetSaveFlag( flags, SaveFlag.Resource ) )
writer.Write( (int) m_Resource );
if ( GetSaveFlag( flags, SaveFlag.xAttributes ) )
m_AosAttributes.Serialize( writer );
if ( GetSaveFlag( flags, SaveFlag.xWeaponAttributes ) )
m_AosWeaponAttributes.Serialize( writer );
if ( GetSaveFlag( flags, SaveFlag.SkillBonuses ) )
m_AosSkillBonuses.Serialize( writer );
if ( GetSaveFlag( flags, SaveFlag.Slayer2 ) )
writer.Write( (int)m_Slayer2 );
if( GetSaveFlag( flags, SaveFlag.ElementalDamages ) )
m_AosElementDamages.Serialize( writer );
}
[Flags]
private enum SaveFlag
{
None = 0x00000000,
DamageLevel = 0x00000001,
AccuracyLevel = 0x00000002,
DurabilityLevel = 0x00000004,
Quality = 0x00000008,
Hits = 0x00000010,
MaxHits = 0x00000020,
Slayer = 0x00000040,
Poison = 0x00000080,
PoisonCharges = 0x00000100,
Crafter = 0x00000200,
Identified = 0x00000400,
StrReq = 0x00000800,
DexReq = 0x00001000,
IntReq = 0x00002000,
MinDamage = 0x00004000,
MaxDamage = 0x00008000,
HitSound = 0x00010000,
MissSound = 0x00020000,
Speed = 0x00040000,
MaxRange = 0x00080000,
Skill = 0x00100000,
Type = 0x00200000,
Animation = 0x00400000,
Resource = 0x00800000,
xAttributes = 0x01000000,
xWeaponAttributes = 0x02000000,
PlayerConstructed = 0x04000000,
SkillBonuses = 0x08000000,
Slayer2 = 0x10000000,
ElementalDamages = 0x20000000
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 8:
case 7:
case 6:
case 5:
{
SaveFlag flags = (SaveFlag)reader.ReadInt();
if ( GetSaveFlag( flags, SaveFlag.DamageLevel ) )
{
m_DamageLevel = (WeaponDamageLevel)reader.ReadInt();
if ( m_DamageLevel > WeaponDamageLevel.Vanq )
m_DamageLevel = WeaponDamageLevel.Ruin;
}
if ( GetSaveFlag( flags, SaveFlag.AccuracyLevel ) )
{
m_AccuracyLevel = (WeaponAccuracyLevel)reader.ReadInt();
if ( m_AccuracyLevel > WeaponAccuracyLevel.Supremely )
m_AccuracyLevel = WeaponAccuracyLevel.Accurate;
}
if ( GetSaveFlag( flags, SaveFlag.DurabilityLevel ) )
{
m_DurabilityLevel = (WeaponDurabilityLevel)reader.ReadInt();
if ( m_DurabilityLevel > WeaponDurabilityLevel.Indestructible )
m_DurabilityLevel = WeaponDurabilityLevel.Durable;
}
if ( GetSaveFlag( flags, SaveFlag.Quality ) )
m_Quality = (WeaponQuality)reader.ReadInt();
else
m_Quality = WeaponQuality.Regular;
if ( GetSaveFlag( flags, SaveFlag.Hits ) )
m_Hits = reader.ReadInt();
if ( GetSaveFlag( flags, SaveFlag.MaxHits ) )
m_MaxHits = reader.ReadInt();
if ( GetSaveFlag( flags, SaveFlag.Slayer ) )
m_Slayer = (SlayerName)reader.ReadInt();
if ( GetSaveFlag( flags, SaveFlag.Poison ) )
m_Poison = Poison.Deserialize( reader );
if ( GetSaveFlag( flags, SaveFlag.PoisonCharges ) )
m_PoisonCharges = reader.ReadInt();
if ( GetSaveFlag( flags, SaveFlag.Crafter ) )
m_Crafter = reader.ReadMobile();
if ( GetSaveFlag( flags, SaveFlag.Identified ) )
m_Identified = ( version >= 6 || reader.ReadBool() );
if ( GetSaveFlag( flags, SaveFlag.StrReq ) )
m_StrReq = reader.ReadInt();
else
m_StrReq = -1;
if ( GetSaveFlag( flags, SaveFlag.DexReq ) )
m_DexReq = reader.ReadInt();
else
m_DexReq = -1;
if ( GetSaveFlag( flags, SaveFlag.IntReq ) )
m_IntReq = reader.ReadInt();
else
m_IntReq = -1;
if ( GetSaveFlag( flags, SaveFlag.MinDamage ) )
m_MinDamage = reader.ReadInt();
else
m_MinDamage = -1;
if ( GetSaveFlag( flags, SaveFlag.MaxDamage ) )
m_MaxDamage = reader.ReadInt();
else
m_MaxDamage = -1;
if ( GetSaveFlag( flags, SaveFlag.HitSound ) )
m_HitSound = reader.ReadInt();
else
m_HitSound = -1;
if ( GetSaveFlag( flags, SaveFlag.MissSound ) )
m_MissSound = reader.ReadInt();
else
m_MissSound = -1;
if ( GetSaveFlag( flags, SaveFlag.Speed ) )
m_Speed = reader.ReadInt();
else
m_Speed = -1;
if ( GetSaveFlag( flags, SaveFlag.MaxRange ) )
m_MaxRange = reader.ReadInt();
else
m_MaxRange = -1;
if ( GetSaveFlag( flags, SaveFlag.Skill ) )
m_Skill = (SkillName)reader.ReadInt();
else
m_Skill = (SkillName)(-1);
if ( GetSaveFlag( flags, SaveFlag.Type ) )
m_Type = (WeaponType)reader.ReadInt();
else
m_Type = (WeaponType)(-1);
if ( GetSaveFlag( flags, SaveFlag.Animation ) )
m_Animation = (WeaponAnimation)reader.ReadInt();
else
m_Animation = (WeaponAnimation)(-1);
if ( GetSaveFlag( flags, SaveFlag.Resource ) )
m_Resource = (CraftResource)reader.ReadInt();
else
m_Resource = CraftResource.Iron;
if ( GetSaveFlag( flags, SaveFlag.xAttributes ) )
m_AosAttributes = new AosAttributes( this, reader );
else
m_AosAttributes = new AosAttributes( this );
if ( GetSaveFlag( flags, SaveFlag.xWeaponAttributes ) )
m_AosWeaponAttributes = new AosWeaponAttributes( this, reader );
else
m_AosWeaponAttributes = new AosWeaponAttributes( this );
if ( UseSkillMod && m_AccuracyLevel != WeaponAccuracyLevel.Regular && Parent is Mobile )
{
m_SkillMod = new DefaultSkillMod( AccuracySkill, true, (int)m_AccuracyLevel * 5 );
((Mobile)Parent).AddSkillMod( m_SkillMod );
}
if ( version < 7 && m_AosWeaponAttributes.MageWeapon != 0 )
m_AosWeaponAttributes.MageWeapon = 30 - m_AosWeaponAttributes.MageWeapon;
if ( Core.AOS && m_AosWeaponAttributes.MageWeapon != 0 && m_AosWeaponAttributes.MageWeapon != 30 && Parent is Mobile )
{
m_MageMod = new DefaultSkillMod( SkillName.Magery, true, -30 + m_AosWeaponAttributes.MageWeapon );
((Mobile)Parent).AddSkillMod( m_MageMod );
}
if ( GetSaveFlag( flags, SaveFlag.PlayerConstructed ) )
m_PlayerConstructed = true;
if( GetSaveFlag( flags, SaveFlag.SkillBonuses ) )
m_AosSkillBonuses = new AosSkillBonuses( this, reader );
else
m_AosSkillBonuses = new AosSkillBonuses( this );
if( GetSaveFlag( flags, SaveFlag.Slayer2 ) )
m_Slayer2 = (SlayerName)reader.ReadInt();
if( GetSaveFlag( flags, SaveFlag.ElementalDamages ) )
m_AosElementDamages = new AosElementAttributes( this, reader );
else
m_AosElementDamages = new AosElementAttributes( this );
break;
}
case 4:
{
m_Slayer = (SlayerName)reader.ReadInt();
goto case 3;
}
case 3:
{
m_StrReq = reader.ReadInt();
m_DexReq = reader.ReadInt();
m_IntReq = reader.ReadInt();
goto case 2;
}
case 2:
{
m_Identified = reader.ReadBool();
goto case 1;
}
case 1:
{
m_MaxRange = reader.ReadInt();
goto case 0;
}
case 0:
{
if ( version == 0 )
m_MaxRange = 1; // default
if ( version < 5 )
{
m_Resource = CraftResource.Iron;
m_AosAttributes = new AosAttributes( this );
m_AosWeaponAttributes = new AosWeaponAttributes( this );
m_AosElementDamages = new AosElementAttributes( this );
m_AosSkillBonuses = new AosSkillBonuses( this );
}
m_MinDamage = reader.ReadInt();
m_MaxDamage = reader.ReadInt();
m_Speed = reader.ReadInt();
m_HitSound = reader.ReadInt();
m_MissSound = reader.ReadInt();
m_Skill = (SkillName)reader.ReadInt();
m_Type = (WeaponType)reader.ReadInt();
m_Animation = (WeaponAnimation)reader.ReadInt();
m_DamageLevel = (WeaponDamageLevel)reader.ReadInt();
m_AccuracyLevel = (WeaponAccuracyLevel)reader.ReadInt();
m_DurabilityLevel = (WeaponDurabilityLevel)reader.ReadInt();
m_Quality = (WeaponQuality)reader.ReadInt();
m_Crafter = reader.ReadMobile();
m_Poison = Poison.Deserialize( reader );
m_PoisonCharges = reader.ReadInt();
if ( m_StrReq == OldStrengthReq )
m_StrReq = -1;
if ( m_DexReq == OldDexterityReq )
m_DexReq = -1;
if ( m_IntReq == OldIntelligenceReq )
m_IntReq = -1;
if ( m_MinDamage == OldMinDamage )
m_MinDamage = -1;
if ( m_MaxDamage == OldMaxDamage )
m_MaxDamage = -1;
if ( m_HitSound == OldHitSound )
m_HitSound = -1;
if ( m_MissSound == OldMissSound )
m_MissSound = -1;
if ( m_Speed == OldSpeed )
m_Speed = -1;
if ( m_MaxRange == OldMaxRange )
m_MaxRange = -1;
if ( m_Skill == OldSkill )
m_Skill = (SkillName)(-1);
if ( m_Type == OldType )
m_Type = (WeaponType)(-1);
if ( m_Animation == OldAnimation )
m_Animation = (WeaponAnimation)(-1);
if ( UseSkillMod && m_AccuracyLevel != WeaponAccuracyLevel.Regular && Parent is Mobile )
{
m_SkillMod = new DefaultSkillMod( AccuracySkill, true, (int)m_AccuracyLevel * 5);
((Mobile)Parent).AddSkillMod( m_SkillMod );
}
break;
}
}
if ( Core.AOS && Parent is Mobile )
m_AosSkillBonuses.AddTo( (Mobile)Parent );
int strBonus = m_AosAttributes.BonusStr;
int dexBonus = m_AosAttributes.BonusDex;
int intBonus = m_AosAttributes.BonusInt;
if ( this.Parent is Mobile && (strBonus != 0 || dexBonus != 0 || intBonus != 0) )
{
Mobile m = (Mobile)this.Parent;
string modName = this.Serial.ToString();
if ( strBonus != 0 )
m.AddStatMod( new StatMod( StatType.Str, modName + "Str", strBonus, TimeSpan.Zero ) );
if ( dexBonus != 0 )
m.AddStatMod( new StatMod( StatType.Dex, modName + "Dex", dexBonus, TimeSpan.Zero ) );
if ( intBonus != 0 )
m.AddStatMod( new StatMod( StatType.Int, modName + "Int", intBonus, TimeSpan.Zero ) );
}
if ( Parent is Mobile )
((Mobile)Parent).CheckStatTimers();
if ( m_Hits <= 0 && m_MaxHits <= 0 )
{
m_Hits = m_MaxHits = Utility.RandomMinMax( InitMinHits, InitMaxHits );
}
if ( version < 6 )
m_PlayerConstructed = true; // we don't know, so, assume it's crafted
}
#endregion
public BaseWeapon( int itemID ) : base( itemID )
{
Layer = (Layer)ItemData.Quality;
m_Quality = WeaponQuality.Regular;
m_StrReq = -1;
m_DexReq = -1;
m_IntReq = -1;
m_MinDamage = -1;
m_MaxDamage = -1;
m_HitSound = -1;
m_MissSound = -1;
m_Speed = -1;
m_MaxRange = -1;
m_Skill = (SkillName)(-1);
m_Type = (WeaponType)(-1);
m_Animation = (WeaponAnimation)(-1);
m_Hits = m_MaxHits = Utility.RandomMinMax( InitMinHits, InitMaxHits );
m_Resource = CraftResource.Iron;
m_AosAttributes = new AosAttributes( this );
m_AosWeaponAttributes = new AosWeaponAttributes( this );
m_AosSkillBonuses = new AosSkillBonuses( this );
m_AosElementDamages = new AosElementAttributes( this );
}
public BaseWeapon( Serial serial ) : base( serial )
{
}
private string GetNameString()
{
string name = this.Name;
if ( name == null )
name = String.Format( "#{0}", LabelNumber );
return name;
}
[Hue, CommandProperty( AccessLevel.GameMaster )]
public override int Hue
{
get{ return base.Hue; }
set{ base.Hue = value; InvalidateProperties(); }
}
public int GetElementalDamageHue()
{
int phys, fire, cold, pois, nrgy;
GetDamageTypes( null, out phys, out fire, out cold, out pois, out nrgy );
//Order is Cold, Energy, Fire, Poison, Physical left
int currentMax = 50;
int hue = 0;
if( pois >= currentMax )
{
hue = 1267 + (pois - 50) / 10;
currentMax = pois;
}
if( fire >= currentMax )
{
hue = 1255 + (fire - 50) / 10;
currentMax = fire;
}
if( nrgy >= currentMax )
{
hue = 1273 + (nrgy - 50) / 10;
currentMax = nrgy;
}
if( cold >= currentMax )
{
hue = 1261 + (cold - 50) / 10;
currentMax = cold;
}
return hue;
}
public override void AddNameProperty( ObjectPropertyList list )
{
string oreType;
if ( Hue == 0 )
{
oreType = "";
}
else
{
switch ( m_Resource )
{
case CraftResource.DullCopper: oreType = "dull copper"; break; // dull copper
case CraftResource.ShadowIron: oreType = "shadow iron"; break; // shadow iron
case CraftResource.Copper: oreType = "copper"; break; // copper
case CraftResource.Bronze: oreType = "bronze"; break; // bronze
case CraftResource.Gold: oreType = "gold"; break; // golden
case CraftResource.Agapite: oreType = "agapite"; break; // agapite
case CraftResource.Verite: oreType = "verite"; break; // verite
case CraftResource.Valorite: oreType = "valorite"; break; // valorite
case CraftResource.Silver: oreType = "silver"; break; // silver
case CraftResource.Platinum: oreType = "platinum"; break; // platinum
case CraftResource.Mythril: oreType = "mythril"; break; // mythril
case CraftResource.Obsidian: oreType = "obsidian"; break; // obsidian
case CraftResource.Jade: oreType = "jade"; break; // jade
case CraftResource.Moonstone: oreType = "moonstone"; break; // moonstone
case CraftResource.Sunstone: oreType = "sunstone"; break; // sunstone
case CraftResource.Bloodstone: oreType = "bloodstone"; break; // bloodstone
case CraftResource.SpinedLeather: oreType = "spined"; break; // spined
case CraftResource.HornedLeather: oreType = "horned"; break; // horned
case CraftResource.BarbedLeather: oreType = "barbed"; break; // barbed
case CraftResource.DragonLeather: oreType = "dragon"; break; // dragon
case CraftResource.DaemonLeather: oreType = "daemon"; break; // daemon
case CraftResource.RedScales: oreType = "red"; break; // red
case CraftResource.YellowScales: oreType = "yellow"; break; // yellow
case CraftResource.BlackScales: oreType = "black"; break; // black
case CraftResource.GreenScales: oreType = "green"; break; // green
case CraftResource.WhiteScales: oreType = "white"; break; // white
case CraftResource.BlueScales: oreType = "blue"; break; // blue
case CraftResource.Pine: oreType = "pine"; break; // pine
case CraftResource.Cedar: oreType = "cedar"; break; // cedar
case CraftResource.Cherry: oreType = "cherry"; break; // cherry
case CraftResource.Mahogany: oreType = "mahogany"; break; // mahogany
case CraftResource.Oak: oreType = "oak"; break; // oak
case CraftResource.Ash: oreType = "ash"; break; // ash
case CraftResource.Yew: oreType = "yew"; break; // yew
case CraftResource.Heartwood: oreType = "heartwood"; break; // heartwood
case CraftResource.Bloodwood: oreType = "bloodwood"; break; // bloodwood
case CraftResource.Frostwood: oreType = "frostwood"; break; // frostwood
default: oreType = ""; break;
}
}
//if ( oreType != 0 )
list.Add( 1053099, "{0}\t{1}", oreType, GetNameString() ); // ~1_oretype~ ~2_armortype~
/*else if ( Name == null )
list.Add( LabelNumber );
else
list.Add( Name );*/
}
public override bool AllowEquipedCast( Mobile from )
{
if ( base.AllowEquipedCast( from ) )
return true;
return ( m_AosAttributes.SpellChanneling != 0 );
}
public virtual int ArtifactRarity
{
get{ return 0; }
}
public virtual int GetLuckBonus()
{
CraftResourceInfo resInfo = CraftResources.GetInfo( m_Resource );
if ( resInfo == null )
return 0;
CraftAttributeInfo attrInfo = resInfo.AttributeInfo;
if ( attrInfo == null )
return 0;
return attrInfo.WeaponLuck;
}
public override void GetProperties( ObjectPropertyList list )
{
base.GetProperties( list );
if ( m_Crafter != null )
list.Add( 1050043, m_Crafter.Name ); // crafted by ~1_NAME~
#region Factions
if ( m_FactionState != null )
list.Add( 1041350 ); // faction item
#endregion
if ( m_AosSkillBonuses != null )
m_AosSkillBonuses.GetProperties( list );
if ( m_Quality == WeaponQuality.Exceptional )
list.Add( 1060636 ); // exceptional
if( RequiredRace == Race.Elf )
list.Add( 1075086 ); // Elves Only
if ( ArtifactRarity > 0 )
list.Add( 1061078, ArtifactRarity.ToString() ); // artifact rarity ~1_val~
if ( this is IUsesRemaining && ((IUsesRemaining)this).ShowUsesRemaining )
list.Add( 1060584, ((IUsesRemaining)this).UsesRemaining.ToString() ); // uses remaining: ~1_val~
if ( m_Poison != null && m_PoisonCharges > 0 )
list.Add( 1062412 + m_Poison.Level, m_PoisonCharges.ToString() );
if( m_Slayer != SlayerName.None )
{
SlayerEntry entry = SlayerGroup.GetEntryByName( m_Slayer );
if( entry != null )
list.Add( entry.Title );
}
if( m_Slayer2 != SlayerName.None )
{
SlayerEntry entry = SlayerGroup.GetEntryByName( m_Slayer2 );
if( entry != null )
list.Add( entry.Title );
}
base.AddResistanceProperties( list );
int prop;
if ( (prop = m_AosWeaponAttributes.UseBestSkill) != 0 )
list.Add( 1060400 ); // use best weapon skill
if ( (prop = (GetDamageBonus() + m_AosAttributes.WeaponDamage)) != 0 )
list.Add( 1060401, prop.ToString() ); // damage increase ~1_val~%
if ( (prop = m_AosAttributes.DefendChance) != 0 )
list.Add( 1060408, prop.ToString() ); // defense chance increase ~1_val~%
if ( (prop = m_AosAttributes.EnhancePotions) != 0 )
list.Add( 1060411, prop.ToString() ); // enhance potions ~1_val~%
if ( (prop = m_AosAttributes.CastRecovery) != 0 )
list.Add( 1060412, prop.ToString() ); // faster cast recovery ~1_val~
if ( (prop = m_AosAttributes.CastSpeed) != 0 )
list.Add( 1060413, prop.ToString() ); // faster casting ~1_val~
if ( (prop = (GetHitChanceBonus() + m_AosAttributes.AttackChance)) != 0 )
list.Add( 1060415, prop.ToString() ); // hit chance increase ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitColdArea) != 0 )
list.Add( 1060416, prop.ToString() ); // hit cold area ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitDispel) != 0 )
list.Add( 1060417, prop.ToString() ); // hit dispel ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitEnergyArea) != 0 )
list.Add( 1060418, prop.ToString() ); // hit energy area ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitFireArea) != 0 )
list.Add( 1060419, prop.ToString() ); // hit fire area ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitFireball) != 0 )
list.Add( 1060420, prop.ToString() ); // hit fireball ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitHarm) != 0 )
list.Add( 1060421, prop.ToString() ); // hit harm ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitLeechHits) != 0 )
list.Add( 1060422, prop.ToString() ); // hit life leech ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitLightning) != 0 )
list.Add( 1060423, prop.ToString() ); // hit lightning ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitLowerAttack) != 0 )
list.Add( 1060424, prop.ToString() ); // hit lower attack ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitLowerDefend) != 0 )
list.Add( 1060425, prop.ToString() ); // hit lower defense ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitMagicArrow) != 0 )
list.Add( 1060426, prop.ToString() ); // hit magic arrow ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitLeechMana) != 0 )
list.Add( 1060427, prop.ToString() ); // hit mana leech ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitPhysicalArea) != 0 )
list.Add( 1060428, prop.ToString() ); // hit physical area ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitPoisonArea) != 0 )
list.Add( 1060429, prop.ToString() ); // hit poison area ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitLeechStam) != 0 )
list.Add( 1060430, prop.ToString() ); // hit stamina leech ~1_val~%
if ( (prop = m_AosAttributes.BonusDex) != 0 )
list.Add( 1060409, prop.ToString() ); // dexterity bonus ~1_val~
if ( (prop = m_AosAttributes.BonusHits) != 0 )
list.Add( 1060431, prop.ToString() ); // hit point increase ~1_val~
if ( (prop = m_AosAttributes.BonusInt) != 0 )
list.Add( 1060432, prop.ToString() ); // intelligence bonus ~1_val~
if ( (prop = m_AosAttributes.LowerManaCost) != 0 )
list.Add( 1060433, prop.ToString() ); // lower mana cost ~1_val~%
if ( (prop = m_AosAttributes.LowerRegCost) != 0 )
list.Add( 1060434, prop.ToString() ); // lower reagent cost ~1_val~%
if ( (prop = GetLowerStatReq()) != 0 )
list.Add( 1060435, prop.ToString() ); // lower requirements ~1_val~%
if ( (prop = (GetLuckBonus() + m_AosAttributes.Luck)) != 0 )
list.Add( 1060436, prop.ToString() ); // luck ~1_val~
if ( (prop = m_AosWeaponAttributes.MageWeapon) != 0 )
list.Add( 1060438, (30 - prop).ToString() ); // mage weapon -~1_val~ skill
if ( (prop = m_AosAttributes.BonusMana) != 0 )
list.Add( 1060439, prop.ToString() ); // mana increase ~1_val~
if ( (prop = m_AosAttributes.RegenMana) != 0 )
list.Add( 1060440, prop.ToString() ); // mana regeneration ~1_val~
if ( (prop = m_AosAttributes.NightSight) != 0 )
list.Add( 1060441 ); // night sight
if ( (prop = m_AosAttributes.ReflectPhysical) != 0 )
list.Add( 1060442, prop.ToString() ); // reflect physical damage ~1_val~%
if ( (prop = m_AosAttributes.RegenStam) != 0 )
list.Add( 1060443, prop.ToString() ); // stamina regeneration ~1_val~
if ( (prop = m_AosAttributes.RegenHits) != 0 )
list.Add( 1060444, prop.ToString() ); // hit point regeneration ~1_val~
if ( (prop = m_AosWeaponAttributes.SelfRepair) != 0 )
list.Add( 1060450, prop.ToString() ); // self repair ~1_val~
if ( (prop = m_AosAttributes.SpellChanneling) != 0 )
list.Add( 1060482 ); // spell channeling
if ( (prop = m_AosAttributes.SpellDamage) != 0 )
list.Add( 1060483, prop.ToString() ); // spell damage increase ~1_val~%
if ( (prop = m_AosAttributes.BonusStam) != 0 )
list.Add( 1060484, prop.ToString() ); // stamina increase ~1_val~
if ( (prop = m_AosAttributes.BonusStr) != 0 )
list.Add( 1060485, prop.ToString() ); // strength bonus ~1_val~
if ( (prop = m_AosAttributes.WeaponSpeed) != 0 )
list.Add( 1060486, prop.ToString() ); // swing speed increase ~1_val~%
int phys, fire, cold, pois, nrgy;
GetDamageTypes( null, out phys, out fire, out cold, out pois, out nrgy );
if ( phys != 0 )
list.Add( 1060403, phys.ToString() ); // physical damage ~1_val~%
if ( fire != 0 )
list.Add( 1060405, fire.ToString() ); // fire damage ~1_val~%
if ( cold != 0 )
list.Add( 1060404, cold.ToString() ); // cold damage ~1_val~%
if ( pois != 0 )
list.Add( 1060406, pois.ToString() ); // poison damage ~1_val~%
if ( nrgy != 0 )
list.Add( 1060407, nrgy.ToString() ); // energy damage ~1_val~%
list.Add( 1061168, "{0}\t{1}", MinDamage.ToString(), MaxDamage.ToString() ); // weapon damage ~1_val~ - ~2_val~
list.Add( 1061167, Speed.ToString() ); // weapon speed ~1_val~
if ( MaxRange > 1 )
list.Add( 1061169, MaxRange.ToString() ); // range ~1_val~
int strReq = AOS.Scale( StrRequirement, 100 - GetLowerStatReq() );
if ( strReq > 0 )
list.Add( 1061170, strReq.ToString() ); // strength requirement ~1_val~
if ( Layer == Layer.TwoHanded )
list.Add( 1061171 ); // two-handed weapon
else
list.Add( 1061824 ); // one-handed weapon
if ( Core.SE || m_AosWeaponAttributes.UseBestSkill == 0 )
{
switch ( Skill )
{
case SkillName.Swords: list.Add( 1061172 ); break; // skill required: swordsmanship
case SkillName.Macing: list.Add( 1061173 ); break; // skill required: mace fighting
case SkillName.Fencing: list.Add( 1061174 ); break; // skill required: fencing
case SkillName.Archery: list.Add( 1061175 ); break; // skill required: archery
}
}
if ( m_Hits >= 0 && m_MaxHits > 0 )
list.Add( 1060639, "{0}\t{1}", m_Hits, m_MaxHits ); // durability ~1_val~ / ~2_val~
}
public override void OnSingleClick( Mobile from )
{
List<EquipInfoAttribute> attrs = new List<EquipInfoAttribute>();
if ( DisplayLootType )
{
if ( LootType == LootType.Blessed )
attrs.Add( new EquipInfoAttribute( 1038021 ) ); // blessed
else if ( LootType == LootType.Cursed )
attrs.Add( new EquipInfoAttribute( 1049643 ) ); // cursed
}
#region Factions
if ( m_FactionState != null )
attrs.Add( new EquipInfoAttribute( 1041350 ) ); // faction item
#endregion
if ( m_Quality == WeaponQuality.Exceptional )
attrs.Add( new EquipInfoAttribute( 1018305 - (int)m_Quality ) );
if ( m_Identified || from.AccessLevel >= AccessLevel.GameMaster )
{
if( m_Slayer != SlayerName.None )
{
SlayerEntry entry = SlayerGroup.GetEntryByName( m_Slayer );
if( entry != null )
attrs.Add( new EquipInfoAttribute( entry.Title ) );
}
if( m_Slayer2 != SlayerName.None )
{
SlayerEntry entry = SlayerGroup.GetEntryByName( m_Slayer2 );
if( entry != null )
attrs.Add( new EquipInfoAttribute( entry.Title ) );
}
if ( m_DurabilityLevel != WeaponDurabilityLevel.Regular )
attrs.Add( new EquipInfoAttribute( 1038000 + (int)m_DurabilityLevel ) );
if ( m_DamageLevel != WeaponDamageLevel.Regular )
attrs.Add( new EquipInfoAttribute( 1038015 + (int)m_DamageLevel ) );
if ( m_AccuracyLevel != WeaponAccuracyLevel.Regular )
attrs.Add( new EquipInfoAttribute( 1038010 + (int)m_AccuracyLevel ) );
}
else if( m_Slayer != SlayerName.None || m_Slayer2 != SlayerName.None || m_DurabilityLevel != WeaponDurabilityLevel.Regular || m_DamageLevel != WeaponDamageLevel.Regular || m_AccuracyLevel != WeaponAccuracyLevel.Regular )
attrs.Add( new EquipInfoAttribute( 1038000 ) ); // Unidentified
if ( m_Poison != null && m_PoisonCharges > 0 )
attrs.Add( new EquipInfoAttribute( 1017383, m_PoisonCharges ) );
int number;
if ( Name == null )
{
number = LabelNumber;
}
else
{
this.LabelTo( from, Name );
number = 1041000;
}
if ( attrs.Count == 0 && Crafter == null && Name != null )
return;
EquipmentInfo eqInfo = new EquipmentInfo( number, m_Crafter, false, attrs.ToArray() );
from.Send( new DisplayEquipmentInfo( this, eqInfo ) );
}
private static BaseWeapon m_Fists; // This value holds the default--fist--weapon
public static BaseWeapon Fists
{
get{ return m_Fists; }
set{ m_Fists = value; }
}
#region ICraftable Members
public int OnCraft( int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool, CraftItem craftItem, int resHue )
{
Quality = (WeaponQuality)quality;
if ( makersMark )
Crafter = from;
PlayerConstructed = true;
Type resourceType = typeRes;
if ( resourceType == null )
resourceType = craftItem.Ressources.GetAt( 0 ).ItemType;
if ( Core.AOS )
{
Resource = CraftResources.GetFromType( resourceType );
CraftContext context = craftSystem.GetContext( from );
if ( context != null && context.DoNotColor )
Hue = 0;
if ( tool is BaseRunicTool )
((BaseRunicTool)tool).ApplyAttributesTo( this );
if ( Quality == WeaponQuality.Exceptional )
{
if ( Attributes.WeaponDamage > 35 )
Attributes.WeaponDamage -= 20;
else
Attributes.WeaponDamage = 15;
if( Core.ML )
{
Attributes.WeaponDamage += (int)(from.Skills.ArmsLore.Value / 20);
from.CheckSkill( SkillName.ArmsLore, 0, 100 );
}
}
}
else if ( tool is BaseRunicTool )
{
CraftResource thisResource = CraftResources.GetFromType( resourceType );
if ( thisResource == ((BaseRunicTool)tool).Resource )
{
Resource = thisResource;
CraftContext context = craftSystem.GetContext( from );
if ( context != null && context.DoNotColor )
Hue = 0;
switch ( thisResource )
{
case CraftResource.DullCopper:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Durable;
AccuracyLevel = WeaponAccuracyLevel.Accurate;
break;
}
case CraftResource.ShadowIron:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Durable;
DamageLevel = WeaponDamageLevel.Ruin;
break;
}
case CraftResource.Copper:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Fortified;
DamageLevel = WeaponDamageLevel.Ruin;
AccuracyLevel = WeaponAccuracyLevel.Surpassingly;
break;
}
case CraftResource.Bronze:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Fortified;
DamageLevel = WeaponDamageLevel.Might;
AccuracyLevel = WeaponAccuracyLevel.Surpassingly;
break;
}
case CraftResource.Gold:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Indestructible;
DamageLevel = WeaponDamageLevel.Force;
AccuracyLevel = WeaponAccuracyLevel.Eminently;
break;
}
case CraftResource.Agapite:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Indestructible;
DamageLevel = WeaponDamageLevel.Power;
AccuracyLevel = WeaponAccuracyLevel.Eminently;
break;
}
case CraftResource.Verite:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Indestructible;
DamageLevel = WeaponDamageLevel.Power;
AccuracyLevel = WeaponAccuracyLevel.Exceedingly;
break;
}
case CraftResource.Valorite:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Indestructible;
DamageLevel = WeaponDamageLevel.Vanq;
AccuracyLevel = WeaponAccuracyLevel.Supremely;
break;
}
}
}
}
return quality;
}
#endregion
}
public enum CheckSlayerResult
{
None,
Slayer,
Opposition
}
}
|
|
|
|
|
|
#2 (permalink) |
|
Master of the Internet
|
this section right here is where the resource is added
can either make it all by removing if AOS or move the resource stuff out of that section so it is always use Code:
if ( Core.AOS )
{
Resource = CraftResources.GetFromType( resourceType );
CraftContext context = craftSystem.GetContext( from );
if ( context != null && context.DoNotColor )
Hue = 0;
if ( tool is BaseRunicTool )
((BaseRunicTool)tool).ApplyAttributesTo( this );
if ( Quality == WeaponQuality.Exceptional )
{
if ( Attributes.WeaponDamage > 35 )
Attributes.WeaponDamage -= 20;
else
Attributes.WeaponDamage = 15;
if( Core.ML )
{
Attributes.WeaponDamage += (int)(from.Skills.ArmsLore.Value / 20);
from.CheckSkill( SkillName.ArmsLore, 0, 100 );
}
}
}
__________________
http://www.AoAUO.com
:) ..... Come for the Customs, Play for the Fun. Return to see your new Friends ..... :) |
|
|
|
|
|
#3 (permalink) |
|
Forum Novice
Join Date: May 2007
Posts: 142
|
Thanks so much that worked perfectly!
Possibly you can help me with another issue, the armor when crafted is not displaying the type of resource that was used (example: A shield made with shadowingots retains the color however does not say that it is made of shadow ore!) Do you know where i could find this and fix it? Thanks so much |
|
|
|
|
|
#4 (permalink) |
|
Master of the Internet
|
look in basearmor (also baseweapon and clothing, etc also) - search for shadowiron
you will find a long list or resources in a "switch" statement block that is where it adds the resource to the name it is probably marked if AOS also
__________________
http://www.AoAUO.com
:) ..... Come for the Customs, Play for the Fun. Return to see your new Friends ..... :) |
|
|
|
|
|
#5 (permalink) | |
|
Forum Novice
Join Date: May 2007
Posts: 142
|
Quote:
Ah i found where you are talking about, but unfortunatly it isnt marked AOS here is my bas weapon.cs: Code:
using System;
using System.Text;
using System.Collections;
using Server.Network;
using Server.Targeting;
using Server.Mobiles;
using Server.Spells;
using Server.Spells.Necromancy;
using Server.Spells.Bushido;
using Server.Spells.Ninjitsu;
using Server.Factions;
using Server.Engines.Craft;
using System.Collections.Generic;
using Server.Spells.Spellweaving;
namespace Server.Items
{
public interface ISlayer
{
SlayerName Slayer { get; set; }
SlayerName Slayer2 { get; set; }
}
public abstract class BaseWeapon : Item, IWeapon, IFactionItem, ICraftable, ISlayer, IDurability
{
#region Factions
private FactionItem m_FactionState;
public FactionItem FactionItemState
{
get{ return m_FactionState; }
set
{
m_FactionState = value;
if ( m_FactionState == null )
Hue = CraftResources.GetHue( Resource );
LootType = ( m_FactionState == null ? LootType.Regular : LootType.Blessed );
}
}
#endregion
/* Weapon internals work differently now (Mar 13 2003)
*
* The attributes defined below default to -1.
* If the value is -1, the corresponding virtual 'Aos/Old' property is used.
* If not, the attribute value itself is used. Here's the list:
* - MinDamage
* - MaxDamage
* - Speed
* - HitSound
* - MissSound
* - StrRequirement, DexRequirement, IntRequirement
* - WeaponType
* - WeaponAnimation
* - MaxRange
*/
#region Var declarations
// Instance values. These values are unique to each weapon.
private WeaponDamageLevel m_DamageLevel;
private WeaponAccuracyLevel m_AccuracyLevel;
private WeaponDurabilityLevel m_DurabilityLevel;
private WeaponQuality m_Quality;
private Mobile m_Crafter;
private Poison m_Poison;
private int m_PoisonCharges;
private bool m_Identified;
private int m_Hits;
private int m_MaxHits;
private SlayerName m_Slayer;
private SlayerName m_Slayer2;
private SkillMod m_SkillMod, m_MageMod;
private CraftResource m_Resource;
private bool m_PlayerConstructed;
private bool m_Cursed; // Is this weapon cursed via Curse Weapon necromancer spell? Temporary; not serialized.
private bool m_Consecrated; // Is this weapon blessed via Consecrate Weapon paladin ability? Temporary; not serialized.
private AosAttributes m_AosAttributes;
private AosWeaponAttributes m_AosWeaponAttributes;
private AosSkillBonuses m_AosSkillBonuses;
private AosElementAttributes m_AosElementDamages;
// Overridable values. These values are provided to override the defaults which get defined in the individual weapon scripts.
private int m_StrReq, m_DexReq, m_IntReq;
private int m_MinDamage, m_MaxDamage;
private int m_HitSound, m_MissSound;
private int m_Speed;
private int m_MaxRange;
private SkillName m_Skill;
private WeaponType m_Type;
private WeaponAnimation m_Animation;
#endregion
#region Virtual Properties
public virtual WeaponAbility PrimaryAbility{ get{ return null; } }
public virtual WeaponAbility SecondaryAbility{ get{ return null; } }
public virtual int DefMaxRange{ get{ return 1; } }
public virtual int DefHitSound{ get{ return 0; } }
public virtual int DefMissSound{ get{ return 0; } }
public virtual SkillName DefSkill{ get{ return SkillName.Swords; } }
public virtual WeaponType DefType{ get{ return WeaponType.Slashing; } }
public virtual WeaponAnimation DefAnimation{ get{ return WeaponAnimation.Slash1H; } }
public virtual int AosStrengthReq{ get{ return 0; } }
public virtual int AosDexterityReq{ get{ return 0; } }
public virtual int AosIntelligenceReq{ get{ return 0; } }
public virtual int AosMinDamage{ get{ return 0; } }
public virtual int AosMaxDamage{ get{ return 0; } }
public virtual int AosSpeed{ get{ return 0; } }
public virtual int AosMaxRange{ get{ return DefMaxRange; } }
public virtual int AosHitSound{ get{ return DefHitSound; } }
public virtual int AosMissSound{ get{ return DefMissSound; } }
public virtual SkillName AosSkill{ get{ return DefSkill; } }
public virtual WeaponType AosType{ get{ return DefType; } }
public virtual WeaponAnimation AosAnimation{ get{ return DefAnimation; } }
public virtual int OldStrengthReq{ get{ return 0; } }
public virtual int OldDexterityReq{ get{ return 0; } }
public virtual int OldIntelligenceReq{ get{ return 0; } }
public virtual int OldMinDamage{ get{ return 0; } }
public virtual int OldMaxDamage{ get{ return 0; } }
public virtual int OldSpeed{ get{ return 0; } }
public virtual int OldMaxRange{ get{ return DefMaxRange; } }
public virtual int OldHitSound{ get{ return DefHitSound; } }
public virtual int OldMissSound{ get{ return DefMissSound; } }
public virtual SkillName OldSkill{ get{ return DefSkill; } }
public virtual WeaponType OldType{ get{ return DefType; } }
public virtual WeaponAnimation OldAnimation{ get{ return DefAnimation; } }
public virtual int InitMinHits{ get{ return 0; } }
public virtual int InitMaxHits{ get{ return 0; } }
public override int PhysicalResistance{ get{ return m_AosWeaponAttributes.ResistPhysicalBonus; } }
public override int FireResistance{ get{ return m_AosWeaponAttributes.ResistFireBonus; } }
public override int ColdResistance{ get{ return m_AosWeaponAttributes.ResistColdBonus; } }
public override int PoisonResistance{ get{ return m_AosWeaponAttributes.ResistPoisonBonus; } }
public override int EnergyResistance{ get{ return m_AosWeaponAttributes.ResistEnergyBonus; } }
public virtual SkillName AccuracySkill { get { return SkillName.Tactics; } }
#endregion
#region Getters & Setters
[CommandProperty( AccessLevel.GameMaster )]
public AosAttributes Attributes
{
get{ return m_AosAttributes; }
set{}
}
[CommandProperty( AccessLevel.GameMaster )]
public AosWeaponAttributes WeaponAttributes
{
get{ return m_AosWeaponAttributes; }
set{}
}
[CommandProperty( AccessLevel.GameMaster )]
public AosSkillBonuses SkillBonuses
{
get{ return m_AosSkillBonuses; }
set{}
}
[CommandProperty( AccessLevel.GameMaster )]
public AosElementAttributes AosElementDamages
{
get { return m_AosElementDamages; }
set { }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool Cursed
{
get{ return m_Cursed; }
set{ m_Cursed = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool Consecrated
{
get{ return m_Consecrated; }
set{ m_Consecrated = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool Identified
{
get{ return m_Identified; }
set{ m_Identified = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int HitPoints
{
get{ return m_Hits; }
set
{
if ( m_Hits == value )
return;
if ( value > m_MaxHits )
value = m_MaxHits;
m_Hits = value;
InvalidateProperties();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int MaxHitPoints
{
get{ return m_MaxHits; }
set{ m_MaxHits = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int PoisonCharges
{
get{ return m_PoisonCharges; }
set{ m_PoisonCharges = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public Poison Poison
{
get{ return m_Poison; }
set{ m_Poison = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public WeaponQuality Quality
{
get{ return m_Quality; }
set{ UnscaleDurability(); m_Quality = value; ScaleDurability(); InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public Mobile Crafter
{
get{ return m_Crafter; }
set{ m_Crafter = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public SlayerName Slayer
{
get{ return m_Slayer; }
set{ m_Slayer = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public SlayerName Slayer2
{
get { return m_Slayer2; }
set { m_Slayer2 = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public CraftResource Resource
{
get{ return m_Resource; }
set{ UnscaleDurability(); m_Resource = value; Hue = CraftResources.GetHue( m_Resource ); InvalidateProperties(); ScaleDurability(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public WeaponDamageLevel DamageLevel
{
get{ return m_DamageLevel; }
set{ m_DamageLevel = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public WeaponDurabilityLevel DurabilityLevel
{
get{ return m_DurabilityLevel; }
set{ UnscaleDurability(); m_DurabilityLevel = value; InvalidateProperties(); ScaleDurability(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool PlayerConstructed
{
get{ return m_PlayerConstructed; }
set{ m_PlayerConstructed = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public int MaxRange
{
get{ return ( m_MaxRange == -1 ? Core.AOS ? AosMaxRange : OldMaxRange : m_MaxRange ); }
set{ m_MaxRange = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public WeaponAnimation Animation
{
get{ return ( m_Animation == (WeaponAnimation)(-1) ? Core.AOS ? AosAnimation : OldAnimation : m_Animation ); }
set{ m_Animation = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public WeaponType Type
{
get{ return ( m_Type == (WeaponType)(-1) ? Core.AOS ? AosType : OldType : m_Type ); }
set{ m_Type = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public SkillName Skill
{
get{ return ( m_Skill == (SkillName)(-1) ? Core.AOS ? AosSkill : OldSkill : m_Skill ); }
set{ m_Skill = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int HitSound
{
get{ return ( m_HitSound == -1 ? Core.AOS ? AosHitSound : OldHitSound : m_HitSound ); }
set{ m_HitSound = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public int MissSound
{
get{ return ( m_MissSound == -1 ? Core.AOS ? AosMissSound : OldMissSound : m_MissSound ); }
set{ m_MissSound = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public int MinDamage
{
get{ return ( m_MinDamage == -1 ? Core.AOS ? AosMinDamage : OldMinDamage : m_MinDamage ); }
set{ m_MinDamage = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int MaxDamage
{
get{ return ( m_MaxDamage == -1 ? Core.AOS ? AosMaxDamage : OldMaxDamage : m_MaxDamage ); }
set{ m_MaxDamage = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int Speed
{
get{ return ( m_Speed == -1 ? Core.AOS ? AosSpeed : OldSpeed : m_Speed ); }
set{ m_Speed = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int StrRequirement
{
get{ return ( m_StrReq == -1 ? Core.AOS ? AosStrengthReq : OldStrengthReq : m_StrReq ); }
set{ m_StrReq = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int DexRequirement
{
get{ return ( m_DexReq == -1 ? Core.AOS ? AosDexterityReq : OldDexterityReq : m_DexReq ); }
set{ m_DexReq = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public int IntRequirement
{
get{ return ( m_IntReq == -1 ? Core.AOS ? AosIntelligenceReq : OldIntelligenceReq : m_IntReq ); }
set{ m_IntReq = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public WeaponAccuracyLevel AccuracyLevel
{
get
{
return m_AccuracyLevel;
}
set
{
if ( m_AccuracyLevel != value )
{
m_AccuracyLevel = value;
if ( UseSkillMod )
{
if ( m_AccuracyLevel == WeaponAccuracyLevel.Regular )
{
if ( m_SkillMod != null )
m_SkillMod.Remove();
m_SkillMod = null;
}
else if ( m_SkillMod == null && Parent is Mobile )
{
m_SkillMod = new DefaultSkillMod( AccuracySkill, true, (int)m_AccuracyLevel * 5 );
((Mobile)Parent).AddSkillMod( m_SkillMod );
}
else if ( m_SkillMod != null )
{
m_SkillMod.Value = (int)m_AccuracyLevel * 5;
}
}
InvalidateProperties();
}
}
}
#endregion
public virtual void UnscaleDurability()
{
int scale = 100 + GetDurabilityBonus();
m_Hits = ((m_Hits * 100) + (scale - 1)) / scale;
m_MaxHits = ((m_MaxHits * 100) + (scale - 1)) / scale;
InvalidateProperties();
}
public virtual void ScaleDurability()
{
int scale = 100 + GetDurabilityBonus();
m_Hits = ((m_Hits * scale) + 99) / 100;
m_MaxHits = ((m_MaxHits * scale) + 99) / 100;
InvalidateProperties();
}
public int GetDurabilityBonus()
{
int bonus = 0;
if ( m_Quality == WeaponQuality.Exceptional )
bonus += 20;
switch ( m_DurabilityLevel )
{
case WeaponDurabilityLevel.Durable: bonus += 20; break;
case WeaponDurabilityLevel.Substantial: bonus += 50; break;
case WeaponDurabilityLevel.Massive: bonus += 70; break;
case WeaponDurabilityLevel.Fortified: bonus += 100; break;
case WeaponDurabilityLevel.Indestructible: bonus += 120; break;
}
if ( Core.AOS )
{
bonus += m_AosWeaponAttributes.DurabilityBonus;
CraftResourceInfo resInfo = CraftResources.GetInfo( m_Resource );
CraftAttributeInfo attrInfo = null;
if ( resInfo != null )
attrInfo = resInfo.AttributeInfo;
if ( attrInfo != null )
bonus += attrInfo.WeaponDurability;
}
return bonus;
}
public int GetLowerStatReq()
{
if ( !Core.AOS )
return 0;
int v = m_AosWeaponAttributes.LowerStatReq;
CraftResourceInfo info = CraftResources.GetInfo( m_Resource );
if ( info != null )
{
CraftAttributeInfo attrInfo = info.AttributeInfo;
if ( attrInfo != null )
v += attrInfo.WeaponLowerRequirements;
}
if ( v > 100 )
v = 100;
return v;
}
public static void BlockEquip( Mobile m, TimeSpan duration )
{
if ( m.BeginAction( typeof( BaseWeapon ) ) )
new ResetEquipTimer( m, duration ).Start();
}
private class ResetEquipTimer : Timer
{
private Mobile m_Mobile;
public ResetEquipTimer( Mobile m, TimeSpan duration ) : base( duration )
{
m_Mobile = m;
}
protected override void OnTick()
{
m_Mobile.EndAction( typeof( BaseWeapon ) );
}
}
public override bool CheckConflictingLayer( Mobile m, Item item, Layer layer )
{
if ( base.CheckConflictingLayer( m, item, layer ) )
return true;
if ( this.Layer == Layer.TwoHanded && layer == Layer.OneHanded )
{
m.SendLocalizedMessage( 500214 ); // You already have something in both hands.
return true;
}
else if ( this.Layer == Layer.OneHanded && layer == Layer.TwoHanded && !(item is BaseShield) && !(item is BaseEquipableLight) )
{
m.SendLocalizedMessage( 500215 ); // You can only wield one weapon at a time.
return true;
}
return false;
}
public override bool AllowSecureTrade( Mobile from, Mobile to, Mobile newOwner, bool accepted )
{
if ( !Ethics.Ethic.CheckTrade( from, to, newOwner, this ) )
return false;
return base.AllowSecureTrade( from, to, newOwner, accepted );
}
public virtual Race RequiredRace { get { return null; } } //On OSI, there are no weapons with race requirements, this is for custom stuff
public override bool CanEquip( Mobile from )
{
if ( !Ethics.Ethic.CheckEquip( from, this ) )
return false;
if( RequiredRace != null && from.Race != RequiredRace )
{
if( RequiredRace == Race.Elf )
from.SendLocalizedMessage( 1072203 ); // Only Elves may use this.
else
from.SendMessage( "Only {0} may use this.", RequiredRace.PluralName );
return false;
}
else if ( from.Dex < DexRequirement )
{
from.SendMessage( "You are not nimble enough to equip that." );
return false;
}
else if ( from.Str < AOS.Scale( StrRequirement, 100 - GetLowerStatReq() ) )
{
from.SendLocalizedMessage( 500213 ); // You are not strong enough to equip that.
return false;
}
else if ( from.Int < IntRequirement )
{
from.SendMessage( "You are not smart enough to equip that." );
return false;
}
else if ( !from.CanBeginAction( typeof( BaseWeapon ) ) )
{
return false;
}
else
{
return base.CanEquip( from );
}
}
public virtual bool UseSkillMod{ get{ return !Core.AOS; } }
public override bool OnEquip( Mobile from )
{
int strBonus = m_AosAttributes.BonusStr;
int dexBonus = m_AosAttributes.BonusDex;
int intBonus = m_AosAttributes.BonusInt;
if ( (strBonus != 0 || dexBonus != 0 || intBonus != 0) )
{
Mobile m = from;
string modName = this.Serial.ToString();
if ( strBonus != 0 )
m.AddStatMod( new StatMod( StatType.Str, modName + "Str", strBonus, TimeSpan.Zero ) );
if ( dexBonus != 0 )
m.AddStatMod( new StatMod( StatType.Dex, modName + "Dex", dexBonus, TimeSpan.Zero ) );
if ( intBonus != 0 )
m.AddStatMod( new StatMod( StatType.Int, modName + "Int", intBonus, TimeSpan.Zero ) );
}
from.NextCombatTime = DateTime.Now + GetDelay( from );
if ( UseSkillMod && m_AccuracyLevel != WeaponAccuracyLevel.Regular )
{
if ( m_SkillMod != null )
m_SkillMod.Remove();
m_SkillMod = new DefaultSkillMod( AccuracySkill, true, (int)m_AccuracyLevel * 5 );
from.AddSkillMod( m_SkillMod );
}
if ( Core.AOS && m_AosWeaponAttributes.MageWeapon != 0 && m_AosWeaponAttributes.MageWeapon != 30 )
{
if ( m_MageMod != null )
m_MageMod.Remove();
m_MageMod = new DefaultSkillMod( SkillName.Magery, true, -30 + m_AosWeaponAttributes.MageWeapon );
from.AddSkillMod( m_MageMod );
}
return true;
}
public override void OnAdded( object parent )
{
base.OnAdded( parent );
if ( parent is Mobile )
{
Mobile from = (Mobile)parent;
if ( Core.AOS )
m_AosSkillBonuses.AddTo( from );
from.CheckStatTimers();
from.Delta( MobileDelta.WeaponDamage );
}
}
public override void OnRemoved( object parent )
{
if ( parent is Mobile )
{
Mobile m = (Mobile)parent;
BaseWeapon weapon = m.Weapon as BaseWeapon;
string modName = this.Serial.ToString();
m.RemoveStatMod( modName + "Str" );
m.RemoveStatMod( modName + "Dex" );
m.RemoveStatMod( modName + "Int" );
if ( weapon != null )
m.NextCombatTime = DateTime.Now + weapon.GetDelay( m );
if ( UseSkillMod && m_SkillMod != null )
{
m_SkillMod.Remove();
m_SkillMod = null;
}
if ( m_MageMod != null )
{
m_MageMod.Remove();
m_MageMod = null;
}
if ( Core.AOS )
m_AosSkillBonuses.Remove();
m.CheckStatTimers();
m.Delta( MobileDelta.WeaponDamage );
}
}
public virtual SkillName GetUsedSkill( Mobile m, bool checkSkillAttrs )
{
SkillName sk;
if ( checkSkillAttrs && m_AosWeaponAttributes.UseBestSkill != 0 )
{
double swrd = m.Skills[SkillName.Swords].Value;
double fenc = m.Skills[SkillName.Fencing].Value;
double mcng = m.Skills[SkillName.Macing].Value;
double val;
sk = SkillName.Swords;
val = swrd;
if ( fenc > val ){ sk = SkillName.Fencing; val = fenc; }
if ( mcng > val ){ sk = SkillName.Macing; val = mcng; }
}
else if ( m_AosWeaponAttributes.MageWeapon != 0 )
{
if ( m.Skills[SkillName.Magery].Value > m.Skills[Skill].Value )
sk = SkillName.Magery;
else
sk = Skill;
}
else
{
sk = Skill;
if ( sk != SkillName.Wrestling && !m.Player && !m.Body.IsHuman && m.Skills[SkillName.Wrestling].Value > m.Skills[sk].Value )
sk = SkillName.Wrestling;
}
return sk;
}
public virtual double GetAttackSkillValue( Mobile attacker, Mobile defender )
{
return attacker.Skills[GetUsedSkill( attacker, true )].Value;
}
public virtual double GetDefendSkillValue( Mobile attacker, Mobile defender )
{
return defender.Skills[GetUsedSkill( defender, true )].Value;
}
private static bool CheckAnimal( Mobile m, Type type )
{
return AnimalForm.UnderTransformation( m, type );
}
public virtual bool CheckHit( Mobile attacker, Mobile defender )
{
BaseWeapon atkWeapon = attacker.Weapon as BaseWeapon;
BaseWeapon defWeapon = defender.Weapon as BaseWeapon;
Skill atkSkill = attacker.Skills[atkWeapon.Skill];
Skill defSkill = defender.Skills[defWeapon.Skill];
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();
if ( Core.AOS )
{
if ( atkValue <= -20.0 )
atkValue = -19.9;
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;
if ( Spells.Chivalry.DivineFurySpell.UnderEffect( attacker ) )
bonus += 10; // attacker gets 10% bonus when they're under divine fury
if ( CheckAnimal( attacker, typeof( GreyWolf ) ) || CheckAnimal( attacker, typeof( BakeKitsune ) ) )
bonus += 20; // attacker gets 20% bonus when under Wolf or Bake Kitsune form
if ( HitLower.IsUnderAttackEffect( attacker ) )
bonus -= 25; // Under Hit Lower Attack effect -> 25% malus
ourValue = (atkValue + 20.0) * (100 + bonus);
// Defense Chance Increase = 45%
bonus = AosAttributes.GetValue( defender, AosAttribute.DefendChance );
if ( bonus > 45 )
bonus = 45;
if ( Spells.Chivalry.DivineFurySpell.UnderEffect( defender ) )
bonus -= 20; // defender loses 20% bonus when they're under divine fury
if ( HitLower.IsUnderDefenseEffect( defender ) )
bonus -= 25; // Under Hit Lower Defense effect -> 25% malus
int blockBonus = 0;
if ( Block.GetBonus( defender, ref blockBonus ) )
bonus += blockBonus;
int surpriseMalus = 0;
if ( SurpriseAttack.GetMalus( defender, ref surpriseMalus ) )
bonus -= surpriseMalus;
int discordanceEffect = 0;
// Defender loses -0/-28% if under the effect of Discordance.
if ( SkillHandlers.Discordance.GetEffect( attacker, ref discordanceEffect ) )
bonus -= discordanceEffect;
theirValue = (defValue + 20.0) * (100 + bonus);
bonus = 0;
}
else
{
if ( atkValue <= -50.0 )
atkValue = -49.9;
if ( defValue <= -50.0 )
defValue = -49.9;
ourValue = (atkValue + 50.0);
theirValue = (defValue + 50.0);
}
double chance = ourValue / (theirValue * 2.0);
chance *= 1.0 + ((double)bonus / 100);
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 )
{
int speed = this.Speed;
if ( speed == 0 )
return TimeSpan.FromHours( 1.0 );
double delayInSeconds;
if ( Core.SE )
{
/*
* This is likely true for Core.AOS as well... both guides report the same
* formula, and both are wrong.
* The old formula left in for AOS for legacy & because we aren't quite 100%
* Sure that AOS has THIS formula
*/
int bonus = AosAttributes.GetValue( m, AosAttribute.WeaponSpeed );
if ( Spells.Chivalry.DivineFurySpell.UnderEffect( m ) )
bonus += 10;
// Bonus granted by successful use of Honorable Execution.
bonus += HonorableExecution.GetSwingBonus( m );
if( DualWield.Registry.Contains( m ) )
bonus += ((DualWield.DualWieldTimer)DualWield.Registry[m]).BonusSwingSpeed;
if( Feint.Registry.Contains( m ) )
bonus -= ((Feint.FeintTimer)Feint.Registry[m]).SwingSpeedReduction;
TransformContext context = TransformationSpellHelper.GetContext( m );
if( context != null && context.Spell is ReaperFormSpell )
bonus += ((ReaperFormSpell)context.Spell).SwingSpeedBonus;
int discordanceEffect = 0;
// Discordance gives a malus of -0/-28% to swing speed.
if ( SkillHandlers.Discordance.GetEffect( m, ref discordanceEffect ) )
bonus -= discordanceEffect;
if( EssenceOfWindSpell.IsDebuffed( m ) )
bonus -= EssenceOfWindSpell.GetSSIMalus( m );
if ( bonus > 60 )
bonus = 60;
speed = (int)Math.Floor( speed * (bonus + 100.0) / 100.0 );
if ( speed <= 0 )
speed = 1;
int ticks = (int)Math.Floor( (80000.0 / ((m.Stam + 100) * speed)) - 2 );
// Swing speed currently capped at one swing every 1.25 seconds (5 ticks).
if ( ticks < 5 )
ticks = 5;
delayInSeconds = ticks * 0.25;
}
else if ( Core.AOS )
{
int v = (m.Stam + 100) * speed;
int bonus = AosAttributes.GetValue( m, AosAttribute.WeaponSpeed );
if ( Spells.Chivalry.DivineFurySpell.UnderEffect( m ) )
bonus += 10;
int discordanceEffect = 0;
// Discordance gives a malus of -0/-28% to swing speed.
if ( SkillHandlers.Discordance.GetEffect( m, ref discordanceEffect ) )
bonus -= discordanceEffect;
v += AOS.Scale( v, bonus );
if ( v <= 0 )
v = 1;
delayInSeconds = Math.Floor( 40000.0 / v ) * 0.5;
// Maximum swing rate capped at one swing per second
// OSI dev said that it has and is supposed to be 1.25
if ( delayInSeconds < 0.55 )
delayInSeconds = 0.55;
}
else
{
int v = (m.Stam + 100) * speed;
if ( v <= 0 )
v = 1;
delayInSeconds = 15000.0 / v;
}
return TimeSpan.FromSeconds( delayInSeconds );
}
public virtual void OnBeforeSwing( Mobile attacker, Mobile defender )
{
WeaponAbility a = WeaponAbility.GetCurrentAbility( attacker );
if( a != null && !a.OnBeforeSwing( attacker, defender ) )
WeaponAbility.ClearCurrentAbility( attacker );
SpecialMove move = SpecialMove.GetCurrentMove( attacker );
if( move != null && !move.OnBeforeSwing( attacker, defender ) )
SpecialMove.ClearCurrentMove( attacker );
}
public virtual TimeSpan OnSwing( Mobile attacker, Mobile defender )
{
return OnSwing( attacker, defender, 1.0 );
}
public virtual TimeSpan OnSwing( Mobile attacker, Mobile defender, double damageBonus )
{
bool canSwing = true;
if ( Core.AOS )
{
canSwing = ( !attacker.Paralyzed && !attacker.Frozen );
if ( canSwing )
{
Spell sp = attacker.Spell as Spell;
canSwing = ( sp == null || !sp.IsCasting || !sp.BlocksMovement );
}
}
if ( canSwing && attacker.HarmfulCheck( defender ) )
{
attacker.DisruptiveAction();
if ( attacker.NetState != null )
attacker.Send( new Swing( 0, attacker, defender ) );
if ( attacker is BaseCreature )
{
BaseCreature bc = (BaseCreature)attacker;
WeaponAbility ab = bc.GetWeaponAbility();
if ( ab != null )
{
if ( bc.WeaponAbilityChance > Utility.RandomDouble() )
WeaponAbility.SetCurrentAbility( bc, ab );
else
WeaponAbility.ClearCurrentAbility( bc );
}
}
if ( CheckHit( attacker, defender ) )
OnHit( attacker, defender, damageBonus );
else
OnMiss( attacker, defender );
}
return GetDelay( attacker );
}
#region Sounds
public virtual int GetHitAttackSound( Mobile attacker, Mobile defender )
{
int sound = attacker.GetAttackSound();
if ( sound == -1 )
sound = HitSound;
return sound;
}
public virtual int GetHitDefendSound( Mobile attacker, Mobile defender )
{
return defender.GetHurtSound();
}
public virtual int GetMissAttackSound( Mobile attacker, Mobile defender )
{
if ( attacker.GetAttackSound() == -1 )
return MissSound;
else
return -1;
}
public virtual int GetMissDefendSound( Mobile attacker, Mobile defender )
{
return -1;
}
#endregion
public static bool CheckParry( Mobile defender )
{
if ( defender == null )
return false;
BaseShield shield = defender.FindItemOnLayer( Layer.TwoHanded ) as BaseShield;
double parry = defender.Skills[SkillName.Parry].Value;
double bushidoNonRacial = defender.Skills[SkillName.Bushido].NonRacialValue;
double bushido = defender.Skills[SkillName.Bushido].Value;
if ( shield != null )
{
double chance = (parry - bushidoNonRacial) / 400.0; //As per OSI, no negitive effect from the Racial stuffs, ie, 120 parry and '0' bushido with humans
// Parry over 100 grants a 5% bonus.
if ( parry >= 100.0 )
chance += 0.05;
// Evasion grants a variable bonus post ML. 50% prior.
if ( Evasion.IsEvading( defender ) )
chance *= Evasion.GetParryScalar( defender );
// Low dexterity lowers the chance.
if ( defender.Dex < 80 )
chance = chance * (20 + defender.Dex) / 100;
return defender.CheckSkill( SkillName.Parry, chance );
}
else if ( !(defender.Weapon is Fists) && !(defender.Weapon is BaseRanged) )
{
BaseWeapon weapon = defender.Weapon as BaseWeapon;
double divisor = (weapon.Layer == Layer.OneHanded) ? 48000.0 : 41140.0;
double chance = (parry * bushido) / divisor;
double aosChance = parry / 800.0;
// Parry or Bushido over 100 grant a 5% bonus.
if( parry >= 100.0 )
{
chance += 0.05;
aosChance += 0.05;
}
else if( bushido >= 100.0 )
{
chance += 0.05;
}
// Evasion grants a variable bonus post ML. 50% prior.
if( Evasion.IsEvading( defender ) )
chance *= Evasion.GetParryScalar( defender );
// Low dexterity lowers the chance.
if( defender.Dex < 80 )
chance = chance * (20 + defender.Dex) / 100;
if ( chance > aosChance )
return defender.CheckSkill( SkillName.Parry, chance );
else
return (aosChance > Utility.RandomDouble()); // Only skillcheck if wielding a shield & there's no effect from Bushido
}
return false;
}
public virtual int AbsorbDamageAOS( Mobile attacker, Mobile defender, int damage )
{
bool blocked = false;
if ( defender.Player || defender.Body.IsHuman )
{
blocked = CheckParry( defender );
if ( blocked )
{
defender.FixedEffect( 0x37B9, 10, 16 );
damage = 0;
// Successful block removes the Honorable Execution penalty.
HonorableExecution.RemovePenalty( defender );
if ( CounterAttack.IsCountering( defender ) )
{
BaseWeapon weapon = defender.Weapon as BaseWeapon;
if ( weapon != null )
weapon.OnSwing( defender, attacker );
CounterAttack.StopCountering( defender );
}
if ( Confidence.IsConfident( defender ) )
{
defender.SendLocalizedMessage( 1063117 ); // Your confidence reassures you as you successfully block your opponent's blow.
double bushido = defender.Skills.Bushido.Value;
defender.Hits += Utility.RandomMinMax( 1, (int)(bushido / 12) );
defender.Stam += Utility.RandomMinMax( 1, (int)(bushido / 5) );
}
BaseShield shield = defender.FindItemOnLayer( Layer.TwoHanded ) as BaseShield;
if ( shield != null )
{
shield.OnHit( this, damage );
}
}
}
if ( !blocked )
{
double positionChance = Utility.RandomDouble();
Item armorItem;
if( positionChance < 0.07 )
armorItem = defender.NeckArmor;
else if( positionChance < 0.14 )
armorItem = defender.HandArmor;
else if( positionChance < 0.28 )
armorItem = defender.ArmsArmor;
else if( positionChance < 0.43 )
armorItem = defender.HeadArmor;
else if( positionChance < 0.65 )
armorItem = defender.LegsArmor;
else
armorItem = defender.ChestArmor;
IWearableDurability armor = armorItem as IWearableDurability;
if ( armor != null )
armor.OnHit( this, damage ); // call OnHit to lose durability
}
return damage;
}
public virtual int AbsorbDamage( Mobile attacker, Mobile defender, int damage )
{
if ( Core.AOS )
return AbsorbDamageAOS( attacker, defender, damage );
double chance = Utility.RandomDouble();
Item armorItem;
if( chance < 0.07 )
armorItem = defender.NeckArmor;
else if( chance < 0.14 )
armorItem = defender.HandArmor;
else if( chance < 0.28 )
armorItem = defender.ArmsArmor;
else if( chance < 0.43 )
armorItem = defender.HeadArmor;
else if( chance < 0.65 )
armorItem = defender.LegsArmor;
else
armorItem = defender.ChestArmor;
IWearableDurability armor = armorItem as IWearableDurability;
if ( armor != null )
damage = armor.OnHit( this, damage );
BaseShield shield = defender.FindItemOnLayer( Layer.TwoHanded ) as BaseShield;
if ( shield != null )
damage = shield.OnHit( this, damage );
int virtualArmor = defender.VirtualArmor + defender.VirtualArmorMod;
if ( virtualArmor > 0 )
{
double scalar;
if ( chance < 0.14 )
scalar = 0.07;
else if ( chance < 0.28 )
scalar = 0.14;
else if ( chance < 0.43 )
scalar = 0.15;
else if ( chance < 0.65 )
scalar = 0.22;
else
scalar = 0.35;
int from = (int)(virtualArmor * scalar) / 2;
int to = (int)(virtualArmor * scalar);
damage -= Utility.Random( from, (to - from) + 1 );
}
return damage;
}
public virtual int GetPackInstinctBonus( Mobile attacker, Mobile defender )
{
if ( attacker.Player || defender.Player )
return 0;
BaseCreature bc = attacker as BaseCreature;
if ( bc == null || bc.PackInstinct == PackInstinct.None || (!bc.Controlled && !bc.Summoned) )
return 0;
Mobile master = bc.ControlMaster;
if ( master == null )
master = bc.SummonMaster;
if ( master == null )
return 0;
int inPack = 1;
foreach ( Mobile m in defender.GetMobilesInRange( 1 ) )
{
if ( m != attacker && m is BaseCreature )
{
BaseCreature tc = (BaseCreature)m;
if ( (tc.PackInstinct & bc.PackInstinct) == 0 || (!tc.Controlled && !tc.Summoned) )
continue;
Mobile theirMaster = tc.ControlMaster;
if ( theirMaster == null )
theirMaster = tc.SummonMaster;
if ( master == theirMaster && tc.Combatant == defender )
++inPack;
}
}
if ( inPack >= 5 )
return 100;
else if ( inPack >= 4 )
return 75;
else if ( inPack >= 3 )
return 50;
else if ( inPack >= 2 )
return 25;
return 0;
}
private static bool m_InDoubleStrike;
public static bool InDoubleStrike
{
get{ return m_InDoubleStrike; }
set{ m_InDoubleStrike = value; }
}
public void OnHit( Mobile attacker, Mobile defender )
{
OnHit( attacker, defender, 1.0 );
}
public virtual void OnHit( Mobile attacker, Mobile defender, double damageBonus )
{
if ( MirrorImage.HasClone( defender ) && (defender.Skills.Ninjitsu.Value / 150.0) > Utility.RandomDouble() )
{
Clone bc;
foreach ( Mobile m in defender.GetMobilesInRange( 4 ) )
{
bc = m as Clone;
if ( bc != null && bc.Summoned && bc.SummonMaster == defender )
{
attacker.SendLocalizedMessage( 1063141 ); // Your attack has been diverted to a nearby mirror image of your target!
defender.SendLocalizedMessage( 1063140 ); // You manage to divert the attack onto one of your nearby mirror images.
/*
* TODO: What happens if the Clone parries a blow?
* And what about if the attacker is using Honorable Execution
* and kills it?
*/
defender = m;
break;
}
}
}
PlaySwingAnimation( attacker );
PlayHurtAnimation( defender );
attacker.PlaySound( GetHitAttackSound( attacker, defender ) );
defender.PlaySound( GetHitDefendSound( attacker, defender ) );
int damage = ComputeDamage( attacker, defender );
#region Damage Multipliers
/*
* The following damage bonuses multiply damage by a factor.
* Capped at x3 (300%).
*/
//double factor = 1.0;
int percentageBonus = 0;
WeaponAbility a = WeaponAbility.GetCurrentAbility( attacker );
SpecialMove move = SpecialMove.GetCurrentMove( attacker );
if( a != null )
{
//factor *= a.DamageScalar;
percentageBonus += (int)(a.DamageScalar * 100) - 100;
}
if( move != null )
{
//factor *= move.GetDamageScalar( attacker, defender );
percentageBonus += (int)(move.GetDamageScalar( attacker, defender ) * 100) - 100;
}
//factor *= damageBonus;
percentageBonus += (int)(damageBonus * 100) - 100;
CheckSlayerResult cs = CheckSlayers( attacker, defender );
if ( cs != CheckSlayerResult.None )
{
if ( cs == CheckSlayerResult.Slayer )
defender.FixedEffect( 0x37B9, 10, 5 );
//factor *= 2.0;
percentageBonus += 100;
}
if ( !attacker.Player )
{
if ( defender is PlayerMobile )
{
PlayerMobile pm = (PlayerMobile)defender;
if( pm.EnemyOfOneType != null && pm.EnemyOfOneType != attacker.GetType() )
{
//factor *= 2.0;
percentageBonus += 100;
}
}
}
else if ( !defender.Player )
{
if ( attacker is PlayerMobile )
{
PlayerMobile pm = (PlayerMobile)attacker;
if ( pm.WaitingForEnemy )
{
pm.EnemyOfOneType = defender.GetType();
pm.WaitingForEnemy = false;
}
if ( pm.EnemyOfOneType == defender.GetType() )
{
defender.FixedEffect( 0x37B9, 10, 5, 1160, 0 );
//factor *= 1.5;
percentageBonus += 50;
}
}
}
int packInstinctBonus = GetPackInstinctBonus( attacker, defender );
if( packInstinctBonus != 0 )
{
//factor *= 1.0 + (double)packInstinctBonus / 100.0;
percentageBonus += packInstinctBonus;
}
if( m_InDoubleStrike )
{
//factor *= 0.9; // 10% loss when attacking with double-strike
percentageBonus -= 10;
}
TransformContext context = TransformationSpellHelper.GetContext( defender );
if( (m_Slayer == SlayerName.Silver || m_Slayer2 == SlayerName.Silver) && context != null && context.Spell is NecromancerSpell && context.Type != typeof( HorrificBeastSpell ) )
{
//factor *= 1.25; // Every necromancer transformation other than horrific beast takes an additional 25% damage
percentageBonus += 25;
}
if ( attacker is PlayerMobile && !(Core.ML && defender is PlayerMobile ))
{
PlayerMobile pmAttacker = (PlayerMobile) attacker;
if( pmAttacker.HonorActive && pmAttacker.InRange( defender, 1 ) )
{
//factor *= 1.25;
percentageBonus += 25;
}
if( pmAttacker.SentHonorContext != null && pmAttacker.SentHonorContext.Target == defender )
{
//pmAttacker.SentHonorContext.ApplyPerfectionDamageBonus( ref factor );
percentageBonus += pmAttacker.SentHonorContext.PerfectionDamageBonus;
}
}
//if ( factor > 3.0 )
// factor = 3.0;
percentageBonus = Math.Min( percentageBonus, 300 );
//damage = (int)(damage * factor);
damage = AOS.Scale( damage, 100 + percentageBonus );
#endregion
if ( attacker is BaseCreature )
((BaseCreature)attacker).AlterMeleeDamageTo( defender, ref damage );
if ( defender is BaseCreature )
((BaseCreature)defender).AlterMeleeDamageFrom( attacker, ref damage );
damage = AbsorbDamage( attacker, defender, damage );
if ( !Core.AOS && damage < 1 )
damage = 1;
else if ( Core.AOS && damage == 0 ) // parried
{
if ( a != null && a.Validate( attacker ) /*&& a.CheckMana( attacker, true )*/ ) // Parried special moves have no mana cost
{
a = null;
WeaponAbility.ClearCurrentAbility( attacker );
attacker.SendLocalizedMessage( 1061140 ); // Your attack was parried!
}
}
AddBlood( attacker, defender, damage );
int phys, fire, cold, pois, nrgy;
GetDamageTypes( attacker, out phys, out fire, out cold, out pois, out nrgy );
if ( m_Consecrated )
{
phys = defender.PhysicalResistance;
fire = defender.FireResistance;
cold = defender.ColdResistance;
pois = defender.PoisonResistance;
nrgy = defender.EnergyResistance;
int low = phys, type = 0;
if ( fire < low ){ low = fire; type = 1; }
if ( cold < low ){ low = cold; type = 2; }
if ( pois < low ){ low = pois; type = 3; }
if ( nrgy < low ){ low = nrgy; type = 4; }
phys = fire = cold = pois = nrgy = 0;
if ( type == 0 ) phys = 100;
else if ( type == 1 ) fire = 100;
else if ( type == 2 ) cold = 100;
else if ( type == 3 ) pois = 100;
else if ( type == 4 ) nrgy = 100;
}
int damageGiven = damage;
if ( a != null && !a.OnBeforeDamage( attacker, defender ) )
{
WeaponAbility.ClearCurrentAbility( attacker );
a = null;
}
if ( move != null && !move.OnBeforeDamage( attacker, defender ) )
{
SpecialMove.ClearCurrentMove( attacker );
move = null;
}
bool ignoreArmor = ( a is ArmorIgnore || (move != null && move.IgnoreArmor( attacker )) );
damageGiven = AOS.Damage( defender, attacker, damage, ignoreArmor, phys, fire, cold, pois, nrgy );
double propertyBonus = ( move == null ) ? 1.0 : move.GetPropertyBonus( attacker );
if ( Core.AOS )
{
int lifeLeech = 0;
int stamLeech = 0;
int manaLeech = 0;
int wraithLeech = 0;
if ( (int)(m_AosWeaponAttributes.HitLeechHits * propertyBonus) > Utility.Random( 100 ) )
lifeLeech += 30; // HitLeechHits% chance to leech 30% of damage as hit points
if ( (int)(m_AosWeaponAttributes.HitLeechStam * propertyBonus) > Utility.Random( 100 ) )
stamLeech += 100; // HitLeechStam% chance to leech 100% of damage as stamina
if ( (int)(m_AosWeaponAttributes.HitLeechMana * propertyBonus) > Utility.Random( 100 ) )
manaLeech += 40; // HitLeechMana% chance to leech 40% of damage as mana
if ( m_Cursed )
lifeLeech += 50; // Additional 50% life leech for cursed weapons (necro spell)
context = TransformationSpellHelper.GetContext( attacker );
if ( context != null && context.Type == typeof( VampiricEmbraceSpell ) )
lifeLeech += 20; // Vampiric embrace gives an additional 20% life leech
if ( context != null && context.Type == typeof( WraithFormSpell ) )
{
wraithLeech = (5 + (int)((15 * attacker.Skills.SpiritSpeak.Value) / 100)); // Wraith form gives an additional 5-20% mana leech
// Mana leeched by the Wraith Form spell is actually stolen, not just leeched.
defender.Mana -= AOS.Scale( damageGiven, wraithLeech );
manaLeech += wraithLeech;
}
if ( lifeLeech != 0 )
attacker.Hits += AOS.Scale( damageGiven, lifeLeech );
if ( stamLeech != 0 )
attacker.Stam += AOS.Scale( damageGiven, stamLeech );
if ( manaLeech != 0 )
attacker.Mana += AOS.Scale( damageGiven, manaLeech );
if ( lifeLeech != 0 || stamLeech != 0 || manaLeech != 0 )
attacker.PlaySound( 0x44D );
}
if ( m_MaxHits > 0 && ((MaxRange <= 1 && (defender is Slime || defender is ToxicElemental)) || Utility.Random( 25 ) == 0) ) // Stratics says 50% chance, seems more like 4%..
{
if ( MaxRange <= 1 && (defender is Slime || defender is ToxicElemental) )
attacker.LocalOverheadMessage( MessageType.Regular, 0x3B2, 500263 ); // *Acid blood scars your weapon!*
if ( Core.AOS && m_AosWeaponAttributes.SelfRepair > Utility.Random( 10 ) )
{
HitPoints += 2;
}
else
{
if ( m_Hits > 0 )
{
--HitPoints;
}
else if ( m_MaxHits > 1 )
{
--MaxHitPoints;
if ( Parent is Mobile )
((Mobile)Parent).LocalOverheadMessage( MessageType.Regular, 0x3B2, 1061121 ); // Your equipment is severely damaged.
}
else
{
Delete();
}
}
}
if ( attacker is VampireBatFamiliar )
{
BaseCreature bc = (BaseCreature)attacker;
Mobile caster = bc.ControlMaster;
if ( caster == null )
caster = bc.SummonMaster;
if ( caster != null && caster.Map == bc.Map && caster.InRange( bc, 2 ) )
caster.Hits += damage;
else
bc.Hits += damage;
}
if ( Core.AOS )
{
int physChance = (int)(m_AosWeaponAttributes.HitPhysicalArea * propertyBonus);
int fireChance = (int)(m_AosWeaponAttributes.HitFireArea * propertyBonus);
int coldChance = (int)(m_AosWeaponAttributes.HitColdArea * propertyBonus);
int poisChance = (int)(m_AosWeaponAttributes.HitPoisonArea * propertyBonus);
int nrgyChance = (int)(m_AosWeaponAttributes.HitEnergyArea * propertyBonus);
if ( physChance != 0 && physChance > Utility.Random( 100 ) )
DoAreaAttack( attacker, defender, 0x10E, 50, 100, 0, 0, 0, 0 );
if ( fireChance != 0 && fireChance > Utility.Random( 100 ) )
DoAreaAttack( attacker, defender, 0x11D, 1160, 0, 100, 0, 0, 0 );
if ( coldChance != 0 && coldChance > Utility.Random( 100 ) )
DoAreaAttack( attacker, defender, 0x0FC, 2100, 0, 0, 100, 0, 0 );
if ( poisChance != 0 && poisChance > Utility.Random( 100 ) )
DoAreaAttack( attacker, defender, 0x205, 1166, 0, 0, 0, 100, 0 );
if ( nrgyChance != 0 && nrgyChance > Utility.Random( 100 ) )
DoAreaAttack( attacker, defender, 0x1F1, 120, 0, 0, 0, 0, 100 );
int maChance = (int)(m_AosWeaponAttributes.HitMagicArrow * propertyBonus);
int harmChance = (int)(m_AosWeaponAttributes.HitHarm * propertyBonus);
int fireballChance = (int)(m_AosWeaponAttributes.HitFireball * propertyBonus);
int lightningChance = (int)(m_AosWeaponAttributes.HitLightning * propertyBonus);
int dispelChance = (int)(m_AosWeaponAttributes.HitDispel * propertyBonus);
if ( maChance != 0 && maChance > Utility.Random( 100 ) )
DoMagicArrow( attacker, defender );
if ( harmChance != 0 && harmChance > Utility.Random( 100 ) )
DoHarm( attacker, defender );
if ( fireballChance != 0 && fireballChance > Utility.Random( 100 ) )
DoFireball( attacker, defender );
if ( lightningChance != 0 && lightningChance > Utility.Random( 100 ) )
DoLightning( attacker, defender );
if ( dispelChance != 0 && dispelChance > Utility.Random( 100 ) )
DoDispel( attacker, defender );
int laChance = (int)(m_AosWeaponAttributes.HitLowerAttack * propertyBonus);
int ldChance = (int)(m_AosWeaponAttributes.HitLowerDefend * propertyBonus);
if ( laChance != 0 && laChance > Utility.Random( 100 ) )
DoLowerAttack( attacker, defender );
if ( ldChance != 0 && ldChance > Utility.Random( 100 ) )
DoLowerDefense( attacker, defender );
}
if ( attacker is BaseCreature )
((BaseCreature)attacker).OnGaveMeleeAttack( defender );
if ( defender is BaseCreature )
((BaseCreature)defender).OnGotMeleeAttack( attacker );
if ( a != null )
a.OnHit( attacker, defender, damage );
if ( move != null )
move.OnHit( attacker, defender, damage );
if ( defender is IHonorTarget && ((IHonorTarget)defender).ReceivedHonorContext != null )
((IHonorTarget)defender).ReceivedHonorContext.OnTargetHit( attacker );
if ( !(this is BaseRanged) )
{
if ( AnimalForm.UnderTransformation( attacker, typeof( GiantSerpent ) ) )
defender.ApplyPoison( attacker, Poison.Lesser );
if ( AnimalForm.UnderTransformation( defender, typeof( BullFrog ) ) )
attacker.ApplyPoison( defender, Poison.Regular );
}
}
public virtual double GetAosDamage( Mobile attacker, int bonus, int dice, int sides )
{
int damage = Utility.Dice( dice, sides, bonus ) * 100;
int damageBonus = 0;
// Inscription bonus
int inscribeSkill = attacker.Skills[SkillName.Inscribe].Fixed;
damageBonus += inscribeSkill / 200;
if ( inscribeSkill >= 1000 )
damageBonus += 5;
if ( attacker.Player )
{
// Int bonus
damageBonus += (attacker.Int / 10);
// SDI bonus
damageBonus += AosAttributes.GetValue( attacker, AosAttribute.SpellDamage );
TransformContext context = TransformationSpellHelper.GetContext( attacker );
if( context != null && context.Spell is ReaperFormSpell )
damageBonus += ((ReaperFormSpell)context.Spell).SpellDamageBonus;
}
damage = AOS.Scale( damage, 100 + damageBonus );
return damage / 100;
}
#region Do<AoSEffect>
public virtual void DoMagicArrow( Mobile attacker, Mobile defender )
{
if ( !attacker.CanBeHarmful( defender, false ) )
return;
attacker.DoHarmful( defender );
double damage = GetAosDamage( attacker, 10, 1, 4 );
attacker.MovingParticles( defender, 0x36E4, 5, 0, false, true, 3006, 4006, 0 );
attacker.PlaySound( 0x1E5 );
SpellHelper.Damage( TimeSpan.FromSeconds( 1.0 ), defender, attacker, damage, 0, 100, 0, 0, 0 );
}
public virtual void DoHarm( Mobile attacker, Mobile defender )
{
if ( !attacker.CanBeHarmful( defender, false ) )
return;
attacker.DoHarmful( defender );
double damage = GetAosDamage( attacker, 17, 1, 5 );
if ( !defender.InRange( attacker, 2 ) )
damage *= 0.25; // 1/4 damage at > 2 tile range
else if ( !defender.InRange( attacker, 1 ) )
damage *= 0.50; // 1/2 damage at 2 tile range
defender.FixedParticles( 0x374A, 10, 30, 5013, 1153, 2, EffectLayer.Waist );
defender.PlaySound( 0x0FC );
SpellHelper.Damage( TimeSpan.Zero, defender, attacker, damage, 0, 0, 100, 0, 0 );
}
public virtual void DoFireball( Mobile attacker, Mobile defender )
{
if ( !attacker.CanBeHarmful( defender, false ) )
return;
attacker.DoHarmful( defender );
double damage = GetAosDamage( attacker, 19, 1, 5 );
attacker.MovingParticles( defender, 0x36D4, 7, 0, false, true, 9502, 4019, 0x160 );
attacker.PlaySound( 0x15E );
SpellHelper.Damage( TimeSpan.FromSeconds( 1.0 ), defender, attacker, damage, 0, 100, 0, 0, 0 );
}
public virtual void DoLightning( Mobile attacker, Mobile defender )
{
if ( !attacker.CanBeHarmful( defender, false ) )
return;
attacker.DoHarmful( defender );
double damage = GetAosDamage( attacker, 23, 1, 4 );
defender.BoltEffect( 0 );
SpellHelper.Damage( TimeSpan.Zero, defender, attacker, damage, 0, 0, 0, 0, 100 );
}
public virtual void DoDispel( Mobile attacker, Mobile defender )
{
bool dispellable = false;
if ( defender is BaseCreature )
dispellable = ((BaseCreature)defender).Summoned && !((BaseCreature)defender).IsAnimatedDead;
if ( !dispellable )
return;
if ( !attacker.CanBeHarmful( defender, false ) )
return;
attacker.DoHarmful( defender );
Spells.MagerySpell sp = new Spells.Sixth.DispelSpell( attacker, null );
if ( sp.CheckResisted( defender ) )
{
defender.FixedEffect( 0x3779, 10, 20 );
}
else
{
Effects.SendLocationParticles( EffectItem.Create( defender.Location, defender.Map, EffectItem.DefaultDuration ), 0x3728, 8, 20, 5042 );
Effects.PlaySound( defender, defender.Map, 0x201 );
defender.Delete();
}
}
public virtual void DoLowerAttack( Mobile from, Mobile defender )
{
if ( HitLower.ApplyAttack( defender ) )
{
defender.PlaySound( 0x28E );
Effects.SendTargetEffect( defender, 0x37BE, 1, 4, 0xA, 3 );
}
}
public virtual void DoLowerDefense( Mobile from, Mobile defender )
{
if ( HitLower.ApplyDefense( defender ) )
{
defender.PlaySound( 0x28E );
Effects.SendTargetEffect( defender, 0x37BE, 1, 4, 0x23, 3 );
}
}
public virtual void DoAreaAttack( Mobile from, Mobile defender, int sound, int hue, int phys, int fire, int cold, int pois, int nrgy )
{
Map map = from.Map;
if ( map == null )
return;
List<Mobile> list = new List<Mobile>();
foreach ( Mobile m in from.GetMobilesInRange( 10 ) )
{
if ( from != m && defender != m && SpellHelper.ValidIndirectTarget( from, m ) && from.CanBeHarmful( m, false ) && ( !Core.ML || from.InLOS( m ) ) )
list.Add( m );
}
if ( list.Count == 0 )
return;
Effects.PlaySound( from.Location, map, sound );
// TODO: What is the damage calculation?
for ( int i = 0; i < list.Count; ++i )
{
Mobile m = list[i];
double scalar = (11 - from.GetDistanceToSqrt( m )) / 10;
if ( scalar > 1.0 )
scalar = 1.0;
else if ( scalar < 0.0 )
continue;
from.DoHarmful( m, true );
m.FixedEffect( 0x3779, 1, 15, hue, 0 );
AOS.Damage( m, from, (int)(GetBaseDamage( from ) * scalar), phys, fire, cold, pois, nrgy );
}
}
#endregion
public virtual CheckSlayerResult CheckSlayers( Mobile attacker, Mobile defender )
{
BaseWeapon atkWeapon = attacker.Weapon as BaseWeapon;
SlayerEntry atkSlayer = SlayerGroup.GetEntryByName( atkWeapon.Slayer );
SlayerEntry atkSlayer2 = SlayerGroup.GetEntryByName( atkWeapon.Slayer2 );
if ( atkSlayer != null && atkSlayer.Slays( defender ) || atkSlayer2 != null && atkSlayer2.Slays( defender ) )
return CheckSlayerResult.Slayer;
if ( !Core.SE )
{
ISlayer defISlayer = Spellbook.FindEquippedSpellbook( defender );
if( defISlayer == null )
defISlayer = defender.Weapon as ISlayer;
if( defISlayer != null )
{
SlayerEntry defSlayer = SlayerGroup.GetEntryByName( defISlayer.Slayer );
SlayerEntry defSlayer2 = SlayerGroup.GetEntryByName( defISlayer.Slayer2 );
if( defSlayer != null && defSlayer.Group.OppositionSuperSlays( attacker ) || defSlayer2 != null && defSlayer2.Group.OppositionSuperSlays( attacker ) )
return CheckSlayerResult.Opposition;
}
}
return CheckSlayerResult.None;
}
public virtual void AddBlood( Mobile attacker, Mobile defender, int damage )
{
if ( damage > 0 )
{
new Blood().MoveToWorld( defender.Location, defender.Map );
int extraBlood = (Core.SE ? Utility.RandomMinMax( 3, 4 ) : Utility.RandomMinMax( 0, 1 ) );
for( int i = 0; i < extraBlood; i++ )
{
new Blood().MoveToWorld( new Point3D(
defender.X + Utility.RandomMinMax( -1, 1 ),
defender.Y + Utility.RandomMinMax( -1, 1 ),
defender.Z ), defender.Map );
}
}
}
public virtual void GetDamageTypes( Mobile wielder, out int phys, out int fire, out int cold, out int pois, out int nrgy )
{
if( wielder is BaseCreature )
{
BaseCreature bc = (BaseCreature)wielder;
phys = bc.PhysicalDamage;
fire = bc.FireDamage;
cold = bc.ColdDamage;
pois = bc.PoisonDamage;
nrgy = bc.EnergyDamage;
}
else
{
fire = m_AosElementDamages.Fire;
cold = m_AosElementDamages.Cold;
pois = m_AosElementDamages.Poison;
nrgy = m_AosElementDamages.Energy;
phys = 100 - fire - cold - pois - nrgy;
CraftResourceInfo resInfo = CraftResources.GetInfo( m_Resource );
if( resInfo != null )
{
CraftAttributeInfo attrInfo = resInfo.AttributeInfo;
if( attrInfo != null )
{
int left = phys;
left = ApplyCraftAttributeElementDamage( attrInfo.WeaponColdDamage, ref cold, left );
left = ApplyCraftAttributeElementDamage( attrInfo.WeaponEnergyDamage, ref nrgy, left );
left = ApplyCraftAttributeElementDamage( attrInfo.WeaponFireDamage, ref fire, left );
left = ApplyCraftAttributeElementDamage( attrInfo.WeaponPoisonDamage, ref pois, left );
phys = left;
}
}
}
}
private int ApplyCraftAttributeElementDamage( int attrDamage, ref int element, int totalRemaining )
{
if( totalRemaining <= 0 )
return 0;
if ( attrDamage <= 0 )
return totalRemaining;
int appliedDamage = attrDamage;
if ( (appliedDamage + element) > 100 )
appliedDamage = 100 - element;
if( appliedDamage > totalRemaining )
appliedDamage = totalRemaining;
element += appliedDamage;
return totalRemaining - appliedDamage;
}
public virtual void OnMiss( Mobile attacker, Mobile defender )
{
PlaySwingAnimation( attacker );
attacker.PlaySound( GetMissAttackSound( attacker, defender ) );
defender.PlaySound( GetMissDefendSound( attacker, defender ) );
WeaponAbility ability = WeaponAbility.GetCurrentAbility( attacker );
if ( ability != null )
ability.OnMiss( attacker, defender );
SpecialMove move = SpecialMove.GetCurrentMove( attacker );
if ( move != null )
move.OnMiss( attacker, defender );
if ( defender is IHonorTarget && ((IHonorTarget)defender).ReceivedHonorContext != null )
((IHonorTarget)defender).ReceivedHonorContext.OnTargetMissed( attacker );
}
public virtual void GetBaseDamageRange( Mobile attacker, out int min, out int max )
{
if ( attacker is BaseCreature )
{
BaseCreature c = (BaseCreature)attacker;
if ( c.DamageMin >= 0 )
{
min = c.DamageMin;
max = c.DamageMax;
return;
}
if ( this is Fists && !attacker.Body.IsHuman )
{
min = attacker.Str / 28;
max = attacker.Str / 28;
return;
}
}
min = MinDamage;
max = MaxDamage;
}
public virtual double GetBaseDamage( Mobile attacker )
{
int min, max;
GetBaseDamageRange( attacker, out min, out max );
return Utility.RandomMinMax( min, max );
}
public virtual double GetBonus( double value, double scalar, double threshold, double offset )
{
double bonus = value * scalar;
if ( value >= threshold )
bonus += offset;
return bonus / 100;
}
public virtual int GetHitChanceBonus()
{
if ( !Core.AOS )
return 0;
int bonus = 0;
switch ( m_AccuracyLevel )
{
case WeaponAccuracyLevel.Accurate: bonus += 02; break;
case WeaponAccuracyLevel.Surpassingly: bonus += 04; break;
case WeaponAccuracyLevel.Eminently: bonus += 06; break;
case WeaponAccuracyLevel.Exceedingly: bonus += 08; break;
case WeaponAccuracyLevel.Supremely: bonus += 10; break;
}
return bonus;
}
public virtual int GetDamageBonus()
{
int bonus = VirtualDamageBonus;
switch ( m_Quality )
{
case WeaponQuality.Low: bonus -= 20; break;
case WeaponQuality.Exceptional: bonus += 20; break;
}
switch ( m_DamageLevel )
{
case WeaponDamageLevel.Ruin: bonus += 15; break;
case WeaponDamageLevel.Might: bonus += 20; break;
case WeaponDamageLevel.Force: bonus += 25; break;
case WeaponDamageLevel.Power: bonus += 30; break;
case WeaponDamageLevel.Vanq: bonus += 35; break;
}
return bonus;
}
public virtual void GetStatusDamage( Mobile from, out int min, out int max )
{
int baseMin, baseMax;
GetBaseDamageRange( from, out baseMin, out baseMax );
if ( Core.AOS )
{
min = Math.Max( (int)ScaleDamageAOS( from, baseMin, false ), 1 );
max = Math.Max( (int)ScaleDamageAOS( from, baseMax, false ), 1 );
}
else
{
min = Math.Max( (int)ScaleDamageOld( from, baseMin, false ), 1 );
max = Math.Max( (int)ScaleDamageOld( from, baseMax, false ), 1 );
}
}
public virtual double ScaleDamageAOS( Mobile attacker, double damage, bool checkSkills )
{
if ( checkSkills )
{
attacker.CheckSkill( SkillName.Tactics, 0.0, 120.0 ); // Passively check tactics for gain
attacker.CheckSkill( SkillName.Anatomy, 0.0, 120.0 ); // Passively check Anatomy for gain
if ( Type == WeaponType.Axe )
attacker.CheckSkill( SkillName.Lumberjacking, 0.0, 100.0 ); // Passively check Lumberjacking for gain
}
#region Physical bonuses
/*
* These are the bonuses given by the physical characteristics of the mobile.
* No caps apply.
*/
double strengthBonus = GetBonus( attacker.Str, 0.300, 100.0, 5.00 );
double anatomyBonus = GetBonus( attacker.Skills[SkillName.Anatomy].Value, 0.500, 100.0, 5.00 );
double tacticsBonus = GetBonus( attacker.Skills[SkillName.Tactics].Value, 0.625, 100.0, 6.25 );
double lumberBonus = GetBonus( attacker.Skills[SkillName.Lumberjacking].Value, 0.200, 100.0, 10.00 );
if ( Type != WeaponType.Axe )
lumberBonus = 0.0;
#endregion
#region Modifiers
/*
* The following are damage modifiers whose effect shows on the status bar.
* Capped at 100% total.
*/
int damageBonus = AosAttributes.GetValue( attacker, AosAttribute.WeaponDamage );
// Horrific Beast transformation gives a +25% bonus to damage.
if( TransformationSpellHelper.UnderTransformation( attacker, typeof( HorrificBeastSpell ) ) )
damageBonus += 25;
// Divine Fury gives a +10% bonus to damage.
if ( Spells.Chivalry.DivineFurySpell.UnderEffect( attacker ) )
damageBonus += 10;
int defenseMasteryMalus = 0;
// Defense Mastery gives a -50%/-80% malus to damage.
if ( Server.Items.DefenseMastery.GetMalus( attacker, ref defenseMasteryMalus ) )
damageBonus -= defenseMasteryMalus;
int discordanceEffect = 0;
// Discordance gives a -2%/-48% malus to damage.
if ( SkillHandlers.Discordance.GetEffect( attacker, ref discordanceEffect ) )
damageBonus -= discordanceEffect * 2;
if ( damageBonus > 100 )
damageBonus = 100;
#endregion
double totalBonus = strengthBonus + anatomyBonus + tacticsBonus + lumberBonus + ((double)(GetDamageBonus() + damageBonus) / 100.0);
return damage + (int)(damage * totalBonus);
}
public virtual int VirtualDamageBonus{ get{ return 0; } }
public virtual int ComputeDamageAOS( Mobile attacker, Mobile defender )
{
return (int)ScaleDamageAOS( attacker, GetBaseDamage( attacker ), true );
}
public virtual double ScaleDamageOld( Mobile attacker, double damage, bool checkSkills )
{
if ( checkSkills )
{
attacker.CheckSkill( SkillName.Tactics, 0.0, 120.0 ); // Passively check tactics for gain
attacker.CheckSkill( SkillName.Anatomy, 0.0, 120.0 ); // Passively check Anatomy for gain
if ( Type == WeaponType.Axe )
attacker.CheckSkill( SkillName.Lumberjacking, 0.0, 100.0 ); // Passively check Lumberjacking for gain
}
/* Compute tactics modifier
* : 0.0 = 50% loss
* : 50.0 = unchanged
* : 100.0 = 50% bonus
*/
double tacticsBonus = (attacker.Skills[SkillName.Tactics].Value - 50.0) / 100.0;
/* Compute strength modifier
* : 1% bonus for every 5 strength
*/
double strBonus = (attacker.Str / 5.0) / 100.0;
/* Compute anatomy modifier
* : 1% bonus for every 5 points of anatomy
* : +10% bonus at Grandmaster or higher
*/
double anatomyValue = attacker.Skills[SkillName.Anatomy].Value;
double anatomyBonus = (anatomyValue / 5.0) / 100.0;
if ( anatomyValue >= 100.0 )
anatomyBonus += 0.1;
/* Compute lumberjacking bonus
* : 1% bonus for every 5 points of lumberjacking
* : +10% bonus at Grandmaster or higher
*/
double lumberBonus;
if ( Type == WeaponType.Axe )
{
double lumberValue = attacker.Skills[SkillName.Lumberjacking].Value;
lumberBonus = (lumberValue / 5.0) / 100.0;
if ( lumberValue >= 100.0 )
lumberBonus += 0.1;
}
else
{
lumberBonus = 0.0;
}
// New quality bonus:
double qualityBonus = ((int)m_Quality - 1) * 0.2;
// Apply bonuses
damage += (damage * tacticsBonus) + (damage * strBonus) + (damage * anatomyBonus) + (damage * lumberBonus) + (damage * qualityBonus) + ((damage * VirtualDamageBonus) / 100);
// Old quality bonus:
#if false
/* Apply quality offset
* : Low : -4
* : Regular : 0
* : Exceptional : +4
*/
damage += ((int)m_Quality - 1) * 4.0;
#endif
/* Apply damage level offset
* : Regular : 0
* : Ruin : 1
* : Might : 3
* : Force : 5
* : Power : 7
* : Vanq : 9
*/
if ( m_DamageLevel != WeaponDamageLevel.Regular )
damage += (2.0 * (int)m_DamageLevel) - 1.0;
// Halve the computed damage and return
damage /= 2.0;
return ScaleDamageByDurability( (int)damage );
}
public virtual int ScaleDamageByDurability( int damage )
{
int scale = 100;
if ( m_MaxHits > 0 && m_Hits < m_MaxHits )
scale = 50 + ((50 * m_Hits) / m_MaxHits);
return AOS.Scale( damage, scale );
}
public virtual int ComputeDamage( Mobile attacker, Mobile defender )
{
if ( Core.AOS )
return ComputeDamageAOS( attacker, defender );
return (int)ScaleDamageOld( attacker, GetBaseDamage( attacker ), true );
}
public virtual void PlayHurtAnimation( Mobile from )
{
int action;
int frames;
switch ( from.Body.Type )
{
case BodyType.Sea:
case BodyType.Animal:
{
action = 7;
frames = 5;
break;
}
case BodyType.Monster:
{
action = 10;
frames = 4;
break;
}
case BodyType.Human:
{
action = 20;
frames = 5;
break;
}
default: return;
}
if ( from.Mounted )
return;
from.Animate( action, frames, 1, true, false, 0 );
}
public virtual void PlaySwingAnimation( Mobile from )
{
int action;
switch ( from.Body.Type )
{
case BodyType.Sea:
case BodyType.Animal:
{
action = Utility.Random( 5, 2 );
break;
}
case BodyType.Monster:
{
switch ( Animation )
{
default:
case WeaponAnimation.Wrestle:
case WeaponAnimation.Bash1H:
case WeaponAnimation.Pierce1H:
case WeaponAnimation.Slash1H:
case WeaponAnimation.Bash2H:
case WeaponAnimation.Pierce2H:
case WeaponAnimation.Slash2H: action = Utility.Random( 4, 3 ); break;
case WeaponAnimation.ShootBow: return; // 7
case WeaponAnimation.ShootXBow: return; // 8
}
break;
}
case BodyType.Human:
{
if ( !from.Mounted )
{
action = (int)Animation;
}
else
{
switch ( Animation )
{
default:
case WeaponAnimation.Wrestle:
case WeaponAnimation.Bash1H:
case WeaponAnimation.Pierce1H:
case WeaponAnimation.Slash1H: action = 26; break;
case WeaponAnimation.Bash2H:
case WeaponAnimation.Pierce2H:
case WeaponAnimation.Slash2H: action = 29; break;
case WeaponAnimation.ShootBow: action = 27; break;
case WeaponAnimation.ShootXBow: action = 28; break;
}
}
break;
}
default: return;
}
from.Animate( action, 7, 1, true, false, 0 );
}
#region Serialization/Deserialization
private static void SetSaveFlag( ref SaveFlag flags, SaveFlag toSet, bool setIf )
{
if ( setIf )
flags |= toSet;
}
private static bool GetSaveFlag( SaveFlag flags, SaveFlag toGet )
{
return ( (flags & toGet) != 0 );
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 8 ); // version
SaveFlag flags = SaveFlag.None;
SetSaveFlag( ref flags, SaveFlag.DamageLevel, m_DamageLevel != WeaponDamageLevel.Regular );
SetSaveFlag( ref flags, SaveFlag.AccuracyLevel, m_AccuracyLevel != WeaponAccuracyLevel.Regular );
SetSaveFlag( ref flags, SaveFlag.DurabilityLevel, m_DurabilityLevel != WeaponDurabilityLevel.Regular );
SetSaveFlag( ref flags, SaveFlag.Quality, m_Quality != WeaponQuality.Regular );
SetSaveFlag( ref flags, SaveFlag.Hits, m_Hits != 0 );
SetSaveFlag( ref flags, SaveFlag.MaxHits, m_MaxHits != 0 );
SetSaveFlag( ref flags, SaveFlag.Slayer, m_Slayer != SlayerName.None );
SetSaveFlag( ref flags, SaveFlag.Poison, m_Poison != null );
SetSaveFlag( ref flags, SaveFlag.PoisonCharges, m_PoisonCharges != 0 );
SetSaveFlag( ref flags, SaveFlag.Crafter, m_Crafter != null );
SetSaveFlag( ref flags, SaveFlag.Identified, m_Identified != false );
SetSaveFlag( ref flags, SaveFlag.StrReq, m_StrReq != -1 );
SetSaveFlag( ref flags, SaveFlag.DexReq, m_DexReq != -1 );
SetSaveFlag( ref flags, SaveFlag.IntReq, m_IntReq != -1 );
SetSaveFlag( ref flags, SaveFlag.MinDamage, m_MinDamage != -1 );
SetSaveFlag( ref flags, SaveFlag.MaxDamage, m_MaxDamage != -1 );
SetSaveFlag( ref flags, SaveFlag.HitSound, m_HitSound != -1 );
SetSaveFlag( ref flags, SaveFlag.MissSound, m_MissSound != -1 );
SetSaveFlag( ref flags, SaveFlag.Speed, m_Speed != -1 );
SetSaveFlag( ref flags, SaveFlag.MaxRange, m_MaxRange != -1 );
SetSaveFlag( ref flags, SaveFlag.Skill, m_Skill != (SkillName)(-1) );
SetSaveFlag( ref flags, SaveFlag.Type, m_Type != (WeaponType)(-1) );
SetSaveFlag( ref flags, SaveFlag.Animation, m_Animation != (WeaponAnimation)(-1) );
SetSaveFlag( ref flags, SaveFlag.Resource, m_Resource != CraftResource.Iron );
SetSaveFlag( ref flags, SaveFlag.xAttributes, !m_AosAttributes.IsEmpty );
SetSaveFlag( ref flags, SaveFlag.xWeaponAttributes, !m_AosWeaponAttributes.IsEmpty );
SetSaveFlag( ref flags, SaveFlag.PlayerConstructed, m_PlayerConstructed );
SetSaveFlag( ref flags, SaveFlag.SkillBonuses, !m_AosSkillBonuses.IsEmpty );
SetSaveFlag( ref flags, SaveFlag.Slayer2, m_Slayer2 != SlayerName.None );
SetSaveFlag( ref flags, SaveFlag.ElementalDamages, !m_AosElementDamages.IsEmpty );
writer.Write( (int) flags );
if ( GetSaveFlag( flags, SaveFlag.DamageLevel ) )
writer.Write( (int) m_DamageLevel );
if ( GetSaveFlag( flags, SaveFlag.AccuracyLevel ) )
writer.Write( (int) m_AccuracyLevel );
if ( GetSaveFlag( flags, SaveFlag.DurabilityLevel ) )
writer.Write( (int) m_DurabilityLevel );
if ( GetSaveFlag( flags, SaveFlag.Quality ) )
writer.Write( (int) m_Quality );
if ( GetSaveFlag( flags, SaveFlag.Hits ) )
writer.Write( (int) m_Hits );
if ( GetSaveFlag( flags, SaveFlag.MaxHits ) )
writer.Write( (int) m_MaxHits );
if ( GetSaveFlag( flags, SaveFlag.Slayer ) )
writer.Write( (int) m_Slayer );
if ( GetSaveFlag( flags, SaveFlag.Poison ) )
Poison.Serialize( m_Poison, writer );
if ( GetSaveFlag( flags, SaveFlag.PoisonCharges ) )
writer.Write( (int) m_PoisonCharges );
if ( GetSaveFlag( flags, SaveFlag.Crafter ) )
writer.Write( (Mobile) m_Crafter );
if ( GetSaveFlag( flags, SaveFlag.StrReq ) )
writer.Write( (int) m_StrReq );
if ( GetSaveFlag( flags, SaveFlag.DexReq ) )
writer.Write( (int) m_DexReq );
if ( GetSaveFlag( flags, SaveFlag.IntReq ) )
writer.Write( (int) m_IntReq );
if ( GetSaveFlag( flags, SaveFlag.MinDamage ) )
writer.Write( (int) m_MinDamage );
if ( GetSaveFlag( flags, SaveFlag.MaxDamage ) )
writer.Write( (int) m_MaxDamage );
if ( GetSaveFlag( flags, SaveFlag.HitSound ) )
writer.Write( (int) m_HitSound );
if ( GetSaveFlag( flags, SaveFlag.MissSound ) )
writer.Write( (int) m_MissSound );
if ( GetSaveFlag( flags, SaveFlag.Speed ) )
writer.Write( (int) m_Speed );
if ( GetSaveFlag( flags, SaveFlag.MaxRange ) )
writer.Write( (int) m_MaxRange );
if ( GetSaveFlag( flags, SaveFlag.Skill ) )
writer.Write( (int) m_Skill );
if ( GetSaveFlag( flags, SaveFlag.Type ) )
writer.Write( (int) m_Type );
if ( GetSaveFlag( flags, SaveFlag.Animation ) )
writer.Write( (int) m_Animation );
if ( GetSaveFlag( flags, SaveFlag.Resource ) )
writer.Write( (int) m_Resource );
if ( GetSaveFlag( flags, SaveFlag.xAttributes ) )
m_AosAttributes.Serialize( writer );
if ( GetSaveFlag( flags, SaveFlag.xWeaponAttributes ) )
m_AosWeaponAttributes.Serialize( writer );
if ( GetSaveFlag( flags, SaveFlag.SkillBonuses ) )
m_AosSkillBonuses.Serialize( writer );
if ( GetSaveFlag( flags, SaveFlag.Slayer2 ) )
writer.Write( (int)m_Slayer2 );
if( GetSaveFlag( flags, SaveFlag.ElementalDamages ) )
m_AosElementDamages.Serialize( writer );
}
[Flags]
private enum SaveFlag
{
None = 0x00000000,
DamageLevel = 0x00000001,
AccuracyLevel = 0x00000002,
DurabilityLevel = 0x00000004,
Quality = 0x00000008,
Hits = 0x00000010,
MaxHits = 0x00000020,
Slayer = 0x00000040,
Poison = 0x00000080,
PoisonCharges = 0x00000100,
Crafter = 0x00000200,
Identified = 0x00000400,
StrReq = 0x00000800,
DexReq = 0x00001000,
IntReq = 0x00002000,
MinDamage = 0x00004000,
MaxDamage = 0x00008000,
HitSound = 0x00010000,
MissSound = 0x00020000,
Speed = 0x00040000,
MaxRange = 0x00080000,
Skill = 0x00100000,
Type = 0x00200000,
Animation = 0x00400000,
Resource = 0x00800000,
xAttributes = 0x01000000,
xWeaponAttributes = 0x02000000,
PlayerConstructed = 0x04000000,
SkillBonuses = 0x08000000,
Slayer2 = 0x10000000,
ElementalDamages = 0x20000000
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 8:
case 7:
case 6:
case 5:
{
SaveFlag flags = (SaveFlag)reader.ReadInt();
if ( GetSaveFlag( flags, SaveFlag.DamageLevel ) )
{
m_DamageLevel = (WeaponDamageLevel)reader.ReadInt();
if ( m_DamageLevel > WeaponDamageLevel.Vanq )
m_DamageLevel = WeaponDamageLevel.Ruin;
}
if ( GetSaveFlag( flags, SaveFlag.AccuracyLevel ) )
{
m_AccuracyLevel = (WeaponAccuracyLevel)reader.ReadInt();
if ( m_AccuracyLevel > WeaponAccuracyLevel.Supremely )
m_AccuracyLevel = WeaponAccuracyLevel.Accurate;
}
if ( GetSaveFlag( flags, SaveFlag.DurabilityLevel ) )
{
m_DurabilityLevel = (WeaponDurabilityLevel)reader.ReadInt();
if ( m_DurabilityLevel > WeaponDurabilityLevel.Indestructible )
m_DurabilityLevel = WeaponDurabilityLevel.Durable;
}
if ( GetSaveFlag( flags, SaveFlag.Quality ) )
m_Quality = (WeaponQuality)reader.ReadInt();
else
m_Quality = WeaponQuality.Regular;
if ( GetSaveFlag( flags, SaveFlag.Hits ) )
m_Hits = reader.ReadInt();
if ( GetSaveFlag( flags, SaveFlag.MaxHits ) )
m_MaxHits = reader.ReadInt();
if ( GetSaveFlag( flags, SaveFlag.Slayer ) )
m_Slayer = (SlayerName)reader.ReadInt();
if ( GetSaveFlag( flags, SaveFlag.Poison ) )
m_Poison = Poison.Deserialize( reader );
if ( GetSaveFlag( flags, SaveFlag.PoisonCharges ) )
m_PoisonCharges = reader.ReadInt();
if ( GetSaveFlag( flags, SaveFlag.Crafter ) )
m_Crafter = reader.ReadMobile();
if ( GetSaveFlag( flags, SaveFlag.Identified ) )
m_Identified = ( version >= 6 || reader.ReadBool() );
if ( GetSaveFlag( flags, SaveFlag.StrReq ) )
m_StrReq = reader.ReadInt();
else
m_StrReq = -1;
if ( GetSaveFlag( flags, SaveFlag.DexReq ) )
m_DexReq = reader.ReadInt();
else
m_DexReq = -1;
if ( GetSaveFlag( flags, SaveFlag.IntReq ) )
m_IntReq = reader.ReadInt();
else
m_IntReq = -1;
if ( GetSaveFlag( flags, SaveFlag.MinDamage ) )
m_MinDamage = reader.ReadInt();
else
m_MinDamage = -1;
if ( GetSaveFlag( flags, SaveFlag.MaxDamage ) )
m_MaxDamage = reader.ReadInt();
else
m_MaxDamage = -1;
if ( GetSaveFlag( flags, SaveFlag.HitSound ) )
m_HitSound = reader.ReadInt();
else
m_HitSound = -1;
if ( GetSaveFlag( flags, SaveFlag.MissSound ) )
m_MissSound = reader.ReadInt();
else
m_MissSound = -1;
if ( GetSaveFlag( flags, SaveFlag.Speed ) )
m_Speed = reader.ReadInt();
else
m_Speed = -1;
if ( GetSaveFlag( flags, SaveFlag.MaxRange ) )
m_MaxRange = reader.ReadInt();
else
m_MaxRange = -1;
if ( GetSaveFlag( flags, SaveFlag.Skill ) )
m_Skill = (SkillName)reader.ReadInt();
else
m_Skill = (SkillName)(-1);
if ( GetSaveFlag( flags, SaveFlag.Type ) )
m_Type = (WeaponType)reader.ReadInt();
else
m_Type = (WeaponType)(-1);
if ( GetSaveFlag( flags, SaveFlag.Animation ) )
m_Animation = (WeaponAnimation)reader.ReadInt();
else
m_Animation = (WeaponAnimation)(-1);
if ( GetSaveFlag( flags, SaveFlag.Resource ) )
m_Resource = (CraftResource)reader.ReadInt();
else
m_Resource = CraftResource.Iron;
if ( GetSaveFlag( flags, SaveFlag.xAttributes ) )
m_AosAttributes = new AosAttributes( this, reader );
else
m_AosAttributes = new AosAttributes( this );
if ( GetSaveFlag( flags, SaveFlag.xWeaponAttributes ) )
m_AosWeaponAttributes = new AosWeaponAttributes( this, reader );
else
m_AosWeaponAttributes = new AosWeaponAttributes( this );
if ( UseSkillMod && m_AccuracyLevel != WeaponAccuracyLevel.Regular && Parent is Mobile )
{
m_SkillMod = new DefaultSkillMod( AccuracySkill, true, (int)m_AccuracyLevel * 5 );
((Mobile)Parent).AddSkillMod( m_SkillMod );
}
if ( version < 7 && m_AosWeaponAttributes.MageWeapon != 0 )
m_AosWeaponAttributes.MageWeapon = 30 - m_AosWeaponAttributes.MageWeapon;
if ( Core.AOS && m_AosWeaponAttributes.MageWeapon != 0 && m_AosWeaponAttributes.MageWeapon != 30 && Parent is Mobile )
{
m_MageMod = new DefaultSkillMod( SkillName.Magery, true, -30 + m_AosWeaponAttributes.MageWeapon );
((Mobile)Parent).AddSkillMod( m_MageMod );
}
if ( GetSaveFlag( flags, SaveFlag.PlayerConstructed ) )
m_PlayerConstructed = true;
if( GetSaveFlag( flags, SaveFlag.SkillBonuses ) )
m_AosSkillBonuses = new AosSkillBonuses( this, reader );
else
m_AosSkillBonuses = new AosSkillBonuses( this );
if( GetSaveFlag( flags, SaveFlag.Slayer2 ) )
m_Slayer2 = (SlayerName)reader.ReadInt();
if( GetSaveFlag( flags, SaveFlag.ElementalDamages ) )
m_AosElementDamages = new AosElementAttributes( this, reader );
else
m_AosElementDamages = new AosElementAttributes( this );
break;
}
case 4:
{
m_Slayer = (SlayerName)reader.ReadInt();
goto case 3;
}
case 3:
{
m_StrReq = reader.ReadInt();
m_DexReq = reader.ReadInt();
m_IntReq = reader.ReadInt();
goto case 2;
}
case 2:
{
m_Identified = reader.ReadBool();
goto case 1;
}
case 1:
{
m_MaxRange = reader.ReadInt();
goto case 0;
}
case 0:
{
if ( version == 0 )
m_MaxRange = 1; // default
if ( version < 5 )
{
m_Resource = CraftResource.Iron;
m_AosAttributes = new AosAttributes( this );
m_AosWeaponAttributes = new AosWeaponAttributes( this );
m_AosElementDamages = new AosElementAttributes( this );
m_AosSkillBonuses = new AosSkillBonuses( this );
}
m_MinDamage = reader.ReadInt();
m_MaxDamage = reader.ReadInt();
m_Speed = reader.ReadInt();
m_HitSound = reader.ReadInt();
m_MissSound = reader.ReadInt();
m_Skill = (SkillName)reader.ReadInt();
m_Type = (WeaponType)reader.ReadInt();
m_Animation = (WeaponAnimation)reader.ReadInt();
m_DamageLevel = (WeaponDamageLevel)reader.ReadInt();
m_AccuracyLevel = (WeaponAccuracyLevel)reader.ReadInt();
m_DurabilityLevel = (WeaponDurabilityLevel)reader.ReadInt();
m_Quality = (WeaponQuality)reader.ReadInt();
m_Crafter = reader.ReadMobile();
m_Poison = Poison.Deserialize( reader );
m_PoisonCharges = reader.ReadInt();
if ( m_StrReq == OldStrengthReq )
m_StrReq = -1;
if ( m_DexReq == OldDexterityReq )
m_DexReq = -1;
if ( m_IntReq == OldIntelligenceReq )
m_IntReq = -1;
if ( m_MinDamage == OldMinDamage )
m_MinDamage = -1;
if ( m_MaxDamage == OldMaxDamage )
m_MaxDamage = -1;
if ( m_HitSound == OldHitSound )
m_HitSound = -1;
if ( m_MissSound == OldMissSound )
m_MissSound = -1;
if ( m_Speed == OldSpeed )
m_Speed = -1;
if ( m_MaxRange == OldMaxRange )
m_MaxRange = -1;
if ( m_Skill == OldSkill )
m_Skill = (SkillName)(-1);
if ( m_Type == OldType )
m_Type = (WeaponType)(-1);
if ( m_Animation == OldAnimation )
m_Animation = (WeaponAnimation)(-1);
if ( UseSkillMod && m_AccuracyLevel != WeaponAccuracyLevel.Regular && Parent is Mobile )
{
m_SkillMod = new DefaultSkillMod( AccuracySkill, true, (int)m_AccuracyLevel * 5);
((Mobile)Parent).AddSkillMod( m_SkillMod );
}
break;
}
}
if ( Core.AOS && Parent is Mobile )
m_AosSkillBonuses.AddTo( (Mobile)Parent );
int strBonus = m_AosAttributes.BonusStr;
int dexBonus = m_AosAttributes.BonusDex;
int intBonus = m_AosAttributes.BonusInt;
if ( this.Parent is Mobile && (strBonus != 0 || dexBonus != 0 || intBonus != 0) )
{
Mobile m = (Mobile)this.Parent;
string modName = this.Serial.ToString();
if ( strBonus != 0 )
m.AddStatMod( new StatMod( StatType.Str, modName + "Str", strBonus, TimeSpan.Zero ) );
if ( dexBonus != 0 )
m.AddStatMod( new StatMod( StatType.Dex, modName + "Dex", dexBonus, TimeSpan.Zero ) );
if ( intBonus != 0 )
m.AddStatMod( new StatMod( StatType.Int, modName + "Int", intBonus, TimeSpan.Zero ) );
}
if ( Parent is Mobile )
((Mobile)Parent).CheckStatTimers();
if ( m_Hits <= 0 && m_MaxHits <= 0 )
{
m_Hits = m_MaxHits = Utility.RandomMinMax( InitMinHits, InitMaxHits );
}
if ( version < 6 )
m_PlayerConstructed = true; // we don't know, so, assume it's crafted
}
#endregion
public BaseWeapon( int itemID ) : base( itemID )
{
Layer = (Layer)ItemData.Quality;
m_Quality = WeaponQuality.Regular;
m_StrReq = -1;
m_DexReq = -1;
m_IntReq = -1;
m_MinDamage = -1;
m_MaxDamage = -1;
m_HitSound = -1;
m_MissSound = -1;
m_Speed = -1;
m_MaxRange = -1;
m_Skill = (SkillName)(-1);
m_Type = (WeaponType)(-1);
m_Animation = (WeaponAnimation)(-1);
m_Hits = m_MaxHits = Utility.RandomMinMax( InitMinHits, InitMaxHits );
m_Resource = CraftResource.Iron;
m_AosAttributes = new AosAttributes( this );
m_AosWeaponAttributes = new AosWeaponAttributes( this );
m_AosSkillBonuses = new AosSkillBonuses( this );
m_AosElementDamages = new AosElementAttributes( this );
}
public BaseWeapon( Serial serial ) : base( serial )
{
}
private string GetNameString()
{
string name = this.Name;
if ( name == null )
name = String.Format( "#{0}", LabelNumber );
return name;
}
[Hue, CommandProperty( AccessLevel.GameMaster )]
public override int Hue
{
get{ return base.Hue; }
set{ base.Hue = value; InvalidateProperties(); }
}
public int GetElementalDamageHue()
{
int phys, fire, cold, pois, nrgy;
GetDamageTypes( null, out phys, out fire, out cold, out pois, out nrgy );
//Order is Cold, Energy, Fire, Poison, Physical left
int currentMax = 50;
int hue = 0;
if( pois >= currentMax )
{
hue = 1267 + (pois - 50) / 10;
currentMax = pois;
}
if( fire >= currentMax )
{
hue = 1255 + (fire - 50) / 10;
currentMax = fire;
}
if( nrgy >= currentMax )
{
hue = 1273 + (nrgy - 50) / 10;
currentMax = nrgy;
}
if( cold >= currentMax )
{
hue = 1261 + (cold - 50) / 10;
currentMax = cold;
}
return hue;
}
public override void AddNameProperty( ObjectPropertyList list )
{
string oreType;
if ( Hue == 0 )
{
oreType = "";
}
else
{
switch ( m_Resource )
{
case CraftResource.DullCopper: oreType = "dull copper"; break; // dull copper
case CraftResource.ShadowIron: oreType = "shadow iron"; break; // shadow iron
case CraftResource.Copper: oreType = "copper"; break; // copper
case CraftResource.Bronze: oreType = "bronze"; break; // bronze
case CraftResource.Gold: oreType = "gold"; break; // golden
case CraftResource.Agapite: oreType = "agapite"; break; // agapite
case CraftResource.Verite: oreType = "verite"; break; // verite
case CraftResource.Valorite: oreType = "valorite"; break; // valorite
case CraftResource.Silver: oreType = "silver"; break; // silver
case CraftResource.Platinum: oreType = "platinum"; break; // platinum
case CraftResource.Mythril: oreType = "mythril"; break; // mythril
case CraftResource.Obsidian: oreType = "obsidian"; break; // obsidian
case CraftResource.Jade: oreType = "jade"; break; // jade
case CraftResource.Moonstone: oreType = "moonstone"; break; // moonstone
case CraftResource.Sunstone: oreType = "sunstone"; break; // sunstone
case CraftResource.Bloodstone: oreType = "bloodstone"; break; // bloodstone
case CraftResource.SpinedLeather: oreType = "spined"; break; // spined
case CraftResource.HornedLeather: oreType = "horned"; break; // horned
case CraftResource.BarbedLeather: oreType = "barbed"; break; // barbed
case CraftResource.DragonLeather: oreType = "dragon"; break; // dragon
case CraftResource.DaemonLeather: oreType = "daemon"; break; // daemon
case CraftResource.RedScales: oreType = "red"; break; // red
case CraftResource.YellowScales: oreType = "yellow"; break; // yellow
case CraftResource.BlackScales: oreType = "black"; break; // black
case CraftResource.GreenScales: oreType = "green"; break; // green
case CraftResource.WhiteScales: oreType = "white"; break; // white
case CraftResource.BlueScales: oreType = "blue"; break; // blue
case CraftResource.Pine: oreType = "pine"; break; // pine
case CraftResource.Cedar: oreType = "cedar"; break; // cedar
case CraftResource.Cherry: oreType = "cherry"; break; // cherry
case CraftResource.Mahogany: oreType = "mahogany"; break; // mahogany
case CraftResource.Oak: oreType = "oak"; break; // oak
case CraftResource.Ash: oreType = "ash"; break; // ash
case CraftResource.Yew: oreType = "yew"; break; // yew
case CraftResource.Heartwood: oreType = "heartwood"; break; // heartwood
case CraftResource.Bloodwood: oreType = "bloodwood"; break; // bloodwood
case CraftResource.Frostwood: oreType = "frostwood"; break; // frostwood
default: oreType = ""; break;
}
}
//if ( oreType != 0 )
list.Add( 1053099, "{0}\t{1}", oreType, GetNameString() ); // ~1_oretype~ ~2_armortype~
/*else if ( Name == null )
list.Add( LabelNumber );
else
list.Add( Name );*/
}
public override bool AllowEquipedCast( Mobile from )
{
if ( base.AllowEquipedCast( from ) )
return true;
return ( m_AosAttributes.SpellChanneling != 0 );
}
public virtual int ArtifactRarity
{
get{ return 0; }
}
public virtual int GetLuckBonus()
{
CraftResourceInfo resInfo = CraftResources.GetInfo( m_Resource );
if ( resInfo == null )
return 0;
CraftAttributeInfo attrInfo = resInfo.AttributeInfo;
if ( attrInfo == null )
return 0;
return attrInfo.WeaponLuck;
}
public override void GetProperties( ObjectPropertyList list )
{
base.GetProperties( list );
if ( m_Crafter != null )
list.Add( 1050043, m_Crafter.Name ); // crafted by ~1_NAME~
#region Factions
if ( m_FactionState != null )
list.Add( 1041350 ); // faction item
#endregion
if ( m_AosSkillBonuses != null )
m_AosSkillBonuses.GetProperties( list );
if ( m_Quality == WeaponQuality.Exceptional )
list.Add( 1060636 ); // exceptional
if( RequiredRace == Race.Elf )
list.Add( 1075086 ); // Elves Only
if ( ArtifactRarity > 0 )
list.Add( 1061078, ArtifactRarity.ToString() ); // artifact rarity ~1_val~
if ( this is IUsesRemaining && ((IUsesRemaining)this).ShowUsesRemaining )
list.Add( 1060584, ((IUsesRemaining)this).UsesRemaining.ToString() ); // uses remaining: ~1_val~
if ( m_Poison != null && m_PoisonCharges > 0 )
list.Add( 1062412 + m_Poison.Level, m_PoisonCharges.ToString() );
if( m_Slayer != SlayerName.None )
{
SlayerEntry entry = SlayerGroup.GetEntryByName( m_Slayer );
if( entry != null )
list.Add( entry.Title );
}
if( m_Slayer2 != SlayerName.None )
{
SlayerEntry entry = SlayerGroup.GetEntryByName( m_Slayer2 );
if( entry != null )
list.Add( entry.Title );
}
base.AddResistanceProperties( list );
int prop;
if ( (prop = m_AosWeaponAttributes.UseBestSkill) != 0 )
list.Add( 1060400 ); // use best weapon skill
if ( (prop = (GetDamageBonus() + m_AosAttributes.WeaponDamage)) != 0 )
list.Add( 1060401, prop.ToString() ); // damage increase ~1_val~%
if ( (prop = m_AosAttributes.DefendChance) != 0 )
list.Add( 1060408, prop.ToString() ); // defense chance increase ~1_val~%
if ( (prop = m_AosAttributes.EnhancePotions) != 0 )
list.Add( 1060411, prop.ToString() ); // enhance potions ~1_val~%
if ( (prop = m_AosAttributes.CastRecovery) != 0 )
list.Add( 1060412, prop.ToString() ); // faster cast recovery ~1_val~
if ( (prop = m_AosAttributes.CastSpeed) != 0 )
list.Add( 1060413, prop.ToString() ); // faster casting ~1_val~
if ( (prop = (GetHitChanceBonus() + m_AosAttributes.AttackChance)) != 0 )
list.Add( 1060415, prop.ToString() ); // hit chance increase ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitColdArea) != 0 )
list.Add( 1060416, prop.ToString() ); // hit cold area ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitDispel) != 0 )
list.Add( 1060417, prop.ToString() ); // hit dispel ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitEnergyArea) != 0 )
list.Add( 1060418, prop.ToString() ); // hit energy area ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitFireArea) != 0 )
list.Add( 1060419, prop.ToString() ); // hit fire area ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitFireball) != 0 )
list.Add( 1060420, prop.ToString() ); // hit fireball ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitHarm) != 0 )
list.Add( 1060421, prop.ToString() ); // hit harm ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitLeechHits) != 0 )
list.Add( 1060422, prop.ToString() ); // hit life leech ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitLightning) != 0 )
list.Add( 1060423, prop.ToString() ); // hit lightning ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitLowerAttack) != 0 )
list.Add( 1060424, prop.ToString() ); // hit lower attack ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitLowerDefend) != 0 )
list.Add( 1060425, prop.ToString() ); // hit lower defense ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitMagicArrow) != 0 )
list.Add( 1060426, prop.ToString() ); // hit magic arrow ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitLeechMana) != 0 )
list.Add( 1060427, prop.ToString() ); // hit mana leech ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitPhysicalArea) != 0 )
list.Add( 1060428, prop.ToString() ); // hit physical area ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitPoisonArea) != 0 )
list.Add( 1060429, prop.ToString() ); // hit poison area ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitLeechStam) != 0 )
list.Add( 1060430, prop.ToString() ); // hit stamina leech ~1_val~%
if ( (prop = m_AosAttributes.BonusDex) != 0 )
list.Add( 1060409, prop.ToString() ); // dexterity bonus ~1_val~
if ( (prop = m_AosAttributes.BonusHits) != 0 )
list.Add( 1060431, prop.ToString() ); // hit point increase ~1_val~
if ( (prop = m_AosAttributes.BonusInt) != 0 )
list.Add( 1060432, prop.ToString() ); // intelligence bonus ~1_val~
if ( (prop = m_AosAttributes.LowerManaCost) != 0 )
list.Add( 1060433, prop.ToString() ); // lower mana cost ~1_val~%
if ( (prop = m_AosAttributes.LowerRegCost) != 0 )
list.Add( 1060434, prop.ToString() ); // lower reagent cost ~1_val~%
if ( (prop = GetLowerStatReq()) != 0 )
list.Add( 1060435, prop.ToString() ); // lower requirements ~1_val~%
if ( (prop = (GetLuckBonus() + m_AosAttributes.Luck)) != 0 )
list.Add( 1060436, prop.ToString() ); // luck ~1_val~
if ( (prop = m_AosWeaponAttributes.MageWeapon) != 0 )
list.Add( 1060438, (30 - prop).ToString() ); // mage weapon -~1_val~ skill
if ( (prop = m_AosAttributes.BonusMana) != 0 )
list.Add( 1060439, prop.ToString() ); // mana increase ~1_val~
if ( (prop = m_AosAttributes.RegenMana) != 0 )
list.Add( 1060440, prop.ToString() ); // mana regeneration ~1_val~
if ( (prop = m_AosAttributes.NightSight) != 0 )
list.Add( 1060441 ); // night sight
if ( (prop = m_AosAttributes.ReflectPhysical) != 0 )
list.Add( 1060442, prop.ToString() ); // reflect physical damage ~1_val~%
if ( (prop = m_AosAttributes.RegenStam) != 0 )
list.Add( 1060443, prop.ToString() ); // stamina regeneration ~1_val~
if ( (prop = m_AosAttributes.RegenHits) != 0 )
list.Add( 1060444, prop.ToString() ); // hit point regeneration ~1_val~
if ( (prop = m_AosWeaponAttributes.SelfRepair) != 0 )
list.Add( 1060450, prop.ToString() ); // self repair ~1_val~
if ( (prop = m_AosAttributes.SpellChanneling) != 0 )
list.Add( 1060482 ); // spell channeling
if ( (prop = m_AosAttributes.SpellDamage) != 0 )
list.Add( 1060483, prop.ToString() ); // spell damage increase ~1_val~%
if ( (prop = m_AosAttributes.BonusStam) != 0 )
list.Add( 1060484, prop.ToString() ); // stamina increase ~1_val~
if ( (prop = m_AosAttributes.BonusStr) != 0 )
list.Add( 1060485, prop.ToString() ); // strength bonus ~1_val~
if ( (prop = m_AosAttributes.WeaponSpeed) != 0 )
list.Add( 1060486, prop.ToString() ); // swing speed increase ~1_val~%
int phys, fire, cold, pois, nrgy;
GetDamageTypes( null, out phys, out fire, out cold, out pois, out nrgy );
if ( phys != 0 )
list.Add( 1060403, phys.ToString() ); // physical damage ~1_val~%
if ( fire != 0 )
list.Add( 1060405, fire.ToString() ); // fire damage ~1_val~%
if ( cold != 0 )
list.Add( 1060404, cold.ToString() ); // cold damage ~1_val~%
if ( pois != 0 )
list.Add( 1060406, pois.ToString() ); // poison damage ~1_val~%
if ( nrgy != 0 )
list.Add( 1060407, nrgy.ToString() ); // energy damage ~1_val~%
list.Add( 1061168, "{0}\t{1}", MinDamage.ToString(), MaxDamage.ToString() ); // weapon damage ~1_val~ - ~2_val~
list.Add( 1061167, Speed.ToString() ); // weapon speed ~1_val~
if ( MaxRange > 1 )
list.Add( 1061169, MaxRange.ToString() ); // range ~1_val~
int strReq = AOS.Scale( StrRequirement, 100 - GetLowerStatReq() );
if ( strReq > 0 )
list.Add( 1061170, strReq.ToString() ); // strength requirement ~1_val~
if ( Layer == Layer.TwoHanded )
list.Add( 1061171 ); // two-handed weapon
else
list.Add( 1061824 ); // one-handed weapon
if ( Core.SE || m_AosWeaponAttributes.UseBestSkill == 0 )
{
switch ( Skill )
{
case SkillName.Swords: list.Add( 1061172 ); break; // skill required: swordsmanship
case SkillName.Macing: list.Add( 1061173 ); break; // skill required: mace fighting
case SkillName.Fencing: list.Add( 1061174 ); break; // skill required: fencing
case SkillName.Archery: list.Add( 1061175 ); break; // skill required: archery
}
}
if ( m_Hits >= 0 && m_MaxHits > 0 )
list.Add( 1060639, "{0}\t{1}", m_Hits, m_MaxHits ); // durability ~1_val~ / ~2_val~
}
public override void OnSingleClick( Mobile from )
{
List<EquipInfoAttribute> attrs = new List<EquipInfoAttribute>();
if ( DisplayLootType )
{
if ( LootType == LootType.Blessed )
attrs.Add( new EquipInfoAttribute( 1038021 ) ); // blessed
else if ( LootType == LootType.Cursed )
attrs.Add( new EquipInfoAttribute( 1049643 ) ); // cursed
}
#region Factions
if ( m_FactionState != null )
attrs.Add( new EquipInfoAttribute( 1041350 ) ); // faction item
#endregion
if ( m_Quality == WeaponQuality.Exceptional )
attrs.Add( new EquipInfoAttribute( 1018305 - (int)m_Quality ) );
if ( m_Identified || from.AccessLevel >= AccessLevel.GameMaster )
{
if( m_Slayer != SlayerName.None )
{
SlayerEntry entry = SlayerGroup.GetEntryByName( m_Slayer );
if( entry != null )
attrs.Add( new EquipInfoAttribute( entry.Title ) );
}
if( m_Slayer2 != SlayerName.None )
{
SlayerEntry entry = SlayerGroup.GetEntryByName( m_Slayer2 );
if( entry != null )
attrs.Add( new EquipInfoAttribute( entry.Title ) );
}
if ( m_DurabilityLevel != WeaponDurabilityLevel.Regular )
attrs.Add( new EquipInfoAttribute( 1038000 + (int)m_DurabilityLevel ) );
if ( m_DamageLevel != WeaponDamageLevel.Regular )
attrs.Add( new EquipInfoAttribute( 1038015 + (int)m_DamageLevel ) );
if ( m_AccuracyLevel != WeaponAccuracyLevel.Regular )
attrs.Add( new EquipInfoAttribute( 1038010 + (int)m_AccuracyLevel ) );
}
else if( m_Slayer != SlayerName.None || m_Slayer2 != SlayerName.None || m_DurabilityLevel != WeaponDurabilityLevel.Regular || m_DamageLevel != WeaponDamageLevel.Regular || m_AccuracyLevel != WeaponAccuracyLevel.Regular )
attrs.Add( new EquipInfoAttribute( 1038000 ) ); // Unidentified
if ( m_Poison != null && m_PoisonCharges > 0 )
attrs.Add( new EquipInfoAttribute( 1017383, m_PoisonCharges ) );
int number;
if ( Name == null )
{
number = LabelNumber;
}
else
{
this.LabelTo( from, Name );
number = 1041000;
}
if ( attrs.Count == 0 && Crafter == null && Name != null )
return;
EquipmentInfo eqInfo = new EquipmentInfo( number, m_Crafter, false, attrs.ToArray() );
from.Send( new DisplayEquipmentInfo( this, eqInfo ) );
}
private static BaseWeapon m_Fists; // This value holds the default--fist--weapon
public static BaseWeapon Fists
{
get{ return m_Fists; }
set{ m_Fists = value; }
}
#region ICraftable Members
public int OnCraft( int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool, CraftItem craftItem, int resHue )
{
Quality = (WeaponQuality)quality;
if ( makersMark )
Crafter = from;
PlayerConstructed = true;
Type resourceType = typeRes;
if ( resourceType == null )
resourceType = craftItem.Ressources.GetAt( 0 ).ItemType;
//////////////if ( Core.AOS )
{
Resource = CraftResources.GetFromType( resourceType );
CraftContext context = craftSystem.GetContext( from );
if ( context != null && context.DoNotColor )
Hue = 0;
if ( tool is BaseRunicTool )
((BaseRunicTool)tool).ApplyAttributesTo( this );
if ( Quality == WeaponQuality.Exceptional )
{
if ( Attributes.WeaponDamage > 35 )
Attributes.WeaponDamage -= 20;
else
Attributes.WeaponDamage = 15;
if( Core.ML )
{
Attributes.WeaponDamage += (int)(from.Skills.ArmsLore.Value / 20);
from.CheckSkill( SkillName.ArmsLore, 0, 100 );
}
}
}
////else
if ( tool is BaseRunicTool )
{
CraftResource thisResource = CraftResources.GetFromType( resourceType );
if ( thisResource == ((BaseRunicTool)tool).Resource )
{
Resource = thisResource;
CraftContext context = craftSystem.GetContext( from );
if ( context != null && context.DoNotColor )
Hue = 0;
switch ( thisResource )
{
case CraftResource.DullCopper:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Durable;
AccuracyLevel = WeaponAccuracyLevel.Accurate;
break;
}
case CraftResource.ShadowIron:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Durable;
DamageLevel = WeaponDamageLevel.Ruin;
break;
}
case CraftResource.Copper:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Fortified;
DamageLevel = WeaponDamageLevel.Ruin;
AccuracyLevel = WeaponAccuracyLevel.Surpassingly;
break;
}
case CraftResource.Bronze:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Fortified;
DamageLevel = WeaponDamageLevel.Might;
AccuracyLevel = WeaponAccuracyLevel.Surpassingly;
break;
}
case CraftResource.Gold:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Indestructible;
DamageLevel = WeaponDamageLevel.Force;
AccuracyLevel = WeaponAccuracyLevel.Eminently;
break;
}
case CraftResource.Agapite:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Indestructible;
DamageLevel = WeaponDamageLevel.Power;
AccuracyLevel = WeaponAccuracyLevel.Eminently;
break;
}
case CraftResource.Verite:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Indestructible;
DamageLevel = WeaponDamageLevel.Power;
AccuracyLevel = WeaponAccuracyLevel.Exceedingly;
break;
}
case CraftResource.Valorite:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Indestructible;
DamageLevel = WeaponDamageLevel.Vanq;
AccuracyLevel = WeaponAccuracyLevel.Supremely;
break;
}
}
}
}
return quality;
}
#endregion
}
public enum CheckSlayerResult
{
None,
Slayer,
Opposition
}
}
any ideas why a crafted item dosent display its type of ore? TY! Edit--- Could this be it!?! Code:
if ( Core.AOS )
{
bonus += m_AosWeaponAttributes.DurabilityBonus;
CraftResourceInfo resInfo = CraftResources.GetInfo( m_Resource );
CraftAttributeInfo attrInfo = null;
if ( resInfo != null )
attrInfo = resInfo.AttributeInfo;
if ( attrInfo != null )
bonus += attrInfo.WeaponDurability;
}
Last edited by AvariceShard; 07-04-2009 at 10:57 PM. |
|
|
|
|
|
|
#6 (permalink) |
|
Master of the Internet
|
that is it - the part in red - was that in the oncraft like i said in the other one?
thought you have changed them all on that lol
__________________
http://www.AoAUO.com
:) ..... Come for the Customs, Play for the Fun. Return to see your new Friends ..... :) |
|
|
|
|
|
#7 (permalink) |
|
Forum Novice
Join Date: May 2007
Posts: 142
|
lol but why would my resource name still not be showing? When a weapon is crafted, it states only its name and wether it is exceptional, not the type of resource used.
This was the switch statment block you were referring to right? BaseWeapon.cs: Code:
public override void AddNameProperty( ObjectPropertyList list )
{
string oreType;
if ( Hue == 0 )
{
oreType = "";
}
else
{
switch ( m_Resource )
{
case CraftResource.DullCopper: oreType = "dull copper"; break; // dull copper
case CraftResource.ShadowIron: oreType = "shadow iron"; break; // shadow iron
case CraftResource.Copper: oreType = "copper"; break; // copper
case CraftResource.Bronze: oreType = "bronze"; break; // bronze
case CraftResource.Gold: oreType = "gold"; break; // golden
case CraftResource.Agapite: oreType = "agapite"; break; // agapite
case CraftResource.Verite: oreType = "verite"; break; // verite
case CraftResource.Valorite: oreType = "valorite"; break; // valorite
case CraftResource.Silver: oreType = "silver"; break; // silver
case CraftResource.Platinum: oreType = "platinum"; break; // platinum
case CraftResource.Mythril: oreType = "mythril"; break; // mythril
case CraftResource.Obsidian: oreType = "obsidian"; break; // obsidian
case CraftResource.Jade: oreType = "jade"; break; // jade
case CraftResource.Moonstone: oreType = "moonstone"; break; // moonstone
case CraftResource.Sunstone: oreType = "sunstone"; break; // sunstone
case CraftResource.Bloodstone: oreType = "bloodstone"; break; // bloodstone
case CraftResource.SpinedLeather: oreType = "spined"; break; // spined
case CraftResource.HornedLeather: oreType = "horned"; break; // horned
case CraftResource.BarbedLeather: oreType = "barbed"; break; // barbed
case CraftResource.DragonLeather: oreType = "dragon"; break; // dragon
case CraftResource.DaemonLeather: oreType = "daemon"; break; // daemon
case CraftResource.RedScales: oreType = "red"; break; // red
case CraftResource.YellowScales: oreType = "yellow"; break; // yellow
case CraftResource.BlackScales: oreType = "black"; break; // black
case CraftResource.GreenScales: oreType = "green"; break; // green
case CraftResource.WhiteScales: oreType = "white"; break; // white
case CraftResource.BlueScales: oreType = "blue"; break; // blue
case CraftResource.Pine: oreType = "pine"; break; // pine
case CraftResource.Cedar: oreType = "cedar"; break; // cedar
case CraftResource.Cherry: oreType = "cherry"; break; // cherry
case CraftResource.Mahogany: oreType = "mahogany"; break; // mahogany
case CraftResource.Oak: oreType = "oak"; break; // oak
case CraftResource.Ash: oreType = "ash"; break; // ash
case CraftResource.Yew: oreType = "yew"; break; // yew
case CraftResource.Heartwood: oreType = "heartwood"; break; // heartwood
case CraftResource.Bloodwood: oreType = "bloodwood"; break; // bloodwood
case CraftResource.Frostwood: oreType = "frostwood"; break; // frostwood
default: oreType = ""; break;
}
}
//if ( oreType != 0 )
list.Add( 1053099, "{0}\t{1}", oreType, GetNameString() ); // ~1_oretype~ ~2_armortype~
/*else if ( Name == null )
list.Add( LabelNumber );
else
list.Add( Name );*/
}
|
|
|
|
|
|
#8 (permalink) |
|
Master of the Internet
|
that was the switch block
BUT if it is not retained/set up in the oncraft section to have a resource, then resource is none, and thus no name
__________________
http://www.AoAUO.com
:) ..... Come for the Customs, Play for the Fun. Return to see your new Friends ..... :) |
|
|
|
|
|
#9 (permalink) | |
|
Forum Novice
Join Date: May 2007
Posts: 142
|
Quote:
Code:
public int OnCraft( int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool, CraftItem craftItem, int resHue )
{
Quality = (WeaponQuality)quality;
if ( makersMark )
Crafter = from;
PlayerConstructed = true;
Type resourceType = typeRes;
if ( resourceType == null )
resourceType = craftItem.Ressources.GetAt( 0 ).ItemType;
{
Resource = CraftResources.GetFromType( resourceType );
CraftContext context = craftSystem.GetContext( from );
![]() |
|
|
|
|
|
|
#10 (permalink) |
|
Master of the Internet
|
that should be assigning the resource to it in on craft section
so it should be showing the resource in the name then 2 things to check 1) set the resource to a weapon like so: [set resource valorite -- click on the weapon and see if it chenges name 2) when crafting - make sure it is not set for "no hue" option - in the menu for changing resource type at the bottom of each page of ingot list it shoudl say "do not color" if it says use color then it is set for do not color (it is backwayards to how it looks lol) else post complete basearmor script
__________________
http://www.AoAUO.com
:) ..... Come for the Customs, Play for the Fun. Return to see your new Friends ..... :) |
|
|
|
|
|
#11 (permalink) | |
|
Forum Novice
Join Date: May 2007
Posts: 142
|
Quote:
Thanks for all this help I really do appreciate it! When i set a Katana to [set resource valorite it still only says Katana! Heres my BaseWeapon.cs: Code:
using System;
using System.Text;
using System.Collections;
using Server.Network;
using Server.Targeting;
using Server.Mobiles;
using Server.Spells;
using Server.Spells.Necromancy;
using Server.Spells.Bushido;
using Server.Spells.Ninjitsu;
using Server.Factions;
using Server.Engines.Craft;
using System.Collections.Generic;
using Server.Spells.Spellweaving;
namespace Server.Items
{
public interface ISlayer
{
SlayerName Slayer { get; set; }
SlayerName Slayer2 { get; set; }
}
public abstract class BaseWeapon : Item, IWeapon, IFactionItem, ICraftable, ISlayer, IDurability
{
#region Factions
private FactionItem m_FactionState;
public FactionItem FactionItemState
{
get{ return m_FactionState; }
set
{
m_FactionState = value;
if ( m_FactionState == null )
Hue = CraftResources.GetHue( Resource );
LootType = ( m_FactionState == null ? LootType.Regular : LootType.Blessed );
}
}
#endregion
/* Weapon internals work differently now (Mar 13 2003)
*
* The attributes defined below default to -1.
* If the value is -1, the corresponding virtual 'Aos/Old' property is used.
* If not, the attribute value itself is used. Here's the list:
* - MinDamage
* - MaxDamage
* - Speed
* - HitSound
* - MissSound
* - StrRequirement, DexRequirement, IntRequirement
* - WeaponType
* - WeaponAnimation
* - MaxRange
*/
#region Var declarations
// Instance values. These values are unique to each weapon.
private WeaponDamageLevel m_DamageLevel;
private WeaponAccuracyLevel m_AccuracyLevel;
private WeaponDurabilityLevel m_DurabilityLevel;
private WeaponQuality m_Quality;
private Mobile m_Crafter;
private Poison m_Poison;
private int m_PoisonCharges;
private bool m_Identified;
private int m_Hits;
private int m_MaxHits;
private SlayerName m_Slayer;
private SlayerName m_Slayer2;
private SkillMod m_SkillMod, m_MageMod;
private CraftResource m_Resource;
private bool m_PlayerConstructed;
private bool m_Cursed; // Is this weapon cursed via Curse Weapon necromancer spell? Temporary; not serialized.
private bool m_Consecrated; // Is this weapon blessed via Consecrate Weapon paladin ability? Temporary; not serialized.
private AosAttributes m_AosAttributes;
private AosWeaponAttributes m_AosWeaponAttributes;
private AosSkillBonuses m_AosSkillBonuses;
private AosElementAttributes m_AosElementDamages;
// Overridable values. These values are provided to override the defaults which get defined in the individual weapon scripts.
private int m_StrReq, m_DexReq, m_IntReq;
private int m_MinDamage, m_MaxDamage;
private int m_HitSound, m_MissSound;
private int m_Speed;
private int m_MaxRange;
private SkillName m_Skill;
private WeaponType m_Type;
private WeaponAnimation m_Animation;
#endregion
#region Virtual Properties
public virtual WeaponAbility PrimaryAbility{ get{ return null; } }
public virtual WeaponAbility SecondaryAbility{ get{ return null; } }
public virtual int DefMaxRange{ get{ return 1; } }
public virtual int DefHitSound{ get{ return 0; } }
public virtual int DefMissSound{ get{ return 0; } }
public virtual SkillName DefSkill{ get{ return SkillName.Swords; } }
public virtual WeaponType DefType{ get{ return WeaponType.Slashing; } }
public virtual WeaponAnimation DefAnimation{ get{ return WeaponAnimation.Slash1H; } }
public virtual int AosStrengthReq{ get{ return 0; } }
public virtual int AosDexterityReq{ get{ return 0; } }
public virtual int AosIntelligenceReq{ get{ return 0; } }
public virtual int AosMinDamage{ get{ return 0; } }
public virtual int AosMaxDamage{ get{ return 0; } }
public virtual int AosSpeed{ get{ return 0; } }
public virtual int AosMaxRange{ get{ return DefMaxRange; } }
public virtual int AosHitSound{ get{ return DefHitSound; } }
public virtual int AosMissSound{ get{ return DefMissSound; } }
public virtual SkillName AosSkill{ get{ return DefSkill; } }
public virtual WeaponType AosType{ get{ return DefType; } }
public virtual WeaponAnimation AosAnimation{ get{ return DefAnimation; } }
public virtual int OldStrengthReq{ get{ return 0; } }
public virtual int OldDexterityReq{ get{ return 0; } }
public virtual int OldIntelligenceReq{ get{ return 0; } }
public virtual int OldMinDamage{ get{ return 0; } }
public virtual int OldMaxDamage{ get{ return 0; } }
public virtual int OldSpeed{ get{ return 0; } }
public virtual int OldMaxRange{ get{ return DefMaxRange; } }
public virtual int OldHitSound{ get{ return DefHitSound; } }
public virtual int OldMissSound{ get{ return DefMissSound; } }
public virtual SkillName OldSkill{ get{ return DefSkill; } }
public virtual WeaponType OldType{ get{ return DefType; } }
public virtual WeaponAnimation OldAnimation{ get{ return DefAnimation; } }
public virtual int InitMinHits{ get{ return 0; } }
public virtual int InitMaxHits{ get{ return 0; } }
public override int PhysicalResistance{ get{ return m_AosWeaponAttributes.ResistPhysicalBonus; } }
public override int FireResistance{ get{ return m_AosWeaponAttributes.ResistFireBonus; } }
public override int ColdResistance{ get{ return m_AosWeaponAttributes.ResistColdBonus; } }
public override int PoisonResistance{ get{ return m_AosWeaponAttributes.ResistPoisonBonus; } }
public override int EnergyResistance{ get{ return m_AosWeaponAttributes.ResistEnergyBonus; } }
public virtual SkillName AccuracySkill { get { return SkillName.Tactics; } }
#endregion
#region Getters & Setters
[CommandProperty( AccessLevel.GameMaster )]
public AosAttributes Attributes
{
get{ return m_AosAttributes; }
set{}
}
[CommandProperty( AccessLevel.GameMaster )]
public AosWeaponAttributes WeaponAttributes
{
get{ return m_AosWeaponAttributes; }
set{}
}
[CommandProperty( AccessLevel.GameMaster )]
public AosSkillBonuses SkillBonuses
{
get{ return m_AosSkillBonuses; }
set{}
}
[CommandProperty( AccessLevel.GameMaster )]
public AosElementAttributes AosElementDamages
{
get { return m_AosElementDamages; }
set { }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool Cursed
{
get{ return m_Cursed; }
set{ m_Cursed = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool Consecrated
{
get{ return m_Consecrated; }
set{ m_Consecrated = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool Identified
{
get{ return m_Identified; }
set{ m_Identified = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int HitPoints
{
get{ return m_Hits; }
set
{
if ( m_Hits == value )
return;
if ( value > m_MaxHits )
value = m_MaxHits;
m_Hits = value;
InvalidateProperties();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int MaxHitPoints
{
get{ return m_MaxHits; }
set{ m_MaxHits = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int PoisonCharges
{
get{ return m_PoisonCharges; }
set{ m_PoisonCharges = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public Poison Poison
{
get{ return m_Poison; }
set{ m_Poison = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public WeaponQuality Quality
{
get{ return m_Quality; }
set{ UnscaleDurability(); m_Quality = value; ScaleDurability(); InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public Mobile Crafter
{
get{ return m_Crafter; }
set{ m_Crafter = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public SlayerName Slayer
{
get{ return m_Slayer; }
set{ m_Slayer = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public SlayerName Slayer2
{
get { return m_Slayer2; }
set { m_Slayer2 = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public CraftResource Resource
{
get{ return m_Resource; }
set{ UnscaleDurability(); m_Resource = value; Hue = CraftResources.GetHue( m_Resource ); InvalidateProperties(); ScaleDurability(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public WeaponDamageLevel DamageLevel
{
get{ return m_DamageLevel; }
set{ m_DamageLevel = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public WeaponDurabilityLevel DurabilityLevel
{
get{ return m_DurabilityLevel; }
set{ UnscaleDurability(); m_DurabilityLevel = value; InvalidateProperties(); ScaleDurability(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool PlayerConstructed
{
get{ return m_PlayerConstructed; }
set{ m_PlayerConstructed = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public int MaxRange
{
get{ return ( m_MaxRange == -1 ? Core.AOS ? AosMaxRange : OldMaxRange : m_MaxRange ); }
set{ m_MaxRange = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public WeaponAnimation Animation
{
get{ return ( m_Animation == (WeaponAnimation)(-1) ? Core.AOS ? AosAnimation : OldAnimation : m_Animation ); }
set{ m_Animation = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public WeaponType Type
{
get{ return ( m_Type == (WeaponType)(-1) ? Core.AOS ? AosType : OldType : m_Type ); }
set{ m_Type = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public SkillName Skill
{
get{ return ( m_Skill == (SkillName)(-1) ? Core.AOS ? AosSkill : OldSkill : m_Skill ); }
set{ m_Skill = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int HitSound
{
get{ return ( m_HitSound == -1 ? Core.AOS ? AosHitSound : OldHitSound : m_HitSound ); }
set{ m_HitSound = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public int MissSound
{
get{ return ( m_MissSound == -1 ? Core.AOS ? AosMissSound : OldMissSound : m_MissSound ); }
set{ m_MissSound = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public int MinDamage
{
get{ return ( m_MinDamage == -1 ? Core.AOS ? AosMinDamage : OldMinDamage : m_MinDamage ); }
set{ m_MinDamage = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int MaxDamage
{
get{ return ( m_MaxDamage == -1 ? Core.AOS ? AosMaxDamage : OldMaxDamage : m_MaxDamage ); }
set{ m_MaxDamage = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int Speed
{
get{ return ( m_Speed == -1 ? Core.AOS ? AosSpeed : OldSpeed : m_Speed ); }
set{ m_Speed = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int StrRequirement
{
get{ return ( m_StrReq == -1 ? Core.AOS ? AosStrengthReq : OldStrengthReq : m_StrReq ); }
set{ m_StrReq = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int DexRequirement
{
get{ return ( m_DexReq == -1 ? Core.AOS ? AosDexterityReq : OldDexterityReq : m_DexReq ); }
set{ m_DexReq = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public int IntRequirement
{
get{ return ( m_IntReq == -1 ? Core.AOS ? AosIntelligenceReq : OldIntelligenceReq : m_IntReq ); }
set{ m_IntReq = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public WeaponAccuracyLevel AccuracyLevel
{
get
{
return m_AccuracyLevel;
}
set
{
if ( m_AccuracyLevel != value )
{
m_AccuracyLevel = value;
if ( UseSkillMod )
{
if ( m_AccuracyLevel == WeaponAccuracyLevel.Regular )
{
if ( m_SkillMod != null )
m_SkillMod.Remove();
m_SkillMod = null;
}
else if ( m_SkillMod == null && Parent is Mobile )
{
m_SkillMod = new DefaultSkillMod( AccuracySkill, true, (int)m_AccuracyLevel * 5 );
((Mobile)Parent).AddSkillMod( m_SkillMod );
}
else if ( m_SkillMod != null )
{
m_SkillMod.Value = (int)m_AccuracyLevel * 5;
}
}
InvalidateProperties();
}
}
}
#endregion
public virtual void UnscaleDurability()
{
int scale = 100 + GetDurabilityBonus();
m_Hits = ((m_Hits * 100) + (scale - 1)) / scale;
m_MaxHits = ((m_MaxHits * 100) + (scale - 1)) / scale;
InvalidateProperties();
}
public virtual void ScaleDurability()
{
int scale = 100 + GetDurabilityBonus();
m_Hits = ((m_Hits * scale) + 99) / 100;
m_MaxHits = ((m_MaxHits * scale) + 99) / 100;
InvalidateProperties();
}
public int GetDurabilityBonus()
{
int bonus = 0;
if ( m_Quality == WeaponQuality.Exceptional )
bonus += 20;
switch ( m_DurabilityLevel )
{
case WeaponDurabilityLevel.Durable: bonus += 20; break;
case WeaponDurabilityLevel.Substantial: bonus += 50; break;
case WeaponDurabilityLevel.Massive: bonus += 70; break;
case WeaponDurabilityLevel.Fortified: bonus += 100; break;
case WeaponDurabilityLevel.Indestructible: bonus += 120; break;
}
if ( Core.AOS )
{
bonus += m_AosWeaponAttributes.DurabilityBonus;
CraftResourceInfo resInfo = CraftResources.GetInfo( m_Resource );
CraftAttributeInfo attrInfo = null;
if ( resInfo != null )
attrInfo = resInfo.AttributeInfo;
if ( attrInfo != null )
bonus += attrInfo.WeaponDurability;
}
return bonus;
}
public int GetLowerStatReq()
{
if ( !Core.AOS )
return 0;
int v = m_AosWeaponAttributes.LowerStatReq;
CraftResourceInfo info = CraftResources.GetInfo( m_Resource );
if ( info != null )
{
CraftAttributeInfo attrInfo = info.AttributeInfo;
if ( attrInfo != null )
v += attrInfo.WeaponLowerRequirements;
}
if ( v > 100 )
v = 100;
return v;
}
public static void BlockEquip( Mobile m, TimeSpan duration )
{
if ( m.BeginAction( typeof( BaseWeapon ) ) )
new ResetEquipTimer( m, duration ).Start();
}
private class ResetEquipTimer : Timer
{
private Mobile m_Mobile;
public ResetEquipTimer( Mobile m, TimeSpan duration ) : base( duration )
{
m_Mobile = m;
}
protected override void OnTick()
{
m_Mobile.EndAction( typeof( BaseWeapon ) );
}
}
public override bool CheckConflictingLayer( Mobile m, Item item, Layer layer )
{
if ( base.CheckConflictingLayer( m, item, layer ) )
return true;
if ( this.Layer == Layer.TwoHanded && layer == Layer.OneHanded )
{
m.SendLocalizedMessage( 500214 ); // You already have something in both hands.
return true;
}
else if ( this.Layer == Layer.OneHanded && layer == Layer.TwoHanded && !(item is BaseShield) && !(item is BaseEquipableLight) )
{
m.SendLocalizedMessage( 500215 ); // You can only wield one weapon at a time.
return true;
}
return false;
}
public override bool AllowSecureTrade( Mobile from, Mobile to, Mobile newOwner, bool accepted )
{
if ( !Ethics.Ethic.CheckTrade( from, to, newOwner, this ) )
return false;
return base.AllowSecureTrade( from, to, newOwner, accepted );
}
public virtual Race RequiredRace { get { return null; } } //On OSI, there are no weapons with race requirements, this is for custom stuff
public override bool CanEquip( Mobile from )
{
if ( !Ethics.Ethic.CheckEquip( from, this ) )
return false;
if( RequiredRace != null && from.Race != RequiredRace )
{
if( RequiredRace == Race.Elf )
from.SendLocalizedMessage( 1072203 ); // Only Elves may use this.
else
from.SendMessage( "Only {0} may use this.", RequiredRace.PluralName );
return false;
}
else if ( from.Dex < DexRequirement )
{
from.SendMessage( "You are not nimble enough to equip that." );
return false;
}
else if ( from.Str < AOS.Scale( StrRequirement, 100 - GetLowerStatReq() ) )
{
from.SendLocalizedMessage( 500213 ); // You are not strong enough to equip that.
return false;
}
else if ( from.Int < IntRequirement )
{
from.SendMessage( "You are not smart enough to equip that." );
return false;
}
else if ( !from.CanBeginAction( typeof( BaseWeapon ) ) )
{
return false;
}
else
{
return base.CanEquip( from );
}
}
public virtual bool UseSkillMod{ get{ return !Core.AOS; } }
public override bool OnEquip( Mobile from )
{
int strBonus = m_AosAttributes.BonusStr;
int dexBonus = m_AosAttributes.BonusDex;
int intBonus = m_AosAttributes.BonusInt;
if ( (strBonus != 0 || dexBonus != 0 || intBonus != 0) )
{
Mobile m = from;
string modName = this.Serial.ToString();
if ( strBonus != 0 )
m.AddStatMod( new StatMod( StatType.Str, modName + "Str", strBonus, TimeSpan.Zero ) );
if ( dexBonus != 0 )
m.AddStatMod( new StatMod( StatType.Dex, modName + "Dex", dexBonus, TimeSpan.Zero ) );
if ( intBonus != 0 )
m.AddStatMod( new StatMod( StatType.Int, modName + "Int", intBonus, TimeSpan.Zero ) );
}
from.NextCombatTime = DateTime.Now + GetDelay( from );
if ( UseSkillMod && m_AccuracyLevel != WeaponAccuracyLevel.Regular )
{
if ( m_SkillMod != null )
m_SkillMod.Remove();
m_SkillMod = new DefaultSkillMod( AccuracySkill, true, (int)m_AccuracyLevel * 5 );
from.AddSkillMod( m_SkillMod );
}
if ( Core.AOS && m_AosWeaponAttributes.MageWeapon != 0 && m_AosWeaponAttributes.MageWeapon != 30 )
{
if ( m_MageMod != null )
m_MageMod.Remove();
m_MageMod = new DefaultSkillMod( SkillName.Magery, true, -30 + m_AosWeaponAttributes.MageWeapon );
from.AddSkillMod( m_MageMod );
}
return true;
}
public override void OnAdded( object parent )
{
base.OnAdded( parent );
if ( parent is Mobile )
{
Mobile from = (Mobile)parent;
if ( Core.AOS )
m_AosSkillBonuses.AddTo( from );
from.CheckStatTimers();
from.Delta( MobileDelta.WeaponDamage );
}
}
public override void OnRemoved( object parent )
{
if ( parent is Mobile )
{
Mobile m = (Mobile)parent;
BaseWeapon weapon = m.Weapon as BaseWeapon;
string modName = this.Serial.ToString();
m.RemoveStatMod( modName + "Str" );
m.RemoveStatMod( modName + "Dex" );
m.RemoveStatMod( modName + "Int" );
if ( weapon != null )
m.NextCombatTime = DateTime.Now + weapon.GetDelay( m );
if ( UseSkillMod && m_SkillMod != null )
{
m_SkillMod.Remove();
m_SkillMod = null;
}
if ( m_MageMod != null )
{
m_MageMod.Remove();
m_MageMod = null;
}
if ( Core.AOS )
m_AosSkillBonuses.Remove();
m.CheckStatTimers();
m.Delta( MobileDelta.WeaponDamage );
}
}
public virtual SkillName GetUsedSkill( Mobile m, bool checkSkillAttrs )
{
SkillName sk;
if ( checkSkillAttrs && m_AosWeaponAttributes.UseBestSkill != 0 )
{
double swrd = m.Skills[SkillName.Swords].Value;
double fenc = m.Skills[SkillName.Fencing].Value;
double mcng = m.Skills[SkillName.Macing].Value;
double val;
sk = SkillName.Swords;
val = swrd;
if ( fenc > val ){ sk = SkillName.Fencing; val = fenc; }
if ( mcng > val ){ sk = SkillName.Macing; val = mcng; }
}
else if ( m_AosWeaponAttributes.MageWeapon != 0 )
{
if ( m.Skills[SkillName.Magery].Value > m.Skills[Skill].Value )
sk = SkillName.Magery;
else
sk = Skill;
}
else
{
sk = Skill;
if ( sk != SkillName.Wrestling && !m.Player && !m.Body.IsHuman && m.Skills[SkillName.Wrestling].Value > m.Skills[sk].Value )
sk = SkillName.Wrestling;
}
return sk;
}
public virtual double GetAttackSkillValue( Mobile attacker, Mobile defender )
{
return attacker.Skills[GetUsedSkill( attacker, true )].Value;
}
public virtual double GetDefendSkillValue( Mobile attacker, Mobile defender )
{
return defender.Skills[GetUsedSkill( defender, true )].Value;
}
private static bool CheckAnimal( Mobile m, Type type )
{
return AnimalForm.UnderTransformation( m, type );
}
public virtual bool CheckHit( Mobile attacker, Mobile defender )
{
BaseWeapon atkWeapon = attacker.Weapon as BaseWeapon;
BaseWeapon defWeapon = defender.Weapon as BaseWeapon;
Skill atkSkill = attacker.Skills[atkWeapon.Skill];
Skill defSkill = defender.Skills[defWeapon.Skill];
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();
if ( Core.AOS )
{
if ( atkValue <= -20.0 )
atkValue = -19.9;
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;
if ( Spells.Chivalry.DivineFurySpell.UnderEffect( attacker ) )
bonus += 10; // attacker gets 10% bonus when they're under divine fury
if ( CheckAnimal( attacker, typeof( GreyWolf ) ) || CheckAnimal( attacker, typeof( BakeKitsune ) ) )
bonus += 20; // attacker gets 20% bonus when under Wolf or Bake Kitsune form
if ( HitLower.IsUnderAttackEffect( attacker ) )
bonus -= 25; // Under Hit Lower Attack effect -> 25% malus
ourValue = (atkValue + 20.0) * (100 + bonus);
// Defense Chance Increase = 45%
bonus = AosAttributes.GetValue( defender, AosAttribute.DefendChance );
if ( bonus > 45 )
bonus = 45;
if ( Spells.Chivalry.DivineFurySpell.UnderEffect( defender ) )
bonus -= 20; // defender loses 20% bonus when they're under divine fury
if ( HitLower.IsUnderDefenseEffect( defender ) )
bonus -= 25; // Under Hit Lower Defense effect -> 25% malus
int blockBonus = 0;
if ( Block.GetBonus( defender, ref blockBonus ) )
bonus += blockBonus;
int surpriseMalus = 0;
if ( SurpriseAttack.GetMalus( defender, ref surpriseMalus ) )
bonus -= surpriseMalus;
int discordanceEffect = 0;
// Defender loses -0/-28% if under the effect of Discordance.
if ( SkillHandlers.Discordance.GetEffect( attacker, ref discordanceEffect ) )
bonus -= discordanceEffect;
theirValue = (defValue + 20.0) * (100 + bonus);
bonus = 0;
}
else
{
if ( atkValue <= -50.0 )
atkValue = -49.9;
if ( defValue <= -50.0 )
defValue = -49.9;
ourValue = (atkValue + 50.0);
theirValue = (defValue + 50.0);
}
double chance = ourValue / (theirValue * 2.0);
chance *= 1.0 + ((double)bonus / 100);
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 )
{
int speed = this.Speed;
if ( speed == 0 )
return TimeSpan.FromHours( 1.0 );
double delayInSeconds;
if ( Core.SE )
{
/*
* This is likely true for Core.AOS as well... both guides report the same
* formula, and both are wrong.
* The old formula left in for AOS for legacy & because we aren't quite 100%
* Sure that AOS has THIS formula
*/
int bonus = AosAttributes.GetValue( m, AosAttribute.WeaponSpeed );
if ( Spells.Chivalry.DivineFurySpell.UnderEffect( m ) )
bonus += 10;
// Bonus granted by successful use of Honorable Execution.
bonus += HonorableExecution.GetSwingBonus( m );
if( DualWield.Registry.Contains( m ) )
bonus += ((DualWield.DualWieldTimer)DualWield.Registry[m]).BonusSwingSpeed;
if( Feint.Registry.Contains( m ) )
bonus -= ((Feint.FeintTimer)Feint.Registry[m]).SwingSpeedReduction;
TransformContext context = TransformationSpellHelper.GetContext( m );
if( context != null && context.Spell is ReaperFormSpell )
bonus += ((ReaperFormSpell)context.Spell).SwingSpeedBonus;
int discordanceEffect = 0;
// Discordance gives a malus of -0/-28% to swing speed.
if ( SkillHandlers.Discordance.GetEffect( m, ref discordanceEffect ) )
bonus -= discordanceEffect;
if( EssenceOfWindSpell.IsDebuffed( m ) )
bonus -= EssenceOfWindSpell.GetSSIMalus( m );
if ( bonus > 60 )
bonus = 60;
speed = (int)Math.Floor( speed * (bonus + 100.0) / 100.0 );
if ( speed <= 0 )
speed = 1;
int ticks = (int)Math.Floor( (80000.0 / ((m.Stam + 100) * speed)) - 2 );
// Swing speed currently capped at one swing every 1.25 seconds (5 ticks).
if ( ticks < 5 )
ticks = 5;
delayInSeconds = ticks * 0.25;
}
else if ( Core.AOS )
{
int v = (m.Stam + 100) * speed;
int bonus = AosAttributes.GetValue( m, AosAttribute.WeaponSpeed );
if ( Spells.Chivalry.DivineFurySpell.UnderEffect( m ) )
bonus += 10;
int discordanceEffect = 0;
// Discordance gives a malus of -0/-28% to swing speed.
if ( SkillHandlers.Discordance.GetEffect( m, ref discordanceEffect ) )
bonus -= discordanceEffect;
v += AOS.Scale( v, bonus );
if ( v <= 0 )
v = 1;
delayInSeconds = Math.Floor( 40000.0 / v ) * 0.5;
// Maximum swing rate capped at one swing per second
// OSI dev said that it has and is supposed to be 1.25
if ( delayInSeconds < 0.55 )
delayInSeconds = 0.55;
}
else
{
int v = (m.Stam + 100) * speed;
if ( v <= 0 )
v = 1;
delayInSeconds = 15000.0 / v;
}
return TimeSpan.FromSeconds( delayInSeconds );
}
public virtual void OnBeforeSwing( Mobile attacker, Mobile defender )
{
WeaponAbility a = WeaponAbility.GetCurrentAbility( attacker );
if( a != null && !a.OnBeforeSwing( attacker, defender ) )
WeaponAbility.ClearCurrentAbility( attacker );
SpecialMove move = SpecialMove.GetCurrentMove( attacker );
if( move != null && !move.OnBeforeSwing( attacker, defender ) )
SpecialMove.ClearCurrentMove( attacker );
}
public virtual TimeSpan OnSwing( Mobile attacker, Mobile defender )
{
return OnSwing( attacker, defender, 1.0 );
}
public virtual TimeSpan OnSwing( Mobile attacker, Mobile defender, double damageBonus )
{
bool canSwing = true;
if ( Core.AOS )
{
canSwing = ( !attacker.Paralyzed && !attacker.Frozen );
if ( canSwing )
{
Spell sp = attacker.Spell as Spell;
canSwing = ( sp == null || !sp.IsCasting || !sp.BlocksMovement );
}
}
if ( canSwing && attacker.HarmfulCheck( defender ) )
{
attacker.DisruptiveAction();
if ( attacker.NetState != null )
attacker.Send( new Swing( 0, attacker, defender ) );
if ( attacker is BaseCreature )
{
BaseCreature bc = (BaseCreature)attacker;
WeaponAbility ab = bc.GetWeaponAbility();
if ( ab != null )
{
if ( bc.WeaponAbilityChance > Utility.RandomDouble() )
WeaponAbility.SetCurrentAbility( bc, ab );
else
WeaponAbility.ClearCurrentAbility( bc );
}
}
if ( CheckHit( attacker, defender ) )
OnHit( attacker, defender, damageBonus );
else
OnMiss( attacker, defender );
}
return GetDelay( attacker );
}
#region Sounds
public virtual int GetHitAttackSound( Mobile attacker, Mobile defender )
{
int sound = attacker.GetAttackSound();
if ( sound == -1 )
sound = HitSound;
return sound;
}
public virtual int GetHitDefendSound( Mobile attacker, Mobile defender )
{
return defender.GetHurtSound();
}
public virtual int GetMissAttackSound( Mobile attacker, Mobile defender )
{
if ( attacker.GetAttackSound() == -1 )
return MissSound;
else
return -1;
}
public virtual int GetMissDefendSound( Mobile attacker, Mobile defender )
{
return -1;
}
#endregion
public static bool CheckParry( Mobile defender )
{
if ( defender == null )
return false;
BaseShield shield = defender.FindItemOnLayer( Layer.TwoHanded ) as BaseShield;
double parry = defender.Skills[SkillName.Parry].Value;
double bushidoNonRacial = defender.Skills[SkillName.Bushido].NonRacialValue;
double bushido = defender.Skills[SkillName.Bushido].Value;
if ( shield != null )
{
double chance = (parry - bushidoNonRacial) / 400.0; //As per OSI, no negitive effect from the Racial stuffs, ie, 120 parry and '0' bushido with humans
// Parry over 100 grants a 5% bonus.
if ( parry >= 100.0 )
chance += 0.05;
// Evasion grants a variable bonus post ML. 50% prior.
if ( Evasion.IsEvading( defender ) )
chance *= Evasion.GetParryScalar( defender );
// Low dexterity lowers the chance.
if ( defender.Dex < 80 )
chance = chance * (20 + defender.Dex) / 100;
return defender.CheckSkill( SkillName.Parry, chance );
}
else if ( !(defender.Weapon is Fists) && !(defender.Weapon is BaseRanged) )
{
BaseWeapon weapon = defender.Weapon as BaseWeapon;
double divisor = (weapon.Layer == Layer.OneHanded) ? 48000.0 : 41140.0;
double chance = (parry * bushido) / divisor;
double aosChance = parry / 800.0;
// Parry or Bushido over 100 grant a 5% bonus.
if( parry >= 100.0 )
{
chance += 0.05;
aosChance += 0.05;
}
else if( bushido >= 100.0 )
{
chance += 0.05;
}
// Evasion grants a variable bonus post ML. 50% prior.
if( Evasion.IsEvading( defender ) )
chance *= Evasion.GetParryScalar( defender );
// Low dexterity lowers the chance.
if( defender.Dex < 80 )
chance = chance * (20 + defender.Dex) / 100;
if ( chance > aosChance )
return defender.CheckSkill( SkillName.Parry, chance );
else
return (aosChance > Utility.RandomDouble()); // Only skillcheck if wielding a shield & there's no effect from Bushido
}
return false;
}
public virtual int AbsorbDamageAOS( Mobile attacker, Mobile defender, int damage )
{
bool blocked = false;
if ( defender.Player || defender.Body.IsHuman )
{
blocked = CheckParry( defender );
if ( blocked )
{
defender.FixedEffect( 0x37B9, 10, 16 );
damage = 0;
// Successful block removes the Honorable Execution penalty.
HonorableExecution.RemovePenalty( defender );
if ( CounterAttack.IsCountering( defender ) )
{
BaseWeapon weapon = defender.Weapon as BaseWeapon;
if ( weapon != null )
weapon.OnSwing( defender, attacker );
CounterAttack.StopCountering( defender );
}
if ( Confidence.IsConfident( defender ) )
{
defender.SendLocalizedMessage( 1063117 ); // Your confidence reassures you as you successfully block your opponent's blow.
double bushido = defender.Skills.Bushido.Value;
defender.Hits += Utility.RandomMinMax( 1, (int)(bushido / 12) );
defender.Stam += Utility.RandomMinMax( 1, (int)(bushido / 5) );
}
BaseShield shield = defender.FindItemOnLayer( Layer.TwoHanded ) as BaseShield;
if ( shield != null )
{
shield.OnHit( this, damage );
}
}
}
if ( !blocked )
{
double positionChance = Utility.RandomDouble();
Item armorItem;
if( positionChance < 0.07 )
armorItem = defender.NeckArmor;
else if( positionChance < 0.14 )
armorItem = defender.HandArmor;
else if( positionChance < 0.28 )
armorItem = defender.ArmsArmor;
else if( positionChance < 0.43 )
armorItem = defender.HeadArmor;
else if( positionChance < 0.65 )
armorItem = defender.LegsArmor;
else
armorItem = defender.ChestArmor;
IWearableDurability armor = armorItem as IWearableDurability;
if ( armor != null )
armor.OnHit( this, damage ); // call OnHit to lose durability
}
return damage;
}
public virtual int AbsorbDamage( Mobile attacker, Mobile defender, int damage )
{
if ( Core.AOS )
return AbsorbDamageAOS( attacker, defender, damage );
double chance = Utility.RandomDouble();
Item armorItem;
if( chance < 0.07 )
armorItem = defender.NeckArmor;
else if( chance < 0.14 )
armorItem = defender.HandArmor;
else if( chance < 0.28 )
armorItem = defender.ArmsArmor;
else if( chance < 0.43 )
armorItem = defender.HeadArmor;
else if( chance < 0.65 )
armorItem = defender.LegsArmor;
else
armorItem = defender.ChestArmor;
IWearableDurability armor = armorItem as IWearableDurability;
if ( armor != null )
damage = armor.OnHit( this, damage );
BaseShield shield = defender.FindItemOnLayer( Layer.TwoHanded ) as BaseShield;
if ( shield != null )
damage = shield.OnHit( this, damage );
int virtualArmor = defender.VirtualArmor + defender.VirtualArmorMod;
if ( virtualArmor > 0 )
{
double scalar;
if ( chance < 0.14 )
scalar = 0.07;
else if ( chance < 0.28 )
scalar = 0.14;
else if ( chance < 0.43 )
scalar = 0.15;
else if ( chance < 0.65 )
scalar = 0.22;
else
scalar = 0.35;
int from = (int)(virtualArmor * scalar) / 2;
int to = (int)(virtualArmor * scalar);
damage -= Utility.Random( from, (to - from) + 1 );
}
return damage;
}
public virtual int GetPackInstinctBonus( Mobile attacker, Mobile defender )
{
if ( attacker.Player || defender.Player )
return 0;
BaseCreature bc = attacker as BaseCreature;
if ( bc == null || bc.PackInstinct == PackInstinct.None || (!bc.Controlled && !bc.Summoned) )
return 0;
Mobile master = bc.ControlMaster;
if ( master == null )
master = bc.SummonMaster;
if ( master == null )
return 0;
int inPack = 1;
foreach ( Mobile m in defender.GetMobilesInRange( 1 ) )
{
if ( m != attacker && m is BaseCreature )
{
BaseCreature tc = (BaseCreature)m;
if ( (tc.PackInstinct & bc.PackInstinct) == 0 || (!tc.Controlled && !tc.Summoned) )
continue;
Mobile theirMaster = tc.ControlMaster;
if ( theirMaster == null )
theirMaster = tc.SummonMaster;
if ( master == theirMaster && tc.Combatant == defender )
++inPack;
}
}
if ( inPack >= 5 )
return 100;
else if ( inPack >= 4 )
return 75;
else if ( inPack >= 3 )
return 50;
else if ( inPack >= 2 )
return 25;
return 0;
}
private static bool m_InDoubleStrike;
public static bool InDoubleStrike
{
get{ return m_InDoubleStrike; }
set{ m_InDoubleStrike = value; }
}
public void OnHit( Mobile attacker, Mobile defender )
{
OnHit( attacker, defender, 1.0 );
}
public virtual void OnHit( Mobile attacker, Mobile defender, double damageBonus )
{
if ( MirrorImage.HasClone( defender ) && (defender.Skills.Ninjitsu.Value / 150.0) > Utility.RandomDouble() )
{
Clone bc;
foreach ( Mobile m in defender.GetMobilesInRange( 4 ) )
{
bc = m as Clone;
if ( bc != null && bc.Summoned && bc.SummonMaster == defender )
{
attacker.SendLocalizedMessage( 1063141 ); // Your attack has been diverted to a nearby mirror image of your target!
defender.SendLocalizedMessage( 1063140 ); // You manage to divert the attack onto one of your nearby mirror images.
/*
* TODO: What happens if the Clone parries a blow?
* And what about if the attacker is using Honorable Execution
* and kills it?
*/
defender = m;
break;
}
}
}
PlaySwingAnimation( attacker );
PlayHurtAnimation( defender );
attacker.PlaySound( GetHitAttackSound( attacker, defender ) );
defender.PlaySound( GetHitDefendSound( attacker, defender ) );
int damage = ComputeDamage( attacker, defender );
#region Damage Multipliers
/*
* The following damage bonuses multiply damage by a factor.
* Capped at x3 (300%).
*/
//double factor = 1.0;
int percentageBonus = 0;
WeaponAbility a = WeaponAbility.GetCurrentAbility( attacker );
SpecialMove move = SpecialMove.GetCurrentMove( attacker );
if( a != null )
{
//factor *= a.DamageScalar;
percentageBonus += (int)(a.DamageScalar * 100) - 100;
}
if( move != null )
{
//factor *= move.GetDamageScalar( attacker, defender );
percentageBonus += (int)(move.GetDamageScalar( attacker, defender ) * 100) - 100;
}
//factor *= damageBonus;
percentageBonus += (int)(damageBonus * 100) - 100;
CheckSlayerResult cs = CheckSlayers( attacker, defender );
if ( cs != CheckSlayerResult.None )
{
if ( cs == CheckSlayerResult.Slayer )
defender.FixedEffect( 0x37B9, 10, 5 );
//factor *= 2.0;
percentageBonus += 100;
}
if ( !attacker.Player )
{
if ( defender is PlayerMobile )
{
PlayerMobile pm = (PlayerMobile)defender;
if( pm.EnemyOfOneType != null && pm.EnemyOfOneType != attacker.GetType() )
{
//factor *= 2.0;
percentageBonus += 100;
}
}
}
else if ( !defender.Player )
{
if ( attacker is PlayerMobile )
{
PlayerMobile pm = (PlayerMobile)attacker;
if ( pm.WaitingForEnemy )
{
pm.EnemyOfOneType = defender.GetType();
pm.WaitingForEnemy = false;
}
if ( pm.EnemyOfOneType == defender.GetType() )
{
defender.FixedEffect( 0x37B9, 10, 5, 1160, 0 );
//factor *= 1.5;
percentageBonus += 50;
}
}
}
int packInstinctBonus = GetPackInstinctBonus( attacker, defender );
if( packInstinctBonus != 0 )
{
//factor *= 1.0 + (double)packInstinctBonus / 100.0;
percentageBonus += packInstinctBonus;
}
if( m_InDoubleStrike )
{
//factor *= 0.9; // 10% loss when attacking with double-strike
percentageBonus -= 10;
}
TransformContext context = TransformationSpellHelper.GetContext( defender );
if( (m_Slayer == SlayerName.Silver || m_Slayer2 == SlayerName.Silver) && context != null && context.Spell is NecromancerSpell && context.Type != typeof( HorrificBeastSpell ) )
{
//factor *= 1.25; // Every necromancer transformation other than horrific beast takes an additional 25% damage
percentageBonus += 25;
}
if ( attacker is PlayerMobile && !(Core.ML && defender is PlayerMobile ))
{
PlayerMobile pmAttacker = (PlayerMobile) attacker;
if( pmAttacker.HonorActive && pmAttacker.InRange( defender, 1 ) )
{
//factor *= 1.25;
percentageBonus += 25;
}
if( pmAttacker.SentHonorContext != null && pmAttacker.SentHonorContext.Target == defender )
{
//pmAttacker.SentHonorContext.ApplyPerfectionDamageBonus( ref factor );
percentageBonus += pmAttacker.SentHonorContext.PerfectionDamageBonus;
}
}
//if ( factor > 3.0 )
// factor = 3.0;
percentageBonus = Math.Min( percentageBonus, 300 );
//damage = (int)(damage * factor);
damage = AOS.Scale( damage, 100 + percentageBonus );
#endregion
if ( attacker is BaseCreature )
((BaseCreature)attacker).AlterMeleeDamageTo( defender, ref damage );
if ( defender is BaseCreature )
((BaseCreature)defender).AlterMeleeDamageFrom( attacker, ref damage );
damage = AbsorbDamage( attacker, defender, damage );
if ( !Core.AOS && damage < 1 )
damage = 1;
else if ( Core.AOS && damage == 0 ) // parried
{
if ( a != null && a.Validate( attacker ) /*&& a.CheckMana( attacker, true )*/ ) // Parried special moves have no mana cost
{
a = null;
WeaponAbility.ClearCurrentAbility( attacker );
attacker.SendLocalizedMessage( 1061140 ); // Your attack was parried!
}
}
AddBlood( attacker, defender, damage );
int phys, fire, cold, pois, nrgy;
GetDamageTypes( attacker, out phys, out fire, out cold, out pois, out nrgy );
if ( m_Consecrated )
{
phys = defender.PhysicalResistance;
fire = defender.FireResistance;
cold = defender.ColdResistance;
pois = defender.PoisonResistance;
nrgy = defender.EnergyResistance;
int low = phys, type = 0;
if ( fire < low ){ low = fire; type = 1; }
if ( cold < low ){ low = cold; type = 2; }
if ( pois < low ){ low = pois; type = 3; }
if ( nrgy < low ){ low = nrgy; type = 4; }
phys = fire = cold = pois = nrgy = 0;
if ( type == 0 ) phys = 100;
else if ( type == 1 ) fire = 100;
else if ( type == 2 ) cold = 100;
else if ( type == 3 ) pois = 100;
else if ( type == 4 ) nrgy = 100;
}
int damageGiven = damage;
if ( a != null && !a.OnBeforeDamage( attacker, defender ) )
{
WeaponAbility.ClearCurrentAbility( attacker );
a = null;
}
if ( move != null && !move.OnBeforeDamage( attacker, defender ) )
{
SpecialMove.ClearCurrentMove( attacker );
move = null;
}
bool ignoreArmor = ( a is ArmorIgnore || (move != null && move.IgnoreArmor( attacker )) );
damageGiven = AOS.Damage( defender, attacker, damage, ignoreArmor, phys, fire, cold, pois, nrgy );
double propertyBonus = ( move == null ) ? 1.0 : move.GetPropertyBonus( attacker );
if ( Core.AOS )
{
int lifeLeech = 0;
int stamLeech = 0;
int manaLeech = 0;
int wraithLeech = 0;
if ( (int)(m_AosWeaponAttributes.HitLeechHits * propertyBonus) > Utility.Random( 100 ) )
lifeLeech += 30; // HitLeechHits% chance to leech 30% of damage as hit points
if ( (int)(m_AosWeaponAttributes.HitLeechStam * propertyBonus) > Utility.Random( 100 ) )
stamLeech += 100; // HitLeechStam% chance to leech 100% of damage as stamina
if ( (int)(m_AosWeaponAttributes.HitLeechMana * propertyBonus) > Utility.Random( 100 ) )
manaLeech += 40; // HitLeechMana% chance to leech 40% of damage as mana
if ( m_Cursed )
lifeLeech += 50; // Additional 50% life leech for cursed weapons (necro spell)
context = TransformationSpellHelper.GetContext( attacker );
if ( context != null && context.Type == typeof( VampiricEmbraceSpell ) )
lifeLeech += 20; // Vampiric embrace gives an additional 20% life leech
if ( context != null && context.Type == typeof( WraithFormSpell ) )
{
wraithLeech = (5 + (int)((15 * attacker.Skills.SpiritSpeak.Value) / 100)); // Wraith form gives an additional 5-20% mana leech
// Mana leeched by the Wraith Form spell is actually stolen, not just leeched.
defender.Mana -= AOS.Scale( damageGiven, wraithLeech );
manaLeech += wraithLeech;
}
if ( lifeLeech != 0 )
attacker.Hits += AOS.Scale( damageGiven, lifeLeech );
if ( stamLeech != 0 )
attacker.Stam += AOS.Scale( damageGiven, stamLeech );
if ( manaLeech != 0 )
attacker.Mana += AOS.Scale( damageGiven, manaLeech );
if ( lifeLeech != 0 || stamLeech != 0 || manaLeech != 0 )
attacker.PlaySound( 0x44D );
}
if ( m_MaxHits > 0 && ((MaxRange <= 1 && (defender is Slime || defender is ToxicElemental)) || Utility.Random( 25 ) == 0) ) // Stratics says 50% chance, seems more like 4%..
{
if ( MaxRange <= 1 && (defender is Slime || defender is ToxicElemental) )
attacker.LocalOverheadMessage( MessageType.Regular, 0x3B2, 500263 ); // *Acid blood scars your weapon!*
if ( Core.AOS && m_AosWeaponAttributes.SelfRepair > Utility.Random( 10 ) )
{
HitPoints += 2;
}
else
{
if ( m_Hits > 0 )
{
--HitPoints;
}
else if ( m_MaxHits > 1 )
{
--MaxHitPoints;
if ( Parent is Mobile )
((Mobile)Parent).LocalOverheadMessage( MessageType.Regular, 0x3B2, 1061121 ); // Your equipment is severely damaged.
}
else
{
Delete();
}
}
}
if ( attacker is VampireBatFamiliar )
{
BaseCreature bc = (BaseCreature)attacker;
Mobile caster = bc.ControlMaster;
if ( caster == null )
caster = bc.SummonMaster;
if ( caster != null && caster.Map == bc.Map && caster.InRange( bc, 2 ) )
caster.Hits += damage;
else
bc.Hits += damage;
}
if ( Core.AOS )
{
int physChance = (int)(m_AosWeaponAttributes.HitPhysicalArea * propertyBonus);
int fireChance = (int)(m_AosWeaponAttributes.HitFireArea * propertyBonus);
int coldChance = (int)(m_AosWeaponAttributes.HitColdArea * propertyBonus);
int poisChance = (int)(m_AosWeaponAttributes.HitPoisonArea * propertyBonus);
int nrgyChance = (int)(m_AosWeaponAttributes.HitEnergyArea * propertyBonus);
if ( physChance != 0 && physChance > Utility.Random( 100 ) )
DoAreaAttack( attacker, defender, 0x10E, 50, 100, 0, 0, 0, 0 );
if ( fireChance != 0 && fireChance > Utility.Random( 100 ) )
DoAreaAttack( attacker, defender, 0x11D, 1160, 0, 100, 0, 0, 0 );
if ( coldChance != 0 && coldChance > Utility.Random( 100 ) )
DoAreaAttack( attacker, defender, 0x0FC, 2100, 0, 0, 100, 0, 0 );
if ( poisChance != 0 && poisChance > Utility.Random( 100 ) )
DoAreaAttack( attacker, defender, 0x205, 1166, 0, 0, 0, 100, 0 );
if ( nrgyChance != 0 && nrgyChance > Utility.Random( 100 ) )
DoAreaAttack( attacker, defender, 0x1F1, 120, 0, 0, 0, 0, 100 );
int maChance = (int)(m_AosWeaponAttributes.HitMagicArrow * propertyBonus);
int harmChance = (int)(m_AosWeaponAttributes.HitHarm * propertyBonus);
int fireballChance = (int)(m_AosWeaponAttributes.HitFireball * propertyBonus);
int lightningChance = (int)(m_AosWeaponAttributes.HitLightning * propertyBonus);
int dispelChance = (int)(m_AosWeaponAttributes.HitDispel * propertyBonus);
if ( maChance != 0 && maChance > Utility.Random( 100 ) )
DoMagicArrow( attacker, defender );
if ( harmChance != 0 && harmChance > Utility.Random( 100 ) )
DoHarm( attacker, defender );
if ( fireballChance != 0 && fireballChance > Utility.Random( 100 ) )
DoFireball( attacker, defender );
if ( lightningChance != 0 && lightningChance > Utility.Random( 100 ) )
DoLightning( attacker, defender );
if ( dispelChance != 0 && dispelChance > Utility.Random( 100 ) )
DoDispel( attacker, defender );
int laChance = (int)(m_AosWeaponAttributes.HitLowerAttack * propertyBonus);
int ldChance = (int)(m_AosWeaponAttributes.HitLowerDefend * propertyBonus);
if ( laChance != 0 && laChance > Utility.Random( 100 ) )
DoLowerAttack( attacker, defender );
if ( ldChance != 0 && ldChance > Utility.Random( 100 ) )
DoLowerDefense( attacker, defender );
}
if ( attacker is BaseCreature )
((BaseCreature)attacker).OnGaveMeleeAttack( defender );
if ( defender is BaseCreature )
((BaseCreature)defender).OnGotMeleeAttack( attacker );
if ( a != null )
a.OnHit( attacker, defender, damage );
if ( move != null )
move.OnHit( attacker, defender, damage );
if ( defender is IHonorTarget && ((IHonorTarget)defender).ReceivedHonorContext != null )
((IHonorTarget)defender).ReceivedHonorContext.OnTargetHit( attacker );
if ( !(this is BaseRanged) )
{
if ( AnimalForm.UnderTransformation( attacker, typeof( GiantSerpent ) ) )
defender.ApplyPoison( attacker, Poison.Lesser );
if ( AnimalForm.UnderTransformation( defender, typeof( BullFrog ) ) )
attacker.ApplyPoison( defender, Poison.Regular );
}
}
public virtual double GetAosDamage( Mobile attacker, int bonus, int dice, int sides )
{
int damage = Utility.Dice( dice, sides, bonus ) * 100;
int damageBonus = 0;
// Inscription bonus
int inscribeSkill = attacker.Skills[SkillName.Inscribe].Fixed;
damageBonus += inscribeSkill / 200;
if ( inscribeSkill >= 1000 )
damageBonus += 5;
if ( attacker.Player )
{
// Int bonus
damageBonus += (attacker.Int / 10);
// SDI bonus
damageBonus += AosAttributes.GetValue( attacker, AosAttribute.SpellDamage );
TransformContext context = TransformationSpellHelper.GetContext( attacker );
if( context != null && context.Spell is ReaperFormSpell )
damageBonus += ((ReaperFormSpell)context.Spell).SpellDamageBonus;
}
damage = AOS.Scale( damage, 100 + damageBonus );
return damage / 100;
}
#region Do<AoSEffect>
public virtual void DoMagicArrow( Mobile attacker, Mobile defender )
{
if ( !attacker.CanBeHarmful( defender, false ) )
return;
attacker.DoHarmful( defender );
double damage = GetAosDamage( attacker, 10, 1, 4 );
attacker.MovingParticles( defender, 0x36E4, 5, 0, false, true, 3006, 4006, 0 );
attacker.PlaySound( 0x1E5 );
SpellHelper.Damage( TimeSpan.FromSeconds( 1.0 ), defender, attacker, damage, 0, 100, 0, 0, 0 );
}
public virtual void DoHarm( Mobile attacker, Mobile defender )
{
if ( !attacker.CanBeHarmful( defender, false ) )
return;
attacker.DoHarmful( defender );
double damage = GetAosDamage( attacker, 17, 1, 5 );
if ( !defender.InRange( attacker, 2 ) )
damage *= 0.25; // 1/4 damage at > 2 tile range
else if ( !defender.InRange( attacker, 1 ) )
damage *= 0.50; // 1/2 damage at 2 tile range
defender.FixedParticles( 0x374A, 10, 30, 5013, 1153, 2, EffectLayer.Waist );
defender.PlaySound( 0x0FC );
SpellHelper.Damage( TimeSpan.Zero, defender, attacker, damage, 0, 0, 100, 0, 0 );
}
public virtual void DoFireball( Mobile attacker, Mobile defender )
{
if ( !attacker.CanBeHarmful( defender, false ) )
return;
attacker.DoHarmful( defender );
double damage = GetAosDamage( attacker, 19, 1, 5 );
attacker.MovingParticles( defender, 0x36D4, 7, 0, false, true, 9502, 4019, 0x160 );
attacker.PlaySound( 0x15E );
SpellHelper.Damage( TimeSpan.FromSeconds( 1.0 ), defender, attacker, damage, 0, 100, 0, 0, 0 );
}
public virtual void DoLightning( Mobile attacker, Mobile defender )
{
if ( !attacker.CanBeHarmful( defender, false ) )
return;
attacker.DoHarmful( defender );
double damage = GetAosDamage( attacker, 23, 1, 4 );
defender.BoltEffect( 0 );
SpellHelper.Damage( TimeSpan.Zero, defender, attacker, damage, 0, 0, 0, 0, 100 );
}
public virtual void DoDispel( Mobile attacker, Mobile defender )
{
bool dispellable = false;
if ( defender is BaseCreature )
dispellable = ((BaseCreature)defender).Summoned && !((BaseCreature)defender).IsAnimatedDead;
if ( !dispellable )
return;
if ( !attacker.CanBeHarmful( defender, false ) )
return;
attacker.DoHarmful( defender );
Spells.MagerySpell sp = new Spells.Sixth.DispelSpell( attacker, null );
if ( sp.CheckResisted( defender ) )
{
defender.FixedEffect( 0x3779, 10, 20 );
}
else
{
Effects.SendLocationParticles( EffectItem.Create( defender.Location, defender.Map, EffectItem.DefaultDuration ), 0x3728, 8, 20, 5042 );
Effects.PlaySound( defender, defender.Map, 0x201 );
defender.Delete();
}
}
public virtual void DoLowerAttack( Mobile from, Mobile defender )
{
if ( HitLower.ApplyAttack( defender ) )
{
defender.PlaySound( 0x28E );
Effects.SendTargetEffect( defender, 0x37BE, 1, 4, 0xA, 3 );
}
}
public virtual void DoLowerDefense( Mobile from, Mobile defender )
{
if ( HitLower.ApplyDefense( defender ) )
{
defender.PlaySound( 0x28E );
Effects.SendTargetEffect( defender, 0x37BE, 1, 4, 0x23, 3 );
}
}
public virtual void DoAreaAttack( Mobile from, Mobile defender, int sound, int hue, int phys, int fire, int cold, int pois, int nrgy )
{
Map map = from.Map;
if ( map == null )
return;
List<Mobile> list = new List<Mobile>();
foreach ( Mobile m in from.GetMobilesInRange( 10 ) )
{
if ( from != m && defender != m && SpellHelper.ValidIndirectTarget( from, m ) && from.CanBeHarmful( m, false ) && ( !Core.ML || from.InLOS( m ) ) )
list.Add( m );
}
if ( list.Count == 0 )
return;
Effects.PlaySound( from.Location, map, sound );
// TODO: What is the damage calculation?
for ( int i = 0; i < list.Count; ++i )
{
Mobile m = list[i];
double scalar = (11 - from.GetDistanceToSqrt( m )) / 10;
if ( scalar > 1.0 )
scalar = 1.0;
else if ( scalar < 0.0 )
continue;
from.DoHarmful( m, true );
m.FixedEffect( 0x3779, 1, 15, hue, 0 );
AOS.Damage( m, from, (int)(GetBaseDamage( from ) * scalar), phys, fire, cold, pois, nrgy );
}
}
#endregion
public virtual CheckSlayerResult CheckSlayers( Mobile attacker, Mobile defender )
{
BaseWeapon atkWeapon = attacker.Weapon as BaseWeapon;
SlayerEntry atkSlayer = SlayerGroup.GetEntryByName( atkWeapon.Slayer );
SlayerEntry atkSlayer2 = SlayerGroup.GetEntryByName( atkWeapon.Slayer2 );
if ( atkSlayer != null && atkSlayer.Slays( defender ) || atkSlayer2 != null && atkSlayer2.Slays( defender ) )
return CheckSlayerResult.Slayer;
if ( !Core.SE )
{
ISlayer defISlayer = Spellbook.FindEquippedSpellbook( defender );
if( defISlayer == null )
defISlayer = defender.Weapon as ISlayer;
if( defISlayer != null )
{
SlayerEntry defSlayer = SlayerGroup.GetEntryByName( defISlayer.Slayer );
SlayerEntry defSlayer2 = SlayerGroup.GetEntryByName( defISlayer.Slayer2 );
if( defSlayer != null && defSlayer.Group.OppositionSuperSlays( attacker ) || defSlayer2 != null && defSlayer2.Group.OppositionSuperSlays( attacker ) )
return CheckSlayerResult.Opposition;
}
}
return CheckSlayerResult.None;
}
public virtual void AddBlood( Mobile attacker, Mobile defender, int damage )
{
if ( damage > 0 )
{
new Blood().MoveToWorld( defender.Location, defender.Map );
int extraBlood = (Core.SE ? Utility.RandomMinMax( 3, 4 ) : Utility.RandomMinMax( 0, 1 ) );
for( int i = 0; i < extraBlood; i++ )
{
new Blood().MoveToWorld( new Point3D(
defender.X + Utility.RandomMinMax( -1, 1 ),
defender.Y + Utility.RandomMinMax( -1, 1 ),
defender.Z ), defender.Map );
}
}
}
public virtual void GetDamageTypes( Mobile wielder, out int phys, out int fire, out int cold, out int pois, out int nrgy )
{
if( wielder is BaseCreature )
{
BaseCreature bc = (BaseCreature)wielder;
phys = bc.PhysicalDamage;
fire = bc.FireDamage;
cold = bc.ColdDamage;
pois = bc.PoisonDamage;
nrgy = bc.EnergyDamage;
}
else
{
fire = m_AosElementDamages.Fire;
cold = m_AosElementDamages.Cold;
pois = m_AosElementDamages.Poison;
nrgy = m_AosElementDamages.Energy;
phys = 100 - fire - cold - pois - nrgy;
CraftResourceInfo resInfo = CraftResources.GetInfo( m_Resource );
if( resInfo != null )
{
CraftAttributeInfo attrInfo = resInfo.AttributeInfo;
if( attrInfo != null )
{
int left = phys;
left = ApplyCraftAttributeElementDamage( attrInfo.WeaponColdDamage, ref cold, left );
left = ApplyCraftAttributeElementDamage( attrInfo.WeaponEnergyDamage, ref nrgy, left );
left = ApplyCraftAttributeElementDamage( attrInfo.WeaponFireDamage, ref fire, left );
left = ApplyCraftAttributeElementDamage( attrInfo.WeaponPoisonDamage, ref pois, left );
phys = left;
}
}
}
}
private int ApplyCraftAttributeElementDamage( int attrDamage, ref int element, int totalRemaining )
{
if( totalRemaining <= 0 )
return 0;
if ( attrDamage <= 0 )
return totalRemaining;
int appliedDamage = attrDamage;
if ( (appliedDamage + element) > 100 )
appliedDamage = 100 - element;
if( appliedDamage > totalRemaining )
appliedDamage = totalRemaining;
element += appliedDamage;
return totalRemaining - appliedDamage;
}
public virtual void OnMiss( Mobile attacker, Mobile defender )
{
PlaySwingAnimation( attacker );
attacker.PlaySound( GetMissAttackSound( attacker, defender ) );
defender.PlaySound( GetMissDefendSound( attacker, defender ) );
WeaponAbility ability = WeaponAbility.GetCurrentAbility( attacker );
if ( ability != null )
ability.OnMiss( attacker, defender );
SpecialMove move = SpecialMove.GetCurrentMove( attacker );
if ( move != null )
move.OnMiss( attacker, defender );
if ( defender is IHonorTarget && ((IHonorTarget)defender).ReceivedHonorContext != null )
((IHonorTarget)defender).ReceivedHonorContext.OnTargetMissed( attacker );
}
public virtual void GetBaseDamageRange( Mobile attacker, out int min, out int max )
{
if ( attacker is BaseCreature )
{
BaseCreature c = (BaseCreature)attacker;
if ( c.DamageMin >= 0 )
{
min = c.DamageMin;
max = c.DamageMax;
return;
}
if ( this is Fists && !attacker.Body.IsHuman )
{
min = attacker.Str / 28;
max = attacker.Str / 28;
return;
}
}
min = MinDamage;
max = MaxDamage;
}
public virtual double GetBaseDamage( Mobile attacker )
{
int min, max;
GetBaseDamageRange( attacker, out min, out max );
return Utility.RandomMinMax( min, max );
}
public virtual double GetBonus( double value, double scalar, double threshold, double offset )
{
double bonus = value * scalar;
if ( value >= threshold )
bonus += offset;
return bonus / 100;
}
public virtual int GetHitChanceBonus()
{
if ( !Core.AOS )
return 0;
int bonus = 0;
switch ( m_AccuracyLevel )
{
case WeaponAccuracyLevel.Accurate: bonus += 02; break;
case WeaponAccuracyLevel.Surpassingly: bonus += 04; break;
case WeaponAccuracyLevel.Eminently: bonus += 06; break;
case WeaponAccuracyLevel.Exceedingly: bonus += 08; break;
case WeaponAccuracyLevel.Supremely: bonus += 10; break;
}
return bonus;
}
public virtual int GetDamageBonus()
{
int bonus = VirtualDamageBonus;
switch ( m_Quality )
{
case WeaponQuality.Low: bonus -= 20; break;
case WeaponQuality.Exceptional: bonus += 20; break;
}
switch ( m_DamageLevel )
{
case WeaponDamageLevel.Ruin: bonus += 15; break;
case WeaponDamageLevel.Might: bonus += 20; break;
case WeaponDamageLevel.Force: bonus += 25; break;
case WeaponDamageLevel.Power: bonus += 30; break;
case WeaponDamageLevel.Vanq: bonus += 35; break;
}
return bonus;
}
public virtual void GetStatusDamage( Mobile from, out int min, out int max )
{
int baseMin, baseMax;
GetBaseDamageRange( from, out baseMin, out baseMax );
if ( Core.AOS )
{
min = Math.Max( (int)ScaleDamageAOS( from, baseMin, false ), 1 );
max = Math.Max( (int)ScaleDamageAOS( from, baseMax, false ), 1 );
}
else
{
min = Math.Max( (int)ScaleDamageOld( from, baseMin, false ), 1 );
max = Math.Max( (int)ScaleDamageOld( from, baseMax, false ), 1 );
}
}
public virtual double ScaleDamageAOS( Mobile attacker, double damage, bool checkSkills )
{
if ( checkSkills )
{
attacker.CheckSkill( SkillName.Tactics, 0.0, 120.0 ); // Passively check tactics for gain
attacker.CheckSkill( SkillName.Anatomy, 0.0, 120.0 ); // Passively check Anatomy for gain
if ( Type == WeaponType.Axe )
attacker.CheckSkill( SkillName.Lumberjacking, 0.0, 100.0 ); // Passively check Lumberjacking for gain
}
#region Physical bonuses
/*
* These are the bonuses given by the physical characteristics of the mobile.
* No caps apply.
*/
double strengthBonus = GetBonus( attacker.Str, 0.300, 100.0, 5.00 );
double anatomyBonus = GetBonus( attacker.Skills[SkillName.Anatomy].Value, 0.500, 100.0, 5.00 );
double tacticsBonus = GetBonus( attacker.Skills[SkillName.Tactics].Value, 0.625, 100.0, 6.25 );
double lumberBonus = GetBonus( attacker.Skills[SkillName.Lumberjacking].Value, 0.200, 100.0, 10.00 );
if ( Type != WeaponType.Axe )
lumberBonus = 0.0;
#endregion
#region Modifiers
/*
* The following are damage modifiers whose effect shows on the status bar.
* Capped at 100% total.
*/
int damageBonus = AosAttributes.GetValue( attacker, AosAttribute.WeaponDamage );
// Horrific Beast transformation gives a +25% bonus to damage.
if( TransformationSpellHelper.UnderTransformation( attacker, typeof( HorrificBeastSpell ) ) )
damageBonus += 25;
// Divine Fury gives a +10% bonus to damage.
if ( Spells.Chivalry.DivineFurySpell.UnderEffect( attacker ) )
damageBonus += 10;
int defenseMasteryMalus = 0;
// Defense Mastery gives a -50%/-80% malus to damage.
if ( Server.Items.DefenseMastery.GetMalus( attacker, ref defenseMasteryMalus ) )
damageBonus -= defenseMasteryMalus;
int discordanceEffect = 0;
// Discordance gives a -2%/-48% malus to damage.
if ( SkillHandlers.Discordance.GetEffect( attacker, ref discordanceEffect ) )
damageBonus -= discordanceEffect * 2;
if ( damageBonus > 100 )
damageBonus = 100;
#endregion
double totalBonus = strengthBonus + anatomyBonus + tacticsBonus + lumberBonus + ((double)(GetDamageBonus() + damageBonus) / 100.0);
return damage + (int)(damage * totalBonus);
}
public virtual int VirtualDamageBonus{ get{ return 0; } }
public virtual int ComputeDamageAOS( Mobile attacker, Mobile defender )
{
return (int)ScaleDamageAOS( attacker, GetBaseDamage( attacker ), true );
}
public virtual double ScaleDamageOld( Mobile attacker, double damage, bool checkSkills )
{
if ( checkSkills )
{
attacker.CheckSkill( SkillName.Tactics, 0.0, 120.0 ); // Passively check tactics for gain
attacker.CheckSkill( SkillName.Anatomy, 0.0, 120.0 ); // Passively check Anatomy for gain
if ( Type == WeaponType.Axe )
attacker.CheckSkill( SkillName.Lumberjacking, 0.0, 100.0 ); // Passively check Lumberjacking for gain
}
/* Compute tactics modifier
* : 0.0 = 50% loss
* : 50.0 = unchanged
* : 100.0 = 50% bonus
*/
double tacticsBonus = (attacker.Skills[SkillName.Tactics].Value - 50.0) / 100.0;
/* Compute strength modifier
* : 1% bonus for every 5 strength
*/
double strBonus = (attacker.Str / 5.0) / 100.0;
/* Compute anatomy modifier
* : 1% bonus for every 5 points of anatomy
* : +10% bonus at Grandmaster or higher
*/
double anatomyValue = attacker.Skills[SkillName.Anatomy].Value;
double anatomyBonus = (anatomyValue / 5.0) / 100.0;
if ( anatomyValue >= 100.0 )
anatomyBonus += 0.1;
/* Compute lumberjacking bonus
* : 1% bonus for every 5 points of lumberjacking
* : +10% bonus at Grandmaster or higher
*/
double lumberBonus;
if ( Type == WeaponType.Axe )
{
double lumberValue = attacker.Skills[SkillName.Lumberjacking].Value;
lumberBonus = (lumberValue / 5.0) / 100.0;
if ( lumberValue >= 100.0 )
lumberBonus += 0.1;
}
else
{
lumberBonus = 0.0;
}
// New quality bonus:
double qualityBonus = ((int)m_Quality - 1) * 0.2;
// Apply bonuses
damage += (damage * tacticsBonus) + (damage * strBonus) + (damage * anatomyBonus) + (damage * lumberBonus) + (damage * qualityBonus) + ((damage * VirtualDamageBonus) / 100);
// Old quality bonus:
#if false
/* Apply quality offset
* : Low : -4
* : Regular : 0
* : Exceptional : +4
*/
damage += ((int)m_Quality - 1) * 4.0;
#endif
/* Apply damage level offset
* : Regular : 0
* : Ruin : 1
* : Might : 3
* : Force : 5
* : Power : 7
* : Vanq : 9
*/
if ( m_DamageLevel != WeaponDamageLevel.Regular )
damage += (2.0 * (int)m_DamageLevel) - 1.0;
// Halve the computed damage and return
damage /= 2.0;
return ScaleDamageByDurability( (int)damage );
}
public virtual int ScaleDamageByDurability( int damage )
{
int scale = 100;
if ( m_MaxHits > 0 && m_Hits < m_MaxHits )
scale = 50 + ((50 * m_Hits) / m_MaxHits);
return AOS.Scale( damage, scale );
}
public virtual int ComputeDamage( Mobile attacker, Mobile defender )
{
if ( Core.AOS )
return ComputeDamageAOS( attacker, defender );
return (int)ScaleDamageOld( attacker, GetBaseDamage( attacker ), true );
}
public virtual void PlayHurtAnimation( Mobile from )
{
int action;
int frames;
switch ( from.Body.Type )
{
case BodyType.Sea:
case BodyType.Animal:
{
action = 7;
frames = 5;
break;
}
case BodyType.Monster:
{
action = 10;
frames = 4;
break;
}
case BodyType.Human:
{
action = 20;
frames = 5;
break;
}
default: return;
}
if ( from.Mounted )
return;
from.Animate( action, frames, 1, true, false, 0 );
}
public virtual void PlaySwingAnimation( Mobile from )
{
int action;
switch ( from.Body.Type )
{
case BodyType.Sea:
case BodyType.Animal:
{
action = Utility.Random( 5, 2 );
break;
}
case BodyType.Monster:
{
switch ( Animation )
{
default:
case WeaponAnimation.Wrestle:
case WeaponAnimation.Bash1H:
case WeaponAnimation.Pierce1H:
case WeaponAnimation.Slash1H:
case WeaponAnimation.Bash2H:
case WeaponAnimation.Pierce2H:
case WeaponAnimation.Slash2H: action = Utility.Random( 4, 3 ); break;
case WeaponAnimation.ShootBow: return; // 7
case WeaponAnimation.ShootXBow: return; // 8
}
break;
}
case BodyType.Human:
{
if ( !from.Mounted )
{
action = (int)Animation;
}
else
{
switch ( Animation )
{
default:
case WeaponAnimation.Wrestle:
case WeaponAnimation.Bash1H:
case WeaponAnimation.Pierce1H:
case WeaponAnimation.Slash1H: action = 26; break;
case WeaponAnimation.Bash2H:
case WeaponAnimation.Pierce2H:
case WeaponAnimation.Slash2H: action = 29; break;
case WeaponAnimation.ShootBow: action = 27; break;
case WeaponAnimation.ShootXBow: action = 28; break;
}
}
break;
}
default: return;
}
from.Animate( action, 7, 1, true, false, 0 );
}
#region Serialization/Deserialization
private static void SetSaveFlag( ref SaveFlag flags, SaveFlag toSet, bool setIf )
{
if ( setIf )
flags |= toSet;
}
private static bool GetSaveFlag( SaveFlag flags, SaveFlag toGet )
{
return ( (flags & toGet) != 0 );
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 8 ); // version
SaveFlag flags = SaveFlag.None;
SetSaveFlag( ref flags, SaveFlag.DamageLevel, m_DamageLevel != WeaponDamageLevel.Regular );
SetSaveFlag( ref flags, SaveFlag.AccuracyLevel, m_AccuracyLevel != WeaponAccuracyLevel.Regular );
SetSaveFlag( ref flags, SaveFlag.DurabilityLevel, m_DurabilityLevel != WeaponDurabilityLevel.Regular );
SetSaveFlag( ref flags, SaveFlag.Quality, m_Quality != WeaponQuality.Regular );
SetSaveFlag( ref flags, SaveFlag.Hits, m_Hits != 0 );
SetSaveFlag( ref flags, SaveFlag.MaxHits, m_MaxHits != 0 );
SetSaveFlag( ref flags, SaveFlag.Slayer, m_Slayer != SlayerName.None );
SetSaveFlag( ref flags, SaveFlag.Poison, m_Poison != null );
SetSaveFlag( ref flags, SaveFlag.PoisonCharges, m_PoisonCharges != 0 );
SetSaveFlag( ref flags, SaveFlag.Crafter, m_Crafter != null );
SetSaveFlag( ref flags, SaveFlag.Identified, m_Identified != false );
SetSaveFlag( ref flags, SaveFlag.StrReq, m_StrReq != -1 );
SetSaveFlag( ref flags, SaveFlag.DexReq, m_DexReq != -1 );
SetSaveFlag( ref flags, SaveFlag.IntReq, m_IntReq != -1 );
SetSaveFlag( ref flags, SaveFlag.MinDamage, m_MinDamage != -1 );
SetSaveFlag( ref flags, SaveFlag.MaxDamage, m_MaxDamage != -1 );
SetSaveFlag( ref flags, SaveFlag.HitSound, m_HitSound != -1 );
SetSaveFlag( ref flags, SaveFlag.MissSound, m_MissSound != -1 );
SetSaveFlag( ref flags, SaveFlag.Speed, m_Speed != -1 );
SetSaveFlag( ref flags, SaveFlag.MaxRange, m_MaxRange != -1 );
SetSaveFlag( ref flags, SaveFlag.Skill, m_Skill != (SkillName)(-1) );
SetSaveFlag( ref flags, SaveFlag.Type, m_Type != (WeaponType)(-1) );
SetSaveFlag( ref flags, SaveFlag.Animation, m_Animation != (WeaponAnimation)(-1) );
SetSaveFlag( ref flags, SaveFlag.Resource, m_Resource != CraftResource.Iron );
SetSaveFlag( ref flags, SaveFlag.xAttributes, !m_AosAttributes.IsEmpty );
SetSaveFlag( ref flags, SaveFlag.xWeaponAttributes, !m_AosWeaponAttributes.IsEmpty );
SetSaveFlag( ref flags, SaveFlag.PlayerConstructed, m_PlayerConstructed );
SetSaveFlag( ref flags, SaveFlag.SkillBonuses, !m_AosSkillBonuses.IsEmpty );
SetSaveFlag( ref flags, SaveFlag.Slayer2, m_Slayer2 != SlayerName.None );
SetSaveFlag( ref flags, SaveFlag.ElementalDamages, !m_AosElementDamages.IsEmpty );
writer.Write( (int) flags );
if ( GetSaveFlag( flags, SaveFlag.DamageLevel ) )
writer.Write( (int) m_DamageLevel );
if ( GetSaveFlag( flags, SaveFlag.AccuracyLevel ) )
writer.Write( (int) m_AccuracyLevel );
if ( GetSaveFlag( flags, SaveFlag.DurabilityLevel ) )
writer.Write( (int) m_DurabilityLevel );
if ( GetSaveFlag( flags, SaveFlag.Quality ) )
writer.Write( (int) m_Quality );
if ( GetSaveFlag( flags, SaveFlag.Hits ) )
writer.Write( (int) m_Hits );
if ( GetSaveFlag( flags, SaveFlag.MaxHits ) )
writer.Write( (int) m_MaxHits );
if ( GetSaveFlag( flags, SaveFlag.Slayer ) )
writer.Write( (int) m_Slayer );
if ( GetSaveFlag( flags, SaveFlag.Poison ) )
Poison.Serialize( m_Poison, writer );
if ( GetSaveFlag( flags, SaveFlag.PoisonCharges ) )
writer.Write( (int) m_PoisonCharges );
if ( GetSaveFlag( flags, SaveFlag.Crafter ) )
writer.Write( (Mobile) m_Crafter );
if ( GetSaveFlag( flags, SaveFlag.StrReq ) )
writer.Write( (int) m_StrReq );
if ( GetSaveFlag( flags, SaveFlag.DexReq ) )
writer.Write( (int) m_DexReq );
if ( GetSaveFlag( flags, SaveFlag.IntReq ) )
writer.Write( (int) m_IntReq );
if ( GetSaveFlag( flags, SaveFlag.MinDamage ) )
writer.Write( (int) m_MinDamage );
if ( GetSaveFlag( flags, SaveFlag.MaxDamage ) )
writer.Write( (int) m_MaxDamage );
if ( GetSaveFlag( flags, SaveFlag.HitSound ) )
writer.Write( (int) m_HitSound );
if ( GetSaveFlag( flags, SaveFlag.MissSound ) )
writer.Write( (int) m_MissSound );
if ( GetSaveFlag( flags, SaveFlag.Speed ) )
writer.Write( (int) m_Speed );
if ( GetSaveFlag( flags, SaveFlag.MaxRange ) )
writer.Write( (int) m_MaxRange );
if ( GetSaveFlag( flags, SaveFlag.Skill ) )
writer.Write( (int) m_Skill );
if ( GetSaveFlag( flags, SaveFlag.Type ) )
writer.Write( (int) m_Type );
if ( GetSaveFlag( flags, SaveFlag.Animation ) )
writer.Write( (int) m_Animation );
if ( GetSaveFlag( flags, SaveFlag.Resource ) )
writer.Write( (int) m_Resource );
if ( GetSaveFlag( flags, SaveFlag.xAttributes ) )
m_AosAttributes.Serialize( writer );
if ( GetSaveFlag( flags, SaveFlag.xWeaponAttributes ) )
m_AosWeaponAttributes.Serialize( writer );
if ( GetSaveFlag( flags, SaveFlag.SkillBonuses ) )
m_AosSkillBonuses.Serialize( writer );
if ( GetSaveFlag( flags, SaveFlag.Slayer2 ) )
writer.Write( (int)m_Slayer2 );
if( GetSaveFlag( flags, SaveFlag.ElementalDamages ) )
m_AosElementDamages.Serialize( writer );
}
[Flags]
private enum SaveFlag
{
None = 0x00000000,
DamageLevel = 0x00000001,
AccuracyLevel = 0x00000002,
DurabilityLevel = 0x00000004,
Quality = 0x00000008,
Hits = 0x00000010,
MaxHits = 0x00000020,
Slayer = 0x00000040,
Poison = 0x00000080,
PoisonCharges = 0x00000100,
Crafter = 0x00000200,
Identified = 0x00000400,
StrReq = 0x00000800,
DexReq = 0x00001000,
IntReq = 0x00002000,
MinDamage = 0x00004000,
MaxDamage = 0x00008000,
HitSound = 0x00010000,
MissSound = 0x00020000,
Speed = 0x00040000,
MaxRange = 0x00080000,
Skill = 0x00100000,
Type = 0x00200000,
Animation = 0x00400000,
Resource = 0x00800000,
xAttributes = 0x01000000,
xWeaponAttributes = 0x02000000,
PlayerConstructed = 0x04000000,
SkillBonuses = 0x08000000,
Slayer2 = 0x10000000,
ElementalDamages = 0x20000000
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 8:
case 7:
case 6:
case 5:
{
SaveFlag flags = (SaveFlag)reader.ReadInt();
if ( GetSaveFlag( flags, SaveFlag.DamageLevel ) )
{
m_DamageLevel = (WeaponDamageLevel)reader.ReadInt();
if ( m_DamageLevel > WeaponDamageLevel.Vanq )
m_DamageLevel = WeaponDamageLevel.Ruin;
}
if ( GetSaveFlag( flags, SaveFlag.AccuracyLevel ) )
{
m_AccuracyLevel = (WeaponAccuracyLevel)reader.ReadInt();
if ( m_AccuracyLevel > WeaponAccuracyLevel.Supremely )
m_AccuracyLevel = WeaponAccuracyLevel.Accurate;
}
if ( GetSaveFlag( flags, SaveFlag.DurabilityLevel ) )
{
m_DurabilityLevel = (WeaponDurabilityLevel)reader.ReadInt();
if ( m_DurabilityLevel > WeaponDurabilityLevel.Indestructible )
m_DurabilityLevel = WeaponDurabilityLevel.Durable;
}
if ( GetSaveFlag( flags, SaveFlag.Quality ) )
m_Quality = (WeaponQuality)reader.ReadInt();
else
m_Quality = WeaponQuality.Regular;
if ( GetSaveFlag( flags, SaveFlag.Hits ) )
m_Hits = reader.ReadInt();
if ( GetSaveFlag( flags, SaveFlag.MaxHits ) )
m_MaxHits = reader.ReadInt();
if ( GetSaveFlag( flags, SaveFlag.Slayer ) )
m_Slayer = (SlayerName)reader.ReadInt();
if ( GetSaveFlag( flags, SaveFlag.Poison ) )
m_Poison = Poison.Deserialize( reader );
if ( GetSaveFlag( flags, SaveFlag.PoisonCharges ) )
m_PoisonCharges = reader.ReadInt();
if ( GetSaveFlag( flags, SaveFlag.Crafter ) )
m_Crafter = reader.ReadMobile();
if ( GetSaveFlag( flags, SaveFlag.Identified ) )
m_Identified = ( version >= 6 || reader.ReadBool() );
if ( GetSaveFlag( flags, SaveFlag.StrReq ) )
m_StrReq = reader.ReadInt();
else
m_StrReq = -1;
if ( GetSaveFlag( flags, SaveFlag.DexReq ) )
m_DexReq = reader.ReadInt();
else
m_DexReq = -1;
if ( GetSaveFlag( flags, SaveFlag.IntReq ) )
m_IntReq = reader.ReadInt();
else
m_IntReq = -1;
if ( GetSaveFlag( flags, SaveFlag.MinDamage ) )
m_MinDamage = reader.ReadInt();
else
m_MinDamage = -1;
if ( GetSaveFlag( flags, SaveFlag.MaxDamage ) )
m_MaxDamage = reader.ReadInt();
else
m_MaxDamage = -1;
if ( GetSaveFlag( flags, SaveFlag.HitSound ) )
m_HitSound = reader.ReadInt();
else
m_HitSound = -1;
if ( GetSaveFlag( flags, SaveFlag.MissSound ) )
m_MissSound = reader.ReadInt();
else
m_MissSound = -1;
if ( GetSaveFlag( flags, SaveFlag.Speed ) )
m_Speed = reader.ReadInt();
else
m_Speed = -1;
if ( GetSaveFlag( flags, SaveFlag.MaxRange ) )
m_MaxRange = reader.ReadInt();
else
m_MaxRange = -1;
if ( GetSaveFlag( flags, SaveFlag.Skill ) )
m_Skill = (SkillName)reader.ReadInt();
else
m_Skill = (SkillName)(-1);
if ( GetSaveFlag( flags, SaveFlag.Type ) )
m_Type = (WeaponType)reader.ReadInt();
else
m_Type = (WeaponType)(-1);
if ( GetSaveFlag( flags, SaveFlag.Animation ) )
m_Animation = (WeaponAnimation)reader.ReadInt();
else
m_Animation = (WeaponAnimation)(-1);
if ( GetSaveFlag( flags, SaveFlag.Resource ) )
m_Resource = (CraftResource)reader.ReadInt();
else
m_Resource = CraftResource.Iron;
if ( GetSaveFlag( flags, SaveFlag.xAttributes ) )
m_AosAttributes = new AosAttributes( this, reader );
else
m_AosAttributes = new AosAttributes( this );
if ( GetSaveFlag( flags, SaveFlag.xWeaponAttributes ) )
m_AosWeaponAttributes = new AosWeaponAttributes( this, reader );
else
m_AosWeaponAttributes = new AosWeaponAttributes( this );
if ( UseSkillMod && m_AccuracyLevel != WeaponAccuracyLevel.Regular && Parent is Mobile )
{
m_SkillMod = new DefaultSkillMod( AccuracySkill, true, (int)m_AccuracyLevel * 5 );
((Mobile)Parent).AddSkillMod( m_SkillMod );
}
if ( version < 7 && m_AosWeaponAttributes.MageWeapon != 0 )
m_AosWeaponAttributes.MageWeapon = 30 - m_AosWeaponAttributes.MageWeapon;
if ( Core.AOS && m_AosWeaponAttributes.MageWeapon != 0 && m_AosWeaponAttributes.MageWeapon != 30 && Parent is Mobile )
{
m_MageMod = new DefaultSkillMod( SkillName.Magery, true, -30 + m_AosWeaponAttributes.MageWeapon );
((Mobile)Parent).AddSkillMod( m_MageMod );
}
if ( GetSaveFlag( flags, SaveFlag.PlayerConstructed ) )
m_PlayerConstructed = true;
if( GetSaveFlag( flags, SaveFlag.SkillBonuses ) )
m_AosSkillBonuses = new AosSkillBonuses( this, reader );
else
m_AosSkillBonuses = new AosSkillBonuses( this );
if( GetSaveFlag( flags, SaveFlag.Slayer2 ) )
m_Slayer2 = (SlayerName)reader.ReadInt();
if( GetSaveFlag( flags, SaveFlag.ElementalDamages ) )
m_AosElementDamages = new AosElementAttributes( this, reader );
else
m_AosElementDamages = new AosElementAttributes( this );
break;
}
case 4:
{
m_Slayer = (SlayerName)reader.ReadInt();
goto case 3;
}
case 3:
{
m_StrReq = reader.ReadInt();
m_DexReq = reader.ReadInt();
m_IntReq = reader.ReadInt();
goto case 2;
}
case 2:
{
m_Identified = reader.ReadBool();
goto case 1;
}
case 1:
{
m_MaxRange = reader.ReadInt();
goto case 0;
}
case 0:
{
if ( version == 0 )
m_MaxRange = 1; // default
if ( version < 5 )
{
m_Resource = CraftResource.Iron;
m_AosAttributes = new AosAttributes( this );
m_AosWeaponAttributes = new AosWeaponAttributes( this );
m_AosElementDamages = new AosElementAttributes( this );
m_AosSkillBonuses = new AosSkillBonuses( this );
}
m_MinDamage = reader.ReadInt();
m_MaxDamage = reader.ReadInt();
m_Speed = reader.ReadInt();
m_HitSound = reader.ReadInt();
m_MissSound = reader.ReadInt();
m_Skill = (SkillName)reader.ReadInt();
m_Type = (WeaponType)reader.ReadInt();
m_Animation = (WeaponAnimation)reader.ReadInt();
m_DamageLevel = (WeaponDamageLevel)reader.ReadInt();
m_AccuracyLevel = (WeaponAccuracyLevel)reader.ReadInt();
m_DurabilityLevel = (WeaponDurabilityLevel)reader.ReadInt();
m_Quality = (WeaponQuality)reader.ReadInt();
m_Crafter = reader.ReadMobile();
m_Poison = Poison.Deserialize( reader );
m_PoisonCharges = reader.ReadInt();
if ( m_StrReq == OldStrengthReq )
m_StrReq = -1;
if ( m_DexReq == OldDexterityReq )
m_DexReq = -1;
if ( m_IntReq == OldIntelligenceReq )
m_IntReq = -1;
if ( m_MinDamage == OldMinDamage )
m_MinDamage = -1;
if ( m_MaxDamage == OldMaxDamage )
m_MaxDamage = -1;
if ( m_HitSound == OldHitSound )
m_HitSound = -1;
if ( m_MissSound == OldMissSound )
m_MissSound = -1;
if ( m_Speed == OldSpeed )
m_Speed = -1;
if ( m_MaxRange == OldMaxRange )
m_MaxRange = -1;
if ( m_Skill == OldSkill )
m_Skill = (SkillName)(-1);
if ( m_Type == OldType )
m_Type = (WeaponType)(-1);
if ( m_Animation == OldAnimation )
m_Animation = (WeaponAnimation)(-1);
if ( UseSkillMod && m_AccuracyLevel != WeaponAccuracyLevel.Regular && Parent is Mobile )
{
m_SkillMod = new DefaultSkillMod( AccuracySkill, true, (int)m_AccuracyLevel * 5);
((Mobile)Parent).AddSkillMod( m_SkillMod );
}
break;
}
}
if ( Core.AOS && Parent is Mobile )
m_AosSkillBonuses.AddTo( (Mobile)Parent );
int strBonus = m_AosAttributes.BonusStr;
int dexBonus = m_AosAttributes.BonusDex;
int intBonus = m_AosAttributes.BonusInt;
if ( this.Parent is Mobile && (strBonus != 0 || dexBonus != 0 || intBonus != 0) )
{
Mobile m = (Mobile)this.Parent;
string modName = this.Serial.ToString();
if ( strBonus != 0 )
m.AddStatMod( new StatMod( StatType.Str, modName + "Str", strBonus, TimeSpan.Zero ) );
if ( dexBonus != 0 )
m.AddStatMod( new StatMod( StatType.Dex, modName + "Dex", dexBonus, TimeSpan.Zero ) );
if ( intBonus != 0 )
m.AddStatMod( new StatMod( StatType.Int, modName + "Int", intBonus, TimeSpan.Zero ) );
}
if ( Parent is Mobile )
((Mobile)Parent).CheckStatTimers();
if ( m_Hits <= 0 && m_MaxHits <= 0 )
{
m_Hits = m_MaxHits = Utility.RandomMinMax( InitMinHits, InitMaxHits );
}
if ( version < 6 )
m_PlayerConstructed = true; // we don't know, so, assume it's crafted
}
#endregion
public BaseWeapon( int itemID ) : base( itemID )
{
Layer = (Layer)ItemData.Quality;
m_Quality = WeaponQuality.Regular;
m_StrReq = -1;
m_DexReq = -1;
m_IntReq = -1;
m_MinDamage = -1;
m_MaxDamage = -1;
m_HitSound = -1;
m_MissSound = -1;
m_Speed = -1;
m_MaxRange = -1;
m_Skill = (SkillName)(-1);
m_Type = (WeaponType)(-1);
m_Animation = (WeaponAnimation)(-1);
m_Hits = m_MaxHits = Utility.RandomMinMax( InitMinHits, InitMaxHits );
m_Resource = CraftResource.Iron;
m_AosAttributes = new AosAttributes( this );
m_AosWeaponAttributes = new AosWeaponAttributes( this );
m_AosSkillBonuses = new AosSkillBonuses( this );
m_AosElementDamages = new AosElementAttributes( this );
}
public BaseWeapon( Serial serial ) : base( serial )
{
}
private string GetNameString()
{
string name = this.Name;
if ( name == null )
name = String.Format( "#{0}", LabelNumber );
return name;
}
[Hue, CommandProperty( AccessLevel.GameMaster )]
public override int Hue
{
get{ return base.Hue; }
set{ base.Hue = value; InvalidateProperties(); }
}
public int GetElementalDamageHue()
{
int phys, fire, cold, pois, nrgy;
GetDamageTypes( null, out phys, out fire, out cold, out pois, out nrgy );
//Order is Cold, Energy, Fire, Poison, Physical left
int currentMax = 50;
int hue = 0;
if( pois >= currentMax )
{
hue = 1267 + (pois - 50) / 10;
currentMax = pois;
}
if( fire >= currentMax )
{
hue = 1255 + (fire - 50) / 10;
currentMax = fire;
}
if( nrgy >= currentMax )
{
hue = 1273 + (nrgy - 50) / 10;
currentMax = nrgy;
}
if( cold >= currentMax )
{
hue = 1261 + (cold - 50) / 10;
currentMax = cold;
}
return hue;
}
public override void AddNameProperty( ObjectPropertyList list )
{
string oreType;
if ( Hue == 0 )
{
oreType = "";
}
else
{
switch ( m_Resource )
{
case CraftResource.DullCopper: oreType = "dull copper"; break; // dull copper
case CraftResource.ShadowIron: oreType = "shadow iron"; break; // shadow iron
case CraftResource.Copper: oreType = "copper"; break; // copper
case CraftResource.Bronze: oreType = "bronze"; break; // bronze
case CraftResource.Gold: oreType = "gold"; break; // golden
case CraftResource.Agapite: oreType = "agapite"; break; // agapite
case CraftResource.Verite: oreType = "verite"; break; // verite
case CraftResource.Valorite: oreType = "valorite"; break; // valorite
case CraftResource.Silver: oreType = "silver"; break; // silver
case CraftResource.Platinum: oreType = "platinum"; break; // platinum
case CraftResource.Mythril: oreType = "mythril"; break; // mythril
case CraftResource.Obsidian: oreType = "obsidian"; break; // obsidian
case CraftResource.Jade: oreType = "jade"; break; // jade
case CraftResource.Moonstone: oreType = "moonstone"; break; // moonstone
case CraftResource.Sunstone: oreType = "sunstone"; break; // sunstone
case CraftResource.Bloodstone: oreType = "bloodstone"; break; // bloodstone
case CraftResource.SpinedLeather: oreType = "spined"; break; // spined
case CraftResource.HornedLeather: oreType = "horned"; break; // horned
case CraftResource.BarbedLeather: oreType = "barbed"; break; // barbed
case CraftResource.DragonLeather: oreType = "dragon"; break; // dragon
case CraftResource.DaemonLeather: oreType = "daemon"; break; // daemon
case CraftResource.RedScales: oreType = "red"; break; // red
case CraftResource.YellowScales: oreType = "yellow"; break; // yellow
case CraftResource.BlackScales: oreType = "black"; break; // black
case CraftResource.GreenScales: oreType = "green"; break; // green
case CraftResource.WhiteScales: oreType = "white"; break; // white
case CraftResource.BlueScales: oreType = "blue"; break; // blue
case CraftResource.Pine: oreType = "pine"; break; // pine
case CraftResource.Cedar: oreType = "cedar"; break; // cedar
case CraftResource.Cherry: oreType = "cherry"; break; // cherry
case CraftResource.Mahogany: oreType = "mahogany"; break; // mahogany
case CraftResource.Oak: oreType = "oak"; break; // oak
case CraftResource.Ash: oreType = "ash"; break; // ash
case CraftResource.Yew: oreType = "yew"; break; // yew
case CraftResource.Heartwood: oreType = "heartwood"; break; // heartwood
case CraftResource.Bloodwood: oreType = "bloodwood"; break; // bloodwood
case CraftResource.Frostwood: oreType = "frostwood"; break; // frostwood
default: oreType = ""; break;
}
}
//if ( oreType != 0 )
list.Add( 1053099, "{0}\t{1}", oreType, GetNameString() ); // ~1_oretype~ ~2_armortype~
/*else if ( Name == null )
list.Add( LabelNumber );
else
list.Add( Name );*/
}
public override bool AllowEquipedCast( Mobile from )
{
if ( base.AllowEquipedCast( from ) )
return true;
return ( m_AosAttributes.SpellChanneling != 0 );
}
public virtual int ArtifactRarity
{
get{ return 0; }
}
public virtual int GetLuckBonus()
{
CraftResourceInfo resInfo = CraftResources.GetInfo( m_Resource );
if ( resInfo == null )
return 0;
CraftAttributeInfo attrInfo = resInfo.AttributeInfo;
if ( attrInfo == null )
return 0;
return attrInfo.WeaponLuck;
}
public override void GetProperties( ObjectPropertyList list )
{
base.GetProperties( list );
if ( m_Crafter != null )
list.Add( 1050043, m_Crafter.Name ); // crafted by ~1_NAME~
#region Factions
if ( m_FactionState != null )
list.Add( 1041350 ); // faction item
#endregion
if ( m_AosSkillBonuses != null )
m_AosSkillBonuses.GetProperties( list );
if ( m_Quality == WeaponQuality.Exceptional )
list.Add( 1060636 ); // exceptional
if( RequiredRace == Race.Elf )
list.Add( 1075086 ); // Elves Only
if ( ArtifactRarity > 0 )
list.Add( 1061078, ArtifactRarity.ToString() ); // artifact rarity ~1_val~
if ( this is IUsesRemaining && ((IUsesRemaining)this).ShowUsesRemaining )
list.Add( 1060584, ((IUsesRemaining)this).UsesRemaining.ToString() ); // uses remaining: ~1_val~
if ( m_Poison != null && m_PoisonCharges > 0 )
list.Add( 1062412 + m_Poison.Level, m_PoisonCharges.ToString() );
if( m_Slayer != SlayerName.None )
{
SlayerEntry entry = SlayerGroup.GetEntryByName( m_Slayer );
if( entry != null )
list.Add( entry.Title );
}
if( m_Slayer2 != SlayerName.None )
{
SlayerEntry entry = SlayerGroup.GetEntryByName( m_Slayer2 );
if( entry != null )
list.Add( entry.Title );
}
base.AddResistanceProperties( list );
int prop;
if ( (prop = m_AosWeaponAttributes.UseBestSkill) != 0 )
list.Add( 1060400 ); // use best weapon skill
if ( (prop = (GetDamageBonus() + m_AosAttributes.WeaponDamage)) != 0 )
list.Add( 1060401, prop.ToString() ); // damage increase ~1_val~%
if ( (prop = m_AosAttributes.DefendChance) != 0 )
list.Add( 1060408, prop.ToString() ); // defense chance increase ~1_val~%
if ( (prop = m_AosAttributes.EnhancePotions) != 0 )
list.Add( 1060411, prop.ToString() ); // enhance potions ~1_val~%
if ( (prop = m_AosAttributes.CastRecovery) != 0 )
list.Add( 1060412, prop.ToString() ); // faster cast recovery ~1_val~
if ( (prop = m_AosAttributes.CastSpeed) != 0 )
list.Add( 1060413, prop.ToString() ); // faster casting ~1_val~
if ( (prop = (GetHitChanceBonus() + m_AosAttributes.AttackChance)) != 0 )
list.Add( 1060415, prop.ToString() ); // hit chance increase ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitColdArea) != 0 )
list.Add( 1060416, prop.ToString() ); // hit cold area ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitDispel) != 0 )
list.Add( 1060417, prop.ToString() ); // hit dispel ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitEnergyArea) != 0 )
list.Add( 1060418, prop.ToString() ); // hit energy area ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitFireArea) != 0 )
list.Add( 1060419, prop.ToString() ); // hit fire area ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitFireball) != 0 )
list.Add( 1060420, prop.ToString() ); // hit fireball ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitHarm) != 0 )
list.Add( 1060421, prop.ToString() ); // hit harm ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitLeechHits) != 0 )
list.Add( 1060422, prop.ToString() ); // hit life leech ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitLightning) != 0 )
list.Add( 1060423, prop.ToString() ); // hit lightning ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitLowerAttack) != 0 )
list.Add( 1060424, prop.ToString() ); // hit lower attack ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitLowerDefend) != 0 )
list.Add( 1060425, prop.ToString() ); // hit lower defense ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitMagicArrow) != 0 )
list.Add( 1060426, prop.ToString() ); // hit magic arrow ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitLeechMana) != 0 )
list.Add( 1060427, prop.ToString() ); // hit mana leech ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitPhysicalArea) != 0 )
list.Add( 1060428, prop.ToString() ); // hit physical area ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitPoisonArea) != 0 )
list.Add( 1060429, prop.ToString() ); // hit poison area ~1_val~%
if ( (prop = m_AosWeaponAttributes.HitLeechStam) != 0 )
list.Add( 1060430, prop.ToString() ); // hit stamina leech ~1_val~%
if ( (prop = m_AosAttributes.BonusDex) != 0 )
list.Add( 1060409, prop.ToString() ); // dexterity bonus ~1_val~
if ( (prop = m_AosAttributes.BonusHits) != 0 )
list.Add( 1060431, prop.ToString() ); // hit point increase ~1_val~
if ( (prop = m_AosAttributes.BonusInt) != 0 )
list.Add( 1060432, prop.ToString() ); // intelligence bonus ~1_val~
if ( (prop = m_AosAttributes.LowerManaCost) != 0 )
list.Add( 1060433, prop.ToString() ); // lower mana cost ~1_val~%
if ( (prop = m_AosAttributes.LowerRegCost) != 0 )
list.Add( 1060434, prop.ToString() ); // lower reagent cost ~1_val~%
if ( (prop = GetLowerStatReq()) != 0 )
list.Add( 1060435, prop.ToString() ); // lower requirements ~1_val~%
if ( (prop = (GetLuckBonus() + m_AosAttributes.Luck)) != 0 )
list.Add( 1060436, prop.ToString() ); // luck ~1_val~
if ( (prop = m_AosWeaponAttributes.MageWeapon) != 0 )
list.Add( 1060438, (30 - prop).ToString() ); // mage weapon -~1_val~ skill
if ( (prop = m_AosAttributes.BonusMana) != 0 )
list.Add( 1060439, prop.ToString() ); // mana increase ~1_val~
if ( (prop = m_AosAttributes.RegenMana) != 0 )
list.Add( 1060440, prop.ToString() ); // mana regeneration ~1_val~
if ( (prop = m_AosAttributes.NightSight) != 0 )
list.Add( 1060441 ); // night sight
if ( (prop = m_AosAttributes.ReflectPhysical) != 0 )
list.Add( 1060442, prop.ToString() ); // reflect physical damage ~1_val~%
if ( (prop = m_AosAttributes.RegenStam) != 0 )
list.Add( 1060443, prop.ToString() ); // stamina regeneration ~1_val~
if ( (prop = m_AosAttributes.RegenHits) != 0 )
list.Add( 1060444, prop.ToString() ); // hit point regeneration ~1_val~
if ( (prop = m_AosWeaponAttributes.SelfRepair) != 0 )
list.Add( 1060450, prop.ToString() ); // self repair ~1_val~
if ( (prop = m_AosAttributes.SpellChanneling) != 0 )
list.Add( 1060482 ); // spell channeling
if ( (prop = m_AosAttributes.SpellDamage) != 0 )
list.Add( 1060483, prop.ToString() ); // spell damage increase ~1_val~%
if ( (prop = m_AosAttributes.BonusStam) != 0 )
list.Add( 1060484, prop.ToString() ); // stamina increase ~1_val~
if ( (prop = m_AosAttributes.BonusStr) != 0 )
list.Add( 1060485, prop.ToString() ); // strength bonus ~1_val~
if ( (prop = m_AosAttributes.WeaponSpeed) != 0 )
list.Add( 1060486, prop.ToString() ); // swing speed increase ~1_val~%
int phys, fire, cold, pois, nrgy;
GetDamageTypes( null, out phys, out fire, out cold, out pois, out nrgy );
if ( phys != 0 )
list.Add( 1060403, phys.ToString() ); // physical damage ~1_val~%
if ( fire != 0 )
list.Add( 1060405, fire.ToString() ); // fire damage ~1_val~%
if ( cold != 0 )
list.Add( 1060404, cold.ToString() ); // cold damage ~1_val~%
if ( pois != 0 )
list.Add( 1060406, pois.ToString() ); // poison damage ~1_val~%
if ( nrgy != 0 )
list.Add( 1060407, nrgy.ToString() ); // energy damage ~1_val~%
list.Add( 1061168, "{0}\t{1}", MinDamage.ToString(), MaxDamage.ToString() ); // weapon damage ~1_val~ - ~2_val~
list.Add( 1061167, Speed.ToString() ); // weapon speed ~1_val~
if ( MaxRange > 1 )
list.Add( 1061169, MaxRange.ToString() ); // range ~1_val~
int strReq = AOS.Scale( StrRequirement, 100 - GetLowerStatReq() );
if ( strReq > 0 )
list.Add( 1061170, strReq.ToString() ); // strength requirement ~1_val~
if ( Layer == Layer.TwoHanded )
list.Add( 1061171 ); // two-handed weapon
else
list.Add( 1061824 ); // one-handed weapon
if ( Core.SE || m_AosWeaponAttributes.UseBestSkill == 0 )
{
switch ( Skill )
{
case SkillName.Swords: list.Add( 1061172 ); break; // skill required: swordsmanship
case SkillName.Macing: list.Add( 1061173 ); break; // skill required: mace fighting
case SkillName.Fencing: list.Add( 1061174 ); break; // skill required: fencing
case SkillName.Archery: list.Add( 1061175 ); break; // skill required: archery
}
}
if ( m_Hits >= 0 && m_MaxHits > 0 )
list.Add( 1060639, "{0}\t{1}", m_Hits, m_MaxHits ); // durability ~1_val~ / ~2_val~
}
public override void OnSingleClick( Mobile from )
{
List<EquipInfoAttribute> attrs = new List<EquipInfoAttribute>();
if ( DisplayLootType )
{
if ( LootType == LootType.Blessed )
attrs.Add( new EquipInfoAttribute( 1038021 ) ); // blessed
else if ( LootType == LootType.Cursed )
attrs.Add( new EquipInfoAttribute( 1049643 ) ); // cursed
}
#region Factions
if ( m_FactionState != null )
attrs.Add( new EquipInfoAttribute( 1041350 ) ); // faction item
#endregion
if ( m_Quality == WeaponQuality.Exceptional )
attrs.Add( new EquipInfoAttribute( 1018305 - (int)m_Quality ) );
if ( m_Identified || from.AccessLevel >= AccessLevel.GameMaster )
{
if( m_Slayer != SlayerName.None )
{
SlayerEntry entry = SlayerGroup.GetEntryByName( m_Slayer );
if( entry != null )
attrs.Add( new EquipInfoAttribute( entry.Title ) );
}
if( m_Slayer2 != SlayerName.None )
{
SlayerEntry entry = SlayerGroup.GetEntryByName( m_Slayer2 );
if( entry != null )
attrs.Add( new EquipInfoAttribute( entry.Title ) );
}
if ( m_DurabilityLevel != WeaponDurabilityLevel.Regular )
attrs.Add( new EquipInfoAttribute( 1038000 + (int)m_DurabilityLevel ) );
if ( m_DamageLevel != WeaponDamageLevel.Regular )
attrs.Add( new EquipInfoAttribute( 1038015 + (int)m_DamageLevel ) );
if ( m_AccuracyLevel != WeaponAccuracyLevel.Regular )
attrs.Add( new EquipInfoAttribute( 1038010 + (int)m_AccuracyLevel ) );
}
else if( m_Slayer != SlayerName.None || m_Slayer2 != SlayerName.None || m_DurabilityLevel != WeaponDurabilityLevel.Regular || m_DamageLevel != WeaponDamageLevel.Regular || m_AccuracyLevel != WeaponAccuracyLevel.Regular )
attrs.Add( new EquipInfoAttribute( 1038000 ) ); // Unidentified
if ( m_Poison != null && m_PoisonCharges > 0 )
attrs.Add( new EquipInfoAttribute( 1017383, m_PoisonCharges ) );
int number;
if ( Name == null )
{
number = LabelNumber;
}
else
{
this.LabelTo( from, Name );
number = 1041000;
}
if ( attrs.Count == 0 && Crafter == null && Name != null )
return;
EquipmentInfo eqInfo = new EquipmentInfo( number, m_Crafter, false, attrs.ToArray() );
from.Send( new DisplayEquipmentInfo( this, eqInfo ) );
}
private static BaseWeapon m_Fists; // This value holds the default--fist--weapon
public static BaseWeapon Fists
{
get{ return m_Fists; }
set{ m_Fists = value; }
}
#region ICraftable Members
public int OnCraft( int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool, CraftItem craftItem, int resHue )
{
Quality = (WeaponQuality)quality;
if ( makersMark )
Crafter = from;
PlayerConstructed = true;
Type resourceType = typeRes;
if ( resourceType == null )
resourceType = craftItem.Ressources.GetAt( 0 ).ItemType;
//////////////if ( Core.AOS )
{
Resource = CraftResources.GetFromType( resourceType );
CraftContext context = craftSystem.GetContext( from );
if ( context != null && context.DoNotColor )
Hue = 0;
if ( tool is BaseRunicTool )
((BaseRunicTool)tool).ApplyAttributesTo( this );
if ( Quality == WeaponQuality.Exceptional )
{
if ( Attributes.WeaponDamage > 35 )
Attributes.WeaponDamage -= 20;
else
Attributes.WeaponDamage = 15;
if( Core.ML )
{
Attributes.WeaponDamage += (int)(from.Skills.ArmsLore.Value / 20);
from.CheckSkill( SkillName.ArmsLore, 0, 100 );
}
}
}
////else
if ( tool is BaseRunicTool )
{
CraftResource thisResource = CraftResources.GetFromType( resourceType );
if ( thisResource == ((BaseRunicTool)tool).Resource )
{
Resource = thisResource;
CraftContext context = craftSystem.GetContext( from );
if ( context != null && context.DoNotColor )
Hue = 0;
switch ( thisResource )
{
case CraftResource.DullCopper:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Durable;
AccuracyLevel = WeaponAccuracyLevel.Accurate;
break;
}
case CraftResource.ShadowIron:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Durable;
DamageLevel = WeaponDamageLevel.Ruin;
break;
}
case CraftResource.Copper:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Fortified;
DamageLevel = WeaponDamageLevel.Ruin;
AccuracyLevel = WeaponAccuracyLevel.Surpassingly;
break;
}
case CraftResource.Bronze:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Fortified;
DamageLevel = WeaponDamageLevel.Might;
AccuracyLevel = WeaponAccuracyLevel.Surpassingly;
break;
}
case CraftResource.Gold:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Indestructible;
DamageLevel = WeaponDamageLevel.Force;
AccuracyLevel = WeaponAccuracyLevel.Eminently;
break;
}
case CraftResource.Agapite:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Indestructible;
DamageLevel = WeaponDamageLevel.Power;
AccuracyLevel = WeaponAccuracyLevel.Eminently;
break;
}
case CraftResource.Verite:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Indestructible;
DamageLevel = WeaponDamageLevel.Power;
AccuracyLevel = WeaponAccuracyLevel.Exceedingly;
break;
}
case CraftResource.Valorite:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Indestructible;
DamageLevel = WeaponDamageLevel.Vanq;
AccuracyLevel = WeaponAccuracyLevel.Supremely;
break;
}
}
}
}
return quality;
}
#endregion
}
public enum CheckSlayerResult
{
None,
Slayer,
Opposition
}
}
Base Armor: Code:
using System;
using System.Collections;
using System.Collections.Generic;
using Server.Network;
using Server.Engines.Craft;
using Server.Factions;
using AMA = Server.Items.ArmorMeditationAllowance;
using AMT = Server.Items.ArmorMaterialType;
using ABT = Server.Items.ArmorBodyType;
namespace Server.Items
{
public abstract class BaseArmor : Item, IScissorable, IFactionItem, ICraftable, IWearableDurability
{
#region Factions
private FactionItem m_FactionState;
public FactionItem FactionItemState
{
get{ return m_FactionState; }
set
{
m_FactionState = value;
if ( m_FactionState == null )
Hue = CraftResources.GetHue( Resource );
LootType = ( m_FactionState == null ? LootType.Regular : LootType.Blessed );
}
}
#endregion
/* Armor internals work differently now (Jun 19 2003)
*
* The attributes defined below default to -1.
* If the value is -1, the corresponding virtual 'Aos/Old' property is used.
* If not, the attribute value itself is used. Here's the list:
* - ArmorBase
* - StrBonus
* - DexBonus
* - IntBonus
* - StrReq
* - DexReq
* - IntReq
* - MeditationAllowance
*/
// Instance values. These values must are unique to each armor piece.
private int m_MaxHitPoints;
private int m_HitPoints;
private Mobile m_Crafter;
private ArmorQuality m_Quality;
private ArmorDurabilityLevel m_Durability;
private ArmorProtectionLevel m_Protection;
private CraftResource m_Resource;
private bool m_Identified, m_PlayerConstructed;
private int m_PhysicalBonus, m_FireBonus, m_ColdBonus, m_PoisonBonus, m_EnergyBonus;
private AosAttributes m_AosAttributes;
private AosArmorAttributes m_AosArmorAttributes;
private AosSkillBonuses m_AosSkillBonuses;
// Overridable values. These values are provided to override the defaults which get defined in the individual armor scripts.
private int m_ArmorBase = -1;
private int m_StrBonus = -1, m_DexBonus = -1, m_IntBonus = -1;
private int m_StrReq = -1, m_DexReq = -1, m_IntReq = -1;
private AMA m_Meditate = (AMA)(-1);
public virtual bool AllowMaleWearer{ get{ return true; } }
public virtual bool AllowFemaleWearer{ get{ return true; } }
public abstract AMT MaterialType{ get; }
public virtual int RevertArmorBase{ get{ return ArmorBase; } }
public virtual int ArmorBase{ get{ return 0; } }
public virtual AMA DefMedAllowance{ get{ return AMA.None; } }
public virtual AMA AosMedAllowance{ get{ return DefMedAllowance; } }
public virtual AMA OldMedAllowance{ get{ return DefMedAllowance; } }
public virtual int AosStrBonus{ get{ return 0; } }
public virtual int AosDexBonus{ get{ return 0; } }
public virtual int AosIntBonus{ get{ return 0; } }
public virtual int AosStrReq{ get{ return 0; } }
public virtual int AosDexReq{ get{ return 0; } }
public virtual int AosIntReq{ get{ return 0; } }
public virtual int OldStrBonus{ get{ return 0; } }
public virtual int OldDexBonus{ get{ return 0; } }
public virtual int OldIntBonus{ get{ return 0; } }
public virtual int OldStrReq{ get{ return 0; } }
public virtual int OldDexReq{ get{ return 0; } }
public virtual int OldIntReq{ get{ return 0; } }
[CommandProperty( AccessLevel.GameMaster )]
public AMA MeditationAllowance
{
get{ return ( m_Meditate == (AMA)(-1) ? Core.AOS ? AosMedAllowance : OldMedAllowance : m_Meditate ); }
set{ m_Meditate = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public int BaseArmorRating
{
get
{
if ( m_ArmorBase == -1 )
return ArmorBase;
else
return m_ArmorBase;
}
set
{
m_ArmorBase = value; Invalidate();
}
}
public double BaseArmorRatingScaled
{
get
{
return ( BaseArmorRating * ArmorScalar );
}
}
public virtual double ArmorRating
{
get
{
int ar = BaseArmorRating;
if ( m_Protection != ArmorProtectionLevel.Regular )
ar += 10 + (5 * (int)m_Protection);
switch ( m_Resource )
{
case CraftResource.DullCopper: ar += 2; break;
case CraftResource.ShadowIron: ar += 4; break;
case CraftResource.Copper: ar += 6; break;
case CraftResource.Bronze: ar += 8; break;
case CraftResource.Gold: ar += 10; break;
case CraftResource.Agapite: ar += 12; break;
case CraftResource.Verite: ar += 14; break;
case CraftResource.Valorite: ar += 16; break;
case CraftResource.Silver: ar += 18; break;
case CraftResource.Platinum: ar += 20; break;
case CraftResource.Mythril: ar += 22; break;
case CraftResource.Obsidian: ar += 24; break;
case CraftResource.Jade: ar += 26; break;
case CraftResource.Moonstone: ar += 28; break;
case CraftResource.Sunstone: ar += 30; break;
case CraftResource.Bloodstone: ar += 32; break;
case CraftResource.SpinedLeather: ar += 10; break;
case CraftResource.HornedLeather: ar += 13; break;
case CraftResource.BarbedLeather: ar += 16; break;
case CraftResource.DragonLeather: ar += 18; break;
case CraftResource.DaemonLeather: ar += 20; break;
}
ar += -8 + (8 * (int)m_Quality);
return ScaleArmorByDurability( ar );
}
}
public double ArmorRatingScaled
{
get
{
return ( ArmorRating * ArmorScalar );
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int StrBonus
{
get{ return ( m_StrBonus == -1 ? Core.AOS ? AosStrBonus : OldStrBonus : m_StrBonus ); }
set{ m_StrBonus = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int DexBonus
{
get{ return ( m_DexBonus == -1 ? Core.AOS ? AosDexBonus : OldDexBonus : m_DexBonus ); }
set{ m_DexBonus = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int IntBonus
{
get{ return ( m_IntBonus == -1 ? Core.AOS ? AosIntBonus : OldIntBonus : m_IntBonus ); }
set{ m_IntBonus = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int StrRequirement
{
get{ return ( m_StrReq == -1 ? Core.AOS ? AosStrReq : OldStrReq : m_StrReq ); }
set{ m_StrReq = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int DexRequirement
{
get{ return ( m_DexReq == -1 ? Core.AOS ? AosDexReq : OldDexReq : m_DexReq ); }
set{ m_DexReq = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int IntRequirement
{
get{ return ( m_IntReq == -1 ? Core.AOS ? AosIntReq : OldIntReq : m_IntReq ); }
set{ m_IntReq = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool Identified
{
get{ return m_Identified; }
set{ m_Identified = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool PlayerConstructed
{
get{ return m_PlayerConstructed; }
set{ m_PlayerConstructed = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public CraftResource Resource
{
get
{
return m_Resource;
}
set
{
if ( m_Resource != value )
{
UnscaleDurability();
m_Resource = value;
Hue = CraftResources.GetHue( m_Resource );
Invalidate();
InvalidateProperties();
if ( Parent is Mobile )
((Mobile)Parent).UpdateResistances();
ScaleDurability();
}
}
}
public virtual double ArmorScalar
{
get
{
int pos = (int)BodyPosition;
if ( pos >= 0 && pos < m_ArmorScalars.Length )
return m_ArmorScalars[pos];
return 1.0;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int MaxHitPoints
{
get{ return m_MaxHitPoints; }
set{ m_MaxHitPoints = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int HitPoints
{
get
{
return m_HitPoints;
}
set
{
if ( value != m_HitPoints && MaxHitPoints > 0 )
{
m_HitPoints = value;
if ( m_HitPoints < 0 )
Delete();
else if ( m_HitPoints > MaxHitPoints )
m_HitPoints = MaxHitPoints;
InvalidateProperties();
}
}
}
[CommandProperty( AccessLevel.GameMaster )]
public Mobile Crafter
{
get{ return m_Crafter; }
set{ m_Crafter = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public ArmorQuality Quality
{
get{ return m_Quality; }
set{ UnscaleDurability(); m_Quality = value; Invalidate(); InvalidateProperties(); ScaleDurability(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public ArmorDurabilityLevel Durability
{
get{ return m_Durability; }
set{ UnscaleDurability(); m_Durability = value; ScaleDurability(); InvalidateProperties(); }
}
public virtual int ArtifactRarity
{
get{ return 0; }
}
[CommandProperty( AccessLevel.GameMaster )]
public ArmorProtectionLevel ProtectionLevel
{
get
{
return m_Protection;
}
set
{
if ( m_Protection != value )
{
m_Protection = value;
Invalidate();
InvalidateProperties();
if ( Parent is Mobile )
((Mobile)Parent).UpdateResistances();
}
}
}
[CommandProperty( AccessLevel.GameMaster )]
public AosAttributes Attributes
{
get{ return m_AosAttributes; }
set{}
}
[CommandProperty( AccessLevel.GameMaster )]
public AosArmorAttributes ArmorAttributes
{
get{ return m_AosArmorAttributes; }
set{}
}
[CommandProperty( AccessLevel.GameMaster )]
public AosSkillBonuses SkillBonuses
{
get{ return m_AosSkillBonuses; }
set{}
}
public int ComputeStatReq( StatType type )
{
int v;
if ( type == StatType.Str )
v = StrRequirement;
else if ( type == StatType.Dex )
v = DexRequirement;
else
v = IntRequirement;
return AOS.Scale( v, 100 - GetLowerStatReq() );
}
public int ComputeStatBonus( StatType type )
{
if ( type == StatType.Str )
return StrBonus + Attributes.BonusStr;
else if ( type == StatType.Dex )
return DexBonus + Attributes.BonusDex;
else
return IntBonus + Attributes.BonusInt;
}
[CommandProperty( AccessLevel.GameMaster )]
public int PhysicalBonus{ get{ return m_PhysicalBonus; } set{ m_PhysicalBonus = value; InvalidateProperties(); } }
[CommandProperty( AccessLevel.GameMaster )]
public int FireBonus{ get{ return m_FireBonus; } set{ m_FireBonus = value; InvalidateProperties(); } }
[CommandProperty( AccessLevel.GameMaster )]
public int ColdBonus{ get{ return m_ColdBonus; } set{ m_ColdBonus = value; InvalidateProperties(); } }
[CommandProperty( AccessLevel.GameMaster )]
public int PoisonBonus{ get{ return m_PoisonBonus; } set{ m_PoisonBonus = value; InvalidateProperties(); } }
[CommandProperty( AccessLevel.GameMaster )]
public int EnergyBonus{ get{ return m_EnergyBonus; } set{ m_EnergyBonus = value; InvalidateProperties(); } }
public virtual int BasePhysicalResistance{ get{ return 0; } }
public virtual int BaseFireResistance{ get{ return 0; } }
public virtual int BaseColdResistance{ get{ return 0; } }
public virtual int BasePoisonResistance{ get{ return 0; } }
public virtual int BaseEnergyResistance{ get{ return 0; } }
public override int PhysicalResistance{ get{ return BasePhysicalResistance + GetProtOffset() + GetResourceAttrs().ArmorPhysicalResist + m_PhysicalBonus; } }
public override int FireResistance{ get{ return BaseFireResistance + GetProtOffset() + GetResourceAttrs().ArmorFireResist + m_FireBonus; } }
public override int ColdResistance{ get{ return BaseColdResistance + GetProtOffset() + GetResourceAttrs().ArmorColdResist + m_ColdBonus; } }
public override int PoisonResistance{ get{ return BasePoisonResistance + GetProtOffset() + GetResourceAttrs().ArmorPoisonResist + m_PoisonBonus; } }
public override int EnergyResistance{ get{ return BaseEnergyResistance + GetProtOffset() + GetResourceAttrs().ArmorEnergyResist + m_EnergyBonus; } }
public virtual int InitMinHits{ get{ return 0; } }
public virtual int InitMaxHits{ get{ return 0; } }
[CommandProperty( AccessLevel.GameMaster )]
public ArmorBodyType BodyPosition
{
get
{
switch ( this.Layer )
{
default:
case Layer.Neck: return ArmorBodyType.Gorget;
case Layer.TwoHanded: return ArmorBodyType.Shield;
case Layer.Gloves: return ArmorBodyType.Gloves;
case Layer.Helm: return ArmorBodyType.Helmet;
case Layer.Arms: return ArmorBodyType.Arms;
case Layer.InnerLegs:
case Layer.OuterLegs:
case Layer.Pants: return ArmorBodyType.Legs;
case Layer.InnerTorso:
case Layer.OuterTorso:
case Layer.Shirt: return ArmorBodyType.Chest;
}
}
}
public void DistributeBonuses( int amount )
{
for ( int i = 0; i < amount; ++i )
{
switch ( Utility.Random( 5 ) )
{
case 0: ++m_PhysicalBonus; break;
case 1: ++m_FireBonus; break;
case 2: ++m_ColdBonus; break;
case 3: ++m_PoisonBonus; break;
case 4: ++m_EnergyBonus; break;
}
}
InvalidateProperties();
}
public CraftAttributeInfo GetResourceAttrs()
{
CraftResourceInfo info = CraftResources.GetInfo( m_Resource );
if ( info == null )
return CraftAttributeInfo.Blank;
return info.AttributeInfo;
}
public int GetProtOffset()
{
switch ( m_Protection )
{
case ArmorProtectionLevel.Guarding: return 1;
case ArmorProtectionLevel.Hardening: return 2;
case ArmorProtectionLevel.Fortification: return 3;
case ArmorProtectionLevel.Invulnerability: return 4;
}
return 0;
}
public void UnscaleDurability()
{
int scale = 100 + GetDurabilityBonus();
m_HitPoints = ((m_HitPoints * 100) + (scale - 1)) / scale;
m_MaxHitPoints = ((m_MaxHitPoints * 100) + (scale - 1)) / scale;
InvalidateProperties();
}
public void ScaleDurability()
{
int scale = 100 + GetDurabilityBonus();
m_HitPoints = ((m_HitPoints * scale) + 99) / 100;
m_MaxHitPoints = ((m_MaxHitPoints * scale) + 99) / 100;
InvalidateProperties();
}
public int GetDurabilityBonus()
{
int bonus = 0;
if ( m_Quality == ArmorQuality.Exceptional )
bonus += 20;
switch ( m_Durability )
{
case ArmorDurabilityLevel.Durable: bonus += 20; break;
case ArmorDurabilityLevel.Substantial: bonus += 50; break;
case ArmorDurabilityLevel.Massive: bonus += 70; break;
case ArmorDurabilityLevel.Fortified: bonus += 100; break;
case ArmorDurabilityLevel.Indestructible: bonus += 120; break;
}
if ( Core.AOS )
{
bonus += m_AosArmorAttributes.DurabilityBonus;
CraftResourceInfo resInfo = CraftResources.GetInfo( m_Resource );
CraftAttributeInfo attrInfo = null;
if ( resInfo != null )
attrInfo = resInfo.AttributeInfo;
if ( attrInfo != null )
bonus += attrInfo.ArmorDurability;
}
return bonus;
}
public bool Scissor( Mobile from, Scissors scissors )
{
if ( !IsChildOf( from.Backpack ) )
{
from.SendLocalizedMessage( 502437 ); // Items you wish to cut must be in your backpack.
return false;
}
if ( Ethics.Ethic.IsImbued( this ) )
{
from.SendLocalizedMessage( 502440 ); // Scissors can not be used on that to produce anything.
return false;
}
CraftSystem system = DefTailoring.CraftSystem;
CraftItem item = system.CraftItems.SearchFor( GetType() );
if ( item != null && item.Ressources.Count == 1 && item.Ressources.GetAt( 0 ).Amount >= 2 )
{
try
{
Item res = (Item)Activator.CreateInstance( CraftResources.GetInfo( m_Resource ).ResourceTypes[0] );
ScissorHelper( from, res, m_PlayerConstructed ? (item.Ressources.GetAt( 0 ).Amount / 2) : 1 );
return true;
}
catch
{
}
}
from.SendLocalizedMessage( 502440 ); // Scissors can not be used on that to produce anything.
return false;
}
private static double[] m_ArmorScalars = { 0.07, 0.07, 0.14, 0.15, 0.22, 0.35 };
public static double[] ArmorScalars
{
get
{
return m_ArmorScalars;
}
set
{
m_ArmorScalars = value;
}
}
public static void ValidateMobile( Mobile m )
{
for ( int i = m.Items.Count - 1; i >= 0; --i )
{
if ( i >= m.Items.Count )
continue;
Item item = m.Items[i];
if ( item is BaseArmor )
{
BaseArmor armor = (BaseArmor)item;
if( armor.RequiredRace != null && m.Race != armor.RequiredRace )
{
if( armor.RequiredRace == Race.Elf )
m.SendLocalizedMessage( 1072203 ); // Only Elves may use this.
else
m.SendMessage( "Only {0} may use this.", armor.RequiredRace.PluralName );
m.AddToBackpack( armor );
}
else if ( !armor.AllowMaleWearer && !m.Female && m.AccessLevel < AccessLevel.GameMaster )
{
if ( armor.AllowFemaleWearer )
m.SendLocalizedMessage( 1010388 ); // Only females can wear this.
else
m.SendMessage( "You may not wear this." );
m.AddToBackpack( armor );
}
else if ( !armor.AllowFemaleWearer && m.Female && m.AccessLevel < AccessLevel.GameMaster )
{
if ( armor.AllowMaleWearer )
m.SendLocalizedMessage( 1063343 ); // Only males can wear this.
else
m.SendMessage( "You may not wear this." );
m.AddToBackpack( armor );
}
}
}
}
public int GetLowerStatReq()
{
if ( !Core.AOS )
return 0;
int v = m_AosArmorAttributes.LowerStatReq;
CraftResourceInfo info = CraftResources.GetInfo( m_Resource );
if ( info != null )
{
CraftAttributeInfo attrInfo = info.AttributeInfo;
if ( attrInfo != null )
v += attrInfo.ArmorLowerRequirements;
}
if ( v > 100 )
v = 100;
return v;
}
public override void OnAdded( object parent )
{
if ( parent is Mobile )
{
Mobile from = (Mobile)parent;
if ( Core.AOS )
m_AosSkillBonuses.AddTo( from );
from.Delta( MobileDelta.Armor ); // Tell them armor rating has changed
}
}
public virtual double ScaleArmorByDurability( double armor )
{
int scale = 100;
if ( m_MaxHitPoints > 0 && m_HitPoints < m_MaxHitPoints )
scale = 50 + ((50 * m_HitPoints) / m_MaxHitPoints);
return ( armor * scale ) / 100;
}
protected void Invalidate()
{
if ( Parent is Mobile )
((Mobile)Parent).Delta( MobileDelta.Armor ); // Tell them armor rating has changed
}
public BaseArmor( Serial serial ) : base( serial )
{
}
private static void SetSaveFlag( ref SaveFlag flags, SaveFlag toSet, bool setIf )
{
if ( setIf )
flags |= toSet;
}
private static bool GetSaveFlag( SaveFlag flags, SaveFlag toGet )
{
return ( (flags & toGet) != 0 );
}
[Flags]
private enum SaveFlag
{
None = 0x00000000,
Attributes = 0x00000001,
ArmorAttributes = 0x00000002,
PhysicalBonus = 0x00000004,
FireBonus = 0x00000008,
ColdBonus = 0x00000010,
PoisonBonus = 0x00000020,
EnergyBonus = 0x00000040,
Identified = 0x00000080,
MaxHitPoints = 0x00000100,
HitPoints = 0x00000200,
Crafter = 0x00000400,
Quality = 0x00000800,
Durability = 0x00001000,
Protection = 0x00002000,
Resource = 0x00004000,
BaseArmor = 0x00008000,
StrBonus = 0x00010000,
DexBonus = 0x00020000,
IntBonus = 0x00040000,
StrReq = 0x00080000,
DexReq = 0x00100000,
IntReq = 0x00200000,
MedAllowance = 0x00400000,
SkillBonuses = 0x00800000,
PlayerConstructed = 0x01000000
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 7 ); // version
SaveFlag flags = SaveFlag.None;
SetSaveFlag( ref flags, SaveFlag.Attributes, !m_AosAttributes.IsEmpty );
SetSaveFlag( ref flags, SaveFlag.ArmorAttributes, !m_AosArmorAttributes.IsEmpty );
SetSaveFlag( ref flags, SaveFlag.PhysicalBonus, m_PhysicalBonus != 0 );
SetSaveFlag( ref flags, SaveFlag.FireBonus, m_FireBonus != 0 );
SetSaveFlag( ref flags, SaveFlag.ColdBonus, m_ColdBonus != 0 );
SetSaveFlag( ref flags, SaveFlag.PoisonBonus, m_PoisonBonus != 0 );
SetSaveFlag( ref flags, SaveFlag.EnergyBonus, m_EnergyBonus != 0 );
SetSaveFlag( ref flags, SaveFlag.Identified, m_Identified != false );
SetSaveFlag( ref flags, SaveFlag.MaxHitPoints, m_MaxHitPoints != 0 );
SetSaveFlag( ref flags, SaveFlag.HitPoints, m_HitPoints != 0 );
SetSaveFlag( ref flags, SaveFlag.Crafter, m_Crafter != null );
SetSaveFlag( ref flags, SaveFlag.Quality, m_Quality != ArmorQuality.Regular );
SetSaveFlag( ref flags, SaveFlag.Durability, m_Durability != ArmorDurabilityLevel.Regular );
SetSaveFlag( ref flags, SaveFlag.Protection, m_Protection != ArmorProtectionLevel.Regular );
SetSaveFlag( ref flags, SaveFlag.Resource, m_Resource != DefaultResource );
SetSaveFlag( ref flags, SaveFlag.BaseArmor, m_ArmorBase != -1 );
SetSaveFlag( ref flags, SaveFlag.StrBonus, m_StrBonus != -1 );
SetSaveFlag( ref flags, SaveFlag.DexBonus, m_DexBonus != -1 );
SetSaveFlag( ref flags, SaveFlag.IntBonus, m_IntBonus != -1 );
SetSaveFlag( ref flags, SaveFlag.StrReq, m_StrReq != -1 );
SetSaveFlag( ref flags, SaveFlag.DexReq, m_DexReq != -1 );
SetSaveFlag( ref flags, SaveFlag.IntReq, m_IntReq != -1 );
SetSaveFlag( ref flags, SaveFlag.MedAllowance, m_Meditate != (AMA)(-1) );
SetSaveFlag( ref flags, SaveFlag.SkillBonuses, !m_AosSkillBonuses.IsEmpty );
SetSaveFlag( ref flags, SaveFlag.PlayerConstructed, m_PlayerConstructed != false );
writer.WriteEncodedInt( (int) flags );
if ( GetSaveFlag( flags, SaveFlag.Attributes ) )
m_AosAttributes.Serialize( writer );
if ( GetSaveFlag( flags, SaveFlag.ArmorAttributes ) )
m_AosArmorAttributes.Serialize( writer );
if ( GetSaveFlag( flags, SaveFlag.PhysicalBonus ) )
writer.WriteEncodedInt( (int) m_PhysicalBonus );
if ( GetSaveFlag( flags, SaveFlag.FireBonus ) )
writer.WriteEncodedInt( (int) m_FireBonus );
if ( GetSaveFlag( flags, SaveFlag.ColdBonus ) )
writer.WriteEncodedInt( (int) m_ColdBonus );
if ( GetSaveFlag( flags, SaveFlag.PoisonBonus ) )
writer.WriteEncodedInt( (int) m_PoisonBonus );
if ( GetSaveFlag( flags, SaveFlag.EnergyBonus ) )
writer.WriteEncodedInt( (int) m_EnergyBonus );
if ( GetSaveFlag( flags, SaveFlag.MaxHitPoints ) )
writer.WriteEncodedInt( (int) m_MaxHitPoints );
if ( GetSaveFlag( flags, SaveFlag.HitPoints ) )
writer.WriteEncodedInt( (int) m_HitPoints );
if ( GetSaveFlag( flags, SaveFlag.Crafter ) )
writer.Write( (Mobile) m_Crafter );
if ( GetSaveFlag( flags, SaveFlag.Quality ) )
writer.WriteEncodedInt( (int) m_Quality );
if ( GetSaveFlag( flags, SaveFlag.Durability ) )
writer.WriteEncodedInt( (int) m_Durability );
if ( GetSaveFlag( flags, SaveFlag.Protection ) )
writer.WriteEncodedInt( (int) m_Protection );
if ( GetSaveFlag( flags, SaveFlag.Resource ) )
writer.WriteEncodedInt( (int) m_Resource );
if ( GetSaveFlag( flags, SaveFlag.BaseArmor ) )
writer.WriteEncodedInt( (int) m_ArmorBase );
if ( GetSaveFlag( flags, SaveFlag.StrBonus ) )
writer.WriteEncodedInt( (int) m_StrBonus );
if ( GetSaveFlag( flags, SaveFlag.DexBonus ) )
writer.WriteEncodedInt( (int) m_DexBonus );
if ( GetSaveFlag( flags, SaveFlag.IntBonus ) )
writer.WriteEncodedInt( (int) m_IntBonus );
if ( GetSaveFlag( flags, SaveFlag.StrReq ) )
writer.WriteEncodedInt( (int) m_StrReq );
if ( GetSaveFlag( flags, SaveFlag.DexReq ) )
writer.WriteEncodedInt( (int) m_DexReq );
if ( GetSaveFlag( flags, SaveFlag.IntReq ) )
writer.WriteEncodedInt( (int) m_IntReq );
if ( GetSaveFlag( flags, SaveFlag.MedAllowance ) )
writer.WriteEncodedInt( (int) m_Meditate );
if ( GetSaveFlag( flags, SaveFlag.SkillBonuses ) )
m_AosSkillBonuses.Serialize( writer );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 7:
case 6:
case 5:
{
SaveFlag flags = (SaveFlag)reader.ReadEncodedInt();
if ( GetSaveFlag( flags, SaveFlag.Attributes ) )
m_AosAttributes = new AosAttributes( this, reader );
else
m_AosAttributes = new AosAttributes( this );
if ( GetSaveFlag( flags, SaveFlag.ArmorAttributes ) )
m_AosArmorAttributes = new AosArmorAttributes( this, reader );
else
m_AosArmorAttributes = new AosArmorAttributes( this );
if ( GetSaveFlag( flags, SaveFlag.PhysicalBonus ) )
m_PhysicalBonus = reader.ReadEncodedInt();
if ( GetSaveFlag( flags, SaveFlag.FireBonus ) )
m_FireBonus = reader.ReadEncodedInt();
if ( GetSaveFlag( flags, SaveFlag.ColdBonus ) )
m_ColdBonus = reader.ReadEncodedInt();
if ( GetSaveFlag( flags, SaveFlag.PoisonBonus ) )
m_PoisonBonus = reader.ReadEncodedInt();
if ( GetSaveFlag( flags, SaveFlag.EnergyBonus ) )
m_EnergyBonus = reader.ReadEncodedInt();
if ( GetSaveFlag( flags, SaveFlag.Identified ) )
m_Identified = ( version >= 7 || reader.ReadBool() );
if ( GetSaveFlag( flags, SaveFlag.MaxHitPoints ) )
m_MaxHitPoints = reader.ReadEncodedInt();
if ( GetSaveFlag( flags, SaveFlag.HitPoints ) )
m_HitPoints = reader.ReadEncodedInt();
if ( GetSaveFlag( flags, SaveFlag.Crafter ) )
m_Crafter = reader.ReadMobile();
if ( GetSaveFlag( flags, SaveFlag.Quality ) )
m_Quality = (ArmorQuality)reader.ReadEncodedInt();
else
m_Quality = ArmorQuality.Regular;
if ( version == 5 && m_Quality == ArmorQuality.Low )
m_Quality = ArmorQuality.Regular;
if ( GetSaveFlag( flags, SaveFlag.Durability ) )
{
m_Durability = (ArmorDurabilityLevel)reader.ReadEncodedInt();
if ( m_Durability > ArmorDurabilityLevel.Indestructible )
m_Durability = ArmorDurabilityLevel.Durable;
}
if ( GetSaveFlag( flags, SaveFlag.Protection ) )
{
m_Protection = (ArmorProtectionLevel)reader.ReadEncodedInt();
if ( m_Protection > ArmorProtectionLevel.Invulnerability )
m_Protection = ArmorProtectionLevel.Defense;
}
if ( GetSaveFlag( flags, SaveFlag.Resource ) )
m_Resource = (CraftResource)reader.ReadEncodedInt();
else
m_Resource = DefaultResource;
if ( m_Resource == CraftResource.None )
m_Resource = DefaultResource;
if ( GetSaveFlag( flags, SaveFlag.BaseArmor ) )
m_ArmorBase = reader.ReadEncodedInt();
else
m_ArmorBase = -1;
if ( GetSaveFlag( flags, SaveFlag.StrBonus ) )
m_StrBonus = reader.ReadEncodedInt();
else
m_StrBonus = -1;
if ( GetSaveFlag( flags, SaveFlag.DexBonus ) )
m_DexBonus = reader.ReadEncodedInt();
else
m_DexBonus = -1;
if ( GetSaveFlag( flags, SaveFlag.IntBonus ) )
m_IntBonus = reader.ReadEncodedInt();
else
m_IntBonus = -1;
if ( GetSaveFlag( flags, SaveFlag.StrReq ) )
m_StrReq = reader.ReadEncodedInt();
else
m_StrReq = -1;
if ( GetSaveFlag( flags, SaveFlag.DexReq ) )
m_DexReq = reader.ReadEncodedInt();
else
m_DexReq = -1;
if ( GetSaveFlag( flags, SaveFlag.IntReq ) )
m_IntReq = reader.ReadEncodedInt();
else
m_IntReq = -1;
if ( GetSaveFlag( flags, SaveFlag.MedAllowance ) )
m_Meditate = (AMA)reader.ReadEncodedInt();
else
m_Meditate = (AMA)(-1);
if ( GetSaveFlag( flags, SaveFlag.SkillBonuses ) )
m_AosSkillBonuses = new AosSkillBonuses( this, reader );
if ( GetSaveFlag( flags, SaveFlag.PlayerConstructed ) )
m_PlayerConstructed = true;
break;
}
case 4:
{
m_AosAttributes = new AosAttributes( this, reader );
m_AosArmorAttributes = new AosArmorAttributes( this, reader );
goto case 3;
}
case 3:
{
m_PhysicalBonus = reader.ReadInt();
m_FireBonus = reader.ReadInt();
m_ColdBonus = reader.ReadInt();
m_PoisonBonus = reader.ReadInt();
m_EnergyBonus = reader.ReadInt();
goto case 2;
}
case 2:
case 1:
{
m_Identified = reader.ReadBool();
goto case 0;
}
case 0:
{
m_ArmorBase = reader.ReadInt();
m_MaxHitPoints = reader.ReadInt();
m_HitPoints = reader.ReadInt();
m_Crafter = reader.ReadMobile();
m_Quality = (ArmorQuality)reader.ReadInt();
m_Durability = (ArmorDurabilityLevel)reader.ReadInt();
m_Protection = (ArmorProtectionLevel)reader.ReadInt();
AMT mat = (AMT)reader.ReadInt();
if ( m_ArmorBase == RevertArmorBase )
m_ArmorBase = -1;
/*m_BodyPos = (ArmorBodyType)*/reader.ReadInt();
if ( version < 4 )
{
m_AosAttributes = new AosAttributes( this );
m_AosArmorAttributes = new AosArmorAttributes( this );
}
if ( version < 3 && m_Quality == ArmorQuality.Exceptional )
DistributeBonuses( 6 );
if ( version >= 2 )
{
m_Resource = (CraftResource)reader.ReadInt();
}
else
{
OreInfo info;
switch ( reader.ReadInt() )
{
default:
case 0: info = OreInfo.Iron; break;
case 1: info = OreInfo.DullCopper; break;
case 2: info = OreInfo.ShadowIron; break;
case 3: info = OreInfo.Copper; break;
case 4: info = OreInfo.Bronze; break;
case 5: info = OreInfo.Gold; break;
case 6: info = OreInfo.Agapite; break;
case 7: info = OreInfo.Verite; break;
case 8: info = OreInfo.Valorite; break;
case 9: info = OreInfo.Silver; break;
case 10: info = OreInfo.Platinum; break;
case 11: info = OreInfo.Mythril; break;
case 12: info = OreInfo.Obsidian; break;
case 13: info = OreInfo.Jade; break;
case 14: info = OreInfo.Moonstone; break;
case 15: info = OreInfo.Sunstone; break;
case 16: info = OreInfo.Bloodstone; break;
}
m_Resource = CraftResources.GetFromOreInfo( info, mat );
}
m_StrBonus = reader.ReadInt();
m_DexBonus = reader.ReadInt();
m_IntBonus = reader.ReadInt();
m_StrReq = reader.ReadInt();
m_DexReq = reader.ReadInt();
m_IntReq = reader.ReadInt();
if ( m_StrBonus == OldStrBonus )
m_StrBonus = -1;
if ( m_DexBonus == OldDexBonus )
m_DexBonus = -1;
if ( m_IntBonus == OldIntBonus )
m_IntBonus = -1;
if ( m_StrReq == OldStrReq )
m_StrReq = -1;
if ( m_DexReq == OldDexReq )
m_DexReq = -1;
if ( m_IntReq == OldIntReq )
m_IntReq = -1;
m_Meditate = (AMA)reader.ReadInt();
if ( m_Meditate == OldMedAllowance )
m_Meditate = (AMA)(-1);
if ( m_Resource == CraftResource.None )
{
if ( mat == ArmorMaterialType.Studded || mat == ArmorMaterialType.Leather )
m_Resource = CraftResource.RegularLeather;
else if ( mat == ArmorMaterialType.Spined )
m_Resource = CraftResource.SpinedLeather;
else if ( mat == ArmorMaterialType.Horned )
m_Resource = CraftResource.HornedLeather;
else if ( mat == ArmorMaterialType.Barbed )
m_Resource = CraftResource.BarbedLeather;
else if ( mat == ArmorMaterialType.DragonL )
m_Resource = CraftResource.DragonLeather;
else if ( mat == ArmorMaterialType.Daemon )
m_Resource = CraftResource.DaemonLeather;
else
m_Resource = CraftResource.Iron;
}
if ( m_MaxHitPoints == 0 && m_HitPoints == 0 )
m_HitPoints = m_MaxHitPoints = Utility.RandomMinMax( InitMinHits, InitMaxHits );
break;
}
}
if ( m_AosSkillBonuses == null )
m_AosSkillBonuses = new AosSkillBonuses( this );
if ( Core.AOS && Parent is Mobile )
m_AosSkillBonuses.AddTo( (Mobile)Parent );
int strBonus = ComputeStatBonus( StatType.Str );
int dexBonus = ComputeStatBonus( StatType.Dex );
int intBonus = ComputeStatBonus( StatType.Int );
if ( Parent is Mobile && (strBonus != 0 || dexBonus != 0 || intBonus != 0) )
{
Mobile m = (Mobile)Parent;
string modName = Serial.ToString();
if ( strBonus != 0 )
m.AddStatMod( new StatMod( StatType.Str, modName + "Str", strBonus, TimeSpan.Zero ) );
if ( dexBonus != 0 )
m.AddStatMod( new StatMod( StatType.Dex, modName + "Dex", dexBonus, TimeSpan.Zero ) );
if ( intBonus != 0 )
m.AddStatMod( new StatMod( StatType.Int, modName + "Int", intBonus, TimeSpan.Zero ) );
}
if ( Parent is Mobile )
((Mobile)Parent).CheckStatTimers();
if ( version < 7 )
m_PlayerConstructed = true; // we don't know, so, assume it's crafted
}
public virtual CraftResource DefaultResource{ get{ return CraftResource.Iron; } }
public BaseArmor( int itemID ) : base( itemID )
{
m_Quality = ArmorQuality.Regular;
m_Durability = ArmorDurabilityLevel.Regular;
m_Crafter = null;
m_Resource = DefaultResource;
Hue = CraftResources.GetHue( m_Resource );
m_HitPoints = m_MaxHitPoints = Utility.RandomMinMax( InitMinHits, InitMaxHits );
this.Layer = (Layer)ItemData.Quality;
m_AosAttributes = new AosAttributes( this );
m_AosArmorAttributes = new AosArmorAttributes( this );
m_AosSkillBonuses = new AosSkillBonuses( this );
}
public override bool AllowSecureTrade( Mobile from, Mobile to, Mobile newOwner, bool accepted )
{
if ( !Ethics.Ethic.CheckTrade( from, to, newOwner, this ) )
return false;
return base.AllowSecureTrade( from, to, newOwner, accepted );
}
public virtual Race RequiredRace { get { return null; } }
public override bool CanEquip( Mobile from )
{
if( !Ethics.Ethic.CheckEquip( from, this ) )
return false;
if( from.AccessLevel < AccessLevel.GameMaster )
{
if( RequiredRace != null && from.Race != RequiredRace )
{
if( RequiredRace == Race.Elf )
from.SendLocalizedMessage( 1072203 ); // Only Elves may use this.
else
from.SendMessage( "Only {0} may use this.", RequiredRace.PluralName );
return false;
}
else if( !AllowMaleWearer && !from.Female )
{
if( AllowFemaleWearer )
from.SendLocalizedMessage( 1010388 ); // Only females can wear this.
else
from.SendMessage( "You may not wear this." );
return false;
}
else if( !AllowFemaleWearer && from.Female )
{
if( AllowMaleWearer )
from.SendLocalizedMessage( 1063343 ); // Only males can wear this.
else
from.SendMessage( "You may not wear this." );
return false;
}
else
{
int strBonus = ComputeStatBonus( StatType.Str ), strReq = ComputeStatReq( StatType.Str );
int dexBonus = ComputeStatBonus( StatType.Dex ), dexReq = ComputeStatReq( StatType.Dex );
int intBonus = ComputeStatBonus( StatType.Int ), intReq = ComputeStatReq( StatType.Int );
if( from.Dex < dexReq || (from.Dex + dexBonus) < 1 )
{
from.SendLocalizedMessage( 502077 ); // You do not have enough dexterity to equip this item.
return false;
}
else if( from.Str < strReq || (from.Str + strBonus) < 1 )
{
from.SendLocalizedMessage( 500213 ); // You are not strong enough to equip that.
return false;
}
else if( from.Int < intReq || (from.Int + intBonus) < 1 )
{
from.SendMessage( "You are not smart enough to equip that." );
return false;
}
}
}
return base.CanEquip( from );
}
public override bool CheckPropertyConfliction( Mobile m )
{
if ( base.CheckPropertyConfliction( m ) )
return true;
if ( Layer == Layer.Pants )
return ( m.FindItemOnLayer( Layer.InnerLegs ) != null );
if ( Layer == Layer.Shirt )
return ( m.FindItemOnLayer( Layer.InnerTorso ) != null );
return false;
}
public override bool OnEquip( Mobile from )
{
from.CheckStatTimers();
int strBonus = ComputeStatBonus( StatType.Str );
int dexBonus = ComputeStatBonus( StatType.Dex );
int intBonus = ComputeStatBonus( StatType.Int );
if ( strBonus != 0 || dexBonus != 0 || intBonus != 0 )
{
string modName = this.Serial.ToString();
if ( strBonus != 0 )
from.AddStatMod( new StatMod( StatType.Str, modName + "Str", strBonus, TimeSpan.Zero ) );
if ( dexBonus != 0 )
from.AddStatMod( new StatMod( StatType.Dex, modName + "Dex", dexBonus, TimeSpan.Zero ) );
if ( intBonus != 0 )
from.AddStatMod( new StatMod( StatType.Int, modName + "Int", intBonus, TimeSpan.Zero ) );
}
return base.OnEquip( from );
}
public override void OnRemoved( object parent )
{
if ( parent is Mobile )
{
Mobile m = (Mobile)parent;
string modName = this.Serial.ToString();
m.RemoveStatMod( modName + "Str" );
m.RemoveStatMod( modName + "Dex" );
m.RemoveStatMod( modName + "Int" );
if ( Core.AOS )
m_AosSkillBonuses.Remove();
((Mobile)parent).Delta( MobileDelta.Armor ); // Tell them armor rating has changed
m.CheckStatTimers();
}
base.OnRemoved( parent );
}
public virtual int OnHit( BaseWeapon weapon, int damageTaken )
{
double HalfAr = ArmorRating / 2.0;
int Absorbed = (int)(HalfAr + HalfAr*Utility.RandomDouble());
damageTaken -= Absorbed;
if ( damageTaken < 0 )
damageTaken = 0;
if ( Absorbed < 2 )
Absorbed = 2;
if ( 25 > Utility.Random( 100 ) ) // 25% chance to lower durability
{
if ( Core.AOS && m_AosArmorAttributes.SelfRepair > Utility.Random( 10 ) )
{
HitPoints += 2;
}
else
{
int wear;
if ( weapon.Type == WeaponType.Bashing )
wear = Absorbed / 2;
else
wear = Utility.Random( 2 );
if ( wear > 0 && m_MaxHitPoints > 0 )
{
if ( m_HitPoints >= wear )
{
HitPoints -= wear;
wear = 0;
}
else
{
wear -= HitPoints;
HitPoints = 0;
}
if ( wear > 0 )
{
if ( m_MaxHitPoints > wear )
{
MaxHitPoints -= wear;
if ( Parent is Mobile )
((Mobile)Parent).LocalOverheadMessage( MessageType.Regular, 0x3B2, 1061121 ); // Your equipment is severely damaged.
}
else
{
Delete();
}
}
}
}
}
return damageTaken;
}
private string GetNameString()
{
string name = this.Name;
if ( name == null )
name = String.Format( "#{0}", LabelNumber );
return name;
}
[Hue, CommandProperty( AccessLevel.GameMaster )]
public override int Hue
{
get{ return base.Hue; }
set{ base.Hue = value; InvalidateProperties(); }
}
public override void AddNameProperty( ObjectPropertyList list )
{
string oreType;
if ( Hue == 0 )
{
oreType = "";
}
else
{
switch ( m_Resource )
{
case CraftResource.DullCopper: oreType = "dull copper"; break; // dull copper
case CraftResource.ShadowIron: oreType = "shadow iron"; break; // shadow iron
case CraftResource.Copper: oreType = "copper"; break; // copper
case CraftResource.Bronze: oreType = "bronze"; break; // bronze
case CraftResource.Gold: oreType = "gold"; break; // golden
case CraftResource.Agapite: oreType = "agapite"; break; // agapite
case CraftResource.Verite: oreType = "verite"; break; // verite
case CraftResource.Valorite: oreType = "valorite"; break; // valorite
case CraftResource.Silver: oreType = "silver"; break; // silver
case CraftResource.Platinum: oreType = "platinum"; break; // platinum
case CraftResource.Mythril: oreType = "mythril"; break; // mythril
case CraftResource.Obsidian: oreType = "obsidian"; break; // obsidian
case CraftResource.Jade: oreType = "jade"; break; // jade
case CraftResource.Moonstone: oreType = "moonstone"; break; // moonstone
case CraftResource.Sunstone: oreType = "sunstone"; break; // sunstone
case CraftResource.Bloodstone: oreType = "bloodstone"; break; // bloodstone
case CraftResource.SpinedLeather: oreType = "spined"; break; // spined
case CraftResource.HornedLeather: oreType = "horned"; break; // horned
case CraftResource.BarbedLeather: oreType = "barbed"; break; // barbed
case CraftResource.DragonLeather: oreType = "dragon"; break; // dragon
case CraftResource.DaemonLeather: oreType = "daemon"; break; // daemon
case CraftResource.RedScales: oreType = "red"; break; // red
case CraftResource.YellowScales: oreType = "yellow"; break; // yellow
case CraftResource.BlackScales: oreType = "black"; break; // black
case CraftResource.GreenScales: oreType = "green"; break; // green
case CraftResource.WhiteScales: oreType = "white"; break; // white
case CraftResource.BlueScales: oreType = "blue"; break; // blue
default: oreType = ""; break;
}
}
if ( m_Quality == ArmorQuality.Exceptional )
{
//if ( oreType != 0 )
list.Add( 1053100, "{0}\t{1}", oreType, GetNameString() ); // exceptional ~1_oretype~ ~2_armortype~
/*else
list.Add( 1050040, GetNameString() ); // exceptional ~1_ITEMNAME~*/
}
else
{
//if ( oreType != 0 )
list.Add( 1053099, "{0}\t{1}", oreType, GetNameString() ); // ~1_oretype~ ~2_armortype~
/*else if ( Name == null )
list.Add( LabelNumber );
else
list.Add( Name );*/
}
}
public override bool AllowEquipedCast( Mobile from )
{
if ( base.AllowEquipedCast( from ) )
return true;
return ( m_AosAttributes.SpellChanneling != 0 );
}
public virtual int GetLuckBonus()
{
CraftResourceInfo resInfo = CraftResources.GetInfo( m_Resource );
if ( resInfo == null )
return 0;
CraftAttributeInfo attrInfo = resInfo.AttributeInfo;
if ( attrInfo == null )
return 0;
return attrInfo.ArmorLuck;
}
public override void GetProperties( ObjectPropertyList list )
{
base.GetProperties( list );
if ( m_Crafter != null )
list.Add( 1050043, m_Crafter.Name ); // crafted by ~1_NAME~
#region Factions
if ( m_FactionState != null )
list.Add( 1041350 ); // faction item
#endregion
if( RequiredRace == Race.Elf )
list.Add( 1075086 ); // Elves Only
m_AosSkillBonuses.GetProperties( list );
int prop;
if ( (prop = ArtifactRarity) > 0 )
list.Add( 1061078, prop.ToString() ); // artifact rarity ~1_val~
if ( (prop = m_AosAttributes.WeaponDamage) != 0 )
list.Add( 1060401, prop.ToString() ); // damage increase ~1_val~%
if ( (prop = m_AosAttributes.DefendChance) != 0 )
list.Add( 1060408, prop.ToString() ); // defense chance increase ~1_val~%
if ( (prop = m_AosAttributes.BonusDex) != 0 )
list.Add( 1060409, prop.ToString() ); // dexterity bonus ~1_val~
if ( (prop = m_AosAttributes.EnhancePotions) != 0 )
list.Add( 1060411, prop.ToString() ); // enhance potions ~1_val~%
if ( (prop = m_AosAttributes.CastRecovery) != 0 )
list.Add( 1060412, prop.ToString() ); // faster cast recovery ~1_val~
if ( (prop = m_AosAttributes.CastSpeed) != 0 )
list.Add( 1060413, prop.ToString() ); // faster casting ~1_val~
if ( (prop = m_AosAttributes.AttackChance) != 0 )
list.Add( 1060415, prop.ToString() ); // hit chance increase ~1_val~%
if ( (prop = m_AosAttributes.BonusHits) != 0 )
list.Add( 1060431, prop.ToString() ); // hit point increase ~1_val~
if ( (prop = m_AosAttributes.BonusInt) != 0 )
list.Add( 1060432, prop.ToString() ); // intelligence bonus ~1_val~
if ( (prop = m_AosAttributes.LowerManaCost) != 0 )
list.Add( 1060433, prop.ToString() ); // lower mana cost ~1_val~%
if ( (prop = m_AosAttributes.LowerRegCost) != 0 )
list.Add( 1060434, prop.ToString() ); // lower reagent cost ~1_val~%
if ( (prop = GetLowerStatReq()) != 0 )
list.Add( 1060435, prop.ToString() ); // lower requirements ~1_val~%
if ( (prop = (GetLuckBonus() + m_AosAttributes.Luck)) != 0 )
list.Add( 1060436, prop.ToString() ); // luck ~1_val~
if ( (prop = m_AosArmorAttributes.MageArmor) != 0 )
list.Add( 1060437 ); // mage armor
if ( (prop = m_AosAttributes.BonusMana) != 0 )
list.Add( 1060439, prop.ToString() ); // mana increase ~1_val~
if ( (prop = m_AosAttributes.RegenMana) != 0 )
list.Add( 1060440, prop.ToString() ); // mana regeneration ~1_val~
if ( (prop = m_AosAttributes.NightSight) != 0 )
list.Add( 1060441 ); // night sight
if ( (prop = m_AosAttributes.ReflectPhysical) != 0 )
list.Add( 1060442, prop.ToString() ); // reflect physical damage ~1_val~%
if ( (prop = m_AosAttributes.RegenStam) != 0 )
list.Add( 1060443, prop.ToString() ); // stamina regeneration ~1_val~
if ( (prop = m_AosAttributes.RegenHits) != 0 )
list.Add( 1060444, prop.ToString() ); // hit point regeneration ~1_val~
if ( (prop = m_AosArmorAttributes.SelfRepair) != 0 )
list.Add( 1060450, prop.ToString() ); // self repair ~1_val~
if ( (prop = m_AosAttributes.SpellChanneling) != 0 )
list.Add( 1060482 ); // spell channeling
if ( (prop = m_AosAttributes.SpellDamage) != 0 )
list.Add( 1060483, prop.ToString() ); // spell damage increase ~1_val~%
if ( (prop = m_AosAttributes.BonusStam) != 0 )
list.Add( 1060484, prop.ToString() ); // stamina increase ~1_val~
if ( (prop = m_AosAttributes.BonusStr) != 0 )
list.Add( 1060485, prop.ToString() ); // strength bonus ~1_val~
if ( (prop = m_AosAttributes.WeaponSpeed) != 0 )
list.Add( 1060486, prop.ToString() ); // swing speed increase ~1_val~%
base.AddResistanceProperties( list );
if ( (prop = GetDurabilityBonus()) > 0 )
list.Add( 1060410, prop.ToString() ); // durability ~1_val~%
if ( (prop = ComputeStatReq( StatType.Str )) > 0 )
list.Add( 1061170, prop.ToString() ); // strength requirement ~1_val~
if ( m_HitPoints >= 0 && m_MaxHitPoints > 0 )
list.Add( 1060639, "{0}\t{1}", m_HitPoints, m_MaxHitPoints ); // durability ~1_val~ / ~2_val~
}
public override void OnSingleClick( Mobile from )
{
List<EquipInfoAttribute> attrs = new List<EquipInfoAttribute>();
if ( DisplayLootType )
{
if ( LootType == LootType.Blessed )
attrs.Add( new EquipInfoAttribute( 1038021 ) ); // blessed
else if ( LootType == LootType.Cursed )
attrs.Add( new EquipInfoAttribute( 1049643 ) ); // cursed
}
#region Factions
if ( m_FactionState != null )
attrs.Add( new EquipInfoAttribute( 1041350 ) ); // faction item
#endregion
if ( m_Quality == ArmorQuality.Exceptional )
attrs.Add( new EquipInfoAttribute( 1018305 - (int)m_Quality ) );
if ( m_Identified || from.AccessLevel >= AccessLevel.GameMaster)
{
if ( m_Durability != ArmorDurabilityLevel.Regular )
attrs.Add( new EquipInfoAttribute( 1038000 + (int)m_Durability ) );
if ( m_Protection > ArmorProtectionLevel.Regular && m_Protection <= ArmorProtectionLevel.Invulnerability )
attrs.Add( new EquipInfoAttribute( 1038005 + (int)m_Protection ) );
}
else if ( m_Durability != ArmorDurabilityLevel.Regular || (m_Protection > ArmorProtectionLevel.Regular && m_Protection <= ArmorProtectionLevel.Invulnerability) )
attrs.Add( new EquipInfoAttribute( 1038000 ) ); // Unidentified
int number;
if ( Name == null )
{
number = LabelNumber;
}
else
{
this.LabelTo( from, Name );
number = 1041000;
}
if ( attrs.Count == 0 && Crafter == null && Name != null )
return;
EquipmentInfo eqInfo = new EquipmentInfo( number, m_Crafter, false, attrs.ToArray() );
from.Send( new DisplayEquipmentInfo( this, eqInfo ) );
}
#region ICraftable Members
public int OnCraft( int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool, CraftItem craftItem, int resHue )
{
Quality = (ArmorQuality)quality;
if ( makersMark )
Crafter = from;
Type resourceType = typeRes;
if ( resourceType == null )
resourceType = craftItem.Ressources.GetAt( 0 ).ItemType;
Resource = CraftResources.GetFromType( resourceType );
PlayerConstructed = true;
CraftContext context = craftSystem.GetContext( from );
if ( context != null && context.DoNotColor )
Hue = 0;
if( Quality == ArmorQuality.Exceptional )
{
DistributeBonuses( (tool is BaseRunicTool ? 6 : Core.SE ? 15 : 14) ); // Not sure since when, but right now 15 points are added, not 14.
if( Core.ML && !(this is BaseShield) )
{
int bonus = (int)(from.Skills.ArmsLore.Value / 20);
for( int i = 0; i < bonus; i++ )
{
switch( Utility.Random( 5 ) )
{
case 0: m_PhysicalBonus++; break;
case 1: m_FireBonus++; break;
case 2: m_ColdBonus++; break;
case 3: m_EnergyBonus++; break;
case 4: m_PoisonBonus++; break;
}
}
from.CheckSkill( SkillName.ArmsLore, 0, 100 );
}
}
if ( Core.AOS && tool is BaseRunicTool )
((BaseRunicTool)tool).ApplyAttributesTo( this );
return quality;
}
#endregion
}
}
Again, thank you! |
|
|
|
|
|
|
#12 (permalink) |
|
Master of the Internet
|
i do not see a real reason for it
amybe because C# is semi annal - can try this - does not matter supposedly, but never hurts remove the begining { and the ending } from this section, sense they are not needed Code:
{
Resource = CraftResources.GetFromType( resourceType );
CraftContext context = craftSystem.GetContext( from );
if ( context != null && context.DoNotColor )
Hue = 0;
if ( tool is BaseRunicTool )
((BaseRunicTool)tool).ApplyAttributesTo( this );
if ( Quality == WeaponQuality.Exceptional )
{
if ( Attributes.WeaponDamage > 35 )
Attributes.WeaponDamage -= 20;
else
Attributes.WeaponDamage = 15;
if( Core.ML )
{
Attributes.WeaponDamage += (int)(from.Skills.ArmsLore.Value / 20);
from.CheckSkill( SkillName.ArmsLore, 0, 100 );
}
}
}
__________________
http://www.AoAUO.com
:) ..... Come for the Customs, Play for the Fun. Return to see your new Friends ..... :) |
|
|
|
|
|
#13 (permalink) | |
|
Forum Novice
Join Date: May 2007
Posts: 142
|
Quote:
Code:
Errors:
+ AAA CUSTOM/AAA NEWEST/KarmaOres/ModifiedDistro/BaseWeapon.cs:
CS0136: Line 3399: A local variable named 'context' cannot be declared in th
is scope because it would give a different meaning to 'context', which is alread
y used in a 'parent or current' scope to denote something else
Code:
//////////////if ( Core.AOS )
Resource = CraftResources.GetFromType( resourceType );
CraftContext context = craftSystem.GetContext( from );
if ( context != null && context.DoNotColor )
Hue = 0;
if ( tool is BaseRunicTool )
((BaseRunicTool)tool).ApplyAttributesTo( this );
if ( Quality == WeaponQuality.Exceptional )
{
if ( Attributes.WeaponDamage > 35 )
Attributes.WeaponDamage -= 20;
else
Attributes.WeaponDamage = 15;
if( Core.ML )
{
Attributes.WeaponDamage += (int)(from.Skills.ArmsLore.Value / 20);
from.CheckSkill( SkillName.ArmsLore, 0, 100 );
}
}
////else
if ( tool is BaseRunicTool )
{
CraftResource thisResource = CraftResources.GetFromType( resourceType );
if ( thisResource == ((BaseRunicTool)tool).Resource )
{
Resource = thisResource;
CraftContext context = craftSystem.GetContext( from );
if ( context != null && context.DoNotColor )
Hue = 0;
switch ( thisResource )
{
|
|
|
|
|
|
|
#14 (permalink) |
|
Master of the Internet
|
i am trying to figure out why the if runic tool is that way and pointing to that stuff under it, that is normaly for if the weapon was made in Not AOS types, which you want
I have a feeling you messed up in pulling some stuff out lets try this for the on crafdt section: Code:
public int OnCraft( int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool, CraftItem craftItem, int resHue )
{
Quality = (WeaponQuality)quality;
if ( makersMark ) Crafter = from;
PlayerConstructed = true;
Type resourceType = typeRes;
if ( resourceType == null ) resourceType = craftItem.Ressources.GetAt( 0 ).ItemType;
Resource = CraftResources.GetFromType( resourceType );
CraftContext context = craftSystem.GetContext( from );
if ( context != null && context.DoNotColor ) Hue = 0;
CraftResource thisResource = CraftResources.GetFromType( resourceType );
switch ( thisResource )
{
case CraftResource.DullCopper:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Durable;
AccuracyLevel = WeaponAccuracyLevel.Accurate;
break;
}
case CraftResource.ShadowIron:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Durable;
DamageLevel = WeaponDamageLevel.Ruin;
break;
}
case CraftResource.Copper:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Fortified;
DamageLevel = WeaponDamageLevel.Ruin;
AccuracyLevel = WeaponAccuracyLevel.Surpassingly;
break;
}
case CraftResource.Bronze:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Fortified;
DamageLevel = WeaponDamageLevel.Might;
AccuracyLevel = WeaponAccuracyLevel.Surpassingly;
break;
}
case CraftResource.Gold:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Indestructible;
DamageLevel = WeaponDamageLevel.Force;
AccuracyLevel = WeaponAccuracyLevel.Eminently;
break;
}
case CraftResource.Agapite:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Indestructible;
DamageLevel = WeaponDamageLevel.Power;
AccuracyLevel = WeaponAccuracyLevel.Eminently;
break;
}
case CraftResource.Verite:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Indestructible;
DamageLevel = WeaponDamageLevel.Power;
AccuracyLevel = WeaponAccuracyLevel.Exceedingly;
break;
}
case CraftResource.Valorite:
{
Identified = true;
DurabilityLevel = WeaponDurabilityLevel.Indestructible;
DamageLevel = WeaponDamageLevel.Vanq;
AccuracyLevel = WeaponAccuracyLevel.Supremely;
break;
}
// remember to add in props for new materials added
}
if ( tool is BaseRunicTool ) ((BaseRunicTool)tool).ApplyAttributesTo( this );
return quality;
}
#endregion
__________________
http://www.AoAUO.com
:) ..... Come for the Customs, Play for the Fun. Return to see your new Friends ..... :) |
|
|
|
|
|
#16 (permalink) |
|
Master of the Internet
|
is it retaining the valorite color?
__________________
http://www.AoAUO.com
:) ..... Come for the Customs, Play for the Fun. Return to see your new Friends ..... :) |
|
|
|
|
|
#18 (permalink) |
|
Master of the Internet
|
ok - just the on single click or mouse over?
the on single click works a little different than mouseover you basicaly have call the name in there differently, I have not worked with it, since it is only used in pre-AOS but you might have to add the base props list in there (like mouse over has) or some other way of doing the name
__________________
http://www.AoAUO.com
:) ..... Come for the Customs, Play for the Fun. Return to see your new Friends ..... :) |
|
|
|
|
|
#19 (permalink) | |
|
Forum Novice
Join Date: May 2007
Posts: 142
|
Quote:
Thanks for all this help ! Oh i see exxxxxactly what youre saying! here in base weapon its calling for exactly what is commented out in the Resource Block! Code:
public override void OnSingleClick( Mobile from )
{
List<EquipInfoAttribute> attrs = new List<EquipInfoAttribute>();
if ( DisplayLootType )
{
if ( LootType == LootType.Blessed )
attrs.Add( new EquipInfoAttribute( 1038021 ) ); // blessed
else if ( LootType == LootType.Cursed )
attrs.Add( new EquipInfoAttribute( 1049643 ) ); // cursed
}
#region Factions
if ( m_FactionState != null )
attrs.Add( new EquipInfoAttribute( 1041350 ) ); // faction item
#endregion
if ( m_Quality == WeaponQuality.Exceptional )
attrs.Add( new EquipInfoAttribute( 1018305 - (int)m_Quality ) );
if ( m_Identified || from.AccessLevel >= AccessLevel.GameMaster )
{
if( m_Slayer != SlayerName.None )
{
SlayerEntry entry = SlayerGroup.GetEntryByName( m_Slayer );
if( entry != null )
attrs.Add( new EquipInfoAttribute( entry.Title ) );
}
if( m_Slayer2 != SlayerName.None )
{
SlayerEntry entry = SlayerGroup.GetEntryByName( m_Slayer2 );
if( entry != null )
attrs.Add( new EquipInfoAttribute( entry.Title ) );
}
if ( m_DurabilityLevel != WeaponDurabilityLevel.Regular )
attrs.Add( new EquipInfoAttribute( 1038000 + (int)m_DurabilityLevel ) );
if ( m_DamageLevel != WeaponDamageLevel.Regular )
attrs.Add( new EquipInfoAttribute( 1038015 + (int)m_DamageLevel ) );
if ( m_AccuracyLevel != WeaponAccuracyLevel.Regular )
attrs.Add( new EquipInfoAttribute( 1038010 + (int)m_AccuracyLevel ) );
}
else if( m_Slayer != SlayerName.None || m_Slayer2 != SlayerName.None || m_DurabilityLevel != WeaponDurabilityLevel.Regular || m_DamageLevel != WeaponDamageLevel.Regular || m_AccuracyLevel != WeaponAccuracyLevel.Regular )
attrs.Add( new EquipInfoAttribute( 1038000 ) ); // Unidentified
if ( m_Poison != null && m_PoisonCharges > 0 )
attrs.Add( new EquipInfoAttribute( 1017383, m_PoisonCharges ) );
int number;
if ( Name == null )
{
number = LabelNumber;
}
else
{
this.LabelTo( from, Name );
number = 1041000;
}
if ( attrs.Count == 0 && Crafter == null && Name != null )
return;
EquipmentInfo eqInfo = new EquipmentInfo( number, m_Crafter, false, attrs.ToArray() );
from.Send( new DisplayEquipmentInfo( this, eqInfo ) );
}
Code:
switch ( m_Resource )
{
case CraftResource.DullCopper: oreType = "dull copper"; break; // dull copper
case CraftResource.ShadowIron: oreType = "shadow iron"; break; // shadow iron
case CraftResource.Copper: oreType = "copper"; break; // copper
case CraftResource.Bronze: oreType = "bronze"; break; // bronze
case CraftResource.Gold: oreType = "gold"; break; // golden
case CraftResource.Agapite: oreType = "agapite"; break; // agapite
case CraftResource.Verite: oreType = "verite"; break; // verite
case CraftResource.Valorite: oreType = "valorite"; break; // valorite
case CraftResource.Silver: oreType = "silver"; break; // silver
case CraftResource.Platinum: oreType = "platinum"; break; // platinum
case CraftResource.Mythril: oreType = "mythril"; break; // mythril
case CraftResource.Obsidian: oreType = "obsidian"; break; // obsidian
case CraftResource.Jade: oreType = "jade"; break; // jade
case CraftResource.Moonstone: oreType = "moonstone"; break; // moonstone
case CraftResource.Sunstone: oreType = "sunstone"; break; // sunstone
case CraftResource.Bloodstone: oreType = "bloodstone"; break; // bloodstone
case CraftResource.SpinedLeather: oreType = "spined"; break; // spined
case CraftResource.HornedLeather: oreType = "horned"; break; // horned
case CraftResource.BarbedLeather: oreType = "barbed"; break; // barbed
case CraftResource.DragonLeather: oreType = "dragon"; break; // dragon
case CraftResource.DaemonLeather: oreType = "daemon"; break; // daemon
case CraftResource.RedScales: oreType = "red"; break; // red
case CraftResource.YellowScales: oreType = "yellow"; break; // yellow
case CraftResource.BlackScales: oreType = "black"; break; // black
case CraftResource.GreenScales: oreType = "green"; break; // green
case CraftResource.WhiteScales: oreType = "white"; break; // white
case CraftResource.BlueScales: oreType = "blue"; break; // blue
case CraftResource.Pine: oreType = "pine"; break; // pine
case CraftResource.Cedar: oreType = "cedar"; break; // cedar
case CraftResource.Cherry: oreType = "cherry"; break; // cherry
case CraftResource.Mahogany: oreType = "mahogany"; break; // mahogany
case CraftResource.Oak: oreType = "oak"; break; // oak
case CraftResource.Ash: oreType = "ash"; break; // ash
case CraftResource.Yew: oreType = "yew"; break; // yew
case CraftResource.Heartwood: oreType = "heartwood"; break; // heartwood
case CraftResource.Bloodwood: oreType = "bloodwood"; break; // bloodwood
case CraftResource.Frostwood: oreType = "frostwood"; break; // frostwood
default: oreType = ""; break;
}
}
//if ( oreType != 0 )
list.Add( 1053099, "{0}\t{1}", oreType, GetNameString() ); // ~1_oretype~ ~2_armortype~
/*else if ( Name == null )
list.Add( LabelNumber );
else
list.Add( Name );*/
}
will adding something like this in OnSingleCLick: Code:
Resource = CraftResources.GetFromType( resourceType ); Code:
Type resourceType = typeRes; Last edited by AvariceShard; 07-07-2009 at 02:18 PM. |
|
|
|
|
|
|
#20 (permalink) |
|
Master of the Internet
|
that resource deal is not in the mouse over - baseproperties is in there
need to look where singleclick gets the "name" from and adjust it to use the other name assigned in where the resources are all listed at
__________________
http://www.AoAUO.com
:) ..... Come for the Customs, Play for the Fun. Return to see your new Friends ..... :) |
|
|
|
|
|
#21 (permalink) | |
|
Forum Novice
Join Date: May 2007
Posts: 142
|
Quote:
Code:
switch ( m_Resource )
{
case CraftResource.DullCopper: oreType = "dull copper"; break; // dull copper
case CraftResource.ShadowIron: oreType = "shadow iron"; break; // shadow iron
case CraftResource.Copper: oreType = "copper"; break; // copper
case CraftResource.Bronze: oreType = "bronze"; break; // bronze
case CraftResource.Gold: oreType = "gold"; break; // golden
case CraftResource.Agapite: oreType = "agapite"; break; // agapite
case CraftResource.Verite: oreType = "verite"; break; // verite
case CraftResource.Valorite: oreType = "valorite"; break; // valorite
case CraftResource.Silver: oreType = "silver"; break; // silver
case CraftResource.Platinum: oreType = "platinum"; break; // platinum
case CraftResource.Mythril: oreType = "mythril"; break; // mythril
case CraftResource.Obsidian: oreType = "obsidian"; break; // obsidian
case CraftResource.Jade: oreType = "jade"; break; // jade
case CraftResource.Moonstone: oreType = "moonstone"; break; // moonstone
case CraftResource.Sunstone: oreType = "sunstone"; break; // sunstone
case CraftResource.Bloodstone: oreType = "bloodstone"; break; // bloodstone
case CraftResource.SpinedLeather: oreType = "spined"; break; // spined
case CraftResource.HornedLeather: oreType = "horned"; break; // horned
case CraftResource.BarbedLeather: oreType = "barbed"; break; // barbed
case CraftResource.DragonLeather: oreType = "dragon"; break; // dragon
case CraftResource.DaemonLeather: oreType = "daemon"; break; // daemon
case CraftResource.RedScales: oreType = "red"; break; // red
case CraftResource.YellowScales: oreType = "yellow"; break; // yellow
case CraftResource.BlackScales: oreType = "black"; break; // black
case CraftResource.GreenScales: oreType = "green"; break; // green
case CraftResource.WhiteScales: oreType = "white"; break; // white
case CraftResource.BlueScales: oreType = "blue"; break; // blue
case CraftResource.Pine: oreType = "pine"; break; // pine
case CraftResource.Cedar: oreType = "cedar"; break; // cedar
case CraftResource.Cherry: oreType = "cherry"; break; // cherry
case CraftResource.Mahogany: oreType = "mahogany"; break; // mahogany
case CraftResource.Oak: oreType = "oak"; break; // oak
case CraftResource.Ash: oreType = "ash"; break; // ash
case CraftResource.Yew: oreType = "yew"; break; // yew
case CraftResource.Heartwood: oreType = "heartwood"; break; // heartwood
case CraftResource.Bloodwood: oreType = "bloodwood"; break; // bloodwood
case CraftResource.Frostwood: oreType = "frostwood"; break; // frostwood
default: oreType = ""; break;
}
}
//if ( oreType != 0 )
list.Add( 1053099, "{0}\t{1}", oreType, GetNameString() ); // ~1_oretype~ ~2_armortype~
/*else if ( Name == null )
list.Add( LabelNumber );
else
list.Add( Name );*/
Code:
public override void OnSingleClick( Mobile from )
{
List<EquipInfoAttribute> attrs = new List<EquipInfoAttribute>();
if ( DisplayLootType )
{
if ( LootType == LootType.Blessed )
attrs.Add( new EquipInfoAttribute( 1038021 ) ); // blessed
else if ( LootType == LootType.Cursed )
attrs.Add( new EquipInfoAttribute( 1049643 ) ); // cursed
}
#region Factions
if ( m_FactionState != null )
attrs.Add( new EquipInfoAttribute( 1041350 ) ); // faction item
#endregion
if ( m_Quality == WeaponQuality.Exceptional )
attrs.Add( new EquipInfoAttribute( 1018305 - (int)m_Quality ) );
if ( m_Identified || from.AccessLevel >= AccessLevel.GameMaster )
{
if( m_Slayer != SlayerName.None )
{
SlayerEntry entry = SlayerGroup.GetEntryByName( m_Slayer );
if( entry != null )
attrs.Add( new EquipInfoAttribute( entry.Title ) );
}
if( m_Slayer2 != SlayerName.None )
{
SlayerEntry entry = SlayerGroup.GetEntryByName( m_Slayer2 );
if( entry != null )
attrs.Add( new EquipInfoAttribute( entry.Title ) );
}
if ( m_DurabilityLevel != WeaponDurabilityLevel.Regular )
attrs.Add( new EquipInfoAttribute( 1038000 + (int)m_DurabilityLevel ) );
if ( m_DamageLevel != WeaponDamageLevel.Regular )
attrs.Add( new EquipInfoAttribute( 1038015 + (int)m_DamageLevel ) );
if ( m_AccuracyLevel != WeaponAccuracyLevel.Regular )
attrs.Add( new EquipInfoAttribute( 1038010 + (int)m_AccuracyLevel ) );
}
else if( m_Slayer != SlayerName.None || m_Slayer2 != SlayerName.None || m_DurabilityLevel != WeaponDurabilityLevel.Regular || m_DamageLevel != WeaponDamageLevel.Regular || m_AccuracyLevel != WeaponAccuracyLevel.Regular )
attrs.Add( new EquipInfoAttribute( 1038000 ) ); // Unidentified
if ( m_Poison != null && m_PoisonCharges > 0 )
attrs.Add( new EquipInfoAttribute( 1017383, m_PoisonCharges ) );
int number;
if ( Name == null )
{
number = LabelNumber;
}
else
{
this.LabelTo( from, Name );
number = 1041000;
}
if ( attrs.Count == 0 && Crafter == null && Name != null )
return;
EquipmentInfo eqInfo = new EquipmentInfo( number, m_Crafter, false, attrs.ToArray() );
from.Send( new DisplayEquipmentInfo( this, eqInfo ) );
}
Code:
list.Add( 1053099, "{0}\t{1}", oreType, GetNameString() ); // ~1_oretype~ ~2_armortype~
|
|
|
|
|
|
|
#22 (permalink) |
|
Master of the Internet
|
ok - this just may work
replace the section in blue with this lol - it is a whooper but i have modified a lot of it for it to work correctly, adding in spacing and stuff correctly in the naming, so copy and paste this not nor from origional file Code:
string oreType;
if ( Hue == 0 )
{
oreType = "" ;
}
else
{
switch ( m_Resource )
{
case CraftResource.DullCopper: oreType = " dull copper " ; break; // dull copper
case CraftResource.ShadowIron: oreType = " shadow iron " ; break; // shadow iron
case CraftResource.Copper: oreType = " copper " ; break; // copper
case CraftResource.Bronze: oreType = " bronze " ; break; // bronze
case CraftResource.Gold: oreType = " gold " ; break; // golden
case CraftResource.Agapite: oreType = " agapite " ; break; // agapite
case CraftResource.Verite: oreType = " verite " ; break; // verite
case CraftResource.Valorite: oreType = " valorite " ; break; // valorite
case CraftResource.Silver: oreType = " silver " ; break; // silver
case CraftResource.Platinum: oreType = " platinum " ; break; // platinum
case CraftResource.Mythril: oreType = " mythril " ; break; // mythril
case CraftResource.Obsidian: oreType = " obsidian " ; break; // obsidian
case CraftResource.Jade: oreType = " jade " ; break; // jade
case CraftResource.Moonstone: oreType = " moonstone " ; break; // moonstone
case CraftResource.Sunstone: oreType = " sunstone " ; break; // sunstone
case CraftResource.Bloodstone: oreType = " bloodstone " ; break; // bloodstone
case CraftResource.SpinedLeather: oreType = " spined " ; break; // spined
case CraftResource.HornedLeather: oreType = " horned " ; break; // horned
case CraftResource.BarbedLeather: oreType = " barbed " ; break; // barbed
case CraftResource.DragonLeather: oreType = " dragon " ; break; // dragon
case CraftResource.DaemonLeather: oreType = " daemon " ; break; // daemon
case CraftResource.RedScales: oreType = " red " ; break; // red
case CraftResource.YellowScales: oreType = " yellow " ; break; // yellow
case CraftResource.BlackScales: oreType = " black " ; break; // black
case CraftResource.GreenScales: oreType = " green " ; break; // green
case CraftResource.WhiteScales: oreType = " white " ; break; // white
case CraftResource.BlueScales: oreType = " blue " ; break; // blue
default: oreType = "" ; break;
}
}
string tempname = "" ;
if ( m_Quality == ArmorQuality.Exceptional )
{
tempname = "Exceptional" + oreType + Name;
}
else
{
tempname = oreType + Name;
}
if ( Name == null )
{
number = LabelNumber;
}
else
{
this.LabelTo( from, tempname );
number = 1041000;
}
__________________
http://www.AoAUO.com
:) ..... Come for the Customs, Play for the Fun. Return to see your new Friends ..... :) |
|
|
|
|
|
#23 (permalink) | |
|
Forum Novice
Join Date: May 2007
Posts: 142
|
Quote:
oh wow! haha alright! so just like this and it should work? Code:
public override void OnSingleClick( Mobile from )
{
List<EquipInfoAttribute> attrs = new List<EquipInfoAttribute>();
if ( DisplayLootType )
{
if ( LootType == LootType.Blessed )
attrs.Add( new EquipInfoAttribute( 1038021 ) ); // blessed
else if ( LootType == LootType.Cursed )
attrs.Add( new EquipInfoAttribute( 1049643 ) ); // cursed
}
#region Factions
if ( m_FactionState != null )
attrs.Add( new EquipInfoAttribute( 1041350 ) ); // faction item
#endregion
if ( m_Quality == WeaponQuality.Exceptional )
attrs.Add( new EquipInfoAttribute( 1018305 - (int)m_Quality ) );
if ( m_Identified || from.AccessLevel >= AccessLevel.GameMaster )
{
if( m_Slayer != SlayerName.None )
{
SlayerEntry entry = SlayerGroup.GetEntryByName( m_Slayer );
if( entry != null )
attrs.Add( new EquipInfoAttribute( entry.Title ) );
}
if( m_Slayer2 != SlayerName.None )
{
SlayerEntry entry = SlayerGroup.GetEntryByName( m_Slayer2 );
if( entry != null )
attrs.Add( new EquipInfoAttribute( entry.Title ) );
}
if ( m_DurabilityLevel != WeaponDurabilityLevel.Regular )
attrs.Add( new EquipInfoAttribute( 1038000 + (int)m_DurabilityLevel ) );
if ( m_DamageLevel != WeaponDamageLevel.Regular )
attrs.Add( new EquipInfoAttribute( 1038015 + (int)m_DamageLevel ) );
if ( m_AccuracyLevel != WeaponAccuracyLevel.Regular )
attrs.Add( new EquipInfoAttribute( 1038010 + (int)m_AccuracyLevel ) );
}
else if( m_Slayer != SlayerName.None || m_Slayer2 != SlayerName.None || m_DurabilityLevel != WeaponDurabilityLevel.Regular || m_DamageLevel != WeaponDamageLevel.Regular || m_AccuracyLevel != WeaponAccuracyLevel.Regular )
attrs.Add( new EquipInfoAttribute( 1038000 ) ); // Unidentified
if ( m_Poison != null && m_PoisonCharges > 0 )
attrs.Add( new EquipInfoAttribute( 1017383, m_PoisonCharges ) );
int number;
if ( Name == null )
{
number = LabelNumber;
}
else
{
////this.LabelTo( from, Name );
////number = 1041000;
string oreType;
if ( Hue == 0 )
{
oreType = "" ;
}
else
{
switch ( m_Resource )
{
case CraftResource.DullCopper: oreType = " dull copper " ; break; // dull copper
case CraftResource.ShadowIron: oreType = " shadow iron " ; break; // shadow iron
case CraftResource.Copper: oreType = " copper " ; break; // copper
case CraftResource.Bronze: oreType = " bronze " ; break; // bronze
case CraftResource.Gold: oreType = " gold " ; break; // golden
case CraftResource.Agapite: oreType = " agapite " ; break; // agapite
case CraftResource.Verite: oreType = " verite " ; break; // verite
case CraftResource.Valorite: oreType = " valorite " ; break; // valorite
case CraftResource.Silver: oreType = " silver " ; break; // silver
case CraftResource.Platinum: oreType = " platinum " ; break; // platinum
case CraftResource.Mythril: oreType = " mythril " ; break; // mythril
case CraftResource.Obsidian: oreType = " obsidian " ; break; // obsidian
case CraftResource.Jade: oreType = " jade " ; break; // jade
case CraftResource.Moonstone: oreType = " moonstone " ; break; // moonstone
case CraftResource.Sunstone: oreType = " sunstone " ; break; // sunstone
case CraftResource.Bloodstone: oreType = " bloodstone " ; break; // bloodstone
case CraftResource.SpinedLeather: oreType = " spined " ; break; // spined
case CraftResource.HornedLeather: oreType = " horned " ; break; // horned
case CraftResource.BarbedLeather: oreType = " barbed " ; break; // barbed
case CraftResource.DragonLeather: oreType = " dragon " ; break; // dragon
case CraftResource.DaemonLeather: oreType = " daemon " ; break; // daemon
case CraftResource.RedScales: oreType = " red " ; break; // red
case CraftResource.YellowScales: oreType = " yellow " ; break; // yellow
case CraftResource.BlackScales: oreType = " black " ; break; // black
case CraftResource.GreenScales: oreType = " green " ; break; // green
case CraftResource.WhiteScales: oreType = " white " ; break; // white
case CraftResource.BlueScales: oreType = " blue " ; break; // blue
default: oreType = "" ; break;
}
}
string tempname = "" ;
if ( m_Quality == ArmorQuality.Exceptional )
{
tempname = "Exceptional" + oreType + Name;
}
else
{
tempname = oreType + Name;
}
if ( Name == null )
{
number = LabelNumber;
}
else
{
this.LabelTo( from, tempname );
number = 1041000;
}
}
if ( attrs.Count == 0 && Crafter == null && Name != null )
return;
EquipmentInfo eqInfo = new EquipmentInfo( number, m_Crafter, false, attrs.ToArray() );
from.Send( new DisplayEquipmentInfo( this, eqInfo ) );
}
|
|
|
|
|
|
|
#24 (permalink) |
|
Master of the Internet
|
looks about right - only way to know for sure is to try it
![]()
__________________
http://www.AoAUO.com
:) ..... Come for the Customs, Play for the Fun. Return to see your new Friends ..... :) |
|
|
|
|
|
#25 (permalink) | |
|
Forum Novice
Join Date: May 2007
Posts: 142
|
Quote:
I just gave it a try and i got one error: Code:
Errors:
+ AAA CUSTOM/AAA NEWEST/KarmaOres/ModifiedDistro/BaseWeapon.cs:
CS0019: Line 3372: Operator '==' cannot be applied to operands of type 'Serv
er.Items.WeaponQuality' and 'Server.Items.ArmorQuality'
and upon removing one of the "=" this is my error: Code:
[Errors:
+ AAA CUSTOM/AAA NEWEST/KarmaOres/ModifiedDistro/BaseWeapon.cs:
CS0266: Line 3372: Cannot implicitly convert type 'Server.Items.ArmorQuality
' to 'Server.Items.WeaponQuality'. An explicit conversion exists (are you missin
g a cast?)
CS0029: Line 3372: Cannot implicitly convert type 'Server.Items.WeaponQualit
y' to 'bool'
Last edited by AvariceShard; 07-07-2009 at 11:25 PM. |
|
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|