From fd8755ef904bf9e64230bcb12f46e18d873f360e Mon Sep 17 00:00:00 2001 From: Jayden Bailey Date: Mon, 29 Jan 2024 18:51:23 +0000 Subject: [PATCH] ui: add overhead prayers (#186) --- src/enums/Prayer.ts | 43 ++++++++++++++++++++++++++++++++++++++++++- src/lib/CombatCalc.ts | 26 +++++++++++++++++++------- src/state.tsx | 5 ++++- 3 files changed, 65 insertions(+), 9 deletions(-) diff --git a/src/enums/Prayer.ts b/src/enums/Prayer.ts index 628a7f51..9f154661 100644 --- a/src/enums/Prayer.ts +++ b/src/enums/Prayer.ts @@ -14,6 +14,12 @@ import Chivalry from '@/public/img/prayers/Chivalry.png'; import Piety from '@/public/img/prayers/Piety.png'; import Rigour from '@/public/img/prayers/Rigour.png'; import Augury from '@/public/img/prayers/Augury.png'; +import ProtectMagic from '@/public/img/prayers/Protect_from_Magic.png'; +import ProtectMelee from '@/public/img/prayers/Protect_from_Melee.png'; +import ProtectRanged from '@/public/img/prayers/Protect_from_Missiles.png'; +import Redemption from '@/public/img/prayers/Redemption.png'; +import Retribution from '@/public/img/prayers/Retribution.png'; +import Smite from '@/public/img/prayers/Smite.png'; import { StaticImageData } from 'next/image'; import { Factor } from '@/lib/Math'; @@ -34,6 +40,12 @@ export enum Prayer { PIETY, RIGOUR, AUGURY, + PROTECT_MAGIC, + PROTECT_RANGED, + PROTECT_MELEE, + RETRIBUTION, + REDEMPTION, + SMITE, } export const DEFENSIVE_PRAYERS = [ @@ -54,11 +66,16 @@ export const ARM_PRAYERS = [ Prayer.BURST_OF_STRENGTH, Prayer.SUPERHUMAN_STRENGTH, Prayer.ULTIMATE_STRENGTH, ]; +export const OVERHEAD_PRAYERS = [ + Prayer.PROTECT_MAGIC, Prayer.PROTECT_RANGED, Prayer.PROTECT_MELEE, + Prayer.RETRIBUTION, Prayer.REDEMPTION, Prayer.SMITE, +]; + export type PrayerCombatStyle = 'magic' | 'ranged' | 'melee'; export interface PrayerData { name: string, image: StaticImageData, - combatStyle: PrayerCombatStyle, + combatStyle?: PrayerCombatStyle, factorAccuracy?: Factor, factorStrength?: Factor, } @@ -166,4 +183,28 @@ export const PrayerMap: { [k in Prayer]: PrayerData } = { combatStyle: 'magic', factorAccuracy: [5, 4], }, + [Prayer.PROTECT_MAGIC]: { + name: 'Protect from Magic', + image: ProtectMagic, + }, + [Prayer.PROTECT_MELEE]: { + name: 'Protect from Melee', + image: ProtectMelee, + }, + [Prayer.PROTECT_RANGED]: { + name: 'Protect from Missiles', + image: ProtectRanged, + }, + [Prayer.RETRIBUTION]: { + name: 'Retribution', + image: Retribution, + }, + [Prayer.REDEMPTION]: { + name: 'Redemption', + image: Redemption, + }, + [Prayer.SMITE]: { + name: 'Smite', + image: Smite, + }, }; diff --git a/src/lib/CombatCalc.ts b/src/lib/CombatCalc.ts index c9ead9bb..db66baee 100644 --- a/src/lib/CombatCalc.ts +++ b/src/lib/CombatCalc.ts @@ -11,7 +11,9 @@ import { WeightedHit, } from '@/lib/HitDist'; import { isBindSpell, isFireSpell, isWaterSpell } from '@/types/Spell'; -import { PrayerData, PrayerMap } from '@/enums/Prayer'; +import { + OVERHEAD_PRAYERS, Prayer, PrayerData, PrayerMap, +} from '@/enums/Prayer'; import { isVampyre, MonsterAttribute } from '@/enums/MonsterAttribute'; import { GLOWING_CRYSTAL_IDS, @@ -589,7 +591,7 @@ export default class CombatCalc { const { style } = this.player; let effectiveLevel: number = this.track(DetailKey.ACCURACY_LEVEL, this.player.skills.atk + this.player.boosts.atk); - for (const p of this.getPrayers(true)) { + for (const p of this.getCombatPrayers(true)) { effectiveLevel = this.trackFactor(DetailKey.ACCURACY_LEVEL_PRAYER, effectiveLevel, p.factorAccuracy!); } @@ -678,7 +680,7 @@ export default class CombatCalc { const baseLevel: number = this.trackAdd(DetailKey.DAMAGE_LEVEL, this.player.skills.str, this.player.boosts.str); let effectiveLevel: number = baseLevel; - for (const p of this.getPrayers(false)) { + for (const p of this.getCombatPrayers(false)) { effectiveLevel = this.trackFactor(DetailKey.DAMAGE_LEVEL_PRAYER, effectiveLevel, p.factorStrength!); } @@ -793,7 +795,7 @@ export default class CombatCalc { const { style } = this.player; let effectiveLevel: number = this.track(DetailKey.ACCURACY_LEVEL, this.player.skills.ranged + this.player.boosts.ranged); - for (const p of this.getPrayers(true)) { + for (const p of this.getCombatPrayers(true)) { effectiveLevel = this.trackFactor(DetailKey.ACCURACY_LEVEL_PRAYER, effectiveLevel, p.factorAccuracy!); } @@ -852,7 +854,7 @@ export default class CombatCalc { const { style } = this.player; let effectiveLevel: number = this.track(DetailKey.DAMAGE_LEVEL, this.player.skills.ranged + this.player.boosts.ranged); - for (const p of this.getPrayers(false)) { + for (const p of this.getCombatPrayers(false)) { effectiveLevel = this.trackFactor(DetailKey.DAMAGE_LEVEL_PRAYER, effectiveLevel, p.factorStrength!); } @@ -914,7 +916,7 @@ export default class CombatCalc { const { style } = this.player; let effectiveLevel: number = this.track(DetailKey.ACCURACY_LEVEL, this.player.skills.magic + this.player.boosts.magic); - for (const p of this.getPrayers(true)) { + for (const p of this.getCombatPrayers(true)) { effectiveLevel = this.trackFactor(DetailKey.ACCURACY_LEVEL_PRAYER, effectiveLevel, p.factorAccuracy!); } @@ -1073,7 +1075,17 @@ export default class CombatCalc { return maxHit; } - private getPrayers(accuracy: boolean): PrayerData[] { + /** + * Get the overhead prayer being used. Only one can be used at a time, so we can just return whichever matches first. + */ + private getOverheadPrayer(): Prayer | null { + return this.player.prayers.find((p) => OVERHEAD_PRAYERS.includes(p)) || null; + } + + /** + * Get the "combat" prayers for the current combat style. These are prayers that aren't overheads. + */ + private getCombatPrayers(accuracy: boolean): PrayerData[] { const style = this.player.style.type; let prayers = this.player.prayers.map((p) => PrayerMap[p]); diff --git a/src/state.tsx b/src/state.tsx index e22e67c9..fe58511d 100644 --- a/src/state.tsx +++ b/src/state.tsx @@ -27,7 +27,7 @@ import getMonsters from '@/lib/Monsters'; import { calculateEquipmentBonusesFromGear } from '@/lib/Equipment'; import { EquipmentCategory } from './enums/EquipmentCategory'; import { - ARM_PRAYERS, BRAIN_PRAYERS, DEFENSIVE_PRAYERS, OFFENSIVE_PRAYERS, Prayer, + ARM_PRAYERS, BRAIN_PRAYERS, DEFENSIVE_PRAYERS, OFFENSIVE_PRAYERS, OVERHEAD_PRAYERS, Prayer, } from './enums/Prayer'; import Potion from './enums/Potion'; @@ -437,6 +437,9 @@ class GlobalState implements State { // If this is a defensive prayer, disable all other defensive prayers if (DEFENSIVE_PRAYERS.includes(prayer)) newPrayers = newPrayers.filter((p) => !DEFENSIVE_PRAYERS.includes(p)); + // If this is an overhead prayer, disable all other defensive prayers + if (OVERHEAD_PRAYERS.includes(prayer)) newPrayers = newPrayers.filter((p) => !OVERHEAD_PRAYERS.includes(p)); + // If this is an offensive prayer... if (OFFENSIVE_PRAYERS.includes(prayer)) { newPrayers = newPrayers.filter((p) => {