forked from nisovin/MagicSpells
-
Notifications
You must be signed in to change notification settings - Fork 68
Dev API
JasperLorelai edited this page Jan 28, 2024
·
14 revisions
On this page, we will document how to add custom spells, modifier conditions, passive listeners, etc. to MagicSpells.
Jump to section:
- Adding the dependency
- Custom spell classes
- Custom modifier conditions, passive listeners, variables, and spell effects
- Custom CleanseSpell cleansers
MagicSpells uses jitpack.io as its repository-service.
You can find guides on how to add MagicSpells as a dependency for your build-environment here.
Or use the example below:
repositories {
maven {url "https://jitpack.io"}
}
dependencies {
implementation "com.github.TheComputerGeek2.MagicSpells:core:main-SNAPSHOT"
}
- Custom spell classes can be placed in the root folder of the plugin or in any folder in the root starting with "classes".
- Custom spell classes are loaded by MagicSpells if a spell uses the classified path in its
spell-class
property. - All you have to do is to extend either the Spell, CommandSpell, InstantSpell, TargetedSpell, or BuffSpell classes.
- TargetedSpell classes may implement the following interfaces: TargetedEntitySpell, TargetedEntityFromLocationSpell, or TargetedLocationSpell.
This example displays a basic instant spell.
package com.example.instant;
import org.bukkit.entity.LivingEntity;
import com.nisovin.magicspells.util.MagicConfig;
import com.nisovin.magicspells.spells.InstantSpell;
import com.nisovin.magicspells.spelleffects.EffectPosition;
public class HelloWorldSpell extends InstantSpell {
public HelloWorldSpell(MagicConfig config, String spellName) {
super(config, spellName);
}
@Override
public PostCastAction castSpell(LivingEntity caster, SpellCastState state, float power, String[] args) {
if (state == SpellCastState.NORMAL) {
caster.sendMessage("Hello World!");
// We should always play the correct effects in the spell.
playSpellEffects(EffectPosition.CASTER, caster);
}
return PostCastAction.HANDLE_NORMALLY;
}
}
hello_world:
spell-class: "com.example.instant.HelloWorldSpell"
This example displays a basic targeted spell, and how to handle targets, and spell effects in targeted spells.
package com.example.targeted;
import org.bukkit.entity.LivingEntity;
import com.nisovin.magicspells.util.TargetInfo;
import com.nisovin.magicspells.util.MagicConfig;
import com.nisovin.magicspells.spells.TargetedSpell;
import com.nisovin.magicspells.spells.TargetedEntitySpell;
import com.nisovin.magicspells.spelleffects.EffectPosition;
public class HelloWorldSpell extends TargetedSpell implements TargetedEntitySpell {
public HelloWorldSpell(MagicConfig config, String spellName) {
super(config, spellName);
}
@Override
public PostCastAction castSpell(LivingEntity caster, SpellCastState state, float power, String[] args) {
if (state == SpellCastState.NORMAL) {
TargetInfo<LivingEntity> targetInfo = getTargetedEntity(caster, power);
if (targetInfo == null) return noTarget(caster);
LivingEntity target = targetInfo.getTarget();
hello(caster, target);
sendMessages(caster, target);
return PostCastAction.NO_MESSAGES;
}
return PostCastAction.HANDLE_NORMALLY;
}
@Override
public boolean castAtEntity(LivingEntity caster, LivingEntity target, float power) {
return hello(caster, target);
}
@Override
public boolean castAtEntity(LivingEntity target, float power) {
return hello(null, target);
}
private boolean hello(LivingEntity caster, LivingEntity target) {
target.sendMessage("Hello World!");
if (caster == null) playSpellEffects(EffectPosition.TARGET, target);
else playSpellEffects(caster, target);
return true;
}
}
hello_world_targeted:
spell-class: "com.example.targeted.HelloWorldSpell"
This example includes configuration reading.
package com.example.instant;
import org.bukkit.entity.Player;
import org.bukkit.entity.LivingEntity;
import com.nisovin.magicspells.util.Util;
import com.nisovin.magicspells.util.MagicConfig;
import com.nisovin.magicspells.spells.InstantSpell;
public class RollDiceSpell extends InstantSpell {
private int min;
private int max;
private final String strMessage;
public RollDiceSpell(MagicConfig config, String spellName) {
super(config, spellName);
min = getConfigInt("min", 0);
max = getConfigInt("max", 10);
strMessage = getConfigString("message", "Dice: ");
}
@Override
public PostCastAction castSpell(LivingEntity livingEntity, SpellCastState state, float power, String[] args) {
// Here we are dealing with a spell that only works for Player casters.
if (state == SpellCastState.NORMAL && livingEntity instanceof Player caster) {
// We're using Util methods not to create duplicate code.
int random = min + Util.getRandomInt(max - min + 1);
caster.sendMessage(strMessage + random);
}
return PostCastAction.HANDLE_NORMALLY;
}
}
roll_dice:
spell-class: "com.example.instant.RollDiceSpell"
min: 0
max: 100
message: "You rolled: "
- This section includes the creation of custom modifier conditions, passive listeners, variables, and spell effects.
- If you would like to add these features, you can use the API from your own custom plugin. However, if you don't want to add a separate plugin, you could utilise a custom spell class to achieve this.
- If you are using a custom plugin to load these modules, you could use this resource in order to load these classes in a simpler way. It could also serve as an example for what follows. If you are using a custom plugin to load these modules, the plugin must "soft depend" on "MagicSpells".
- You have to create an event handler for the module you want to add, then add it through its manager there. The events are:
ConditionsLoadingEvent
,PassiveListenersLoadingEvent
,VariablesLoadingEvent
, andSpellEffectsLoadingEvent
. You can fetch the specific manager from static methods in the MagicSpells class. Each of these managers includes a method to add the module you want. This example shows how to add a custom variable class. For the sakes of this tutorial, we're adding an existing variable under a different name.
@EventHandler
public void onVariableLoad(VariablesLoadingEvent event) {
MagicSpells.getVariableManager().addVariable("altitude", new AltitudeVariable());
}
Warning
Since Beta 14.
It's possible to register custom cleansers for the Cleanse Spell to list under its remove
option. You can find some examples of how to implement a cleanser here.
import com.nisovin.magicspells.spells.targeted.cleanse.util.Cleansers;
. . .
Cleansers.addCleanserClass(/* <Class which extends Cleanser>*/);