skillcaps and things that exceed it Possible threading issue Addition of Generic FindItemsByType - List<T> findItemsByType<T>() Change to make polymorph not have a timer and instead a toggle skill KiAttack no longer works with ranged weapons Poison strike speed and damage changed Necro spells now affected by FC Must have atleast 50 weapon skill if no shield equipped to use Evasion Stalking bonus capped at 10 + skill/10 Stalking bonus now Clears Bugfix w/Guilds Crashguard Exception message moved closer to the top of the file. Character creation of Pallys and necros using advanced skills now gives skill items Honor no longer works on Players Pre-ML area HitArea attacks nolonger require LoS Serialization fix for BladeOfTheRighteous RidingSwipe now has paralyzation immunity as with NerveStrike and ParaBlow AnkhEast renamed to AnkhNorth LeggingsOfBane no longer have 510 HP ElvenWashBasinEastAddon Fixed AnsellaGryen won't be renamed each time the server Restarts DiseasedCats are properly named Localization fixes in DefBlacksmithy BearMasks/DearMAsks and things that extend from them now can be repaired
436 lines
No EOL
12 KiB
C#
436 lines
No EOL
12 KiB
C#
using System;
|
|
using Server;
|
|
using Server.Mobiles;
|
|
using Server.Targeting;
|
|
using Server.Items;
|
|
|
|
namespace Server.Engines.Craft
|
|
{
|
|
public class Repair
|
|
{
|
|
public Repair()
|
|
{
|
|
}
|
|
|
|
public static void Do( Mobile from, CraftSystem craftSystem, BaseTool tool )
|
|
{
|
|
from.Target = new InternalTarget( craftSystem, tool );
|
|
from.SendLocalizedMessage( 1044276 ); // Target an item to repair.
|
|
}
|
|
|
|
public static void Do( Mobile from, CraftSystem craftSystem, RepairDeed deed )
|
|
{
|
|
from.Target = new InternalTarget( craftSystem, deed );
|
|
from.SendLocalizedMessage( 1044276 ); // Target an item to repair.
|
|
}
|
|
|
|
private class InternalTarget : Target
|
|
{
|
|
private CraftSystem m_CraftSystem;
|
|
private BaseTool m_Tool;
|
|
private RepairDeed m_Deed;
|
|
|
|
public InternalTarget( CraftSystem craftSystem, BaseTool tool ) : base ( 2, false, TargetFlags.None )
|
|
{
|
|
m_CraftSystem = craftSystem;
|
|
m_Tool = tool;
|
|
}
|
|
|
|
public InternalTarget( CraftSystem craftSystem, RepairDeed deed ) : base( 2, false, TargetFlags.None )
|
|
{
|
|
m_CraftSystem = craftSystem;
|
|
m_Deed = deed;
|
|
}
|
|
|
|
private static void EndGolemRepair( object state )
|
|
{
|
|
((Mobile)state).EndAction( typeof( Golem ) );
|
|
}
|
|
|
|
private int GetWeakenChance( Mobile mob, SkillName skill, int curHits, int maxHits )
|
|
{
|
|
// 40% - (1% per hp lost) - (1% per 10 craft skill)
|
|
return (40 + (maxHits - curHits)) - (int)(((m_Deed != null)? m_Deed.SkillLevel : mob.Skills[skill].Value) / 10);
|
|
}
|
|
|
|
private bool CheckWeaken( Mobile mob, SkillName skill, int curHits, int maxHits )
|
|
{
|
|
return ( GetWeakenChance( mob, skill, curHits, maxHits ) > Utility.Random( 100 ) );
|
|
}
|
|
|
|
private int GetRepairDifficulty( int curHits, int maxHits )
|
|
{
|
|
return (((maxHits - curHits) * 1250) / Math.Max( maxHits, 1 )) - 250;
|
|
}
|
|
|
|
private bool CheckRepairDifficulty( Mobile mob, SkillName skill, int curHits, int maxHits )
|
|
{
|
|
double difficulty = GetRepairDifficulty( curHits, maxHits ) * 0.1;
|
|
|
|
|
|
if( m_Deed != null )
|
|
{
|
|
double value = m_Deed.SkillLevel;
|
|
double minSkill = difficulty - 25.0;
|
|
double maxSkill = difficulty + 25;
|
|
|
|
if( value < minSkill )
|
|
return false; // Too difficult
|
|
else if( value >= maxSkill )
|
|
return true; // No challenge
|
|
|
|
double chance = (value - minSkill) / (maxSkill - minSkill);
|
|
|
|
return (chance >= Utility.RandomDouble());
|
|
}
|
|
else
|
|
{
|
|
return mob.CheckSkill( skill, difficulty - 25.0, difficulty + 25.0 );
|
|
}
|
|
}
|
|
|
|
private bool CheckDeed( Mobile from )
|
|
{
|
|
if( m_Deed != null )
|
|
{
|
|
return m_Deed.Check( from );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private bool IsSpecialClothing( BaseClothing clothing )
|
|
{
|
|
// Armor repairable but not craftable
|
|
|
|
if( m_CraftSystem is DefTailoring )
|
|
{
|
|
return (clothing is BearMask)
|
|
|| (clothing is DeerMask);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private bool IsSpecialWeapon( BaseWeapon weapon )
|
|
{
|
|
// Weapons repairable but not craftable
|
|
|
|
if ( m_CraftSystem is DefTinkering )
|
|
{
|
|
return ( weapon is Cleaver )
|
|
|| ( weapon is Hatchet )
|
|
|| ( weapon is Pickaxe )
|
|
|| ( weapon is ButcherKnife )
|
|
|| ( weapon is SkinningKnife );
|
|
}
|
|
else if ( m_CraftSystem is DefCarpentry )
|
|
{
|
|
return ( weapon is Club )
|
|
|| ( weapon is BlackStaff )
|
|
|| ( weapon is MagicWand );
|
|
}
|
|
else if ( m_CraftSystem is DefBlacksmithy )
|
|
{
|
|
return ( weapon is Pitchfork );
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
protected override void OnTarget( Mobile from, object targeted )
|
|
{
|
|
int number;
|
|
|
|
if( !CheckDeed( from ) )
|
|
return;
|
|
|
|
|
|
bool usingDeed = (m_Deed != null);
|
|
bool toDelete = false;
|
|
|
|
//TODO: Make a IRepairable
|
|
|
|
if ( m_CraftSystem is DefTinkering && targeted is Golem )
|
|
{
|
|
Golem g = (Golem)targeted;
|
|
int damage = g.HitsMax - g.Hits;
|
|
|
|
if ( g.IsDeadBondedPet )
|
|
{
|
|
number = 500426; // You can't repair that.
|
|
}
|
|
else if ( damage <= 0 )
|
|
{
|
|
number = 500423; // That is already in full repair.
|
|
}
|
|
else
|
|
{
|
|
double skillValue = (usingDeed)? m_Deed.SkillLevel : from.Skills[SkillName.Tinkering].Value;
|
|
|
|
if ( skillValue < 60.0 )
|
|
{
|
|
number = 1044153; // You don't have the required skills to attempt this item. //TODO: How does OSI handle this with deeds with golems?
|
|
}
|
|
else if ( !from.CanBeginAction( typeof( Golem ) ) )
|
|
{
|
|
number = 501789; // You must wait before trying again.
|
|
}
|
|
else
|
|
{
|
|
if ( damage > (int)(skillValue * 0.3) )
|
|
damage = (int)(skillValue * 0.3);
|
|
|
|
damage += 30;
|
|
|
|
if ( !from.CheckSkill( SkillName.Tinkering, 0.0, 100.0 ) )
|
|
damage /= 2;
|
|
|
|
Container pack = from.Backpack;
|
|
|
|
if ( pack != null )
|
|
{
|
|
int v = pack.ConsumeUpTo( typeof( IronIngot ), (damage+4)/5 );
|
|
|
|
if ( v > 0 )
|
|
{
|
|
g.Hits += v*5;
|
|
|
|
number = 1044279; // You repair the item.
|
|
toDelete = true;
|
|
|
|
from.BeginAction( typeof( Golem ) );
|
|
Timer.DelayCall( TimeSpan.FromSeconds( 12.0 ), new TimerStateCallback( EndGolemRepair ), from );
|
|
}
|
|
else
|
|
{
|
|
number = 1044037; // You do not have sufficient metal to make that.
|
|
}
|
|
}
|
|
else
|
|
{
|
|
number = 1044037; // You do not have sufficient metal to make that.
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if ( targeted is BaseWeapon )
|
|
{
|
|
BaseWeapon weapon = (BaseWeapon)targeted;
|
|
SkillName skill = m_CraftSystem.MainSkill;
|
|
int toWeaken = 0;
|
|
|
|
if ( Core.AOS )
|
|
{
|
|
toWeaken = 1;
|
|
}
|
|
else if ( skill != SkillName.Tailoring )
|
|
{
|
|
double skillLevel = (usingDeed)? m_Deed.SkillLevel : from.Skills[skill].Base;
|
|
|
|
if ( skillLevel >= 90.0 )
|
|
toWeaken = 1;
|
|
else if ( skillLevel >= 70.0 )
|
|
toWeaken = 2;
|
|
else
|
|
toWeaken = 3;
|
|
}
|
|
|
|
if ( m_CraftSystem.CraftItems.SearchForSubclass( weapon.GetType() ) == null && !IsSpecialWeapon( weapon ) )
|
|
{
|
|
number = (usingDeed)? 1061136 : 1044277; // That item cannot be repaired. // You cannot repair that item with this type of repair contract.
|
|
}
|
|
else if ( !weapon.IsChildOf( from.Backpack ) )
|
|
{
|
|
number = 1044275; // The item must be in your backpack to repair it.
|
|
}
|
|
else if ( weapon.MaxHitPoints <= 0 || weapon.HitPoints == weapon.MaxHitPoints )
|
|
{
|
|
number = 1044281; // That item is in full repair
|
|
}
|
|
else if ( weapon.MaxHitPoints <= toWeaken )
|
|
{
|
|
number = 1044278; // That item has been repaired many times, and will break if repairs are attempted again.
|
|
}
|
|
else
|
|
{
|
|
if ( CheckWeaken( from, skill, weapon.HitPoints, weapon.MaxHitPoints ) )
|
|
{
|
|
weapon.MaxHitPoints -= toWeaken;
|
|
weapon.HitPoints = Math.Max( 0, weapon.HitPoints - toWeaken );
|
|
}
|
|
|
|
if ( CheckRepairDifficulty( from, skill, weapon.HitPoints, weapon.MaxHitPoints ) )
|
|
{
|
|
number = 1044279; // You repair the item.
|
|
m_CraftSystem.PlayCraftEffect( from );
|
|
weapon.HitPoints = weapon.MaxHitPoints;
|
|
}
|
|
else
|
|
{
|
|
number = (usingDeed)? 1061137 : 1044280; // You fail to repair the item. [And the contract is destroyed]
|
|
m_CraftSystem.PlayCraftEffect( from );
|
|
}
|
|
|
|
toDelete = true;
|
|
}
|
|
}
|
|
else if ( targeted is BaseArmor )
|
|
{
|
|
BaseArmor armor = (BaseArmor)targeted;
|
|
SkillName skill = m_CraftSystem.MainSkill;
|
|
int toWeaken = 0;
|
|
|
|
if ( Core.AOS )
|
|
{
|
|
toWeaken = 1;
|
|
}
|
|
else if ( skill != SkillName.Tailoring )
|
|
{
|
|
double skillLevel = (usingDeed)? m_Deed.SkillLevel : from.Skills[skill].Base;
|
|
|
|
if ( skillLevel >= 90.0 )
|
|
toWeaken = 1;
|
|
else if ( skillLevel >= 70.0 )
|
|
toWeaken = 2;
|
|
else
|
|
toWeaken = 3;
|
|
}
|
|
|
|
if ( m_CraftSystem.CraftItems.SearchForSubclass( armor.GetType() ) == null )
|
|
{
|
|
number = (usingDeed)? 1061136 : 1044277; // That item cannot be repaired. // You cannot repair that item with this type of repair contract.
|
|
}
|
|
else if ( !armor.IsChildOf( from.Backpack ) )
|
|
{
|
|
number = 1044275; // The item must be in your backpack to repair it.
|
|
}
|
|
else if ( armor.MaxHitPoints <= 0 || armor.HitPoints == armor.MaxHitPoints )
|
|
{
|
|
number = 1044281; // That item is in full repair
|
|
}
|
|
else if ( armor.MaxHitPoints <= toWeaken )
|
|
{
|
|
number = 1044278; // That item has been repaired many times, and will break if repairs are attempted again.
|
|
}
|
|
else
|
|
{
|
|
if ( CheckWeaken( from, skill, armor.HitPoints, armor.MaxHitPoints ) )
|
|
{
|
|
armor.MaxHitPoints -= toWeaken;
|
|
armor.HitPoints = Math.Max( 0, armor.HitPoints - toWeaken );
|
|
}
|
|
|
|
if ( CheckRepairDifficulty( from, skill, armor.HitPoints, armor.MaxHitPoints ) )
|
|
{
|
|
number = 1044279; // You repair the item.
|
|
m_CraftSystem.PlayCraftEffect( from );
|
|
armor.HitPoints = armor.MaxHitPoints;
|
|
}
|
|
else
|
|
{
|
|
number = (usingDeed)? 1061137 : 1044280; // You fail to repair the item. [And the contract is destroyed]
|
|
m_CraftSystem.PlayCraftEffect( from );
|
|
}
|
|
|
|
toDelete = true;
|
|
}
|
|
}
|
|
else if ( targeted is BaseClothing )
|
|
{
|
|
BaseClothing clothing = (BaseClothing)targeted;
|
|
SkillName skill = m_CraftSystem.MainSkill;
|
|
int toWeaken = 0;
|
|
|
|
if ( Core.AOS )
|
|
{
|
|
toWeaken = 1;
|
|
}
|
|
else if ( skill != SkillName.Tailoring )
|
|
{
|
|
double skillLevel = (usingDeed) ? m_Deed.SkillLevel : from.Skills[skill].Base;
|
|
|
|
if ( skillLevel >= 90.0 )
|
|
toWeaken = 1;
|
|
else if ( skillLevel >= 70.0 )
|
|
toWeaken = 2;
|
|
else
|
|
toWeaken = 3;
|
|
}
|
|
|
|
if ( m_CraftSystem.CraftItems.SearchForSubclass( clothing.GetType() ) == null && !IsSpecialClothing( clothing ))
|
|
{
|
|
number = (usingDeed) ? 1061136 : 1044277; // That item cannot be repaired. // You cannot repair that item with this type of repair contract.
|
|
}
|
|
else if ( !clothing.IsChildOf( from.Backpack ) )
|
|
{
|
|
number = 1044275; // The item must be in your backpack to repair it.
|
|
}
|
|
else if ( clothing.MaxHitPoints <= 0 || clothing.HitPoints == clothing.MaxHitPoints )
|
|
{
|
|
number = 1044281; // That item is in full repair
|
|
}
|
|
else if ( clothing.MaxHitPoints <= toWeaken )
|
|
{
|
|
number = 1044278; // That item has been repaired many times, and will break if repairs are attempted again.
|
|
}
|
|
else
|
|
{
|
|
if ( CheckWeaken( from, skill, clothing.HitPoints, clothing.MaxHitPoints ) )
|
|
{
|
|
clothing.MaxHitPoints -= toWeaken;
|
|
clothing.HitPoints = Math.Max( 0, clothing.HitPoints - toWeaken );
|
|
}
|
|
|
|
if ( CheckRepairDifficulty( from, skill, clothing.HitPoints, clothing.MaxHitPoints ) )
|
|
{
|
|
number = 1044279; // You repair the item.
|
|
m_CraftSystem.PlayCraftEffect( from );
|
|
clothing.HitPoints = clothing.MaxHitPoints;
|
|
}
|
|
else
|
|
{
|
|
number = (usingDeed) ? 1061137 : 1044280; // You fail to repair the item. [And the contract is destroyed]
|
|
m_CraftSystem.PlayCraftEffect( from );
|
|
}
|
|
|
|
toDelete = true;
|
|
}
|
|
}
|
|
else if( !usingDeed && targeted is BlankScroll )
|
|
{
|
|
SkillName skill = m_CraftSystem.MainSkill;
|
|
|
|
if( from.Skills[skill].Value >= 50.0 )
|
|
{
|
|
((BlankScroll)targeted).Consume( 1 );
|
|
RepairDeed deed = new RepairDeed( RepairDeed.GetTypeFor( m_CraftSystem ), from.Skills[skill].Value, from );
|
|
from.AddToBackpack( deed );
|
|
|
|
number = 500442; // You create the item and put it in your backpack.
|
|
}
|
|
else
|
|
number = 1047005; // You must be at least apprentice level to create a repair service contract.
|
|
}
|
|
else if ( targeted is Item )
|
|
{
|
|
number = (usingDeed)? 1061136 : 1044277; // That item cannot be repaired. // You cannot repair that item with this type of repair contract.
|
|
}
|
|
else
|
|
{
|
|
number = 500426; // You can't repair that.
|
|
}
|
|
|
|
if( !usingDeed )
|
|
{
|
|
CraftContext context = m_CraftSystem.GetContext( from );
|
|
from.SendGump( new CraftGump( from, m_CraftSystem, m_Tool, number ) );
|
|
}
|
|
else if( toDelete )
|
|
{
|
|
m_Deed.Delete();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |