Skip to content

Developer API

kangarko edited this page Apr 29, 2019 · 15 revisions

img Boss contains easy-to-understand developer API that allows you to find and track Bosses, add or remove Bosses, or edit custom skills

All API Classes

img

Where should you start? Use BossAPI to access main API calls and BossSkillRegistry to add custom skills.

Adding New Skills

Creating new skills is a simple process that takes two steps. Firstly, you need to create the skill itself. Then, you need to register it within the plugin. They will appear in the Boss' menu automatically.

Creating a new Skill

Please take a look at the example skill to understand how a Skill should be made:

package me.kangarko.boss.skills;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import org.bukkit.Material;
import org.bukkit.entity.Creature;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Fireball;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.ExplosionPrimeEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.metadata.FixedMetadataValue;

import me.kangarko.boss.BossPlugin;
import me.kangarko.boss.api.BossAPI;
import me.kangarko.boss.api.model.BossSkill;
import me.kangarko.boss.api.model.BossSkillDelay;
import me.kangarko.boss.api.model.SpawnedBoss;

// Extend the BossSkill class to make a new Skill
public final class SkillFireballExample extends BossSkill {

	// You can set custom properties in your skill classes.
	private float power;

	// The name of the skill. Used in:
	// a) The Skill Menu in-game.
	// b) As a name of the skill configuration file for this skill in /skills folder.
	@Override
	public final String getName() {
		return "Shoot Fireball";
	}

	// Get the icon as it should display in the Boss Menu.
	// It will be inserted there automatically!
	@Override
	public ItemStack getIcon() {
		final ItemStack it = new ItemStack(Material.FIREBALL);
		final ItemMeta m = it.getItemMeta();

		m.setDisplayName("§fShoot Fireball");
		m.setLore(Arrays.asList(
				"",
				"§rThe Boss will throw",
				"§ra fireball on the player."
				));

		it.setItemMeta(m);
		return it;
	}

	// Get the default delay (how long to wait between the next execution).
	// This will be copied to the skill settings file.
	@Override
	public final BossSkillDelay getDefaultDelay() {
		return new BossSkillDelay("20 seconds", "50 seconds");
	}

	// Get the default random message to the player that has been targetted by this skill.
	// A line will be picked up randomly from the array.
	// This will be copied to the skill settings file.
	@Override
	public String[] getDefaultMessage() {
		return new String[] {
				"You have been &cfireballed &7by the boss!",
				"The {boss} has &claunched a fireball &7at you!",
				"Hellfire! Do you like small or big fireballs?"
		};
	}

	// Get the default message inserted to the header in the skill configuration file.
	@Override
	public String[] getDefaultHeader() {
		return new String[] {
				"  Power - The strength of the explosion caused by the fireball.",
				"  Destroy_Blocks - Should the fireball explosion also destroy blocks?"
		};
	}

	// The main method. What happens when the skill is run?
	// Return true if the skill was run successfully, otherwise return false.
	@Override
	public final boolean execute(SpawnedBoss spawned) {

		// Find the target using our own method below.
		final Player target = getTargetPlayer(spawned.getEntity());

		// Fail if the target is not valid or null.
		if (target == null)
			return false;

		// Launch a projectile - a fireball - from this boss.
		// If you are advanced, you can change its direction so it is always shot to the player.
		final Fireball ball = spawned.getEntity().launchProjectile(Fireball.class);

		// Give a secret mark to the projectile so we can identify it later.
		ball.setMetadata("BossFireball", new FixedMetadataValue(/* Change this to your plugin's main class. */BossPlugin.getInstance(), ""));

		// Send the skill message to the player.
		// YOU MUST CALL THIS METHOD MANUALLY.
		sendSkillMessage(target, spawned);

		// The skill is successfull.
		return true;
	}

	private final Player getTargetPlayer(Entity entity) {
		final LivingEntity t = getTarget(entity);

		return t != null && t instanceof Player ? (Player) t : null;
	}

	private final LivingEntity getTarget(Entity entity) {
		return entity != null && entity instanceof Creature ? ((Creature)entity).getTarget() : null;
	}

	//
	// Each BossSkill is capable of listening for events!
	//
	// This event is called when the fireball is about to explode,
	// and if the fireball has been shoot from our Boss, we will adjust the explosion power.
	@EventHandler
	public final void onPrime(ExplosionPrimeEvent e) {
		if (e.getEntity().hasMetadata("BossFireball"))
			e.setRadius(power);
	}

