Skip to content

Commit

Permalink
Merge pull request #8914 from robojumper/breakermod-artifact-breakers
Browse files Browse the repository at this point in the history
Add breakermod to match weapons with seasonal artifact breaker mods
  • Loading branch information
bhollis authored Sep 3, 2024
2 parents 755bc1a + 94401d9 commit 549be33
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 14 deletions.
1 change: 1 addition & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[submodule "destiny-icons"]
path = destiny-icons
url = https://github.com/justrealmilk/destiny-icons
branch = master
2 changes: 1 addition & 1 deletion destiny-icons
2 changes: 2 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## Next

* `breaker:` searches now match items that can have that breaker type granted by this season's artifact (whether or not the correct artifact mods are enabled). The effective breaker type from artifact mods also now shows up on item tiles and in the Armory.

## 8.35.1 <span class="changelog-date">(2024-09-01)</span>

* Fix the "track record" button not appearing on hover.
Expand Down
14 changes: 10 additions & 4 deletions src/app/armory/Armory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { Reward } from 'app/progress/Reward';
import { AppIcon, compareIcon } from 'app/shell/icons';
import { useIsPhonePortrait } from 'app/shell/selectors';
import { useThunkDispatch } from 'app/store/thunk-dispatch';
import { getItemYear } from 'app/utils/item-utils';
import { getBreakerTypeHash, getItemYear } from 'app/utils/item-utils';
import clsx from 'clsx';
import { D2EventInfo } from 'data/d2/d2-event-info-v2';
import { ItemCategoryHashes } from 'data/d2/generated-enums';
Expand Down Expand Up @@ -91,6 +91,14 @@ export default function Armory({
const screenshot = ornamentSocket?.plugged?.plugDef.screenshot || itemDef.screenshot;
const flavorText = itemDef.flavorText || itemDef.displaySource;

let breakerType = item.breakerType;
if (!breakerType) {
const breakerTypeHash = getBreakerTypeHash(item);
if (breakerTypeHash) {
breakerType = defs.BreakerType.get(breakerTypeHash);
}
}

// TODO: Show Catalyst benefits for exotics

return (
Expand All @@ -115,9 +123,7 @@ export default function Armory({
<div className={styles.headerContent}>
<div className={styles.subtitle}>
<ElementIcon element={item.element} className={styles.element} />
{item.breakerType && (
<BungieImage src={item.breakerType.displayProperties.icon} height={15} />
)}
{breakerType && <BungieImage src={breakerType.displayProperties.icon} height={15} />}
{item.destinyVersion === 2 && item.ammoType > 0 && <AmmoIcon type={item.ammoType} />}
<ItemTypeName item={item} />
{item.pursuit?.questLine && (
Expand Down
3 changes: 2 additions & 1 deletion src/app/item-popup/ItemPopupHeader.m.scss
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@

.legendary {
background-color: $legendary;
.primary {
.primary,
.breakerIcon {
opacity: 0.8;
}
}
Expand Down
19 changes: 13 additions & 6 deletions src/app/item-popup/ItemPopupHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import ElementIcon from 'app/dim-ui/ElementIcon';
import RichDestinyText from 'app/dim-ui/destiny-symbols/RichDestinyText';
import { useHotkey } from 'app/hotkeys/useHotkey';
import { t } from 'app/i18next-t';
import { useD2Definitions } from 'app/manifest/selectors';
import { D1BucketHashes } from 'app/search/d1-known-values';
import type { ItemTierName } from 'app/search/d2-known-values';
import { getBreakerTypeHash } from 'app/utils/item-utils';
import { LookupTable } from 'app/utils/util-types';
import { DestinyAmmunitionType, DestinyClass } from 'bungie-api-ts/destiny2';
import clsx from 'clsx';
Expand Down Expand Up @@ -33,13 +35,22 @@ export default function ItemPopupHeader({
/** Don't allow opening Armory from the header link */
noLink?: boolean;
}) {
const defs = useD2Definitions()!;
const [showArmory, setShowArmory] = useState(false);
useHotkey('a', t('Hotkey.Armory'), () => setShowArmory(true));

const showElementIcon = Boolean(item.element);

const linkToArmory = !noLink && item.destinyVersion === 2;

let breakerType = item.breakerType;
if (!breakerType) {
const breakerTypeHash = getBreakerTypeHash(item);
if (breakerTypeHash) {
breakerType = defs.BreakerType.get(breakerTypeHash);
}
}

return (
<button
type="button"
Expand All @@ -60,16 +71,12 @@ export default function ItemPopupHeader({
<RichDestinyText text={item.name} ownerId={item.owner} />
</h1>
)}

<div className={styles.subtitle}>
<div className={styles.type}>
<ItemTypeName item={item} className={styles.itemType} />
{item.destinyVersion === 2 && item.ammoType > 0 && <AmmoIcon type={item.ammoType} />}
{item.breakerType && (
<BungieImage
className={styles.breakerIcon}
src={item.breakerType.displayProperties.icon}
/>
{breakerType && (
<BungieImage className={styles.breakerIcon} src={breakerType.displayProperties.icon} />
)}
</div>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
declare module 'data/d2/artifact-breaker-weapon-types.json' {
const x: Record<
import('data/d2/generated-enums').BreakerTypeHashes,
import('data/d2/generated-enums').ItemCategoryHashes[]
>;
export default x;
}
7 changes: 6 additions & 1 deletion src/app/search/items/search-filters/known-values.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
DestinyClass,
DestinyRecordState,
} from 'bungie-api-ts/destiny2';
import artifactBreakerMods from 'data/d2/artifact-breaker-weapon-types.json';
import { D2EventEnum, D2EventInfo } from 'data/d2/d2-event-info-v2';
import focusingOutputs from 'data/d2/focusing-item-outputs.json';
import { BreakerTypeHashes, ItemCategoryHashes } from 'data/d2/generated-enums';
Expand Down Expand Up @@ -225,7 +226,11 @@ const knownValuesFilters: ItemFilterDefinition[] = [
if (!breakerType) {
throw new Error(`Unknown breaker type ${filterValue}`);
}
return (item) => breakerType.includes(item.breakerType?.hash as BreakerTypeHashes);
const breakingIchs = breakerType.flatMap((ty) => artifactBreakerMods[ty] || []);
return (item) =>
item.breakerType
? breakerType.includes(item.breakerType?.hash as BreakerTypeHashes)
: item.itemCategoryHashes.some((ich) => breakingIchs.includes(ich));
},
},
{
Expand Down
37 changes: 36 additions & 1 deletion src/app/utils/item-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,16 @@ import modSocketMetadata, {
} from 'app/search/specialty-modslots';
import { DamageType, DestinyClass, DestinyInventoryItemDefinition } from 'bungie-api-ts/destiny2';
import adeptWeaponHashes from 'data/d2/adept-weapon-hashes.json';
import artifactBreakerMods from 'data/d2/artifact-breaker-weapon-types.json';
import enhancedIntrinsics from 'data/d2/crafting-enhanced-intrinsics';
import { BucketHashes, PlugCategoryHashes, StatHashes, TraitHashes } from 'data/d2/generated-enums';
import {
BreakerTypeHashes,
BucketHashes,
ItemCategoryHashes,
PlugCategoryHashes,
StatHashes,
TraitHashes,
} from 'data/d2/generated-enums';
import masterworksWithCondStats from 'data/d2/masterworks-with-cond-stats.json';
import _ from 'lodash';
import { filterMap, objectifyArray } from './collections';
Expand Down Expand Up @@ -407,3 +415,30 @@ export function isShiny(item: DimItem) {
s.plugOptions.some((s) => s.plugDef.plug.plugCategoryIdentifier === 'holofoil_skins_shared'), //
);
}

const ichToBreakerType = Object.entries(artifactBreakerMods).reduce<
Partial<Record<ItemCategoryHashes, BreakerTypeHashes>>
>((memo, [breakerType, iches]) => {
const breakerTypeNum = parseInt(breakerType, 10);
for (const ich of iches) {
memo[ich] = breakerTypeNum;
}
return memo;
}, {});

/**
* Get the effective breaker type of a weapon, which is either its intrinsic
* breaker type (for some exotics) or one of the breaker types enabled by this
* season's artifact mods.
*/
export function getBreakerTypeHash(item: DimItem): number | undefined {
if (item.breakerType) {
return item.breakerType.hash;
} else if (item.bucket.inWeapons) {
for (const ich of item.itemCategoryHashes) {
if (ichToBreakerType[ich as ItemCategoryHashes]) {
return ichToBreakerType[ich as ItemCategoryHashes];
}
}
}
}

0 comments on commit 549be33

Please sign in to comment.