If you change the properties of a spell between restarts, you’ll need to regenerate the Iron’s Spells server config by deleting it and joining the world again.
Example script:
// Spell registry goes in the startup_scripts folder
StartupEvents.registry('irons_spellbooks:spells', event => {
event.create('bloodfed')
.setCastTime(60) // Cast time in ticks
.setCooldownSeconds(10) // Spell cooldown in seconds
.setManaCostPerLevel(20) // How much additional mana is needed per level
.setCastType('continuous') // Cast type can be "continuous", "long", "instant", or "none"
.setSchool('irons_spellbooks:blood') // The school type. This is the ID of the school you want to use
.setMinRarity('epic') // The minimum rarity of the spell. Can be "common", "uncommon", "rare", "epic", or "legendary"
.setMaxLevel(2) // The maximum level
.setStartSound('item.honey_bottle.drink') // The sound to be played when you start casting the spell. Used for long spells
.setFinishSound('item.honey_bottle.drink') // Plays when the spell has finished casting
.onCast(ctx => global.bloodfed(ctx)) // The function to be called when the spell is cast
// Other methods like these also exist:
.onClientCast(ctx => {}) // Client-side only cast method. Useful for particles and sounds
.onPreCast(ctx => {}) // Called before the spell is cast.
.onPreClientCast(ctx => {})
.setAllowLooting(true) // Setting this to false will disallow looting the spell from mobs or chests
.needsLearning(false) // Usually this one is used for Eldritch spells
.canBeCraftedBy(player => true)
.setUniqueInfo((spellLevel, caster) => { // Caster refers to the player
return [
// You need to return an array of components for this method. They can be any text you want.
Component.green(`Health: ${spellLevel / 2}`),
Component.green(`Hunger Usage: ${caster.getFoodData().getFoodLevel() * (spellLevel / 2)}`)
]
})
.checkPreCastConditions(ctx => { // This method can be used to check if the spell can be cast. If it returns false, the spell won't be cast.
// You can use this for targeting spells, like how the Slow spell works. preCastTargetHelper returns true or false based on the target conditions.
// The parameters of this method include the level, entity, the player's magic data, the spell, the range, and the aim assist.
return ISSUtils.preCastTargetHelper(ctx.level, ctx.entity, ctx.playerMagicData, ctx.spell, 48, 0.35)
})
})
// The functions for certain methods with callbacks like onCast can go in a global variable if you want it to be reloadable by using /kubejs reload startup_scripts
// It is recommended to use ProbeJS for this, to see all the available methods and properties in the context object.
global.bloodfed = (ctx) => {
let player = ctx.entity
if ((player.getFoodData().getFoodLevel() * (ctx.getSpellLevel() / 2)) < 2
|| !ctx.entity.isPlayer()) return
player.heal(ctx.getSpellLevel() / 2)
player.getFoodData().setFoodLevel(player.getFoodData().getFoodLevel() - 2 * (ctx.getSpellLevel() / 2))
}
Listening to Iron’s Spells Events:
// These two go in server_scripts
PlayerEvents.changeMana(event => {
// This makes it so that casting any spell consumes only 10 mana
if (event.getMagicData().getCastSource() != 'SPELLBOOK') return
event.setNewMana(event.getOldMana() - 10)
})
// There is also spellPreCast, which is cancelable
PlayerEvents.spellOnCast(event => {
// Casting any spell kills the player who casted it
event.player.kill()
})
// The one below goes in startup_scripts
// You can add spells to the spell selection wheel without requiring the player to have a spell book, magic sword or scroll
PlayerEvents.spellSelection(event => {
// This event is fired when the spell selection wheel changes or appears, or on login
// You can add spells to the selection wheel by using the addSelectionOption method, which requires SpellData (the spell and spell level), a selection option ID, and the local slot index
event.addSelectionOption(new SpellData('kubejs:test_with_ctx', 1), "custom", 0) // Usually the last parameter should be 0.
event.addSelectionOption(new SpellData('irons_spellbooks:blood_slash', 1), "custom2", 0)
})
Creating Spell Schools:
To create a spell school, you’ll first need to create two attributes for spell power and spell resistance.
// This goes in startup_scripts
StartupEvents.registry("attribute", event => {
// Use the `spell` type for these attributes and set all the values needed. The default value has to be higher than the minimum value and lower than the maximum value.
event.create("test_spell_power", "irons_spells_js:spell").setDefaultValue(1.0).setMinimumValue(0.0).setMaximumValue(10.0)
event.create("test_spell_resistance", "irons_spells_js:spell").setDefaultValue(1.0).setMinimumValue(0.0).setMaximumValue(10.0)
})
Then, in the next few lines, you need to apply these attributes to entities.
// You can listen to mod bus events by using `ForgeModEvents.onEvent`, and then inputting the event class.
ForgeModEvents.onEvent("net.minecraftforge.event.entity.EntityAttributeModificationEvent", event => {
// Here, we loop through all the entity types and add both attributes to each and every one of them.
// This makes sure that every entity that has magic capabilities can use these attributes.
event.types.forEach(type => {
event.add(type, 'kubejs:test_spell_power')
event.add(type, 'kubejs:test_spell_resistance')
})
})
If you have EntityJS, you can do this easier:
EntityJSEvents.attributes(event => {
event.allTypes.forEach(type => {
event.modify(type, (a) => {
a.add('kubejs:test_spell_power')
a.add('kubejs:test_spell_resistance')
})
})
})
Finally, we need to register the school.
StartupEvents.registry("irons_spellbooks:schools", event => {
// This creates a school named `Test` with the ID `kubejs:test`.
// You can use the ID of this school in any spell you create, or to change the school of an existing spell using the Iron's Spells server config.
event.create("test")
.setName(Component.of("Test").aqua()) // This sets what the school will be displayed as. This needs to be a Component.
.setFocus("kubejs:test_focus") // The focus needs to be an item tag. You can add this same tag to an item to make it the focus.
.setPowerAttribute("kubejs:test_spell_power") // This sets the power attribute.
.setResistanceAttribute("kubejs:test_spell_resistance") // This sets the resistance attribute.
.setDefaultCastSound('minecraft:entity.chicken.death') // You can also set a default cast sound for each spell in the school.
// In 1.20.1 and up, creating spell schools requires a damage type to be inputted.
// You can create a damage type using datapacks. https://minecraft.wiki/w/Damage_type
// .setDamageType('kubejs:test_spell_damage_type')
})