From a9a5b8ab94821701aa95a023b5940112c7828bc8 Mon Sep 17 00:00:00 2001 From: Arthur Khokhlov Date: Sun, 10 May 2026 02:02:32 +0200 Subject: [PATCH 1/6] weapon boost functionality --- build/extract-packs.ts | 2 +- .../sf2e/equipment-effects/effect-boost.json | 47 +++++++++++++++++++ src/module/actor/character/auxiliary.ts | 20 +++++++- src/module/actor/character/helpers.ts | 17 +++++++ static/lang/action-en.json | 4 ++ 5 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 packs/sf2e/equipment-effects/effect-boost.json diff --git a/build/extract-packs.ts b/build/extract-packs.ts index ff3edede14e..7ce923f81ab 100644 --- a/build/extract-packs.ts +++ b/build/extract-packs.ts @@ -16,7 +16,7 @@ const args = argv describe: "The FVTT for which to extract packs", type: "string", choices: ["pf2e", "sf2e"], - default: "pf2e", + default: "sf2e", }) .option("disablePresort", { describe: "Turn off data item presorting", diff --git a/packs/sf2e/equipment-effects/effect-boost.json b/packs/sf2e/equipment-effects/effect-boost.json new file mode 100644 index 00000000000..23c241ed86b --- /dev/null +++ b/packs/sf2e/equipment-effects/effect-boost.json @@ -0,0 +1,47 @@ +{ + "_id": "YVm3rVSAYxoSrOvb", + "img": "systems/sf2e/icons/abilities/blue-battery.webp", + "name": "Effect: Boost", + "system": { + "description": { + "value": "

The weapon is currently boosted.

" + }, + "duration": { + "expiry": "turn-end", + "sustained": false, + "unit": "rounds", + "value": 1 + }, + "fromSpell": false, + "level": { + "value": 1 + }, + "publication": { + "license": "ORC", + "remaster": true, + "title": "Starfinder Player Core" + }, + "rules": [ + { + "critical": false, + "diceNumber": "@weapon.system.damage.dice", + "dieSize": "d10", + "key": "DamageDice", + "selector": [ + "strike-damage" + ] + } + ], + "start": { + "initiative": null, + "value": 0 + }, + "tokenIcon": { + "show": true + }, + "traits": { + "value": [] + } + }, + "type": "effect" +} diff --git a/src/module/actor/character/auxiliary.ts b/src/module/actor/character/auxiliary.ts index f06dde9b24c..582155e8a07 100644 --- a/src/module/actor/character/auxiliary.ts +++ b/src/module/actor/character/auxiliary.ts @@ -9,11 +9,12 @@ import { getActionGlyph, localizeList, sluggify } from "@util"; import { traitSlugToObject } from "@util/tags.ts"; import * as R from "remeda"; import { CharacterPF2e } from "./document.ts"; +import type { DamageDiceRuleElement } from "@module/rules/rule-element/damage-dice.ts"; interface AuxiliaryInteractParams { weapon: WeaponPF2e; action: "interact"; - annotation: "draw" | "grip" | "modular" | "pick-up" | "retrieve" | "sheathe"; + annotation: "draw" | "grip" | "modular" | "pick-up" | "retrieve" | "sheathe" | "boost"; hands?: ZeroToTwo; } @@ -85,6 +86,8 @@ class WeaponAuxiliaryAction { return [1, null, annotation]; case "drop": return [0, "dropped", annotation]; + case "boost": + return [1, null, annotation]; case "tower-shield": { const cost = this.action === "take-cover" ? 1 : 0; return [cost, null, null]; @@ -157,6 +160,21 @@ class WeaponAuxiliaryAction { selected: Number(selection), }); if (!updated) return; + } else if (this.annotation === "boost") { + const alreadyBoosted = actor.itemTypes.effect.some((e) => e.slug === "effect-boost"); + if (alreadyBoosted) return; + const effect = await fromUuid(`Compendium.${SYSTEM_ID}.equipment-effects.Item.YVm3rVSAYxoSrOvb`); + if (effect instanceof EffectPF2e) { + const data = { ...effect.toObject(), _id: null }; + data.flags[SYSTEM_ID] = { grantedBy: { id: weapon.id, onDelete: "cascade" } }; + data.system.description.value += `\n@UUID[Actor.${actor.id}.Item.${weapon.id}]{${weapon.name}}`; + const rule = data.system.rules.find((r) => r.key === "DamageDice") as DamageDiceRuleElement; + const boostTrait = weapon.system.traits.value.find((t) => t.startsWith("boost-")); + // The die size is encoded in the boost trait, e.g. "boost-1d8" + rule.dieSize = boostTrait?.substring(7) || null; + rule.selector = [`${weapon.id}-damage`]; + await actor.createEmbeddedDocuments("Item", [data]); + } } else if (this.action === "raise-a-shield") { // Apply Effect: Raise a Shield const alreadyRaised = actor.itemTypes.effect.some((e) => e.slug === "raise-a-shield"); diff --git a/src/module/actor/character/helpers.ts b/src/module/actor/character/helpers.ts index d02fffea22c..038b0cae9ff 100644 --- a/src/module/actor/character/helpers.ts +++ b/src/module/actor/character/helpers.ts @@ -247,6 +247,23 @@ function getWeaponAuxiliaryActions(weapon: WeaponPF2e): WeaponAux } } + if ( + traitsArray.includes("boost-1d4") || + traitsArray.includes("boost-1d6") || + traitsArray.includes("boost-1d8") || + traitsArray.includes("boost-1d10") || + traitsArray.includes("boost-1d12") + ) { + const isBoosted = actor.itemTypes.effect.some( + (e) => e.slug === "effect-boost" && e.flags.sf2e.grantedBy?.id === weapon.id, + ); + if (!isBoosted) { + auxiliaryActions.push( + new WeaponAuxiliaryAction({ weapon, action: "interact", annotation: "boost" }), + ); + } + } + if (weapon.handsHeld === 2) { auxiliaryActions.push( new WeaponAuxiliaryAction({ weapon, action: "release", annotation: "grip", hands: 1 }), diff --git a/static/lang/action-en.json b/static/lang/action-en.json index 966cef2f41b..b6dbfbf50f0 100644 --- a/static/lang/action-en.json +++ b/static/lang/action-en.json @@ -595,6 +595,10 @@ "Description": "{actor} sheathes their {weapon}.", "Title": "Sheathe" }, + "Boost": { + "Description": "{actor} boosts their {weapon}.", + "Title": "Boost" + }, "Title": "Interact" }, "Leap": { From 0bfe2d403599fcac0f526db2f0301c8319e23bc3 Mon Sep 17 00:00:00 2001 From: Arthur Khokhlov Date: Sun, 10 May 2026 02:08:32 +0200 Subject: [PATCH 2/6] cleaning --- build/extract-packs.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/extract-packs.ts b/build/extract-packs.ts index 7ce923f81ab..ff3edede14e 100644 --- a/build/extract-packs.ts +++ b/build/extract-packs.ts @@ -16,7 +16,7 @@ const args = argv describe: "The FVTT for which to extract packs", type: "string", choices: ["pf2e", "sf2e"], - default: "sf2e", + default: "pf2e", }) .option("disablePresort", { describe: "Turn off data item presorting", From 87853beac2b87a0f558fee2f1f44e06a3a66ff84 Mon Sep 17 00:00:00 2001 From: Arthur Khokhlov Date: Sun, 10 May 2026 14:12:50 +0200 Subject: [PATCH 3/6] refactoring --- build/duplicates.json | 3 ++- .../equipment-effects/effect-boost.json | 12 ++++-------- src/module/actor/character/auxiliary.ts | 15 +++++++++------ src/module/system/damage/weapon.ts | 18 ++++++++++++++++++ 4 files changed, 33 insertions(+), 15 deletions(-) rename packs/{sf2e => pf2e}/equipment-effects/effect-boost.json (72%) diff --git a/build/duplicates.json b/build/duplicates.json index 0eac7b09896..4cf88890fb9 100644 --- a/build/duplicates.json +++ b/build/duplicates.json @@ -210,7 +210,8 @@ ], "equipment-effects": [ "Effect: Parry", - "Effect: Raise a Shield" + "Effect: Raise a Shield", + "Effect: Boost" ], "feats": [ "Adapted Cantrip", diff --git a/packs/sf2e/equipment-effects/effect-boost.json b/packs/pf2e/equipment-effects/effect-boost.json similarity index 72% rename from packs/sf2e/equipment-effects/effect-boost.json rename to packs/pf2e/equipment-effects/effect-boost.json index 23c241ed86b..9441da48a03 100644 --- a/packs/sf2e/equipment-effects/effect-boost.json +++ b/packs/pf2e/equipment-effects/effect-boost.json @@ -1,6 +1,6 @@ { "_id": "YVm3rVSAYxoSrOvb", - "img": "systems/sf2e/icons/abilities/blue-battery.webp", + "img": "systems/pf2e/icons/abilities/blue-battery.webp", "name": "Effect: Boost", "system": { "description": { @@ -23,13 +23,9 @@ }, "rules": [ { - "critical": false, - "diceNumber": "@weapon.system.damage.dice", - "dieSize": "d10", - "key": "DamageDice", - "selector": [ - "strike-damage" - ] + "key": "RollOption", + "domain": "strike-damage", + "option": "item:weapon:boosted" } ], "start": { diff --git a/src/module/actor/character/auxiliary.ts b/src/module/actor/character/auxiliary.ts index 582155e8a07..e1ec4d1885b 100644 --- a/src/module/actor/character/auxiliary.ts +++ b/src/module/actor/character/auxiliary.ts @@ -9,7 +9,7 @@ import { getActionGlyph, localizeList, sluggify } from "@util"; import { traitSlugToObject } from "@util/tags.ts"; import * as R from "remeda"; import { CharacterPF2e } from "./document.ts"; -import type { DamageDiceRuleElement } from "@module/rules/rule-element/damage-dice.ts"; +import type { RollOptionRuleElement } from "@module/rules/rule-element/roll-option/rule-element.ts"; interface AuxiliaryInteractParams { weapon: WeaponPF2e; @@ -167,12 +167,15 @@ class WeaponAuxiliaryAction { if (effect instanceof EffectPF2e) { const data = { ...effect.toObject(), _id: null }; data.flags[SYSTEM_ID] = { grantedBy: { id: weapon.id, onDelete: "cascade" } }; + // Change rule to affect the specific weapon. + data.system.rules = [ + { + key: "RollOption", + domain: `${weapon.id}-damage`, + option: `item:${weapon.id}:boosted`, + } as RollOptionRuleElement, + ]; data.system.description.value += `\n@UUID[Actor.${actor.id}.Item.${weapon.id}]{${weapon.name}}`; - const rule = data.system.rules.find((r) => r.key === "DamageDice") as DamageDiceRuleElement; - const boostTrait = weapon.system.traits.value.find((t) => t.startsWith("boost-")); - // The die size is encoded in the boost trait, e.g. "boost-1d8" - rule.dieSize = boostTrait?.substring(7) || null; - rule.selector = [`${weapon.id}-damage`]; await actor.createEmbeddedDocuments("Item", [data]); } } else if (this.action === "raise-a-shield") { diff --git a/src/module/system/damage/weapon.ts b/src/module/system/damage/weapon.ts index 4392b63be58..b2c25fd9a40 100644 --- a/src/module/system/damage/weapon.ts +++ b/src/module/system/damage/weapon.ts @@ -359,6 +359,24 @@ class WeaponDamagePF2e { modifiers.push(modifier); } + // Boost trait, ignore invalid boost traits + for (const trait of weaponTraits.filter((t) => t.startsWith("boost-1d"))) { + if (!weapon.isOfType("weapon")) continue; + const dieSize = trait.substring(trait.indexOf("-") + 2) as DamageDieSize; + const isBoosted = options.has(`item:${weapon.id}:boosted`) || options.has("item:weapon:boosted"); + damageDice.push( + new DamageDicePF2e({ + selector: `${weapon.id}-damage`, + slug: trait, + label: traitLabels[trait], + diceNumber: weapon.system.damage.dice, + dieSize, + critical: false, + enabled: isBoosted, + }), + ); + } + // Add roll notes to the context const runeNotes = propertyRunes.flatMap((r) => { const data = RUNE_DATA.weapon.property[r].damage?.notes ?? []; From 888b78a075c61afdbb94e0e724b64148dbe55928 Mon Sep 17 00:00:00 2001 From: Arthur Khokhlov Date: Mon, 11 May 2026 00:10:01 +0200 Subject: [PATCH 4/6] updates --- src/module/actor/character/auxiliary.ts | 7 +++++-- src/module/actor/character/helpers.ts | 17 +++-------------- src/module/system/damage/weapon.ts | 19 ++++++++++++------- 3 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/module/actor/character/auxiliary.ts b/src/module/actor/character/auxiliary.ts index e1ec4d1885b..ba583f6c2e2 100644 --- a/src/module/actor/character/auxiliary.ts +++ b/src/module/actor/character/auxiliary.ts @@ -161,8 +161,11 @@ class WeaponAuxiliaryAction { }); if (!updated) return; } else if (this.annotation === "boost") { - const alreadyBoosted = actor.itemTypes.effect.some((e) => e.slug === "effect-boost"); - if (alreadyBoosted) return; + const isBoosted = actor.itemTypes.effect.some( + (e) => e.slug === "effect-boost" && e.flags.sf2e.grantedBy?.id === weapon.id, + ); + // No op if the weapon is already boosted + if (isBoosted) return; const effect = await fromUuid(`Compendium.${SYSTEM_ID}.equipment-effects.Item.YVm3rVSAYxoSrOvb`); if (effect instanceof EffectPF2e) { const data = { ...effect.toObject(), _id: null }; diff --git a/src/module/actor/character/helpers.ts b/src/module/actor/character/helpers.ts index 038b0cae9ff..c8d40ba7d49 100644 --- a/src/module/actor/character/helpers.ts +++ b/src/module/actor/character/helpers.ts @@ -247,21 +247,10 @@ function getWeaponAuxiliaryActions(weapon: WeaponPF2e): WeaponAux } } - if ( - traitsArray.includes("boost-1d4") || - traitsArray.includes("boost-1d6") || - traitsArray.includes("boost-1d8") || - traitsArray.includes("boost-1d10") || - traitsArray.includes("boost-1d12") - ) { - const isBoosted = actor.itemTypes.effect.some( - (e) => e.slug === "effect-boost" && e.flags.sf2e.grantedBy?.id === weapon.id, + if (weapon.system.traits.config.boost) { + auxiliaryActions.push( + new WeaponAuxiliaryAction({ weapon, action: "interact", annotation: "boost" }), ); - if (!isBoosted) { - auxiliaryActions.push( - new WeaponAuxiliaryAction({ weapon, action: "interact", annotation: "boost" }), - ); - } } if (weapon.handsHeld === 2) { diff --git a/src/module/system/damage/weapon.ts b/src/module/system/damage/weapon.ts index b2c25fd9a40..1a13abd16cd 100644 --- a/src/module/system/damage/weapon.ts +++ b/src/module/system/damage/weapon.ts @@ -359,17 +359,22 @@ class WeaponDamagePF2e { modifiers.push(modifier); } - // Boost trait, ignore invalid boost traits - for (const trait of weaponTraits.filter((t) => t.startsWith("boost-1d"))) { - if (!weapon.isOfType("weapon")) continue; - const dieSize = trait.substring(trait.indexOf("-") + 2) as DamageDieSize; + // Boost trait + if (weapon.system.traits.config.boost) { + const boostConfig = weapon.system.traits.config.boost; + const slug = `boost-${boostConfig}`; + + const dieSize = boostConfig.substring(boostConfig.indexOf("d")) as DamageDieSize; + const baseNumber = Number(/(\d)d\d{1,2}$/.exec(boostConfig)?.at(1)) || 1; + const diceNumber = strikingDice > 0 ? baseNumber + strikingDice : baseNumber; + const isBoosted = options.has(`item:${weapon.id}:boosted`) || options.has("item:weapon:boosted"); damageDice.push( new DamageDicePF2e({ selector: `${weapon.id}-damage`, - slug: trait, - label: traitLabels[trait], - diceNumber: weapon.system.damage.dice, + slug, + label: traitLabels[slug], + diceNumber: diceNumber, dieSize, critical: false, enabled: isBoosted, From d4664c83cf876f73d3dfc216c50648d7de393c51 Mon Sep 17 00:00:00 2001 From: Arthur Khokhlov Date: Tue, 12 May 2026 22:42:39 +0200 Subject: [PATCH 5/6] updates --- .../pf2e/equipment-effects/effect-boost.json | 41 +++++++++++++++++-- src/module/actor/character/auxiliary.ts | 10 +---- src/module/system/damage/weapon.ts | 2 +- src/scripts/config/traits.ts | 4 +- 4 files changed, 42 insertions(+), 15 deletions(-) diff --git a/packs/pf2e/equipment-effects/effect-boost.json b/packs/pf2e/equipment-effects/effect-boost.json index 9441da48a03..0efdeed71ce 100644 --- a/packs/pf2e/equipment-effects/effect-boost.json +++ b/packs/pf2e/equipment-effects/effect-boost.json @@ -23,9 +23,44 @@ }, "rules": [ { - "key": "RollOption", - "domain": "strike-damage", - "option": "item:weapon:boosted" + "choices": { + "ownedItems": true, + "predicate": [ + { + "or": [ + { + "and": [ + "self:type:npc", + "item:type:melee" + ] + }, + { + "and": [ + "self:type:character", + "item:type:weapon" + ] + } + ] + }, + "item:trait:boost" + ], + "types": [ + "melee", + "weapon" + ] + }, + "flag": "weapon", + "rollOption": "item:boosted", + "key": "ChoiceSet", + "prompt": "PF2E.SpecificRule.Prompt.Weapon", + "predicate": [ + { + "or": [ + "self:type:npc", + "self:type:character" + ] + } + ] } ], "start": { diff --git a/src/module/actor/character/auxiliary.ts b/src/module/actor/character/auxiliary.ts index ba583f6c2e2..39825eada7b 100644 --- a/src/module/actor/character/auxiliary.ts +++ b/src/module/actor/character/auxiliary.ts @@ -9,7 +9,7 @@ import { getActionGlyph, localizeList, sluggify } from "@util"; import { traitSlugToObject } from "@util/tags.ts"; import * as R from "remeda"; import { CharacterPF2e } from "./document.ts"; -import type { RollOptionRuleElement } from "@module/rules/rule-element/roll-option/rule-element.ts"; +import { ChoiceSetSource } from "@module/rules/rule-element/choice-set/data.ts"; interface AuxiliaryInteractParams { weapon: WeaponPF2e; @@ -171,13 +171,7 @@ class WeaponAuxiliaryAction { const data = { ...effect.toObject(), _id: null }; data.flags[SYSTEM_ID] = { grantedBy: { id: weapon.id, onDelete: "cascade" } }; // Change rule to affect the specific weapon. - data.system.rules = [ - { - key: "RollOption", - domain: `${weapon.id}-damage`, - option: `item:${weapon.id}:boosted`, - } as RollOptionRuleElement, - ]; + (data.system.rules[0] as ChoiceSetSource).selection = weapon.id; data.system.description.value += `\n@UUID[Actor.${actor.id}.Item.${weapon.id}]{${weapon.name}}`; await actor.createEmbeddedDocuments("Item", [data]); } diff --git a/src/module/system/damage/weapon.ts b/src/module/system/damage/weapon.ts index 1a13abd16cd..d8c7c468349 100644 --- a/src/module/system/damage/weapon.ts +++ b/src/module/system/damage/weapon.ts @@ -368,7 +368,7 @@ class WeaponDamagePF2e { const baseNumber = Number(/(\d)d\d{1,2}$/.exec(boostConfig)?.at(1)) || 1; const diceNumber = strikingDice > 0 ? baseNumber + strikingDice : baseNumber; - const isBoosted = options.has(`item:${weapon.id}:boosted`) || options.has("item:weapon:boosted"); + const isBoosted = options.has(`item:boosted:${weapon.id}`); damageDice.push( new DamageDicePF2e({ selector: `${weapon.id}-damage`, diff --git a/src/scripts/config/traits.ts b/src/scripts/config/traits.ts index 8ee5cdf74cc..a31be91dd31 100644 --- a/src/scripts/config/traits.ts +++ b/src/scripts/config/traits.ts @@ -492,13 +492,11 @@ const weaponTraits = { backstabber: "PF2E.TraitBackstabber", backswing: "PF2E.TraitBackswing", bomb: "PF2E.TraitBomb", - "boost-1": "PF2E.TraitBoost1", "boost-1d10": "PF2E.TraitBoost1d10", "boost-1d12": "PF2E.TraitBoost1d12", "boost-1d4": "PF2E.TraitBoost1d4", "boost-1d6": "PF2E.TraitBoost1d6", "boost-1d8": "PF2E.TraitBoost1d8", - "boost-2d10": "PF2E.TraitBoost2d10", brace: "PF2E.TraitBrace", breakdown: "PF2E.TraitBreakdown", brutal: "PF2E.TraitBrutal", @@ -703,6 +701,7 @@ const npcAttackTraits = { ...weaponTraits, ...preciousMaterials, area: "PF2E.TraitArea", + "boost-2d10": "PF2E.TraitBoost2d10", concentrate: "PF2E.TraitConcentrate", curse: "PF2E.TraitCurse", "deadly-2d4": "PF2E.TraitDeadly2D4", @@ -1347,7 +1346,6 @@ const traitDescriptions = { blight: "PF2E.TraitDescriptionBlight", boggard: "PF2E.TraitDescriptionBoggard", bomb: "PF2E.TraitDescriptionBomb", - "boost-1": "PF2E.TraitDescriptionBoost", "boost-1d4": "PF2E.TraitDescriptionBoost", "boost-1d6": "PF2E.TraitDescriptionBoost", "boost-1d8": "PF2E.TraitDescriptionBoost", From eb33729bfcc3520621d0165b0d57c5068e177577 Mon Sep 17 00:00:00 2001 From: Arthur Khokhlov Date: Tue, 12 May 2026 23:26:32 +0200 Subject: [PATCH 6/6] fixes --- .../pf2e/equipment-effects/effect-boost.json | 28 +++++++++---------- src/module/actor/character/auxiliary.ts | 2 +- src/module/system/damage/weapon.ts | 3 +- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/packs/pf2e/equipment-effects/effect-boost.json b/packs/pf2e/equipment-effects/effect-boost.json index 0efdeed71ce..c2c3a233421 100644 --- a/packs/pf2e/equipment-effects/effect-boost.json +++ b/packs/pf2e/equipment-effects/effect-boost.json @@ -26,23 +26,23 @@ "choices": { "ownedItems": true, "predicate": [ - { - "or": [ { - "and": [ - "self:type:npc", - "item:type:melee" + "or": [ + { + "and": [ + "self:type:npc", + "item:type:melee" + ] + }, + { + "and": [ + "self:type:character", + "item:type:weapon" + ] + } ] }, - { - "and": [ - "self:type:character", - "item:type:weapon" - ] - } - ] - }, - "item:trait:boost" + "item:trait:boost" ], "types": [ "melee", diff --git a/src/module/actor/character/auxiliary.ts b/src/module/actor/character/auxiliary.ts index 39825eada7b..793bd89242f 100644 --- a/src/module/actor/character/auxiliary.ts +++ b/src/module/actor/character/auxiliary.ts @@ -162,7 +162,7 @@ class WeaponAuxiliaryAction { if (!updated) return; } else if (this.annotation === "boost") { const isBoosted = actor.itemTypes.effect.some( - (e) => e.slug === "effect-boost" && e.flags.sf2e.grantedBy?.id === weapon.id, + (e) => e.slug === "effect-boost" && e.flags[SYSTEM_ID].grantedBy?.id === weapon.id, ); // No op if the weapon is already boosted if (isBoosted) return; diff --git a/src/module/system/damage/weapon.ts b/src/module/system/damage/weapon.ts index d8c7c468349..6b8d92492b5 100644 --- a/src/module/system/damage/weapon.ts +++ b/src/module/system/damage/weapon.ts @@ -368,7 +368,6 @@ class WeaponDamagePF2e { const baseNumber = Number(/(\d)d\d{1,2}$/.exec(boostConfig)?.at(1)) || 1; const diceNumber = strikingDice > 0 ? baseNumber + strikingDice : baseNumber; - const isBoosted = options.has(`item:boosted:${weapon.id}`); damageDice.push( new DamageDicePF2e({ selector: `${weapon.id}-damage`, @@ -377,7 +376,7 @@ class WeaponDamagePF2e { diceNumber: diceNumber, dieSize, critical: false, - enabled: isBoosted, + enabled: options.has(`item:boosted:${weapon.id}`), }), ); }