Skip to content

Commit

Permalink
rebase + include leagues
Browse files Browse the repository at this point in the history
  • Loading branch information
LlemonDuck committed Nov 26, 2024
1 parent 4275414 commit 2ddf315
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 66 deletions.
4 changes: 2 additions & 2 deletions src/app/components/player/Bonuses.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ const Bonuses: React.FC = observer(() => {

const player = toJS(store.player);
const monster = toJS(store.monster);
const computedStats = useMemo(() => calculateEquipmentBonusesFromGear(player, monster), [monster, player]);
const computedStats = useMemo(() => calculateEquipmentBonusesFromGear(player, monster), [player, monster]);

return (
<div className="px-4 my-4">
<div className="flex justify-between items-center gap-2">
<h4 className="font-serif font-bold">Bonuses</h4>
{manualMode && (
<button type="button" className="text-xs underline" onClick={() => store.recalculateEquipmentBonusesFromGear()}>
<button type="button" className="text-xs underline" onClick={() => store.updateEquipmentBonuses()}>
Calculate from equipment
</button>
)}
Expand Down
45 changes: 37 additions & 8 deletions src/lib/Equipment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,24 +231,53 @@ export const getCanonicalEquipment = (inputEq: PlayerEquipment) => {

/**
* Calculates the player's attack speed using current stance and equipment.
* @param player - the player
*/
export const calculateAttackSpeed = (player: Player): number => {
export const calculateAttackSpeed = (player: Player, monster: Monster): number => {
let attackSpeed = player.equipment.weapon?.speed || DEFAULT_ATTACK_SPEED;

if (player.style.type === 'ranged' && player.style.stance === 'Rapid') {
attackSpeed -= 1;
}
if (CAST_STANCES.includes(player.style.stance)) {
} else if (CAST_STANCES.includes(player.style.stance)) {
if (player.equipment.weapon?.name === 'Harmonised nightmare staff'
&& player.spell?.spellbook === 'standard'
&& player.style.stance !== 'Manual Cast') {
return 4;
attackSpeed = 4;
} else {
attackSpeed = 5;
}
return 5;
}

return attackSpeed;
// Giant rat (Scurrius)
if (monster.id === 7223 && player.style.stance !== 'Manual Cast') {
if (['Bone mace', 'Bone shortbow', 'Bone staff'].includes(player.equipment.weapon?.name || '')) {
attackSpeed = 1;
}
}

let activeRelic: number;
if (player.style.type === 'ranged') {
activeRelic = player.leagues.five.ranged;
} else if (player.style.type === 'magic') {
activeRelic = player.leagues.five.magic;
} else {
activeRelic = player.leagues.five.melee;
}

if (activeRelic >= 5) {
if (attackSpeed >= 5) {
attackSpeed = Math.trunc(attackSpeed / 2);
} else {
attackSpeed = Math.ceil(attackSpeed / 2);
}
} else if (activeRelic >= 3) {
attackSpeed = Math.trunc(attackSpeed * 4 / 5);
}

if (player.style.type === 'magic' && activeRelic >= 2) {
attackSpeed += player.leagues.five.ticksDelayed;
}

return Math.max(attackSpeed, 1);
};

export const calculateEquipmentBonusesFromGear = (player: Player, monster: Monster): EquipmentBonuses => {
Expand Down Expand Up @@ -351,7 +380,7 @@ export const calculateEquipmentBonusesFromGear = (player: Player, monster: Monst
totals.bonuses.ranged_str += 1;
}

totals.bonuses.attack_speed = calculateAttackSpeed(player);
totals.bonuses.attack_speed = calculateAttackSpeed(player, monster);

return totals;
};
Expand Down
49 changes: 5 additions & 44 deletions src/lib/PlayerVsNPCCalc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ import { isVampyre, MonsterAttribute } from '@/enums/MonsterAttribute';
import {
ALWAYS_MAX_HIT_MONSTERS,
BA_ATTACKER_MONSTERS,
CAST_STANCES,
DEFAULT_ATTACK_SPEED,
FLAT_ARMOUR,
GLOWING_CRYSTAL_IDS,
GUARDIAN_IDS,
HUEYCOATL_PHASE_IDS,
Expand All @@ -48,7 +45,9 @@ import {
import { EquipmentCategory } from '@/enums/EquipmentCategory';
import { DetailKey } from '@/lib/CalcDetails';
import { Factor, MinMax } from '@/lib/Math';
import { AmmoApplicability, ammoApplicability, WEAPON_SPEC_COSTS } from '@/lib/Equipment';
import {
AmmoApplicability, ammoApplicability, calculateAttackSpeed, WEAPON_SPEC_COSTS,
} from '@/lib/Equipment';
import BaseCalc, { CalcOpts, InternalOpts } from '@/lib/BaseCalc';
import { scaleMonster, scaleMonsterHpOnly } from '@/lib/MonsterScaling';
import { CombatStyleType, getRangedDamageType } from '@/types/PlayerCombatStyle';
Expand Down Expand Up @@ -1865,46 +1864,8 @@ export default class PlayerVsNPCCalc extends BaseCalc {
* Returns the player's attack speed.
*/
public getAttackSpeed(): number {
let attackSpeed = this.player.equipment.weapon?.speed || DEFAULT_ATTACK_SPEED;

if (this.player.style.type === 'ranged' && this.player.style.stance === 'Rapid') {
attackSpeed -= 1;
} else if (CAST_STANCES.includes(this.player.style.stance)) {
if (this.player.equipment.weapon?.name === 'Harmonised nightmare staff'
&& this.player.spell?.spellbook === 'standard'
&& this.player.style.stance !== 'Manual Cast') {
attackSpeed = 4;
} else {
attackSpeed = 5;
}
}

// Giant rat (Scurrius)
if (this.monster.id === 7223 && this.player.style.stance !== 'Manual Cast') {
if (['Bone mace', 'Bone shortbow', 'Bone staff'].includes(this.player.equipment.weapon?.name || '')) {
attackSpeed = 1;
}
}

if (this.hasLeaguesMastery('melee', MeleeMastery.MELEE_5)
|| this.hasLeaguesMastery('ranged', RangedMastery.RANGED_5)
|| this.hasLeaguesMastery('magic', MagicMastery.MAGIC_5)) {
if (attackSpeed >= 5) {
attackSpeed = Math.trunc(attackSpeed / 2);
} else {
attackSpeed = Math.ceil(attackSpeed / 2);
}
} else if (this.hasLeaguesMastery('melee', MeleeMastery.MELEE_3)
|| this.hasLeaguesMastery('ranged', RangedMastery.RANGED_3)
|| this.hasLeaguesMastery('magic', MagicMastery.MAGIC_3)) {
attackSpeed = Math.trunc(attackSpeed * 4 / 5);
}

if (this.hasLeaguesMastery('magic', MagicMastery.MAGIC_2)) {
attackSpeed += this.player.leagues.five.ticksDelayed;
}

return attackSpeed;
return this.player.bonuses.attack_speed
?? calculateAttackSpeed(this.player, this.monster);
}

public getExpectedAttackSpeed() {
Expand Down
20 changes: 8 additions & 12 deletions src/state.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { getMonsters, INITIAL_MONSTER_INPUTS } from '@/lib/Monsters';
import { availableEquipment, calculateEquipmentBonusesFromGear } from '@/lib/Equipment';
import { CalcWorker } from '@/worker/CalcWorker';
import { spellByName } from '@/types/Spell';
import { NATURES_REPRISAL_MOCK_ID, NUMBER_OF_LOADOUTS } from '@/lib/constants';
import { DEFAULT_ATTACK_SPEED, NATURES_REPRISAL_MOCK_ID, NUMBER_OF_LOADOUTS } from '@/lib/constants';
import { defaultLeaguesState } from '@/lib/LeaguesV';
import { EquipmentCategory } from './enums/EquipmentCategory';
import {
Expand Down Expand Up @@ -392,19 +392,17 @@ class GlobalState implements State {
this.calcWorker = worker;
}

recalculateEquipmentBonusesFromGear(loadoutIx?: number) {
updateEquipmentBonuses(loadoutIx?: number) {
loadoutIx = loadoutIx !== undefined ? loadoutIx : this.selectedLoadout;

const totals = calculateEquipmentBonusesFromGear(this.loadouts[loadoutIx], this.monster);
this.updatePlayer({
bonuses: totals.bonuses,
offensive: totals.offensive,
defensive: totals.defensive,
}, loadoutIx);
this.loadouts[loadoutIx] = merge(
this.loadouts[loadoutIx],
calculateEquipmentBonusesFromGear(this.loadouts[loadoutIx], this.monster),
);
}

recalculateEquipmentBonusesFromGearAll() {
this.loadouts.forEach((_, i) => this.recalculateEquipmentBonusesFromGear(i));
this.loadouts.forEach((_, i) => this.updateEquipmentBonuses(i));
}

updateUIState(ui: PartialDeep<UI>) {
Expand Down Expand Up @@ -675,9 +673,7 @@ class GlobalState implements State {

this.loadouts[loadoutIx] = merge(this.loadouts[loadoutIx], player);
if (!this.prefs.manualMode) {
if (eq || Object.hasOwn(player, 'spell') || Object.hasOwn(player, 'style')) {
this.recalculateEquipmentBonusesFromGear(loadoutIx);
}
this.updateEquipmentBonuses(loadoutIx);
}
}

Expand Down

0 comments on commit 2ddf315

Please sign in to comment.