ModernUO/Projects/UOContent/Items/Weapons/Axes/BaseAxe.cs
Jack 6cdec42146
fix: Special moves and various UOR+ bonuses (#2384)
## Special moves
Special moves were added [27 Apr, 2000.](https://uo.com/wiki/ultima-online-wiki/technical/previous-publishes/2000-2/2000-publish-05-27th-april/). This is well past the discussed cutoff date for T2A, which is **[Nov 23, 1999 - Publish 1](https://uo.com/wiki/ultima-online-wiki/technical/previous-publishes/1999-2/1999-publish-01-23rd-november/)** as per the UOSecondAge shard which is the golden standard for T2A accuracy and represents a logical cutoff for this era. 

Regarding the specific date: **Nov 23, 1999 (Publish 1)** - the game significantly changed as a "pre-patch" to UOR on this date, and UOSecondAge picks and chooses from this date based on QoL features, while keeping the gameplay accurate to what is widely known as the "T2A era". However this date is ~4 months before the actual UOR release date.

## Defensive wrestling
Defensively wrestling as (eval+anat)/2 was added in [publish 16](https://uo.com/wiki/ultima-online-wiki/technical/previous-publishes/2002-2/publish-16-changes-and-bug-fixes-24th-july/) and should be gated behind !Core.LBR
* "Unarmed “to-be-hit” changes (chance to get hit while unarmed is now the better of either Wrestling skill, or an average of Anatomy & Evaluate Intelligence)."

## Lumberjacking damage bonus

Lumberjacking damage bonus was added in [UOR](https://uo.com/wiki/ultima-online-wiki/technical/previous-publishes/2000-2/2000-publish-05-27th-april/)

## Anatomy and LJ +10% GM bonus
Anatomy/LJ +10% GM bonus was added in [pub 13](https://uo.com/wiki/ultima-online-wiki/technical/previous-publishes/2001-2/2001-publish-13-19th-august/), which was during UOTD.
2026-03-22 10:55:01 -07:00

140 lines
4.3 KiB
C#

using System;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Engines.ConPVP;
using Server.Engines.Harvest;
namespace Server.Items
{
public interface IAxe
{
bool Axe(Mobile from, BaseAxe axe);
}
[SerializationGenerator(0, false)]
public abstract partial class BaseAxe : BaseMeleeWeapon
{
[SerializableField(0)]
[InvalidateProperties]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _showUsesRemaining;
[SerializableField(1)]
[InvalidateProperties]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private int _usesRemaining;
public BaseAxe(int itemID) : base(itemID) => _usesRemaining = 150;
public override int DefHitSound => 0x232;
public override int DefMissSound => 0x23A;
public override SkillName DefSkill => SkillName.Swords;
public override WeaponType DefType => WeaponType.Axe;
public override WeaponAnimation DefAnimation => WeaponAnimation.Slash2H;
public virtual HarvestSystem HarvestSystem => Lumberjacking.System;
public virtual int GetUsesScalar()
{
if (Quality == WeaponQuality.Exceptional)
{
return 200;
}
return 100;
}
public override void UnscaleDurability()
{
base.UnscaleDurability();
var scale = GetUsesScalar();
UsesRemaining = (_usesRemaining * 100 + (scale - 1)) / scale;
InvalidateProperties();
}
public override void ScaleDurability()
{
base.ScaleDurability();
var scale = GetUsesScalar();
UsesRemaining = (_usesRemaining * scale + 99) / 100;
InvalidateProperties();
}
public override void OnDoubleClick(Mobile from)
{
if (HarvestSystem == null || Deleted)
{
return;
}
if (!IsChildOf(from))
{
var loc = GetWorldLocation();
if (!from.InLOS(loc) || !from.InRange(loc, 2))
{
from.LocalOverheadMessage(MessageType.Regular, 0x3E9, 1019045); // I can't reach that
return;
}
}
if (!IsAccessibleTo(from))
{
PublicOverheadMessage(MessageType.Regular, 0x3E9, 1061637); // You are not allowed to access this.
return;
}
if (HarvestSystem is not Mining)
{
from.SendLocalizedMessage(1010018); // What do you want to use this item on?
}
HarvestSystem.BeginHarvesting(from, this);
}
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, ref list);
if (HarvestSystem != null)
{
BaseHarvestTool.AddContextMenuEntries(from, this, ref list, HarvestSystem);
}
}
public override void OnHit(Mobile attacker, Mobile defender, double damageBonus = 1)
{
base.OnHit(attacker, defender, damageBonus);
if (!Core.AOS && Core.UOR && (attacker.Player || attacker.Body.IsHuman) && Layer == Layer.TwoHanded &&
attacker.Skills.Anatomy.Value >= 80 &&
attacker.Skills.Anatomy.Value / 400.0 >= Utility.RandomDouble() &&
DuelContext.AllowSpecialAbility(attacker, "Concussion Blow", false))
{
var mod = defender.GetStatMod("Concussion");
if (mod == null)
{
defender.SendMessage("You receive a concussion blow!");
defender.AddStatMod(
new StatMod(
StatType.Int,
"Concussion",
-(defender.RawInt / 2),
TimeSpan.FromSeconds(30.0)
)
);
attacker.SendMessage("You deliver a concussion blow!");
attacker.PlaySound(0x308);
}
}
}
}
}