npm package: @kp-mods/easy-edict-library
Description: This is a library for creating new and modifying existing skills, edicts, weapons and edict trees in Karryn's Prison.
Author: Automatic Infusion
Latest version: 2.1.0

# Easy Edict Library

This is a library for creating new and modifying existing skills, edicts, weapons
and edict trees in Karryn's Prison.

It works by modifying the game data parsed from the RPGMaker data files and makes
it so that changes can be done programmatically without having to modify the
files themselves.

[TOC]

## Requirements

None

## Download

Download [the latest version of the mod][latest].

## Installation

Use [this installation guide](https://gitgud.io/karryn-prison-mods/modding-wiki/-/wikis/Installation/)

## How to create mod using EEL

- *(optional)* Install npm package with types for IDE IntelliSense support:
  ```bash
  npm install @kp-mods/easy-edict-library
  ```
- Add `EEL` mod (v2.0.0 or newer) as dependency inside your mod
  (in this example, in file `YourMod.js` file):
  ```
  {"name":"EEL","status":true,"description":"","parameters":{"requiredVersion": "^2.0.0"}},
  {"name":"YourMod","status":true,"description":"","parameters":{"version":"1.0.0"}},
  ```
- Call `EEL.configure` function and retrieve, create, save or modify objects
  using provided API.

## Examples

### General mod template

```js
// #MODS TXT LINES:
//    {"name":"EEL","status":true,"description":"","parameters":{}},
//    {"name":"YourMod","status":true,"description":"","parameters":{"version":"1.0.0"}},
// #MODS TXT LINES END

// Creating a lambda and calling it to prevent variable name conflicts with other mods
// Basically, it's a function without a name that is, in this case, called immediately
(() => {
    const modId = 'YourMod';
    const EEL = window.EEL;

    EEL.configure((api) => {
        // Do all changes.
    });
})();
```

If you use typescript you can import module:
```ts
import * as EEL from '@kp-mods/easy-edict-library';

const modId = 'YourMod';

EEL.configure((api) => {
    // Do all changes.
});
```

Asynchronous configuration is supported as well:
```js
    EEL.configure(async (api) => {
        await somePromiseToWaitFor;
        // Do all changes.
    });
```

Below are example of changes you can do using EEL api.

#### Add new skill

```js
/** Saves created skill to the game */
const myBestSkill = api.saveSkill(
    /**
     * Creates new skill. Skill id will be assigned if `localId` and `modId` are specified.
     * You can also manually assign the id to a skill or use an existing id to overwrite a skill,
     * however, in this case, you'll be responsible for resolving conflicts with other skills.
     */
    api.createSkill({
        /**
         * Local id could be any unique id in specified mod (i.e. unique in current mod scope).
         * Ignored if 'id' property is specified.
         */
        localId: 'MyNewBestSkillId',
        /**
         * Mod id to specify scope for local ids.
         * Ignored if 'id' property is specified.
         */
        modId,
        name: "My new best skill",
        stype: EEL.Enum.SkillType.ATTACK,
        successRate: 50,
        iconIndex: 10,
        damage: {
            critical: true,
            type: EEL.Enum.DamageType.CERTAIN_HIT,
            formula: 'a.atk * 10'
        },
        // etc...
        /** All supported properties can be found in {@link SkillData} */
    })
);

/**
 * Then when game save is loaded you can learn new skill.
 * Example:
 */
// $gameActors.actor(ACTOR_KARRYN_ID).learnSkill(myBestSkill.id);
```
Then you can use `myBestSkill.id` variable to learn the skill.

#### Retrieve existing skill or edict

- To get vanilla game skill:
  ```js
  const existingSkill = api.getSkill(EDICT_BAR_DRINK_MENU_I);
  if (!existingSkill) {
      throw new Error(`Skill ${EDICT_BAR_DRINK_MENU_I} doesn't exist.`);
  }
  ```

- To get vanilla game edict pass edict skill type as second parameter:
  ```js
  const existingEdict = api.getSkill(EDICT_BAR_DRINK_MENU_I, EEL.Enum.SkillType.EDICTS);
  /** It will allow you to access edict-specific properties: */
  // console.log(existingEdict.goldCost);
  ```

- To get another EEL mod skill or edict:
  ```js
  const otherModSkill = api.getSkill({localId: '', modId: ''});
  ```
  Make sure you add mod you want to get skill from as dependency in declaration.

#### Create and attach new edict

```js
/** Create and save new edict */
const myNewEdict = api.saveSkill(
    api.createSkill(
        {
            localId: 'MyNewEdictId',
            modId,
            /** Set skill type to EDICTS to access edict-specific properties (like `goldCost`). */
            stypeId: EEL.Enum.SkillType.EDICTS,
            name: "My new edict",
            goldCost: 100,
            // etc...
            /** All supported properties can be found in {@link EdictData} */
        }
    )
);

/** Get existing edict you want to attach your new edict to in the edict tree */
const someExistingEdict = api.getSkill(EDICT_BAR_DRINK_MENU_I, EEL.Enum.SkillType.EDICTS);
if (!someExistingEdict) {
  throw new Error(`Edict ${EDICT_BAR_DRINK_MENU_I} doesn't exist.`);
}

/** Attach the edict */
someExistingEdict.edictTreeChildren.push(myEdict.id);

/** Save the other edict again which will overwrite the original edict */
api.saveEdict(someExistingEdict);
```

#### Create new edict tree

```js
const myEdictTree = api.createEdictTree({
    localId: "My Edict Tree",
    modId,
    name: "My Edict Tree",
    rootEdictIds: [myEdict.id]
    // etc...
    /** All supproted properties can be found in {@link EdictTreeData} */
});

/** You can add your edict tree below an existing edict tree like this */
api.saveEdictTree(myEdictTree, EDICT_TREE_PERSONAL);
/** or at the end: */
// api.saveEdictTree(myEdictTree);
```

#### Add new root edict to existing edict tree

You can also get an existing edict tree and add your edict like this:
```js
/** Get vanilla game edict tree to attach edict to: */
const personalEdictTree = api.getEdictTree(EDICT_TREE_PERSONAL);

/** Or get edict tree created in another mod: */
const otherModEdictTree = api.getEdictTree({
    localId: 'Other mod edict tree id',
    modId: 'Other mod id'
});

/** Add edict id to root edicts of obtained edict tree. */
personalEdictTree.rootEdictIds.push(myEdict.id);

/** Save modified edict tree. */
api.saveEdictTree(personalEdictTree);
```

#### Create new weapon

```js
const myWeapon = api.saveWeapon(
    api.createWeapon({
        localId: 'My new weapon',
        modId,
        name: "My Weapon",
        iconIndex: 12,
        price: 100,
        // etc...
        /** All supproted properties can be found in {@link WeaponData} */
    })
);

/**
 * Then when the game save is loaded you can obtain new weapon.
 * Example:
 */
// $gameParty.gainItem(myWeapon.id, 1, true);
```

#### Retrieve existing weapon

```js
/** To get vanilla weapon: */
const HALBERD_WEAPON_ID = 1;
const vanillaWeapon = api.getWeapon(HALBERD_WEAPON_ID);

/** To get weapon added (via EEL) in different mod: */
const otherModWeapon = api.getWeapon({
    localId: 'Other mod weapon id',
    modId: 'Other mod id'
});
```

[latest]: https://gitgud.io/AutomaticInfusion/kp_easyedictlibrary/-/releases/permalink/latest "The latest release"