Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
Tags

Enchantments

A topic by Ada18980 created Jun 25, 2024 Views: 679
Viewing posts 1 to 1
(3 edits)

Welcome to the enchantments tutorial. Kinky Dungeon 4.35 added a new feature that allows you to create enchanted variants of items. These can be either restraints or armor–they are treated identically as far as wearing them goes. Enchantments typically provide an effect and also change the tooltip using an event (more on that later)

If you want to make your own custom enchantments, there are a few places to add code. The first is understanding the enchantment list:

/**
 * Contains a list of enchantment variant types
 * Can be modified dynamically so mods can add basic curses
 */
let KDEnchantVariantList = {
     "Common": [
        "Evasion",
        "Sneak",
        "Accuracy",
        "SpellWard",
        "BondageResist",
        "DamageResist",
        "DamageBuff",
        "ManaCost",
        "ManaRegen",
        "BaseDamageBuffMelee",
    ],
    "Gold": [
        "ElementalEcho",
        "ElementalDmg",
        "BaseDamageBuffMelee",
        "BaseDamageBuffMagic",
        "ManaRegenOnKill",
        "DamageBuff",
        "ManaCost",
    ],
};

This list contains what are effectively “loot tables” but for enchantments instead. The “Common” enchantment list contains a list of enchantments that are applied to items from relatively low level loot, while the “ Gold” list contains enchantments that are meant to be more rare and special and are therefore added only to gold chests. To start with, in your mod you need to add your enchantment to this list.

KDEnchantVariantList.Common.push("MyEnchantment")

Next, you have to create your enchantment tooltip, otherwise the player will not know what it does. To start, add the text key:

addTextKey("KDVariableModifier_MyEnchantment", "Halo: AMNT fire damage to nearby enemies");

Of note is the first line, which is formatted so the default tooltip system will detect it. The second is what appears ingame. AMNT is replaced with a variable you supply as part of the enchantment

Third, you must define the enchantment itself. The enchantment object is contained in KDEventEnchantmentModular. This list contains the data that makes enchantments work–an enchantment definition contains 3 things: a level (which defines how powerful it is, usually 1-10 for low level enchantments, 11-20 for medium, and 20+ for very rare unique stuff) a weight function (returns the weight for the system to calculate the rarity of the enchantment) an event list (a list of special code injections that the game appends to any events the restraint/armor has to begin with)

For our enchantment, we will make it deal fire damage to nearby enemies. This is the code to add the enchantment:

KDEventEnchantmentModular.MyEnchantment = {
            2: null, //consumable
            1: null, //weapon
            0: /*restraint*/{
        level: 9, // It's fairly powerful but also in the common list, so 9 should fit
        weight: (item) => {
            return 3; // It should be rare since it is quite powerful.
        },
        events: (item, Loot, curse, primaryEnchantment) => {
            let power = Math.max(KDGetItemPower(item), 4); // This line doesn't need to be modified
                        //but if you want the enchantment to have a strong minimum bar despite the restraint power,
                        //increase 4 to something higher
            let amt = 2 + Math.round(KDRandom() * 3 * Math.pow(power, 0.75));
                        // The exponent helps keep high level restraints from being too powerful.
                        // The randomness is there to make the 
                        // The 2 is the base amount which is always added to the damage amount
                        // The 3 is the amount of damage per unit of restraint power
                        // Since the minimum is 4 power, the minimum damage per turn this restraint deals
                        // will be 2 to 14 damage per turn. 
            amt = KDGenericMultEnchantmentAmount(amt, item, Loot, curse, primaryEnchantment); // This line doesnt need to be modified
 
            return [ // This is the event list
                // This is the main line that gives the enchantment its effect
                // Note that in KD all damage values are internally 1/10 of what they are displayed as, so we divide by 10
                // Note: This event does not exist! We will add it next section
                {trigger: "tick", type: "damageEnemiesNearby", power: amt/10, damage: "fire", dist: 1.5, inheritLinked: true, sfx: "FireSpell"},
                // This is the tooltip. msg should be your enchantment name, colors should be set to what you want
                {trigger: "inventoryTooltip", type: "varModifier", msg: "MyEnchantment", power: amt, color: "#ff0000", bgcolor: "#ff5555"},
                // This is the the event that gives the icon a glow in the inventory. We gave it an orange color
                // power should be set to the enchantment's power
                {trigger: "icon", type: "tintIcon", power: 9, color: "#ffaa44"},
            ];}
  },
};

Now, this enchantment will appear in your regular chests when you get an armor item. You may want to set the weight to 9999 to help test it. However, it won’t do anything! This is because the event damageEnemiesNearby does not exist yet! To add an event, we will have to modify the inventory item event list. Here is the code:

KDEventMapInventory.tick.damageEnemiesNearby = (e, item, data) => {
  // This gets the enemies near the player
  let enemies = KDNearbyEnemies(KinkyDungeonPlayerEntity.x, KinkyDungeonPlayerEntity.y, e.dist || 1.5);
  for (let enemy of enemies) {
    // This checks if they are hostile and not already down
    if ((!e.chance || KDRandom() < e.chance) && enemy.hp > 0 && !KDHelpless(enemy) && KDHostile(enemy)) {
      // This deals damage
      KinkyDungeonDamageEnemy(enemy, {
        type: e.damage,
        damage: e.power,
        }, false, true, undefined, undefined, KinkyDungeonPlayerEntity);
      // This plays a sound effect if desired
      KinkyDungeonPlaySound(KinkyDungeonRootDirectory + "Audio/" + e.sfx + ".ogg");
    }
  }
}

This should cover how to add a new enchantment with a new effect. If you want to apply the enchantment directly to an item, you can use KDGiveInventoryVariant(variant) or KDEquipInventoryVariant(variant) and define variant like so:

KDGiveInventoryVariant({
  template: "TrapGag", // Make it a ball gag
  events: KDEventEnchantmentModular.MyEnchantment.types[0].events("TrapGag", {amtMult: 2.0}), // You can make it extra powerful with amtMult
});