	// Do not damage the Boss himself from the fireball explosion.
	@EventHandler
	public final void onDamage(EntityDamageByEntityEvent e) {
		if (BossAPI.isBoss(e.getEntity()) && e.getDamager() != null && e.getDamager().hasMetadata("BossFireball"))
			e.setCancelled(true);
	}

	// Skills can be customized by the user!
	// In this method you can load them from a serialized map directly from the skill settings file.
	// NOTICE: THIS METHOD IS CALLED EVEN IF THE FILE DOES NOT EXIST
	//         BE PREPARED FOR NULL VALUES
	@Override
	public void readSettings(Map<String, Object> map) {
		power = Float.parseFloat( map.getOrDefault("Power", 1.8F).toString() );
	}

	// Write the user settings there.
	// MAKE SURE YOU SERIALIZE THEM PROPERLY (e.g. do not save entire classes, etc.)
	// If you don't know how to serialize, only save primitives (int, double, float, boolean) or Strings.
	@Override
	public Map<String, Object> writeSettings() {
		final Map<String, Object> map = new HashMap<>();

		map.put("Power", power);

		return map;
	}
}

Registering a Skill

When your plugin enables, register the skill inside of the Boss plugin:

BossSkillRegistry.register(new SkillFireballExample());

The Main Class

package me.kangarko.boss.api;

public final class BossAPI {

	private static final BossManager manager = BossPlugin.getBossManager();

	/**
	 * Create a new Boss
	 *
	 * @param fileName the file name in bosses/ folder
	 * @return a Boss, or null if not found
	 */
	public static final Boss createBoss(EntityType type, String fileName) {
		return manager.createBoss(type, fileName);
	}

	/**
	 * Remove an existing boss by name
	 *
	 * @param name the Boss' name
	 */
	public static final void removeBoss(String name) {
		manager.removeBoss(name);
	}

	/**
	 * Determines whether or not this item holds a valid
	 * Boss spawner egg registered within the Boss plugin.
	 *
	 * @param item the {@link ItemStack}
	 * @return if this item holds a Boss
	 */
	public static final boolean isBoss(ItemStack item) {
		return manager.findBoss(item) != null;
	}

	/**
	 * Determines if the entity is registered within the Boss plugin.
	 *
	 * @param entity the {@link Entity}
	 * @return if this entity is a Boss
	 */
	public static final boolean isBoss(Entity entity) {
		return manager.findBoss(entity) != null;
	}

	/**
	 * Attempts to find a registered Boss from an entity.
	 *
	 * @param entity the entity to search for
	 * @return a Boss, or null if not found
	 */
	public static final Boss getBoss(Entity entity) {
		return manager.findBoss(entity);
	}

	/**
	 * Attempts to find a registered Boss from an item.
	 *
	 * @param item the item to evaluate
	 * @return a Boss, or null if not found
	 */
	public static final Boss getBoss(ItemStack item) {
		return manager.findBoss(item);
	}

	/**
	 * Attempts to find a registered Boss directly
	 * from its file name.
	 *
	 * @param fileName the file name in bosses/ folder
	 * @return a Boss, or null if not found
	 */
	public static final Boss getBoss(String fileName) {
		return manager.findBoss(fileName);
	}

	/**
	 * Get all active Bosses in the specific world.
	 *
	 * @param world the world to look in
	 * @return the active Bosses in the world
	 */
	public static final List<SpawnedBoss> getBosses(World world) {
		return manager.findBosses(world).getRaw();
	}

	/**
	 * Get the list of all {@link EntityType} that the the Boss may be of.
	 *
	 * @return a list of all valid Boss' entity types
	 */
	public static final List<EntityType> getValidTypes() {
		return BossManager.getValidTypes();
	}
}

The BossSpawnEvent

Triggered when a new Boss is spawned. Can be cancelled.

package me.kangarko.boss.api.event;

public final class BossSpawnEvent extends Event implements Cancellable {

	private static final HandlerList handlers = new HandlerList();

	@Getter
	private final Boss boss;

	@Getter
	private final LivingEntity entity;

	@Getter
	private final BossSpawnReason spawnReason;

	@Getter
	@Setter
	private boolean cancelled;

	@Override
	public HandlerList getHandlers() {
		return handlers;
	}

	public static HandlerList getHandlerList() {
		return handlers;
	}
}