WeaponOffenseCalculator

Centralized, read-only weapon offense calculator for the player→elite damage formula.

This class is one half of the player→elite damage formula. It handles the weapon adjustment layer — determining how much a player's equipped weapon boosts or reduces their damage output against elite mobs. The other half (skill adjustment) lives in com.magmaguy.elitemobs.api.EliteMobDamagedByPlayerEvent.

Mirrors ArmorDefenseCalculator on the offensive side — where ArmorDefenseCalculator converts armor into a damage reduction multiplier for elite→player, this class converts weapon level into a damage bonus multiplier for player→elite.

Design Goals

  1. Unified item handling — one code path for elite and vanilla weapons. Elite weapons use their stored item level; vanilla weapons get a level derived from their material's DPS via getItemLevel.
  2. No vanilla damage dependency — weapon level determines the bonus, not vanilla attack damage attributes. Vanilla Minecraft weapon damage is completely replaced by the formula.
  3. No data mutation — this class only reads item data through existing APIs. It never writes to items or modifies player state.
  4. Smooth progression curve — two-part linear curve mirrors the defensive gear reduction in getGearReduction.

How This Fits Into the Damage Formula

The full player→elite damage formula is:
finalDamage = max(formulaDamage, 1) × damageModifier × combatMultiplier × critMultiplier

where formulaDamage =
  baseDamage × attackSpeedFactor × skillAdjustment × weaponAdjustment × cooldownOrVelocity × sweepMultiplier

and:
  baseDamage      = normalizedMobHP / 3.0                                         [from LevelScaling]
  attackSpeedFactor = tuned pacing factor from vanilla-equivalent attack speed     [melee only]
  skillAdjustment = 2^((weaponSkillLevel - mobLevel) / 7.5)                       [from LevelScaling]
  weaponAdjustment = 0.5 + bonus(weaponLevel, mobLevel)                           [from THIS class]
  cooldownOrVelocity = tracked melee charge or normalizedArrowVelocity            [0 to 1]
  sweepMultiplier = 0.25 for secondary sweep targets, 1.0 for primary             [from THIS class]

This class computes the attackSpeedFactor, weaponAdjustment, and sweepMultiplier.

Weapon Adjustment Curve (Two-Part Linear)

Adjustment
  1.25 |                              ___________  ← hard cap (WEAPON_MAX_BONUS = 0.75)
       |                            /
  1.00 |..........................X  ← matching weapon = 1.0 (WEAPON_BASE_BONUS = 0.50)
       |                        /
  0.75 |                      /
       |                    /
  0.50 |__________________/___________________________
       0        weaponLevel=mobLevel        weaponLevel

Below matching (weaponLevel ≤ mobLevel):
  bonus = WEAPON_BASE_BONUS × (weaponLevel / mobLevel)   // linear 0 → 0.50
  Slope depends on mob level — linear from 0% bonus to 50% bonus.

Above matching (weaponLevel > mobLevel):
  bonus = WEAPON_BASE_BONUS + (weaponLevel - mobLevel) × WEAPON_BONUS_PER_LEVEL
  bonus = min(bonus, WEAPON_MAX_BONUS)                    // cap at 0.75
  Flat 2.5% per weapon level above mob, up to 75% bonus.
  Requires +10 weapon levels above mob to hit cap.

weaponAdjustment = 0.5 + bonus   // range: [0.50, 1.25]

Target Scenario Table

Bare fists (no weapon)00.000.506 hits (2× slower)
Half-level weaponmobLv/20.250.754 hits
Matching weaponmobLv0.501.003 hits (baseline)
+4 levels abovemobLv+40.601.10~2.7 hits
+10 levels above (cap)mobLv+100.751.25~2.4 hits
+20 levels abovemobLv+200.751.25~2.4 hits (still capped)

Worked Examples

Example 1: Lv25 matched sword vs Lv25 elite (melee)

Player: weaponSkillLevel=25, weapon=elite sword (itemLevel=25)
Mob:    level=25, healthMultiplier=1.0

Step 1 — Base damage: mobHP(25) = 2.1875 * 2^5 = 70.0, baseDamage = 70.0/3 = 23.33
Step 2 — Attack speed factor: sword speed=1.6, factor = 1.0
Step 3 — Skill adjustment: 2^((25-25)/7.5) = 2^0 = 1.0
Step 4 — Weapon adjustment: weaponLevel(25) == mobLevel(25), bonus=0.50, adj = 1.0
Step 5 — Cooldown: full charge = 1.0
Step 6 — Sweep: primary target = 1.0

