Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

blowpipe dart as item var #405

Merged
merged 2 commits into from
Jul 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion src/app/components/player/equipment/EquipmentGridSlot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { observer } from 'mobx-react-lite';
import { useStore } from '@/state';
import { getCdnImage } from '@/utils';
import UserIssueWarning from '@/app/components/generic/UserIssueWarning';
import { BLOWPIPE_IDS } from '@/lib/constants';

interface EquipmentGridSlotProps {
slot: keyof PlayerEquipment;
Expand All @@ -19,6 +20,17 @@ const EquipmentGridSlot: React.FC<EquipmentGridSlotProps> = observer((props) =>
// Determine whether there's any issues with this element
const issues = store.userIssues.filter((i) => i.type.startsWith(`equipment_slot_${slot}`) && i.loadout === `${store.selectedLoadout + 1}`);

const getTooltipContent = () => {
if (currentSlot !== null) {
// Special handling for blowpipes
if (BLOWPIPE_IDS.includes(currentSlot.id)) {
return `${currentSlot.name} (${currentSlot.itemVars?.blowpipeDartName?.replace(' dart', '') || 'Unknown dart'})`;
}
}

return currentSlot?.name;
};

return (
<div className="h-[40px] w-[40px] relative">
{
Expand All @@ -31,7 +43,7 @@ const EquipmentGridSlot: React.FC<EquipmentGridSlotProps> = observer((props) =>
className={`flex justify-center items-center h-[40px] w-[40px] bg-body-100 dark:bg-dark-400 dark:border-dark-400 border border-body-300 transition-colors rounded ${!isEmpty ? 'cursor-pointer hover:border-red' : ''}`}
data-slot={slot}
data-tooltip-id="tooltip"
data-tooltip-content={currentSlot?.name}
data-tooltip-content={getTooltipContent()}
onMouseDown={() => {
if (!isEmpty) store.clearEquipmentSlot(slot);
}}
Expand Down
57 changes: 28 additions & 29 deletions src/app/components/player/equipment/EquipmentSelect.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React, { useMemo } from 'react';
import { useStore } from '@/state';
import { observer } from 'mobx-react-lite';
import { getCdnImage } from '@/utils';
import { getCdnImage, isDefined } from '@/utils';
import { EquipmentPiece } from '@/types/Player';
import LazyImage from '@/app/components/generic/LazyImage';
import { cross } from 'd3-array';
import { availableEquipment, equipmentAliases, noStatExceptions } from '@/lib/Equipment';
import { BLOWPIPE_IDS } from '@/lib/constants';
import Combobox from '../../generic/Combobox';

interface EquipmentOption {
Expand All @@ -16,29 +17,30 @@ interface EquipmentOption {
equipment: EquipmentPiece;
}

const BLOWPIPE_IDS: string[] = [
'12926', // regular
'28688', // blazing
];

const DART_IDS: string[] = [
'806', // bronze
'807', // iron
'808', // steel
'809', // mithril
'810', // adamant
'811', // rune
'3093', // black
'11230', // dragon
'25849', // amethyst
];
const findDart = (name: string): EquipmentPiece | undefined => {
const eq = availableEquipment.find((e) => e.name === name);
if (!eq) {
console.warn(`Failed to locate dart [${name}] for blowpipe dart entry generation, proceeding without this option.`);
}
return eq;
};
const DARTS: EquipmentPiece[] = [
findDart('Bronze dart'),
findDart('Iron dart'),
findDart('Steel dart'),
findDart('Mithril dart'),
findDart('Adamant dart'),
findDart('Rune dart'),
findDart('Black dart'),
findDart('Dragon dart'),
findDart('Amethyst dart'),
].filter(isDefined);

const EquipmentSelect: React.FC = observer(() => {
const store = useStore();

const options: EquipmentOption[] = useMemo(() => {
const blowpipeEntries: EquipmentOption[] = [];
const dartEntries: EquipmentOption[] = [];

const entries: EquipmentOption[] = [];
for (const v of availableEquipment.filter((eq) => {
Expand Down Expand Up @@ -67,27 +69,24 @@ const EquipmentSelect: React.FC = observer(() => {
equipment: v,
};

if (BLOWPIPE_IDS.includes(e.value)) {
if (BLOWPIPE_IDS.includes(v.id)) {
blowpipeEntries.push(e);
} else if (DART_IDS.includes(e.value)) {
dartEntries.push(e);
entries.push(e);
} else {
entries.push(e);
}
}

cross(blowpipeEntries, dartEntries).forEach(([blowpipe, dart]) => {
const newStrength = blowpipe.equipment.bonuses.ranged_str + dart.equipment.bonuses.ranged_str;
cross(blowpipeEntries, DARTS).forEach(([blowpipe, dart]) => {
entries.push({
...blowpipe,
label: `${blowpipe.label} (${dart.label.split(' ', 2)[0]})`,
value: `${blowpipe.value}_${dart.value}`,
label: `${blowpipe.label} (${dart.name.replace(' dart', '')})`,
value: `${blowpipe.value}_${dart.id}`,
equipment: {
...blowpipe.equipment,
bonuses: {
...blowpipe.equipment.bonuses,
ranged_str: newStrength,
itemVars: {
...blowpipe.equipment.itemVars,
blowpipeDartName: dart.name,
blowpipeDartId: dart.id,
},
},
});
Expand Down
11 changes: 10 additions & 1 deletion src/lib/Equipment.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { EquipmentPiece, Player, PlayerEquipment } from '@/types/Player';
import { Monster } from '@/types/Monster';
import { keys } from '@/utils';
import { CAST_STANCES, TOMBS_OF_AMASCUT_MONSTER_IDS } from '@/lib/constants';
import { BLOWPIPE_IDS, CAST_STANCES, TOMBS_OF_AMASCUT_MONSTER_IDS } from '@/lib/constants';
import { sum } from 'd3-array';
import equipment from '../../cdn/json/equipment.json';
import generatedEquipmentAliases from './EquipmentAliases';
Expand Down Expand Up @@ -278,6 +278,15 @@ export const calculateEquipmentBonusesFromGear = (player: Player, monster: Monst
});
});

if (BLOWPIPE_IDS.includes(playerEquipment.weapon?.id || 0)) {
const dart = availableEquipment.find((e) => e.id === playerEquipment.weapon?.itemVars?.blowpipeDartId);
if (dart) {
totals.bonuses.ranged_str += dart.bonuses.ranged_str;
} else {
// todo warn user
}
}

if (playerEquipment.weapon?.name === "Tumeken's shadow" && player.style.stance !== 'Manual Cast') {
const factor = TOMBS_OF_AMASCUT_MONSTER_IDS.includes(monster.id) ? 4 : 3;
totals.bonuses.magic_str *= factor;
Expand Down
5 changes: 5 additions & 0 deletions src/lib/constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { CombatStyleStance } from '@/types/PlayerCombatStyle';

export const BLOWPIPE_IDS: number[] = [
12926, // regular
28688, // blazing
];

export const AKKHA_IDS = [
11789, 11790, 11791, 11792, 11793, 11794, 11795, 11796,
];
Expand Down
9 changes: 8 additions & 1 deletion src/state.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,14 @@ export const parseLoadoutsFromImportedData = (data: ImportableData) => data.load
let item: EquipmentPiece | undefined;
if (Object.hasOwn(v, 'id')) {
item = availableEquipment.find((eq) => eq.id === v.id);
if (!item) console.warn(`[parseLoadoutsFromImportedData] No item found for item ID ${v.id}`);
if (item) {
// include the hidden itemVars inputs that are not present on the availableEquipment store
if (Object.hasOwn(v, 'itemVars')) {
item = { ...item, itemVars: v.itemVars };
}
} else {
console.warn(`[parseLoadoutsFromImportedData] No item found for item ID ${v.id}`);
}
}
// The following line will remove the item entirely if it seems to no longer exist.
loadout.equipment[k as keyof typeof loadout.equipment] = item || null;
Expand Down
4 changes: 4 additions & 0 deletions src/types/Player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ export interface EquipmentPiece extends EquipmentStats {
speed: number;
category: EquipmentCategory;
isTwoHanded: boolean;
itemVars?: {
blowpipeDartName?: string;
blowpipeDartId?: number;
};
}

/**
Expand Down
5 changes: 5 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ export const generateShortlink = async (data: ImportableData): Promise<string> =
return res.data.data;
};

// for type narrowing
export function isDefined<T>(id: T | undefined | null): id is T {
return !!id;
}

/**
* Calculates a player's combat level using their skills
* @param s
Expand Down
Loading