Skip to content

Commit

Permalink
warn on empty blowpipe import
Browse files Browse the repository at this point in the history
Doesn't fully solve the issue, since we still need to fix the import flow to preserve the blowpipe ammo, but this at least prevents users loading empty blowpipes unknowingly and seeing incorrect results.

Closes #293
  • Loading branch information
LlemonDuck committed Jun 24, 2024
1 parent c08d0c8 commit 1cbb29c
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 16 deletions.
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@
"fmt": "next lint --fix",
"analyse": "ANALYSE=true next build",
"test": "jest",
"cdn-docker": "yarn build-docker-scraper && docker run --rm -it -v $(pwd)/cdn:/srv/cdn -v $(pwd)/src/lib/EquipmentAliases.ts:/srv/src/lib/EquipmentAliases.ts weirdgloop/osrs-dps-calc:scraper",
"cdn-docker-base": "docker run --rm -it -v $(pwd)/scripts:/srv/scripts -v $(pwd)/cdn:/srv/cdn -v $(pwd)/src/lib/EquipmentAliases.ts:/srv/src/lib/EquipmentAliases.ts weirdgloop/osrs-dps-calc:scraper",
"cdn-docker": "yarn build-docker-scraper && yarn cdn-docker-base",
"cdn-docker-aliases": "yarn cdn-docker-base python generateEquipmentAliases.py",
"cdn-docker-equipment": "yarn cdn-docker-base python generateEquipment.py",
"cdn-docker-monsters": "yarn cdn-docker-base python generateMonsters.py",
"cdn-dispatch": "gh workflow run regenerate.yml"
},
"dependencies": {
Expand Down
25 changes: 24 additions & 1 deletion src/app/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import type { NextPage } from 'next';
import MonsterContainer from '@/app/components/monster/MonsterContainer';
import { Tooltip } from 'react-tooltip';
import React, { Suspense, useEffect } from 'react';
import React, { Suspense, useEffect, useMemo } from 'react';
import { observer } from 'mobx-react-lite';
import { useStore } from '@/state';
import { ToastContainer } from 'react-toastify';
Expand All @@ -18,6 +18,11 @@ import DebugPanels from '@/app/components/results/DebugPanels';
import { IconAlertTriangle } from '@tabler/icons-react';
import NPCVersusPlayerResultsContainer from '@/app/components/results/NPCVersusPlayerResultsContainer';
import { CalcProvider, useCalc } from '@/worker/CalcWorker';
import UserIssueType from '@/enums/UserIssueType';

const GLOBAL_ISSUE_TYPES: UserIssueType[] = [
UserIssueType.IMPORT_MISSING_DATA,
];

const Home: NextPage = observer(() => {
const calc = useCalc();
Expand Down Expand Up @@ -91,6 +96,23 @@ const Home: NextPage = observer(() => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

const globalIssues = useMemo(() => {
const issues = store.userIssues.filter((is) => GLOBAL_ISSUE_TYPES.includes(is.type));
return (
<>
{issues.map((is) => (
<div
key={`${is.loadout || 'global'}/${is.message}`}
className="w-full bg-orange-500 text-white px-4 py-1 text-sm border-b border-orange-400 flex items-center gap-1"
>
<IconAlertTriangle className="text-orange-200" />
{`${is.loadout ? `Loadout ${is.loadout}: ` : ''}${is.message}`}
</div>
))}
</>
);
}, [store.userIssues]);

return (
<div>
{store.prefs.manualMode && (
Expand All @@ -103,6 +125,7 @@ const Home: NextPage = observer(() => {
Manual mode is enabled! Some things may not function correctly. Click here to disable it.
</button>
)}
{globalIssues}
<Suspense>
<InitialLoad />
</Suspense>
Expand Down
2 changes: 2 additions & 0 deletions src/enums/UserIssueType.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
enum UserIssueType {
EQUIPMENT_MISSING_AMMO = 'equipment_slot_ammo_missing',
EQUIPMENT_WRONG_AMMO = 'equipment_slot_ammo_wrong',
EQUIPMENT_WEAPON_EMPTY = 'equipment_slot_weapon_empty',
EQUIPMENT_SET_EFFECT_UNSUPPORTED = 'equipment_slot_body_unsupported_set_effect',
SPELL_WRONG_WEAPON = 'spell_wrong_weapon',
SPELL_WRONG_MONSTER = 'spell_wrong_monster',
MONSTER_UNIQUE_EFFECTS = 'monster_overall_unique_effects',
IMPORT_MISSING_DATA = 'runelite_import_missing_data',
}

export default UserIssueType;
39 changes: 31 additions & 8 deletions src/lib/BaseCalc.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { EquipmentPiece, Player } from '@/types/Player';
import { Monster } from '@/types/Monster';
import { AmmoApplicability, ammoApplicability, getCanonicalEquipment } from '@/lib/Equipment';
import {
AmmoApplicability,
ammoApplicability,
EMPTY_BLOWPIPE,
getCanonicalEquipment,
} from '@/lib/Equipment';
import UserIssueType from '@/enums/UserIssueType';
import { MonsterAttribute } from '@/enums/MonsterAttribute';
import { CAST_STANCES } from '@/lib/constants';
Expand Down Expand Up @@ -58,6 +63,8 @@ export default class BaseCalc {

userIssues: UserIssue[] = [];

protected fatal: boolean = false;

constructor(player: Player, monster: Monster, opts: CalcOpts = {}) {
this.opts = {
...DEFAULT_OPTS,
Expand Down Expand Up @@ -532,8 +539,14 @@ export default class BaseCalc {
]);
}

protected addIssue(type: UserIssueType, message: string) {
this.userIssues.push({ type, message, loadout: this.opts.loadoutName });
protected addIssue(type: UserIssueType, message: string, severity: UserIssue['severity'] = 'warn') {
this.userIssues.push({
type,
severity,
message,
loadout: this.opts.loadoutName,
});
this.fatal ||= severity === 'fatal';
}

private sanitizeInputs() {
Expand All @@ -558,11 +571,12 @@ export default class BaseCalc {
};
}

if (this.player.style.stance !== 'Manual Cast' && ammoApplicability(eq.weapon?.id, eq.ammo?.id) === AmmoApplicability.INVALID) {
if (ammoApplicability(eq.weapon?.id, eq.ammo?.id) === AmmoApplicability.INVALID) {
const severity = this.player.style.stance === 'Manual Cast' ? 'warn' : 'fatal';
if (eq.ammo?.name) {
this.addIssue(UserIssueType.EQUIPMENT_WRONG_AMMO, 'This ammo does not work with your current weapon.');
this.addIssue(UserIssueType.EQUIPMENT_WRONG_AMMO, 'This ammo does not work with your current weapon.', severity);
} else {
this.addIssue(UserIssueType.EQUIPMENT_MISSING_AMMO, 'Your weapon requires ammo to use.');
this.addIssue(UserIssueType.EQUIPMENT_MISSING_AMMO, 'Your weapon requires ammo to use.', severity);
}
}

Expand All @@ -579,7 +593,7 @@ export default class BaseCalc {
...this.player,
spell: null,
};
this.addIssue(UserIssueType.SPELL_WRONG_WEAPON, 'This spell needs a specific weapon equipped to cast.');
this.addIssue(UserIssueType.SPELL_WRONG_WEAPON, 'This spell needs a specific weapon equipped to cast.', 'fatal');
}

// Certain spells can only be cast on specific monsters
Expand All @@ -591,7 +605,7 @@ export default class BaseCalc {
...this.player,
spell: null,
};
this.addIssue(UserIssueType.SPELL_WRONG_MONSTER, 'This spell cannot be cast on the selected monster.');
this.addIssue(UserIssueType.SPELL_WRONG_MONSTER, 'This spell cannot be cast on the selected monster.', 'fatal');
}

// Some set effects are currently not accounted for
Expand All @@ -601,5 +615,14 @@ export default class BaseCalc {
) {
this.addIssue(UserIssueType.EQUIPMENT_SET_EFFECT_UNSUPPORTED, 'The calculator currently does not account for your equipment set effect.');
}

if (this.wearing(['Toxic blowpipe', 'Blazing blowpipe'])) {
const severity = this.player.style.stance === 'Manual Cast' ? 'warn' : 'fatal';
if (eq.weapon?.version === 'Empty') {
this.addIssue(UserIssueType.EQUIPMENT_WEAPON_EMPTY, 'An empty weapon cannot be used.', severity);
} else if (eq.weapon?.bonuses?.ranged_str === EMPTY_BLOWPIPE?.bonuses?.ranged_str) {
this.addIssue(UserIssueType.IMPORT_MISSING_DATA, 'The import data did not specify darts for the blowpipe equipped', severity);
}
}
}
}
3 changes: 3 additions & 0 deletions src/lib/Equipment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ export type EquipmentBonuses = Pick<Player, 'bonuses' | 'offensive' | 'defensive
* All available equipment that a player can equip.
*/
export const availableEquipment = equipment as EquipmentPiece[];
export const EMPTY_BLOWPIPE = availableEquipment.find(
(e) => e.name === 'Toxic blowpipe' && e.version === 'Charged',
);

export const noStatExceptions = [
'Castle wars bracelet',
Expand Down
12 changes: 6 additions & 6 deletions src/lib/PlayerVsNPCCalc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -707,12 +707,8 @@ export default class PlayerVsNPCCalc extends BaseCalc {
* Get the max hit for this loadout, which is based on the player's current combat style
*/
private getMaxHit(): MinMax {
if (this.player.style.stance !== 'Manual Cast') {
const weaponId = this.player.equipment.weapon?.id;
const ammoId = this.player.equipment.ammo?.id;
if (ammoApplicability(weaponId, ammoId) === AmmoApplicability.INVALID) {
return [0, 0];
}
if (this.fatal) {
return [0, 0];
}

const style = this.player.style.type;
Expand Down Expand Up @@ -818,6 +814,10 @@ export default class PlayerVsNPCCalc extends BaseCalc {
}

private getDistributionImpl(): AttackDistribution {
if (this.fatal) {
return new AttackDistribution([new HitDistribution([new WeightedHit(1.0, [new Hitsplat(0, false)])])]);
}

const mattrs = this.monster.attributes;
const acc = this.getHitChance();
const [min, max] = this.getMaxHit();
Expand Down
1 change: 1 addition & 0 deletions src/types/State.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { DetailEntry } from '@/lib/CalcDetails';

export interface UserIssue {
type: UserIssueType;
severity: 'warn' | 'fatal';
message: string;
loadout?: string;
}
Expand Down

0 comments on commit 1cbb29c

Please sign in to comment.