diff --git a/README.md b/README.md index ad693f4..63b22a7 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,8 @@ All options are supported in all tabs, unless specified. They are white space se * `keepN` * Keeps `N` copies of the item after running +* `stockN` + * (only supported by `mall`, `display`, and `closet`). Ensures `N` copies of the item are stocked in the relevant locations, keeps the rest in your inventory * `N` diff --git a/src/actions.ts b/src/actions.ts index b804ba0..48ac2a0 100644 --- a/src/actions.ts +++ b/src/actions.ts @@ -2,6 +2,8 @@ import { autosell, autosellPrice, cliExecute, + closetAmount, + displayAmount, Item, itemAmount, mallPrice, @@ -9,6 +11,7 @@ import { putCloset, putDisplay, putShop, + shopAmount, use, wellStocked, } from "kolmafia"; @@ -41,6 +44,17 @@ export const actions: { }; } = { mall: (options: Options) => { + if (options.stock) { + return { + action: (item: Item) => + putShop( + 0, + 0, + Math.min(Math.max(0, (options.stock ?? 0) - shopAmount(item)), amount(item, options)), + item + ), + }; + } return { action: (item: Item) => putShop(0, 0, amount(item, options), item) }; }, sell: (options: Options) => { @@ -58,6 +72,18 @@ export const actions: { }; }, display: (options: Options) => { + if (options.stock) { + return { + action: (item: Item) => + putDisplay( + Math.min( + Math.max(0, (options.stock ?? 0) - displayAmount(item)), + amount(item, options) + ), + item + ), + }; + } return { action: (item: Item) => putDisplay(amount(item, options), item) }; }, use: (options: Options) => { @@ -82,6 +108,15 @@ export const actions: { }; }, closet: (options: Options) => { + if (options.stock) { + return { + action: (item: Item) => + putDisplay( + Math.min(Math.max(0, (options.stock ?? 0) - closetAmount(item)), amount(item, options)), + item + ), + }; + } return { action: (item: Item) => putCloset(amount(item, options), item), }; diff --git a/src/options.ts b/src/options.ts index 6d4aa51..17600eb 100644 --- a/src/options.ts +++ b/src/options.ts @@ -2,6 +2,7 @@ import { Item } from "kolmafia"; export class Options { keep?: number; + stock?: number; target?: string; body?: string; priceUpperThreshold?: number; @@ -18,6 +19,11 @@ export class Options { options.keep = parseInt(keep[1]); continue; } + const stock = optionStr.match(/stock(\d+)/); + if (stock && stock[1]) { + options.stock = parseInt(stock[1]); + continue; + } const target = optionStr.match(/#(.*)/); if (target && target[1]) { options.target = target[1]; @@ -50,6 +56,9 @@ export class Options { if (this.keep) { optionsStr.push(`keep: ${this.keep}`); } + if (this.stock) { + optionsStr.push(`stock: ${this.stock}`); + } if (this.target) { optionsStr.push(`target: ${this.target}`); } diff --git a/src/types.ts b/src/types.ts index 91a4381..af4e1f2 100644 --- a/src/types.ts +++ b/src/types.ts @@ -18,7 +18,7 @@ export function isTabTitle(value: string): value is TabTitle { return ALL_TAB_TITLES.includes(value as TabTitle); } -const ALL_ACTION_OPTIONS = ["keep", "target"] as const; +const ALL_ACTION_OPTIONS = ["keep", "stock", "target"] as const; export type ActionOption = typeof ALL_ACTION_OPTIONS[number]; export function isActionOption(value: string): value is ActionOption {