mh3-data
Version:
Monster Hunter Tri data for monsters, quests, and weapons
85 lines • 3.76 kB
JavaScript
import { Weapons } from '../../model';
import { WeaponClass } from '../../model/weapons';
import { isCutHit } from '../../model/weapons/weapon-util';
import { applyDefenseMultiplier, calculateElementalDamage, getRawMultiplier, getSharpnessRawMultiplier, getWeaponClassMultiplier, validateWeaponSharpness } from './damage-util';
const LANCE_VAR_MULTIPLIER = 0.78;
const LANCE_CHARGE_ELEMENTAL_MULTIPLIER = 0.25;
/**
* @returns Attack properties for a {@link LanceTypes.LanceAttack}
*/
function getLanceAttack(attackName) {
const lanceAttacks = Weapons.getWeaponDamageProperties(WeaponClass.LANCE)
.attackModes[0];
const result = lanceAttacks.attacks.find(atk => atk.name === attackName);
if (!result) {
throw new Error(`'${attackName}' is not a valid Lance attack`);
}
return result;
}
/**
* If the impact hitzone * .72 is greater than the cut hitzone then
* that modified impact value will be used instead. Otherwise take cut.
*/
function getLanceHitzoneMultiplier(hit, hitzoneValues) {
if (isCutHit(hit)) {
const varImpact = hitzoneValues.impact * LANCE_VAR_MULTIPLIER;
return varImpact > hitzoneValues.cut ? varImpact : hitzoneValues.cut;
}
// Shield bash should always be impact
return hitzoneValues.impact;
}
function validateLance(weapon) {
if (weapon.type !== WeaponClass.LANCE) {
throw new Error(`'${weapon.name}' is not a '${WeaponClass.LANCE}'`);
}
}
/**
* Calculates damage for a {@link LanceTypes.Lance}.
*/
export function calculateLanceDamage(weaponArgs, monsterMultipliers, damageBuffArgs) {
const { weaponId, attackName, sharpness } = weaponArgs;
const { hitzoneValues, statMultipliers: levelMultipliers } = monsterMultipliers;
const { rawArgs, elementArgs, weaponClassArgs } = damageBuffArgs;
const lance = Weapons.getWeapon(Weapons.WeaponClass.LANCE, weaponId);
validateLance(lance);
validateWeaponSharpness(lance, sharpness);
const { classModifier } = Weapons.getWeaponDamageProperties(WeaponClass.LANCE);
const attack = getLanceAttack(attackName);
const sharpnessMultiplier = getSharpnessRawMultiplier(sharpness);
const rawMultiplier = getRawMultiplier(rawArgs);
const attackBuffMultiplier = getWeaponClassMultiplier(weaponClassArgs);
const attackWithBuffs = lance.attack + attackBuffMultiplier * classModifier;
return attack.hits.map(hit => {
const hitzoneMultiplier = getLanceHitzoneMultiplier(hit, hitzoneValues);
const rawDamage = (attackWithBuffs *
hit.power *
rawMultiplier *
sharpnessMultiplier *
hitzoneMultiplier *
1) / // Lance does not have a [SpecialVar], but this is here for consistency
classModifier;
const baseElementalDamage = calculateElementalDamage({
weapon: lance,
sharpness,
hitzoneValues,
elementArgs
});
// Lance charge elemental damage is cut by 75%
const elementalDamage = attack.name === 'Charge'
? baseElementalDamage * LANCE_CHARGE_ELEMENTAL_MULTIPLIER
: baseElementalDamage;
// Decimal is dropped
const totalDamage = applyDefenseMultiplier(rawDamage + elementalDamage, levelMultipliers.defense);
// KO is always rounded down
const koDamage = !isCutHit(hit)
? Math.floor(hit.ko * sharpnessMultiplier)
: undefined;
return {
rawDamage: applyDefenseMultiplier(rawDamage, levelMultipliers.defense),
elementalDamage: applyDefenseMultiplier(elementalDamage, levelMultipliers.defense),
totalDamage,
koDamage
};
});
}
//# sourceMappingURL=lance-damage.js.map