Add javadocs, add "requiresNearbyEntity" flag to ItemBasedSpell, respect dmg and range values, use <player>.getTargetEntity instead of the randomness before.

Signed-off-by: SticksDev <tanner@teamhydra.dev>
This commit is contained in:
Tanner Sommers 2023-06-05 19:52:03 -04:00
parent a3f581fc8a
commit 616c6ea517
17 changed files with 403 additions and 61 deletions

View File

@ -1,5 +1,6 @@
package me.sticksdev.runicspells; package me.sticksdev.runicspells;
import me.sticksdev.runicspells.commands.ReloadCmd;
import me.sticksdev.runicspells.handlers.CooldownHandler; import me.sticksdev.runicspells.handlers.CooldownHandler;
import me.sticksdev.runicspells.handlers.ManaHandler; import me.sticksdev.runicspells.handlers.ManaHandler;
import me.sticksdev.runicspells.handlers.SpellHandler; import me.sticksdev.runicspells.handlers.SpellHandler;
@ -13,6 +14,7 @@ public final class Runic_spells extends JavaPlugin {
private static Yaml config; private static Yaml config;
private static CooldownHandler cooldownHandler; private static CooldownHandler cooldownHandler;
private static ManaHandler manaHandler; private static ManaHandler manaHandler;
private static SpellHandler spellHandler;
@Override @Override
public void onEnable() { public void onEnable() {
@ -38,7 +40,11 @@ public final class Runic_spells extends JavaPlugin {
getServer().getPluginManager().registerEvents(manaHandler, this); getServer().getPluginManager().registerEvents(manaHandler, this);
// Register spells // Register spells
spellHandler = new SpellHandler();
SpellHandler.registerSpells(); SpellHandler.registerSpells();
// Register commands
getCommand("reloadrs").setExecutor(new ReloadCmd());
} }
@Override @Override
@ -67,4 +73,8 @@ public final class Runic_spells extends JavaPlugin {
public ManaHandler getManaHandler() { public ManaHandler getManaHandler() {
return manaHandler; return manaHandler;
} }
public SpellHandler getSpellHandler() {
return spellHandler;
}
} }

View File

@ -7,20 +7,37 @@ import org.bukkit.entity.Player;
import redis.clients.jedis.JedisPooled; import redis.clients.jedis.JedisPooled;
import redis.clients.jedis.params.SetParams; import redis.clients.jedis.params.SetParams;
import java.util.HashMap; /**
* Handles cooldowns
*/
public class CooldownHandler { public class CooldownHandler {
private final Redis redis = Runic_spells.getInstance().getRedisHandler(); private final Redis redis = Runic_spells.getInstance().getRedisHandler();
private final JedisPooled pool = redis.getPool(); private final JedisPooled pool = redis.getPool();
// Note: Java doesn't support union types for parameters, so we explicitly define the type of the spell // Note: Java doesn't support union types for parameters, so we explicitly define the type of the spell
// Even though it *technically* could be a BaseSpell, it's not worth the hassle of casting it // Even though it *technically* could be a BaseSpell, it's not worth the hassle of casting it
/**
* Sets the cooldown for a player
*
* @param player The player to set the cooldown for
* @param spell The spell to set the cooldown for (type ItemBasedSpell)
* @param cooldown The cooldown to set (in seconds)
*/
public void setCooldown(Player player, ItemBasedSpell spell, int cooldown) { public void setCooldown(Player player, ItemBasedSpell spell, int cooldown) {
pool.set(player.getUniqueId().toString() + ":" + spell.getSpellID() + ":cooldown", String.valueOf(cooldown), new SetParams().ex(cooldown)); pool.set(player.getUniqueId() + ":" + spell.getSpellID() + ":cooldown", String.valueOf(cooldown), new SetParams().ex(cooldown));
} }
/**
* Gets the cooldown for a player
*
* @param player The player to get the cooldown for
* @param spell The spell to get the cooldown for (type ItemBasedSpell)
* @return The cooldown for the player (in seconds)
*/
public double getCooldown(Player player, ItemBasedSpell spell) { public double getCooldown(Player player, ItemBasedSpell spell) {
String key = player.getUniqueId().toString() + ":" + spell.getSpellID() + ":cooldown"; String key = player.getUniqueId() + ":" + spell.getSpellID() + ":cooldown";
String cooldown = pool.get(key); String cooldown = pool.get(key);
// Check if the key exists in Redis // Check if the key exists in Redis

View File

@ -1,7 +1,6 @@
package me.sticksdev.runicspells.handlers; package me.sticksdev.runicspells.handlers;
import me.sticksdev.runicspells.Runic_spells; import me.sticksdev.runicspells.Runic_spells;
import me.sticksdev.runicspells.structures.ItemBasedSpell;
import me.sticksdev.runicspells.utils.Redis; import me.sticksdev.runicspells.utils.Redis;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
@ -13,15 +12,28 @@ import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import redis.clients.jedis.JedisPooled; import redis.clients.jedis.JedisPooled;
/**
* Handles mana
*/
public class ManaHandler implements Listener { public class ManaHandler implements Listener {
private final Redis redis = Runic_spells.getInstance().getRedisHandler(); private final Redis redis = Runic_spells.getInstance().getRedisHandler();
private final JedisPooled pool = redis.getPool(); private final JedisPooled pool = redis.getPool();
private BukkitRunnable manaTimer; private BukkitRunnable manaTimer;
/**
* Sets the mana of a player
*
* @param uuid The UUID of the player
* @param mana The amount of mana to set
*/
public void setMana(String uuid, int mana) { public void setMana(String uuid, int mana) {
pool.set(uuid + ":mana", String.valueOf(mana)); pool.set(uuid + ":mana", String.valueOf(mana));
} }
/**
* Creates the main BukkitRunnable for the mana timer to regenerate mana
* This is called in the onEnable() method of the main class
*/
public void startTimers() { public void startTimers() {
manaTimer = new BukkitRunnable() { manaTimer = new BukkitRunnable() {
@Override @Override
@ -56,10 +68,20 @@ public class ManaHandler implements Listener {
manaTimer.runTaskTimer(Runic_spells.getInstance(), 0, 20); manaTimer.runTaskTimer(Runic_spells.getInstance(), 0, 20);
} }
/**
* Cancels the mana timer
* This is called in the onDisable() method of the main class
*/
public void destroyTimers() { public void destroyTimers() {
manaTimer.cancel(); manaTimer.cancel();
} }
/**
* Gets the mana of a player
*
* @param uuid The UUID of the player
* @return The amount of mana the player has
*/
public int getMana(String uuid) { public int getMana(String uuid) {
String mana = pool.get(uuid + ":mana"); String mana = pool.get(uuid + ":mana");
@ -70,6 +92,12 @@ public class ManaHandler implements Listener {
return Integer.parseInt(mana); return Integer.parseInt(mana);
} }
/**
* Adds mana to a player and updates their EXP bar
*
* @param player The player to add mana to
* @param mana The amount of mana to add
*/
public void addMana(Player player, int mana) { public void addMana(Player player, int mana) {
String uuid = player.getUniqueId().toString(); String uuid = player.getUniqueId().toString();
int currentMana = getMana(uuid); int currentMana = getMana(uuid);
@ -77,6 +105,12 @@ public class ManaHandler implements Listener {
setEXPBar(player); setEXPBar(player);
} }
/**
* Removes mana from a player and updates their EXP bar
*
* @param player The player to remove mana from
* @param mana The amount of mana to remove
*/
public void removeMana(Player player, int mana) { public void removeMana(Player player, int mana) {
String uuid = player.getUniqueId().toString(); String uuid = player.getUniqueId().toString();
int currentMana = getMana(uuid); int currentMana = getMana(uuid);
@ -85,21 +119,34 @@ public class ManaHandler implements Listener {
} }
/**
* Sets the EXP bar of a player to their current mana
*
* @param player The player to set the EXP bar of
*/
public void setEXPBar(Player player) { public void setEXPBar(Player player) {
int mana = getMana(player.getUniqueId().toString()); int mana = getMana(player.getUniqueId().toString());
player.setExp((float) mana / 100); player.setExp((float) mana / 100);
} }
public void refundSpell(Player player, ItemBasedSpell spell) {
addMana(player, spell.getManaCost());
setEXPBar(player);
}
/**
* Checks if a player can cast a spell
*
* @param player The player to check
* @param manaCost The mana cost of the spell
* @return Whether the player can cast the spell
*/
public boolean canCast(Player player, int manaCost) { public boolean canCast(Player player, int manaCost) {
return getMana(player.getUniqueId().toString()) >= manaCost; return getMana(player.getUniqueId().toString()) >= manaCost;
} }
// On player join /**
* On player join, check if they have mana, if not, set it to 100
* If they do, set their EXP bar to their current mana
*
* @param event The PlayerJoinEvent
*/
@EventHandler @EventHandler
public void onPlayerJoin(PlayerJoinEvent event) { public void onPlayerJoin(PlayerJoinEvent event) {
boolean exists = pool.exists(event.getPlayer().getUniqueId() + ":mana"); boolean exists = pool.exists(event.getPlayer().getUniqueId() + ":mana");

View File

@ -11,19 +11,28 @@ import me.sticksdev.runicspells.utils.Yaml;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.event.player.PlayerInteractEvent;
import java.util.HashMap; import java.util.HashMap;
/**
* Handles all spells
*/
public class SpellHandler { public class SpellHandler {
public static HashMap<String, ItemBasedSpell> itemBasedSpells = new HashMap<>(); public static HashMap<String, ItemBasedSpell> itemBasedSpells = new HashMap<>();
private static final Yaml config = Runic_spells.getInstance().getConfigHandler(); private static final Yaml config = Runic_spells.getInstance().getConfigHandler();
private static final Runic_spells plugin = Runic_spells.getInstance(); private static final Runic_spells plugin = Runic_spells.getInstance();
/**
* Registers an item-based spell
*
* @param spell The spell to register
*/
public static void registerItemSpell(ItemBasedSpell spell) { public static void registerItemSpell(ItemBasedSpell spell) {
// Check if the item provided is a valid material // Check if the item provided is a valid material
try { try {
Material itemMaterial = Material.valueOf(spell.getItem()); Material.valueOf(spell.getItem());
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
Logger.warning("Spell " + spell.getName() + " has an invalid item material!"); Logger.warning("Spell " + spell.getName() + " has an invalid item material!");
Logger.warning("Provided material: " + spell.getItem()); Logger.warning("Provided material: " + spell.getItem());
@ -61,10 +70,23 @@ public class SpellHandler {
Logger.info("Registered spell " + spell.getName() + "!"); Logger.info("Registered spell " + spell.getName() + "!");
} }
/**
* Gets an item-based spell by name
*
* @param name The name of the spell
* @return The spell
*/
public static ItemBasedSpell getItemSpell(String name) { public static ItemBasedSpell getItemSpell(String name) {
return itemBasedSpells.get(name); return itemBasedSpells.get(name);
} }
/**
* Executes an item-based spell
*
* @param name The name of the spell
* @param player The player who cast the spell
* @param nearestEntity The nearest entity to the player
*/
public void executeSpell(String name, Player player, Entity nearestEntity) { public void executeSpell(String name, Player player, Entity nearestEntity) {
ItemBasedSpell spell = getItemSpell(name); ItemBasedSpell spell = getItemSpell(name);
if (spell != null) { if (spell != null) {
@ -72,6 +94,9 @@ public class SpellHandler {
} }
} }
/**
* Registers all spells (called on plugin startup)
*/
public static void registerSpells() { public static void registerSpells() {
// Register spells // Register spells
Logger.info("Registering spells..."); Logger.info("Registering spells...");
@ -81,4 +106,19 @@ public class SpellHandler {
registerItemSpell(new LightningSpell()); registerItemSpell(new LightningSpell());
Logger.info("Registered " + itemBasedSpells.size() + " spells!"); Logger.info("Registered " + itemBasedSpells.size() + " spells!");
} }
/**
* Reloads all spells (called on plugin reload)
*/
public void reload() {
// Clear all listeners for spells
Logger.info("Clearing all spell listeners...");
// Remove PlayerInteractEvent listeners
PlayerInteractEvent.getHandlerList().unregister(plugin);
// Clear registered spells and re-initialize
itemBasedSpells.clear();
registerSpells();
}
} }

View File

@ -1,5 +1,4 @@
package me.sticksdev.runicspells.spells; package me.sticksdev.runicspells.spells;
import me.sticksdev.runicspells.Runic_spells; import me.sticksdev.runicspells.Runic_spells;
import me.sticksdev.runicspells.structures.ItemBasedSpell; import me.sticksdev.runicspells.structures.ItemBasedSpell;
import me.sticksdev.runicspells.utils.Utils; import me.sticksdev.runicspells.utils.Utils;
@ -11,10 +10,12 @@ import org.bukkit.World;
public class EarthSpell extends ItemBasedSpell { public class EarthSpell extends ItemBasedSpell {
public EarthSpell() { public EarthSpell() {
super("Earth", "Launches an earth projectile", 2, "DIRT", 25, 40, 15, EarthSpell::castEarth); super("Earth", "Launches an earth projectile", 2, 10, "DIRT", 25, 40, 15, true, EarthSpell::castEarth);
} }
private static void castEarth(Player player, Entity nearestEntity) { private static void castEarth(Player player, Entity nearestEntity) {
EarthSpell earthSpell = new EarthSpell();
// Launches an earth projectile // Launches an earth projectile
Projectile earth = player.launchProjectile(Snowball.class, Utils.getProjectileVelocity(player, nearestEntity)); Projectile earth = player.launchProjectile(Snowball.class, Utils.getProjectileVelocity(player, nearestEntity));
@ -41,12 +42,18 @@ public class EarthSpell extends ItemBasedSpell {
// Set the fuse ticks to 40 (2 seconds) // Set the fuse ticks to 40 (2 seconds)
tnt.setFuseTicks(40); tnt.setFuseTicks(40);
tnt.setIsIncendiary(false);
} }
} }
} }
} }
} }
if (nearestEntity instanceof LivingEntity) {
// Damage the nearest entity
((LivingEntity) nearestEntity).damage(earthSpell.getDamage());
}
// Cancel the task // Cancel the task
cancel(); cancel();
} }

View File

@ -11,11 +11,10 @@ import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile; import org.bukkit.entity.Projectile;
import org.bukkit.entity.Snowball; import org.bukkit.entity.Snowball;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
public class FireSpell extends ItemBasedSpell { public class FireSpell extends ItemBasedSpell {
public FireSpell() { public FireSpell() {
super("Fireball", "Launches a fireball projectile", 1, "FIRE_CHARGE", 6, 25, 15, FireSpell::castFireball); super("Fireball", "Launches a fireball projectile", 1, 15, "FIRE_CHARGE", 6, 25, 15, true, FireSpell::castFireball);
} }
private static void castFireball(Player player, Entity nearestEntity) { private static void castFireball(Player player, Entity nearestEntity) {

View File

@ -1,33 +1,28 @@
package me.sticksdev.runicspells.spells; package me.sticksdev.runicspells.spells;
import me.sticksdev.runicspells.Runic_spells;
import me.sticksdev.runicspells.structures.ItemBasedSpell; import me.sticksdev.runicspells.structures.ItemBasedSpell;
import net.kyori.adventure.text.Component; import org.bukkit.Location;
import net.kyori.adventure.text.TextComponent; import org.bukkit.World;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
public class LightningSpell extends ItemBasedSpell { public class LightningSpell extends ItemBasedSpell {
public LightningSpell() { public LightningSpell() {
super("Lightning", "Strikes lightning at the target", 4, "BLAZE_ROD", 3, 10, 0, LightningSpell::castLightning); super("Lightning", "Strikes lightning at the target", 4, 25, "BLAZE_ROD", 3, 10, 0, true, LightningSpell::castLightning);
} }
private static void castLightning(Player player, Entity nearestEntity) { private static void castLightning(Player player, Entity nearestEntity) {
if (player.getTargetBlock(null, 100).getType().isAir()) { LightningSpell lightningSpell = new LightningSpell();
// Strike lightning at the player
player.getWorld().strikeLightning(player.getTargetBlock(null, 100).getLocation());
} else if(nearestEntity != null) {
// Strike lightning at the nearest entity
player.getWorld().strikeLightning(nearestEntity.getLocation());
} else {
final TextComponent errorMessage = Component.text()
.append(Component.text("[!]", NamedTextColor.RED, TextDecoration.BOLD))
.append(Component.text(" You must be near an entity/mob or player to cast this spell!", NamedTextColor.RED))
.build();
player.sendMessage(errorMessage); World world = nearestEntity.getLocation().getWorld();
Location location = nearestEntity.getLocation();
world.strikeLightningEffect(location);
if (nearestEntity instanceof LivingEntity) {
((LivingEntity) nearestEntity).damage(lightningSpell.getDamage());
} }
} }
} }

View File

@ -3,10 +3,7 @@ package me.sticksdev.runicspells.spells;
import me.sticksdev.runicspells.Runic_spells; import me.sticksdev.runicspells.Runic_spells;
import me.sticksdev.runicspells.structures.ItemBasedSpell; import me.sticksdev.runicspells.structures.ItemBasedSpell;
import me.sticksdev.runicspells.utils.Utils; import me.sticksdev.runicspells.utils.Utils;
import org.bukkit.entity.Entity; import org.bukkit.entity.*;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.Snowball;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
@ -14,12 +11,13 @@ import org.bukkit.World;
public class WaterSpell extends ItemBasedSpell { public class WaterSpell extends ItemBasedSpell {
public WaterSpell() { public WaterSpell() {
super("Water", "Launches a water projectile", 3, "WATER_BUCKET", 3, 10, 0, WaterSpell::castWater); super("Water", "Launches a water projectile", 3, 15, "WATER_BUCKET", 3, 10, 0, true, WaterSpell::castWater);
} }
private static void castWater(Player player, Entity nearestEntity) { private static void castWater(Player player, Entity nearestEntity) {
// Launches a water projectile // Launches a water projectile
Projectile water = player.launchProjectile(Snowball.class, Utils.getProjectileVelocity(player, nearestEntity)); Projectile water = player.launchProjectile(Snowball.class, Utils.getProjectileVelocity(player, nearestEntity));
WaterSpell waterSpell = new WaterSpell();
// Wait for it to hit something // Wait for it to hit something
new BukkitRunnable() { new BukkitRunnable() {
@ -47,6 +45,11 @@ public class WaterSpell extends ItemBasedSpell {
} }
} }
if (nearestEntity instanceof LivingEntity) {
// Damage the nearest entity
((LivingEntity) nearestEntity).damage(waterSpell.getDamage());
}
// Cancel the task // Cancel the task
cancel(); cancel();
} }

View File

@ -7,21 +7,46 @@ public class BaseSpell {
public String name; public String name;
public String description; public String description;
public int spellID; public int spellID;
public int range;
public BaseSpell(String name, String description, int spellID) { /**
* Creates a new BaseSpell object. All parameters are required.
*
* @param name The name of the spell.
* @param description The description of the spell.
* @param range The range of the spell.
* @param spellID The ID of the spell, hardcoded in the spell's class and not editable.
*/
public BaseSpell(String name, String description, int range, int spellID) {
this.name = name; this.name = name;
this.description = description; this.description = description;
this.spellID = spellID; this.spellID = spellID;
this.range = range;
} }
/**
* Gets the name of the spell.
*
* @return The name of the spell.
*/
public String getName() { public String getName() {
return name; return name;
} }
/**
* Gets the description of the spell.
*
* @return The description of the spell.
*/
public String getDescription() { public String getDescription() {
return description; return description;
} }
/**
* Gets the range of the spell.
*
* @return The range of the spell.
*/
public int getSpellID() { public int getSpellID() {
return spellID; return spellID;
} }

View File

@ -19,18 +19,37 @@ import org.jetbrains.annotations.Nullable;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
/**
* The main spells class that most spells extend from
* This class is used for spells that use an item to cast (e.g. a stick)
*/
public class ItemBasedSpell extends BaseSpell implements Listener { public class ItemBasedSpell extends BaseSpell implements Listener {
// Spell that uses Minecraft in-game item to use/cast // Spell that uses Minecraft in-game item to use/cast
private String item; private String item;
private int cooldown; private int cooldown;
private int manaCost; private int manaCost;
private int damage; private int damage;
private final BiConsumer<Player, Entity> castHandler; private boolean requiresNearbyEntity;
private BiConsumer<Player, Entity> castHandler;
private final CooldownHandler cooldownHandler = Runic_spells.getInstance().getCooldownHandler(); private final CooldownHandler cooldownHandler = Runic_spells.getInstance().getCooldownHandler();
private final ManaHandler manaHandler = Runic_spells.getInstance().getManaHandler(); private final ManaHandler manaHandler = Runic_spells.getInstance().getManaHandler();
public ItemBasedSpell(String name, String description, int spellId, String item, int cooldown, int manaCost, int damage, BiConsumer<Player, Entity> castHandler) { /**
super(name, description, spellId); * Creates a new ItemBasedSpell object. All parameters are required (some are pulled from BaseSpell).
*
* @param name The name of the spell
* @param description The description of the spell
* @param spellId The ID of the spell
* @param range The range of the spell (how far away it can be cast, in blocks)
* @param item The item to cast the spell with (e.g. "stick")
* @param cooldown The cooldown of the spell (in seconds)
* @param manaCost The mana cost of the spell
* @param damage The damage to the spell (NOTE: some spells may not use this due to API limitations)
* @param requiresNearbyEntity Whether the spell requires a nearby entity to cast
* @param castHandler The handler to run when the spell is cast
*/
public ItemBasedSpell(String name, String description, int spellId, int range, String item, int cooldown, int manaCost, int damage, boolean requiresNearbyEntity, BiConsumer<Player, Entity> castHandler) {
super(name, description, range, spellId);
this.name = name; this.name = name;
this.description = description; this.description = description;
this.item = item; this.item = item;
@ -38,47 +57,105 @@ public class ItemBasedSpell extends BaseSpell implements Listener {
this.manaCost = manaCost; this.manaCost = manaCost;
this.castHandler = castHandler; this.castHandler = castHandler;
this.damage = damage; this.damage = damage;
this.requiresNearbyEntity = requiresNearbyEntity;
this.range = range;
} }
/**
* Gets the item to cast the spell with
*
* @return The item to cast the spell with
*/
public String getItem() { public String getItem() {
return item; return item;
} }
/**
* Sets the item to cast the spell with
*
* @param item The item to cast the spell with
*/
public void setItem(String item) { public void setItem(String item) {
this.item = item; this.item = item;
} }
/**
* Gets the cooldown of the spell
*
* @return The cooldown of the spell
*/
public int getCooldown() { public int getCooldown() {
return cooldown; return cooldown;
} }
/**
* Sets the cooldown of the spell
*
* @param cooldown The cooldown of the spell
*/
public void setCooldown(int cooldown) { public void setCooldown(int cooldown) {
this.cooldown = cooldown; this.cooldown = cooldown;
} }
/**
* Gets the mana cost of the spell
*
* @return The mana cost of the spell
*/
public int getManaCost() { public int getManaCost() {
return manaCost; return manaCost;
} }
/**
* Sets the mana cost of the spell
*
* @param manaCost The mana cost of the spell
*/
public void setManaCost(int manaCost) { public void setManaCost(int manaCost) {
this.manaCost = manaCost; this.manaCost = manaCost;
} }
/**
* Calls the BiConsumer cast handler of the spell and then casts the spell
*/
public void cast(Player player, Entity nearestEntity) { public void cast(Player player, Entity nearestEntity) {
if (castHandler != null) { if (castHandler != null) {
castHandler.accept(player, nearestEntity); castHandler.accept(player, nearestEntity);
} }
} }
/**
* Gets the damage of the spell
*
* @return The damage of the spell
*/
public int getDamage() { public int getDamage() {
return damage; return damage;
} }
/**
* Sets the damage of the spell
*
* @param damage The damage of the spell
*/
public void setDamage(int damage) { public void setDamage(int damage) {
this.damage = damage; this.damage = damage;
} }
// Listen to the interact event for only the item specified /**
* Sets the spell's range (how far away it can be cast, in blocks)
*
* @param range The spell's range (how far away it can be cast, in blocks)
*/
public void setRange(int range) {
this.range = range;
}
/**
* The main handler for spells that use an item to cast
*
* @param event The PlayerInteractEvent
*/
@EventHandler @EventHandler
public void onPlayerInteract(PlayerInteractEvent event) { public void onPlayerInteract(PlayerInteractEvent event) {
// TODO: Little messy, could clean this up later // TODO: Little messy, could clean this up later
@ -94,8 +171,22 @@ public class ItemBasedSpell extends BaseSpell implements Listener {
// No cooldown check if they have enough mana // No cooldown check if they have enough mana
boolean canCast = manaHandler.canCast(player, this.manaCost); boolean canCast = manaHandler.canCast(player, this.manaCost);
if (canCast) { if (canCast) {
// They have enough mana, so cast the spell // Get nearest entity (in player's line of sight)
cast(player, event.getPlayer().getNearbyEntities(10, 10, 10).stream().findFirst().orElse(null)); Entity nearestEntity = player.getTargetEntity(this.range);
if (nearestEntity == null && requiresNearbyEntity) {
// No entity found, so tell them
final TextComponent manaMessage = Component.text()
.append(Component.text("[!]", NamedTextColor.RED, TextDecoration.BOLD))
.append(Component.text(" Could not find a nearby entity or player to cast "))
.append(Component.text(this.name, NamedTextColor.BLUE, TextDecoration.BOLD))
.append(Component.text("!"))
.build();
player.sendMessage(manaMessage);
return;
}
cast(player, nearestEntity);
cooldownHandler.setCooldown(player, this, this.cooldown); cooldownHandler.setCooldown(player, this, this.cooldown);
manaHandler.removeMana(player, this.manaCost); manaHandler.removeMana(player, this.manaCost);
@ -138,6 +229,11 @@ public class ItemBasedSpell extends BaseSpell implements Listener {
} }
} }
/**
* Set's the spell's overrides
*
* @param overrides The spell's overrides (nullable)
*/
public void setOverrides(@Nullable SpellOverride overrides) { public void setOverrides(@Nullable SpellOverride overrides) {
if (overrides != null) { if (overrides != null) {
if (overrides.OverrideTool != null) { if (overrides.OverrideTool != null) {
@ -164,6 +260,10 @@ public class ItemBasedSpell extends BaseSpell implements Listener {
this.damage = overrides.OverrideDamage; this.damage = overrides.OverrideDamage;
Logger.info("Overriding damage for spell " + this.name + " to " + overrides.OverrideDamage); Logger.info("Overriding damage for spell " + this.name + " to " + overrides.OverrideDamage);
} }
if (overrides.OverrideRange != null && overrides.OverrideRange != 0) {
this.range = overrides.OverrideRange;
Logger.info("Overriding range for spell " + this.name + " to " + overrides.OverrideRange);
}
} else { } else {
Logger.warning("setOverrides() was called for spell " + this.name + " but no overrides were provided - falling back to defaults."); Logger.warning("setOverrides() was called for spell " + this.name + " but no overrides were provided - falling back to defaults.");
} }

View File

@ -1,6 +1,11 @@
package me.sticksdev.runicspells.structures; package me.sticksdev.runicspells.structures;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
/**
* Class to handle overriding a spell's values. (e.g. overriding a spell's tool, mana cost, cooldown, damage, or range)
*/
public class SpellOverride { public class SpellOverride {
@Nullable @Nullable
String OverrideTool; String OverrideTool;
@ -14,21 +19,37 @@ public class SpellOverride {
@Nullable @Nullable
Integer OverrideDamage; Integer OverrideDamage;
public SpellOverride(@Nullable String overrideSpellTool, @Nullable String overrideManaCost, @Nullable String overrideCooldown, @Nullable String overrideDamage) { @Nullable
Integer OverrideRange;
/**
* Creates a new SpellOverride object. If any of the parameters are null, they will not be overridden and default to the spell's values.
*
* @param overrideSpellTool The tool to override the spell's tool with.
* @param overrideManaCost The mana cost to override the spell's mana cost with.
* @param overrideCooldown The cooldown to override the spell's cooldown with.
* @param overrideDamage The damage to override the spell's damage with.
* @param overrideRange The range to override the spell's range with.
*/
public SpellOverride(@Nullable String overrideSpellTool, int overrideManaCost, int overrideCooldown, int overrideDamage, int overrideRange) {
if (overrideSpellTool != null) { if (overrideSpellTool != null) {
this.OverrideTool = overrideSpellTool; this.OverrideTool = overrideSpellTool;
} }
if (overrideManaCost != null) { if (overrideManaCost != 0) {
this.OverrideManaCost = Integer.parseInt(overrideManaCost); this.OverrideManaCost = overrideManaCost;
} }
if (overrideCooldown != null) { if (overrideCooldown != 0) {
this.OverrideCooldown = Integer.parseInt(overrideCooldown); this.OverrideCooldown = overrideCooldown;
} }
if (overrideDamage != null) { if (overrideDamage != 0) {
this.OverrideDamage = Integer.parseInt(overrideDamage); this.OverrideDamage = overrideDamage;
}
if (overrideRange != 0) {
this.OverrideRange = overrideRange;
} }
} }
} }

View File

@ -3,18 +3,38 @@ package me.sticksdev.runicspells.utils;
import me.sticksdev.runicspells.Runic_spells; import me.sticksdev.runicspells.Runic_spells;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/**
* A simple logger class for the plugin.
* Uses the plugin's logger to log messages.
* See {@link java.util.logging.Logger} for more information.
*/
public class Logger { public class Logger {
private static final Runic_spells plugin = Runic_spells.getInstance(); private static final Runic_spells plugin = Runic_spells.getInstance();
private static final java.util.logging.@NotNull Logger logger = plugin.getLogger(); private static final java.util.logging.@NotNull Logger logger = plugin.getLogger();
/**
* Logs a message to the console.
*
* @param message The message to log.
*/
public static void info(String message) { public static void info(String message) {
logger.info(message); logger.info(message);
} }
/**
* Logs a warning to the console.
*
* @param message The message to log.
*/
public static void warning(String message) { public static void warning(String message) {
logger.warning(message); logger.warning(message);
} }
/**
* Logs a severe error to the console.
*
* @param message The message to log.
*/
public static void severe(String message) { public static void severe(String message) {
logger.severe(message); logger.severe(message);
} }

View File

@ -1,12 +1,13 @@
package me.sticksdev.runicspells.utils; package me.sticksdev.runicspells.utils;
import me.sticksdev.runicspells.Runic_spells; import me.sticksdev.runicspells.Runic_spells;
import redis.clients.jedis.CommandObject;
import redis.clients.jedis.JedisPooled; import redis.clients.jedis.JedisPooled;
import redis.clients.jedis.params.SetParams;
import java.util.HashMap;
/**
* Redis connection handler
* This class is used to handle the Redis connections and
* operations for the plugin
*/
public class Redis { public class Redis {
private final Runic_spells plugin = Runic_spells.getInstance(); private final Runic_spells plugin = Runic_spells.getInstance();
private final String host = plugin.getConfigHandler().getConfig().getString("redis.host"); private final String host = plugin.getConfigHandler().getConfig().getString("redis.host");
@ -15,6 +16,9 @@ public class Redis {
// Create a new JedisPooled instance // Create a new JedisPooled instance
private static JedisPooled pool; private static JedisPooled pool;
/**
* Initialize the Redis connection for the current instance
*/
public void init() { public void init() {
try { try {
Logger.info("Connecting to Redis..."); Logger.info("Connecting to Redis...");
@ -31,10 +35,19 @@ public class Redis {
} }
} }
/**
* Gets the current pool handle of the instance
*
* @return JedisPooled instance
*/
public JedisPooled getPool() { public JedisPooled getPool() {
return pool; return pool;
} }
/**
* Shuts down the current Redis connection
* This is only called on plugin disable
*/
public void close() { public void close() {
pool.close(); pool.close();
} }

View File

@ -4,7 +4,18 @@ import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
/**
* Simple Utils class for repeated code or tasks.
*/
public class Utils { public class Utils {
/**
* Gets the velocity of a projectile based on the player's location and the target's location.
*
* @param player The player to get the velocity from.
* @param target The target to get the velocity to.
* @return The velocity of the projectile.
* @see org.bukkit.util.Vector Vector
*/
public static Vector getProjectileVelocity(Player player, Entity target) { public static Vector getProjectileVelocity(Player player, Entity target) {
Vector direction; Vector direction;
if (target != null) { if (target != null) {

View File

@ -11,6 +11,10 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
/**
* YAML file handler
* This class is used to handle the YAML files for the plugin (spells and config)
*/
public class Yaml { public class Yaml {
// Basic YAML Loader and data holder for minecraft plugins // Basic YAML Loader and data holder for minecraft plugins
private final Runic_spells plugin = Runic_spells.getInstance(); private final Runic_spells plugin = Runic_spells.getInstance();
@ -96,6 +100,12 @@ public class Yaml {
return configConfig; return configConfig;
} }
/**
* Returns the spell overrides for a given spell
*
* @param spellName Name of the spell to get overrides for
* @return SpellOverride object or null if no overrides are found
*/
@Nullable @Nullable
public SpellOverride getSpellOverrides(String spellName) { public SpellOverride getSpellOverrides(String spellName) {
ConfigurationSection spellOverridesBlock = getSpellsConfig().getConfigurationSection("overrideSpells"); ConfigurationSection spellOverridesBlock = getSpellsConfig().getConfigurationSection("overrideSpells");
@ -113,14 +123,21 @@ public class Yaml {
} }
String overrideSpellTool = spellOverrides.getString("OverrideTool"); String overrideSpellTool = spellOverrides.getString("OverrideTool");
String overrideManaCost = spellOverrides.getString("OverrideManaCost"); int overrideManaCost = spellOverrides.getInt("OverrideManaCost", 0);
String overrideCooldown = spellOverrides.getString("OverrideCooldown"); int overrideCooldown = spellOverrides.getInt("OverrideCooldown", 0);
String overrideDamage = spellOverrides.getString("OverrideDamage"); int overrideDamage = spellOverrides.getInt("OverrideDamage", 0);
int overrideRange = spellOverrides.getInt("OverrideRange", 0);
return new SpellOverride(overrideSpellTool, overrideManaCost, overrideCooldown, overrideDamage); return new SpellOverride(overrideSpellTool, overrideManaCost, overrideCooldown, overrideDamage, overrideRange);
} }
/**
* Returns whether a spell is enabled in the config
*
* @param spellName Name of the spell to check
* @return boolean
*/
public boolean getIsSpellEnabled(String spellName) { public boolean getIsSpellEnabled(String spellName) {
// Check if it's in the enabledSpells list // Check if it's in the enabledSpells list
List<?> enabledSpells = getSpellsConfig().getList("enabledSpells"); List<?> enabledSpells = getSpellsConfig().getList("enabledSpells");
@ -132,4 +149,12 @@ public class Yaml {
return enabledSpells.contains(spellName); return enabledSpells.contains(spellName);
} }
/**
* Reloads the config file(s)
*/
public void reload() {
destroy();
init();
}
} }

View File

@ -2,3 +2,10 @@ name: runic-spells
version: '${project.version}' version: '${project.version}'
main: me.sticksdev.runicspells.Runic_spells main: me.sticksdev.runicspells.Runic_spells
api-version: 1.19 api-version: 1.19
commands:
reloadrs:
description: Reloads the plugin and configuration files.
usage: /<command>
permission: runicspells.reload
aliases: [ rl ]

View File

@ -18,6 +18,7 @@ enabledSpells:
# OverrideManaCost: 10 # OverrideManaCost: 10
# OverrideCooldown: 10 # OverrideCooldown: 10
# OverrideDamage: 10 # OverrideDamage: 10
# OverrideRange: 10
# By default, this is commented out # By default, this is commented out
# overrideSpells: # overrideSpells:
@ -25,4 +26,5 @@ enabledSpells:
# OverrideTool: "DIAMOND_HOE" # OverrideTool: "DIAMOND_HOE"
# OverrideManaCost: 10 # OverrideManaCost: 10
# OverrideCooldown: 10 # OverrideCooldown: 10
# OverrideDamage: 10 # OverrideDamage: 10
# OverrideRange: 10