formulaDamage = 23.33 × 1.0 × 1.0 × 1.0 × 1.0 × 1.0 = 23.33
Mob HP = 70.0 → hits to kill = 70.0 / 23.33 = 3.0 ✓

Example 2: Lv25 axe vs Lv25 elite (melee)

Player: weaponSkillLevel=25, weapon=elite axe (itemLevel=25)
Mob:    level=25, healthMultiplier=1.0

Step 1 — Base damage: 23.33 (same as above)
Step 2 — Attack speed factor: axe speed=1.0, factor ≈ 1.26
Step 3 — Skill adjustment: 1.0 (matched)
Step 4 — Weapon adjustment: 1.0 (matched)
Step 5 — Cooldown: full charge = 1.0

formulaDamage = 23.33 × 1.26 × 1.0 × 1.0 × 1.0 = 29.5
Hits to kill = 70.0 / 29.5 = 2.37

Example 3: Lv20 bow vs Lv25 elite (ranged)

Player: weaponSkillLevel=20, weapon=elite bow (itemLevel=20)
Mob:    level=25, healthMultiplier=2.0, HP = 70.0 × 2 = 140.0

Step 1 — Base damage: 23.33 (from normalized HP, NOT actual HP)
Step 2 — Attack speed factor: ranged, N/A = 1.0
Step 3 — Skill adjustment: 2^((20-25)/7.5) = 2^(-0.667) = 0.63
Step 4 — Weapon adjustment: weaponLevel(20) < mobLevel(25), bonus = 0.5*(20/25) = 0.4, adj = 0.9
Step 5 — Arrow velocity: full draw = 1.0

formulaDamage = 23.33 × 1.0 × 0.63 × 0.9 × 1.0 = 13.23
Hits to kill = 140.0 / 13.23 = 10.6 hits
(Under-leveled skill AND weapon, fighting a healthMultiplier=2.0 mob)

Comparison to Defensive Mirror

Curve typeTwo-part linearTwo-part linear (same shape)
Below-matching sloperatio-basedratio-based (same)
Above-matching slope2.5% per level2.5% per level (same)
Matching value50% reduction (adj=1.0)50% bonus (adj=1.0)
Cap75% reduction (adj=0.5)75% bonus (adj=1.25)
Levels to cap+10 above mob+10 above mob
Naked/no-weaponadj=2.0 (double damage taken)adj=0.5 (half damage dealt)

Properties

Link copied to clipboard
public final static double BURST_DAMPING_EXPONENT
Burst-heavy melee families no longer receive the full referenceSpeed / weaponSpeed compensation.
Link copied to clipboard
public final static double SWEEP_DAMAGE_FRACTION
Fraction of primary damage dealt to sweep secondary targets.
Link copied to clipboard
public final static double THORNS_PERCENT_PER_LEVEL
Percentage of base damage per thorns enchantment level.
Link copied to clipboard
public final static double WEAPON_BASE_BONUS
Base bonus at matching weapon level (weaponLevel == mobLevel).
Link copied to clipboard
public final static double WEAPON_BONUS_PER_LEVEL
Additional bonus per weapon level above mob level.
Link copied to clipboard
public final static double WEAPON_MAX_BONUS
Maximum bonus achievable (caps the above-matching slope).

Functions

Link copied to clipboard
public static double getAttackSpeedFactor(String typeName, double attackSpeed)
Test-friendly overload for getAttackSpeedFactor.
public static double getAttackSpeedFactor(ItemStack item, double attackSpeed)
Calculates the melee attack-speed factor for the player→elite formula.
Link copied to clipboard
public static double getEffectiveWeaponLevel(ItemStack item)
Returns the effective weapon level for a given item.
Link copied to clipboard
public static double getLegacyAttackSpeedFactor(double attackSpeed)
Link copied to clipboard
public static double getSweepMultiplier(EntityDamageByEntityEvent event)
Returns the sweep damage multiplier for the given damage event.
Link copied to clipboard
public static double getWeaponAdjustment(double weaponLevel, int mobLevel)
Calculates the weapon adjustment multiplier from weapon level vs mob level.
Link copied to clipboard
public static double normalizeArrowVelocity(double launchVelocityMagnitude)
Variant of normalizeArrowVelocity that takes a pre-captured velocity magnitude (typically stored on the projectile at launch via ItemTagger.setArrowLaunchVelocity).
public static double normalizeArrowVelocity(Projectile projectile)
Normalizes arrow velocity to a 0–1 scale for ranged damage calculation.