diff --git a/src/main/java/me/sticksdev/runicspells/Runic_spells.java b/src/main/java/me/sticksdev/runicspells/Runic_spells.java index 1e1011d..62e4598 100644 --- a/src/main/java/me/sticksdev/runicspells/Runic_spells.java +++ b/src/main/java/me/sticksdev/runicspells/Runic_spells.java @@ -1,11 +1,11 @@ package me.sticksdev.runicspells; +import me.sticksdev.runicspells.handlers.SpellHandler; import me.sticksdev.runicspells.utils.Yaml; import org.bukkit.plugin.java.JavaPlugin; public final class Runic_spells extends JavaPlugin { public static Runic_spells instance; - private final Yaml config = new Yaml(this); // TODO: Maybe make this use instance instead of this - was dealing with a null pointer exception @Override @@ -15,6 +15,9 @@ public final class Runic_spells extends JavaPlugin { getLogger().info("Runic Spells has been enabled!"); getLogger().info("Loading config..."); config.init(); + + // Register spells + SpellHandler.registerSpells(); } @Override diff --git a/src/main/java/me/sticksdev/runicspells/handlers/CooldownHandler.java b/src/main/java/me/sticksdev/runicspells/handlers/CooldownHandler.java new file mode 100644 index 0000000..ba12078 --- /dev/null +++ b/src/main/java/me/sticksdev/runicspells/handlers/CooldownHandler.java @@ -0,0 +1,8 @@ +package me.sticksdev.runicspells.handlers; +import org.bukkit.entity.Player; + +import java.util.HashMap; + +public class CooldownHandler { + +} diff --git a/src/main/java/me/sticksdev/runicspells/handlers/ManaHandler.java b/src/main/java/me/sticksdev/runicspells/handlers/ManaHandler.java new file mode 100644 index 0000000..03f1f20 --- /dev/null +++ b/src/main/java/me/sticksdev/runicspells/handlers/ManaHandler.java @@ -0,0 +1,4 @@ +package me.sticksdev.runicspells.handlers; + +public class ManaHandler { +} diff --git a/src/main/java/me/sticksdev/runicspells/handlers/SpellHandler.java b/src/main/java/me/sticksdev/runicspells/handlers/SpellHandler.java new file mode 100644 index 0000000..1fd67a6 --- /dev/null +++ b/src/main/java/me/sticksdev/runicspells/handlers/SpellHandler.java @@ -0,0 +1,56 @@ +package me.sticksdev.runicspells.handlers; +import me.sticksdev.runicspells.Runic_spells; +import me.sticksdev.runicspells.spells.FireSpell; +import me.sticksdev.runicspells.structures.ItemBasedSpell; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.Material; + +import java.util.HashMap; + +public class SpellHandler { + public static HashMap itemBasedSpells = new HashMap<>(); + + public static void registerItemSpell(ItemBasedSpell spell) { + // Check if the item provided is a valid material + try { + Material itemMaterial = Material.valueOf(spell.getItem()); + } catch (IllegalArgumentException e) { + Runic_spells.getInstance().getLogger().warning("Invalid item material provided for spell " + spell.getName() + "!"); + Runic_spells.getInstance().getLogger().warning("Item material provided: " + spell.getItem()); + return; + } + + // Check if the spell is already registered + if (itemBasedSpells.containsKey(spell.getName())) { + Runic_spells.getInstance().getLogger().warning("Spell " + spell.getName() + " is already registered!"); + return; + } + + // Listen for "use" on that item + Runic_spells.getInstance().getServer().getPluginManager().registerEvents(spell, Runic_spells.getInstance()); + + // Register the spell + itemBasedSpells.put(spell.getName(), spell); + + // Log the spell registration + Runic_spells.getInstance().getLogger().info("Registered spell " + spell.getName() + "!"); + } + + public static ItemBasedSpell getItemSpell(String name) { + return itemBasedSpells.get(name); + } + + public void executeSpell(String name, Player player, Entity nearestEntity) { + ItemBasedSpell spell = getItemSpell(name); + if (spell != null) { + spell.cast(player, nearestEntity); + } + } + + public static void registerSpells() { + // Register spells + Runic_spells.getInstance().getLogger().info("Registering spells..."); + registerItemSpell(new FireSpell()); + } +} diff --git a/src/main/java/me/sticksdev/runicspells/spells/FireSpell.java b/src/main/java/me/sticksdev/runicspells/spells/FireSpell.java new file mode 100644 index 0000000..d940ed2 --- /dev/null +++ b/src/main/java/me/sticksdev/runicspells/spells/FireSpell.java @@ -0,0 +1,70 @@ +package me.sticksdev.runicspells.spells; + +import me.sticksdev.runicspells.Runic_spells; +import me.sticksdev.runicspells.structures.ItemBasedSpell; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; +import org.bukkit.entity.Snowball; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +public class FireSpell extends ItemBasedSpell { + public FireSpell() { + super("Fire Spell", "Launches a fireball projectile", "FIRE_CHARGE", 10, 25, 15, FireSpell::castFireball); + } + + private static void castFireball(Player player, Entity nearestEntity) { + // Launches a fireball projectile + Projectile fireball = player.launchProjectile(Snowball.class, getProjectileVelocity(player, nearestEntity)); + + // Set the fireball's damage + fireball.setFireTicks(100); + + // Wait for it to hit something + new BukkitRunnable() { + @Override + public void run() { + if (fireball.isDead() || fireball.isOnGround()) { + // Get the location where the fireball hit + Location impactLocation = fireball.getLocation(); + + // Spawn fire around the impact location + World world = impactLocation.getWorld(); + if (world != null) { + for (int x = -2; x <= 2; x++) { + for (int y = -2; y <= 2; y++) { + for (int z = -2; z <= 2; z++) { + Location fireLocation = impactLocation.clone().add(x, y, z); + if (fireLocation.getBlock().getType() == Material.AIR) { + fireLocation.getBlock().setType(Material.FIRE); + } + + // Add explosion effect + world.createExplosion(fireLocation, 0.0F, false); + } + } + } + } + + // Cancel the task + cancel(); + } + } + }.runTaskTimer(Runic_spells.getInstance(), 0L, 1L); + } + + + private static Vector getProjectileVelocity(Player player, Entity target) { + Vector direction; + if (target != null) { + direction = target.getLocation().toVector().subtract(player.getLocation().toVector()); + } else { + direction = player.getEyeLocation().getDirection(); + } + return direction.normalize().multiply(1.5); + } +} diff --git a/src/main/java/me/sticksdev/runicspells/structures/BaseSpell.java b/src/main/java/me/sticksdev/runicspells/structures/BaseSpell.java index 5ae3464..2af4d82 100644 --- a/src/main/java/me/sticksdev/runicspells/structures/BaseSpell.java +++ b/src/main/java/me/sticksdev/runicspells/structures/BaseSpell.java @@ -7,4 +7,16 @@ public class BaseSpell { public String name; public String description; + public BaseSpell(String name, String description) { + this.name = name; + this.description = description; + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } } diff --git a/src/main/java/me/sticksdev/runicspells/structures/ItemBasedSpell.java b/src/main/java/me/sticksdev/runicspells/structures/ItemBasedSpell.java index 86f743b..ee6504d 100644 --- a/src/main/java/me/sticksdev/runicspells/structures/ItemBasedSpell.java +++ b/src/main/java/me/sticksdev/runicspells/structures/ItemBasedSpell.java @@ -1,19 +1,76 @@ package me.sticksdev.runicspells.structures; -public class ItemBasedSpell extends BaseSpell { - // Spell that uses minecraft in-game item to use/cast - public String item; - public int amount; - public int cooldown; - public int manaCost; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerInteractEvent; +import java.util.function.BiConsumer; - public ItemBasedSpell(String name, String description, String item, int amount, int cooldown, int manaCost) { +public class ItemBasedSpell extends BaseSpell implements Listener { + // Spell that uses Minecraft in-game item to use/cast + private String item; + private int cooldown; + private int manaCost; + private int damage; + private final BiConsumer castHandler; + + public ItemBasedSpell(String name, String description, String item, int cooldown, int manaCost, int damage, BiConsumer castHandler) { + super(name, description); this.name = name; this.description = description; this.item = item; - this.amount = amount; this.cooldown = cooldown; this.manaCost = manaCost; + this.castHandler = castHandler; + this.damage = damage; + } + + public String getItem() { + return item; + } + + public void setItem(String item) { + this.item = item; + } + + public int getCooldown() { + return cooldown; + } + + public void setCooldown(int cooldown) { + this.cooldown = cooldown; + } + + public int getManaCost() { + return manaCost; + } + + public void setManaCost(int manaCost) { + this.manaCost = manaCost; + } + + public void cast(Player player, Entity nearestEntity) { + if (castHandler != null) { + castHandler.accept(player, nearestEntity); + } + } + + public int getDamage() { + return damage; + } + + public void setDamage(int damage) { + this.damage = damage; + } + + // Listen to the interact event for only the item specified + @EventHandler + public void onPlayerInteract(PlayerInteractEvent event) { + if (event.getItem() != null && event.getItem().getType().toString().equals(item)) { + // For now, just cast the spell on the nearest entity + cast(event.getPlayer(), event.getPlayer().getNearbyEntities(5, 5, 5).stream().findFirst().orElse(null)); + } } } diff --git a/src/main/resources/spells.yml b/src/main/resources/spells.yml index 46c0c8e..20486cd 100644 --- a/src/main/resources/spells.yml +++ b/src/main/resources/spells.yml @@ -1 +1,25 @@ -# Spells configuration file \ No newline at end of file +#################### +# Spells Configuration File +#################### + +# Enabled Spells +# If you want to disable a spell, just remove it from this list +enabledSpells: + - "Fireball" + +# Override blocks +# You can override any spell as long as it's enabled in the list above +# Example would be +# Fireball: +# OverrideTool: "DIAMOND_HOE" +# OverrideManaCost: 10 +# OverrideCooldown: 10 +# OverrideDamage: 10 +# By default, this is commented out + +# overrideSpells: +# Fireball: +# OverrideTool: "DIAMOND_HOE" +# OverrideManaCost: 10 +# OverrideCooldown: 10 +# OverrideDamage: 10 \ No newline at end of file