diff --git a/docs/api/components.md b/docs/api/components.md
index 5c81bcbd..1f70b787 100644
--- a/docs/api/components.md
+++ b/docs/api/components.md
@@ -307,3 +307,250 @@ interface SalvageOptionValue {
```
+
+## Examples
+
+The examples below illustrate how to use the component API to create, modify and delete components.
+
+### Creating a component
+
+Once you've [created a crafting system](../systems#create-a-crafting-system) and an item, you can create a component for that item by calling `game.fabricate.api.components.create()`, passing in the component details.
+To create a component, you must provide the ID of the crafting system that the component belongs to and the UUID of the item that the component is associated with.
+If you've [created essences for the crafting system](../essences#create-an-essence), you can also provide a dictionary of essences and their quantities.
+If you've created other components for the crafting system already, you can also provide an array of salvage options for the component.
+Don't worry though; you can always [add essences to the component later](#adding-essences-to-a-component) and [add salvage options to the component later](#adding-salvage-options-to-a-component).
+
+
+
+Example #1 - A component with no essences and no salvage options
+
+
+```typescript
+const myComponentData = {
+ itemUuid: "my-item-uuid", // <-- Replace this with the UUID of your item
+ craftingSystemId: "my-crafting-system-id", // <-- Replace this with the ID of your crafting system
+};
+const component = await game.fabricate.api.components.create(myComponentData);
+```
+
+
+
+
+
+Example #2 - A component with essences and no salvage options
+
+
+```typescript
+const myComponentData = {
+ itemUuid: "my-item-uuid", // <-- Replace this with the UUID of your item
+ craftingSystemId: "my-crafting-system-id", // <-- Replace this with the ID of your crafting system
+ essences: { // <-- Replace the keys with the ID of your desired essences and the values with the quantity of each essence
+ "my-essence-id": 1,
+ "my-other-essence-id": 2
+ }
+};
+const component = await game.fabricate.api.components.create(myComponentData);
+```
+
+
+
+
+
+Example #3 - A component with essences and salvage options
+
+
+```typescript
+const myComponentData = {
+ itemUuid: "my-item-uuid", // <-- Replace this with the UUID of your item
+ craftingSystemId: "my-crafting-system-id", // <-- Replace this with the ID of your crafting system
+ essences: { // <-- Replace the keys with the ID of your desired essences and the values with the quantity of each essence
+ "my-essence-id": 1,
+ "my-other-essence-id": 2
+ },
+ // If a component has mutliple salvage options the names are displayed to the user in the UI
+ // The user can choose which option to use when salvaging the component.
+ // Catalysts are optional. If a component has catalysts, the user must have them in their inventory, but they are not consumed when the component is salvaged.
+ salvageOptions: [
+ {
+ name: "Salvage option 1", // <-- Replace this with the name you want to use for the salvage option
+ results: { // <-- Replace the keys with the IDs of the components you want to produce when the component is salvaged and the values with the quantity to produce
+ "my-salvage-id": 1
+ },
+ catalysts: {} // <-- This salvage option has no catalysts. You can also just leave this property out entirely
+ },
+ {
+ name: "Salvage option 2", // <-- Same here with naming your salvage options
+ results: { // <-- Same here with the salvage results
+ "my-salvage-id": 2
+ },
+ catalysts: { // <-- Replace the keys with the IDs of the components you want to use as catalysts and the values with the quantity of each catalyst
+ "my-catalyst-id": 2
+ }
+ }
+ ]
+};
+const component = await game.fabricate.api.components.create(myComponentData);
+```
+
+
+
+### Getting a component by ID
+
+You can retrieve a component by calling `game.fabricate.api.components.getById()`, passing in the ID of the component to retrieve.
+
+
+
+Example
+
+
+```typescript
+const myComponentId = "my-component-id"; // <-- Replace this with the ID of your component
+const component = await game.fabricate.api.components.getById(myComponentId);
+```
+
+
+
+### Getting all components
+
+You can retrieve all components in all crafting systems by calling `game.fabricate.api.components.getAll()`.
+
+
+
+Example
+
+
+```typescript
+const components = await game.fabricate.api.components.getAll();
+```
+
+
+
+### Getting all components in a crafting system
+
+You can retrieve all components in a crafting system by calling `game.fabricate.api.components.getAllByCraftingSystemId()`, passing in the ID of the crafting system to retrieve components for.
+
+
+
+Example
+
+
+```typescript
+const myCraftingSystemId = "my-crafting-system-id"; // <-- Replace this with the ID of your crafting system
+const components = await game.fabricate.api.components.getAllByCraftingSystemId(myCraftingSystemId);
+```
+
+
+
+### Getting all components for an item
+
+You can retrieve all components for an item by calling `game.fabricate.api.components.getAllByItemUuid()`, passing in the UUID of the item to retrieve components for.
+
+
+
+Example
+
+
+```typescript
+const myItemUuid = "my-item-uuid"; // <-- Replace this with the UUID of your item
+const components = await game.fabricate.api.components.getAllByItemUuid(myItemUuid);
+```
+
+
+
+### Adding essences to a component
+
+You can add essences to a component by fetching it, setting the essences then calling `game.fabricate.api.components.save()`, passing in the modified component.
+You'll need to [create the essences](../essences#create-an-essence) before you can add them to a component.
+
+
+
+Example
+
+
+```typescript
+const myComponentId = "my-component-id"; // <-- Replace this with the ID of your component
+const component = await game.fabricate.api.components.getById(myComponentId);
+componentOne.addEssence("my-fisrt-essence-id"); // <-- Replace this with the ID of your essence. The quantity isoptional (it defaults to 1)
+componentOne.addEssence("my-second-essence-id", 2); // <-- Replace the first argument with the ID of your essence and the second with the quantity to add
+const componentAfterSave = await game.fabricate.api.components.save(component);
+```
+
+
+
+### Removing essences from a component
+
+You can remove essences from a component by fetching it, removing the essences then calling `game.fabricate.api.components.save()`, passing in the modified component.
+
+
+
+Example
+
+
+```typescript
+const myComponentId = "my-component-id"; // <-- Replace this with the ID of your component
+const component = await game.fabricate.api.components.getById(myComponentId);
+// Removes an essence from the component if it exists, regardless of quantity
+component.removeEssence("my-fisrt-essence-id"); // <-- Replace this with the ID of your essence
+// Removes a specific quantity of an essence from the component if it exists
+component.subtractEssence("my-second-essence-id"); // <-- Replace the first argument with the ID of your essence. The quantity isoptional (it defaults to 1)
+component.subtractEssence("my-third-essence-id", 2); // <-- Replace the first argument with the ID of your essence and the second with the quantity to remove
+const componentAfterSave = await game.fabricate.api.components.save(component);
+```
+
+
+
+### Setting the salvage options for a component
+
+You can add salvage options to a component by fetching it, setting the salvage option (or options) then calling `game.fabricate.api.components.save()`, passing in the modified component.
+
+
+
+Example
+
+
+```typescript
+// Get the component
+const myComponentId = "my-component-id"; // <-- Replace this with the ID of your component
+const component = await game.fabricate.api.components.getById(myComponentId);
+
+// Create a new salvage option that requires catalysts
+const mySalvageOptionWithCatalysts = {
+ name: "My new salvage option", // <-- Replace this with the name of your salvage option
+ results: { // <-- Replace the keys with the IDs of the components you want to produce when the component is salvaged and the values with the quantity to produce
+ "my-salvage-id": 1
+ },
+ catalysts: { // <-- Replace the keys with the IDs of the components you want to use as catalysts and the values with the quantity of each catalyst
+ "my-catalyst-id": 2
+ }
+};
+component.setSalvageOption(mySalvageOptionWithCatalysts);
+
+// Create a new salvage option that doesn't require catalysts
+const mySalvageOptionWithoutCatalysts = {
+ name: "My other salvage option", // <-- Same here with naming your salvage options
+ results: { // <-- Same here with configuring the salvage results
+ "my-salvage-id": 1
+ }
+};
+component.setSalvageOption(mySalvageOptionWithoutCatalysts);
+
+// You can overwrite an existing salvage option by adding the ID of the salvage option to overwrite
+// If the ID you provide doesn't match an existing salvage option, this will cause the `setSalvageOption` method to throw an error
+const mySalvageOptionToOverwrite = {
+ id: "my-salvage-option-id-1", // <-- Replace this with the ID of the salvage option to overwite
+ name: "My existing salvage option to replace", // <-- Same here with naming your salvage options
+ results: { // <-- Same here with configuring the salvage results
+ "my-salvage-id": 1
+ }
+};
+component.setSalvageOption(mySalvageOptionToOverwrite);
+
+// You can also delete a salvage option by passing in the ID of the salvage option to delete
+component.deleteSalvageOptionById("my-salvage-option-id-2"); // <-- Replace this with the ID of the salvage option to delete
+
+// Save the component
+const componentAfterSave = await game.fabricate.api.components.save(component);
+```
+
+
+
diff --git a/src/scripts/crafting/component/Component.ts b/src/scripts/crafting/component/Component.ts
index d432609d..d4be3231 100644
--- a/src/scripts/crafting/component/Component.ts
+++ b/src/scripts/crafting/component/Component.ts
@@ -4,10 +4,17 @@ import {SelectableOptions} from "../selection/SelectableOptions";
import {FabricateItemData, ItemLoadingError, NoFabricateItemData} from "../../foundry/DocumentManager";
import {Serializable} from "../../common/Serializable";
import {ComponentReference} from "./ComponentReference";
-import {SalvageOption, SalvageOptionConfig, SalvageOptionJson} from "./SalvageOption";
+import {SalvageOption, SalvageOptionJson} from "./SalvageOption";
import {EssenceReference} from "../essence/EssenceReference";
import {Unit} from "../../common/Unit";
+interface SalvageOptionConfig {
+ id: string;
+ name: string;
+ results: Record;
+ catalysts: Record;
+}
+
interface ComponentJson {
id: string;
embedded: boolean;
@@ -197,13 +204,6 @@ class Component implements Identifiable, Serializable {
this._essences = value;
}
- public addSalvageOption(value: SalvageOption) {
- if (this._salvageOptions.has(value.id)) {
- throw new Error(`Result option ${value.id} already exists in this recipe. `);
- }
- this._salvageOptions.set(value);
- }
-
set salvageOptions(options: SelectableOptions) {
this._salvageOptions = options
}
@@ -261,13 +261,20 @@ class Component implements Identifiable, Serializable {
return this.itemData.loaded;
}
- public setSalvageOption(value: SalvageOptionConfig) {
- const optionId = this._salvageOptions.nextId();
- const salvageOption = SalvageOption.fromJson({
+ public setSalvageOption(salvageOption: SalvageOptionConfig | SalvageOption) {
+ if (salvageOption instanceof SalvageOption) {
+ this._salvageOptions.set(salvageOption);
+ return;
+ }
+ if (salvageOption.id && !this._salvageOptions.has(salvageOption.id)) {
+ throw new Error(`Unable to find salvage option with id ${salvageOption.id}`);
+ }
+ const optionId = salvageOption.id ?? this._salvageOptions.nextId();
+ const created = SalvageOption.fromJson({
id: optionId,
- ...value
+ ...salvageOption
});
- this._salvageOptions.set(salvageOption);
+ this._salvageOptions.set(created);
}
public saveSalvageOption(value: SalvageOption) {
diff --git a/src/scripts/crafting/component/SalvageOption.ts b/src/scripts/crafting/component/SalvageOption.ts
index 9484fad0..8fd7fedc 100644
--- a/src/scripts/crafting/component/SalvageOption.ts
+++ b/src/scripts/crafting/component/SalvageOption.ts
@@ -4,14 +4,6 @@ import {Combination} from "../../common/Combination";
import {ComponentReference} from "./ComponentReference";
import {Unit} from "../../common/Unit";
-interface SalvageOptionConfig {
- name: string;
- results: Record;
- catalysts: Record;
-}
-
-export { SalvageOptionConfig };
-
interface SalvageOptionJson {
id: string;
name: string;