Skip to content

Commit

Permalink
docs: Adds component API examples (#134)
Browse files Browse the repository at this point in the history
  • Loading branch information
misterpotts authored Sep 10, 2023
1 parent e850fb6 commit a357c29
Show file tree
Hide file tree
Showing 3 changed files with 267 additions and 21 deletions.
247 changes: 247 additions & 0 deletions docs/api/components.md
Original file line number Diff line number Diff line change
Expand Up @@ -307,3 +307,250 @@ interface SalvageOptionValue {
```

</details>

## 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).

<details markdown="block">
<summary>
Example #1 - A component with no essences and no salvage options
</summary>

```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);
```

</details>

<details markdown="block">
<summary>
Example #2 - A component with essences and no salvage options
</summary>

```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);
```

</details>

<details markdown="block">
<summary>
Example #3 - A component with essences and salvage options
</summary>

```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);
```

</details>

### 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.

<details markdown="block">
<summary>
Example
</summary>

```typescript
const myComponentId = "my-component-id"; // <-- Replace this with the ID of your component
const component = await game.fabricate.api.components.getById(myComponentId);
```

</details>

### Getting all components

You can retrieve all components in all crafting systems by calling `game.fabricate.api.components.getAll()`.

<details markdown="block">
<summary>
Example
</summary>

```typescript
const components = await game.fabricate.api.components.getAll();
```

</details>

### 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.

<details markdown="block">
<summary>
Example
</summary>

```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);
```

</details>

### 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.

<details markdown="block">
<summary>
Example
</summary>

```typescript
const myItemUuid = "my-item-uuid"; // <-- Replace this with the UUID of your item
const components = await game.fabricate.api.components.getAllByItemUuid(myItemUuid);
```

</details>

### 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.

<details markdown="block">
<summary>
Example
</summary>

```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);
```

</details>

### 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.

<details markdown="block">
<summary>
Example
</summary>

```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);
```

</details>

### 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.

<details markdown="block">
<summary>
Example
</summary>

```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);
```

</details>

33 changes: 20 additions & 13 deletions src/scripts/crafting/component/Component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, number>;
catalysts: Record<string, number>;
}

interface ComponentJson {
id: string;
embedded: boolean;
Expand Down Expand Up @@ -197,13 +204,6 @@ class Component implements Identifiable, Serializable<ComponentJson> {
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<SalvageOptionJson, SalvageOption>) {
this._salvageOptions = options
}
Expand Down Expand Up @@ -261,13 +261,20 @@ class Component implements Identifiable, Serializable<ComponentJson> {
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) {
Expand Down
8 changes: 0 additions & 8 deletions src/scripts/crafting/component/SalvageOption.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,6 @@ import {Combination} from "../../common/Combination";
import {ComponentReference} from "./ComponentReference";
import {Unit} from "../../common/Unit";

interface SalvageOptionConfig {
name: string;
results: Record<string, number>;
catalysts: Record<string, number>;
}

export { SalvageOptionConfig };

interface SalvageOptionJson {
id: string;
name: string;
Expand Down

0 comments on commit a357c29

Please sign in to comment.