diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..4e7f670
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.gitea/workflows/main.yml b/.gitea/workflows/main.yml
index 29cdbdc..2f261c0 100644
--- a/.gitea/workflows/main.yml
+++ b/.gitea/workflows/main.yml
@@ -1,23 +1,29 @@
name: Java CI with Maven
-on: [push]
+on:
+ push:
+ branches:
+ - "main"
+ pull_request:
+ branches:
+ - "*"
jobs:
build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
- - name: Set up JDK 21
- uses: actions/setup-java@v4
- with:
- java-version: '21'
- distribution: 'temurin'
- cache: maven
- - uses: stCarolas/setup-maven@v5
- - name: Build with Maven
- run: mvn -B package --file pom.xml
- - name: Release
- uses: akkuman/gitea-release-action@v1
- with:
- files: ./target/fantasysmp*.jar
- token: '${{secrets.RELEASE_TOKEN}}'
\ No newline at end of file
+ - uses: actions/checkout@v4
+ - name: Set up JDK 21
+ uses: actions/setup-java@v4
+ with:
+ java-version: "21"
+ distribution: "temurin"
+ cache: maven
+ - uses: stCarolas/setup-maven@v5
+ - name: Build with Maven
+ run: mvn -B package --file pom.xml
+ - name: Release
+ uses: akkuman/gitea-release-action@v1
+ with:
+ files: ./target/fantasysmp*.jar
+ token: "${{secrets.RELEASE_TOKEN}}"
diff --git a/.project b/.project
new file mode 100644
index 0000000..301c9e1
--- /dev/null
+++ b/.project
@@ -0,0 +1,34 @@
+
+
+ fantasysmp
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
+
+ 1756828330981
+
+ 30
+
+ org.eclipse.core.resources.regexFilterMatcher
+ node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__
+
+
+
+
diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..abdea9a
--- /dev/null
+++ b/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,4 @@
+eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
+encoding//src/main/resources=UTF-8
+encoding/=UTF-8
diff --git a/.settings/org.eclipse.jdt.apt.core.prefs b/.settings/org.eclipse.jdt.apt.core.prefs
new file mode 100644
index 0000000..d4313d4
--- /dev/null
+++ b/.settings/org.eclipse.jdt.apt.core.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.apt.aptEnabled=false
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..77174c3
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,9 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=21
+org.eclipse.jdt.core.compiler.compliance=21
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.processAnnotations=disabled
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=21
diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/src/main/java/dev/zxq5/fantasysmp/Fantasysmp.java b/src/main/java/dev/zxq5/fantasysmp/Fantasysmp.java
index f8e060b..a27d449 100644
--- a/src/main/java/dev/zxq5/fantasysmp/Fantasysmp.java
+++ b/src/main/java/dev/zxq5/fantasysmp/Fantasysmp.java
@@ -1,11 +1,11 @@
package dev.zxq5.fantasysmp;
-import dev.zxq5.fantasysmp.events.HereticWarner;
-import dev.zxq5.fantasysmp.events.StevenKillCheck;
+import dev.zxq5.fantasysmp.events.*;
+import dev.zxq5.fantasysmp.groups.Commands;
+import dev.zxq5.fantasysmp.groups.Team;
import dev.zxq5.fantasysmp.items.*;
import dev.zxq5.fantasysmp.warps.Warp;
import dev.zxq5.fantasysmp.warps.Warper;
-import org.bukkit.entity.Panda;
import org.bukkit.plugin.java.JavaPlugin;
public final class Fantasysmp extends JavaPlugin {
@@ -19,38 +19,41 @@ public final class Fantasysmp extends JavaPlugin {
try {
Warp.loadWarps();
+ Team.loadTeams();
} catch (Exception e) {
e.printStackTrace();
}
getCommand("home").setExecutor(new Warper());
getCommand("sethome").setExecutor(new Warper());
-
getCommand("setwarp").setExecutor(new Warper());
+ getCommand("delwarp").setExecutor(new Warper());
getCommand("warp").setExecutor(new Warper());
+ getCommand("rewarps").setExecutor(new Warper());
+ getCommand("warps").setExecutor(new Warper());
+ getCommand("team").setExecutor(new Commands());
- getCommand("reloadwarps").setExecutor(new Warper());
+ getServer().getPluginManager().registerEvents(new Chat(), this);
- getServer().broadcastMessage("registered commands + \n /home \n /sethome \n /warp \n /setwarp");
+ HeresyChecker heresyChecker = new HeresyChecker();
+ heresyChecker.scheduleHeresyChecker();
+ getServer().getPluginManager().registerEvents(heresyChecker, this);
- GenericGearSet witherite = new Witherite();
- witherite.registerRecipes();
+ getServer().getPluginManager().registerEvents(new DeathMessageCustomiser(), this);
- Lightning lightning = new Lightning();
- lightning.registerRecipes();
- StevensWrath stevensWrath = new StevensWrath();
- stevensWrath.registerRecipes();
-
- getServer().getPluginManager().registerEvents(new StevenKillCheck(), this);
-
- HereticWarner hereticWarner = new HereticWarner();
- hereticWarner.checkHereticInventory();
+ XrayDetector xrayDetector = new XrayDetector();
+ getServer().getPluginManager().registerEvents(xrayDetector, this);
}
@Override
public void onDisable() {
- // Plugin shutdown logic
+ try {
+ Warp.saveWarps();
+ Team.saveTeams();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
}
diff --git a/src/main/java/dev/zxq5/fantasysmp/chatutils/Chat.java b/src/main/java/dev/zxq5/fantasysmp/chatutils/Chat.java
new file mode 100644
index 0000000..4c1a298
--- /dev/null
+++ b/src/main/java/dev/zxq5/fantasysmp/chatutils/Chat.java
@@ -0,0 +1,22 @@
+package dev.zxq5.fantasysmp.chatutils;
+
+import org.bukkit.ChatColor;
+import org.bukkit.entity.Player;
+
+public class Chat {
+ public static final String EVENT_PREFIX = ChatColor.WHITE + "<" + ChatColor.AQUA + "Server" + ChatColor.WHITE + "> " + ChatColor.RESET;
+
+ private Chat() {}
+
+ public static void success(Player player, String message) {
+ player.sendMessage(EVENT_PREFIX + ChatColor.GREEN + message);
+ }
+
+ public static void error(Player player, String message) {
+ player.sendMessage(EVENT_PREFIX + ChatColor.RED + message);
+ }
+
+ public static void info(Player player, String message) {
+ player.sendMessage(EVENT_PREFIX + message);
+ }
+}
diff --git a/src/main/java/dev/zxq5/fantasysmp/events/Chat.java b/src/main/java/dev/zxq5/fantasysmp/events/Chat.java
new file mode 100644
index 0000000..c4be163
--- /dev/null
+++ b/src/main/java/dev/zxq5/fantasysmp/events/Chat.java
@@ -0,0 +1,16 @@
+package dev.zxq5.fantasysmp.events;
+
+import dev.zxq5.fantasysmp.groups.Team;
+import org.bukkit.ChatColor;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+
+public class Chat implements Listener {
+ @EventHandler
+ public void onChat(org.bukkit.event.player.AsyncPlayerChatEvent event) {
+ Team team = Team.fromMember(event.getPlayer());
+ if (team != null) {
+ event.setFormat(ChatColor.WHITE + "[" + team.getTag() + ChatColor.WHITE + "]" + ChatColor.RESET + " <%s> %s");
+ }
+ }
+}
diff --git a/src/main/java/dev/zxq5/fantasysmp/events/DeathMessageCustomiser.java b/src/main/java/dev/zxq5/fantasysmp/events/DeathMessageCustomiser.java
new file mode 100644
index 0000000..eb736f3
--- /dev/null
+++ b/src/main/java/dev/zxq5/fantasysmp/events/DeathMessageCustomiser.java
@@ -0,0 +1,39 @@
+package dev.zxq5.fantasysmp.events;
+
+import org.bukkit.damage.DamageType;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.entity.PlayerDeathEvent;
+
+import java.util.Random;
+
+public class DeathMessageCustomiser implements Listener {
+ private static final Random random = new Random();
+ private static final String[] FALL_MESSAGES = new String[] {
+ "%p Forgot to use chalk.",
+ "%p Tried to free solo.",
+ "%p Tried lead climbing.",
+ "%p Discovered it was not in fact a jug.",
+ "It was not a v1 in %p's gym.",
+ "%p slipped on a sloper",
+ "%p thought the ravine was a boulder problem",
+ "%p's fingers were not cut out for crack climbing",
+ "%p got a leg cramp",
+ "%p forgot to check their harness",
+ "%p didn't send the dyno",
+ "%p tried to static a 4 block jump",
+ "%p's climbing shoes didn't fit",
+ "%p wasn't flexible enough"
+ };
+
+ @EventHandler
+ public void onPlayerDeath(PlayerDeathEvent event) {
+ int randomIndex = random.nextInt(FALL_MESSAGES.length);
+ Player player = event.getEntity();
+
+ if (event.getDamageSource().getDamageType() == DamageType.FALL) {
+ event.setDeathMessage(FALL_MESSAGES[randomIndex].replace("%p", player.getName()));
+ }
+ }
+}
diff --git a/src/main/java/dev/zxq5/fantasysmp/events/HeresyChecker.java b/src/main/java/dev/zxq5/fantasysmp/events/HeresyChecker.java
new file mode 100644
index 0000000..93a48f0
--- /dev/null
+++ b/src/main/java/dev/zxq5/fantasysmp/events/HeresyChecker.java
@@ -0,0 +1,148 @@
+package dev.zxq5.fantasysmp.events;
+
+import org.bukkit.*;
+import org.bukkit.entity.Chicken;
+import org.bukkit.entity.EntityType;
+import org.bukkit.entity.Item;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.entity.EntityDamageByEntityEvent;
+import org.bukkit.event.entity.EntityDamageEvent;
+import org.bukkit.event.entity.ProjectileHitEvent;
+import org.bukkit.event.player.PlayerItemConsumeEvent;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.plugin.Plugin;
+import org.bukkit.potion.PotionEffect;
+import org.bukkit.potion.PotionEffectType;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.bukkit.Bukkit.*;
+
+public class HeresyChecker implements Listener {
+ private final HashMap heretics;
+ private final HashMap formerHeretics;
+
+ public HeresyChecker() {
+ this.heretics = new HashMap<>();
+ this.formerHeretics = new HashMap<>();
+ }
+
+ @EventHandler
+ public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
+ if (event.getEntity() instanceof Chicken) {
+ event.setCancelled(true);
+
+ if (event.getDamager() instanceof Player heretic) {
+ executeHeretic(heretic);
+ }
+ }
+ }
+
+ @EventHandler
+ public void onEntityDamage(EntityDamageEvent event) {
+ if (event.getEntity() instanceof Chicken) {
+ event.setCancelled(true);
+
+ if ( event.getDamageSource().getCausingEntity() instanceof Player heretic) {
+ executeHeretic(heretic);
+ }
+ }
+ }
+
+ @EventHandler
+ public void onProjectileHit(ProjectileHitEvent event) {
+ if (event.getHitEntity() instanceof Chicken && event.getEntity().getShooter() instanceof Player heretic) {
+ if (event.getEntity().getType() == EntityType.EGG) return;
+ if (event.getEntity().getType() == EntityType.SNOWBALL) return;
+
+ event.setCancelled(true);
+ executeHeretic(heretic);
+ }
+ }
+
+ @EventHandler
+ public void onEntitySpawn(org.bukkit.event.entity.EntitySpawnEvent event) {
+ if (event.getEntity() instanceof Chicken steven) {
+ steven.setCustomName("Steven");
+ }
+ }
+
+ @EventHandler
+ public void onPlayerEatChicken(PlayerItemConsumeEvent event) {
+ Material type = event.getItem().getType();
+
+ if (type == Material.COOKED_CHICKEN || type == Material.CHICKEN) {
+ this.executeHeretic(event.getPlayer());
+ }
+ }
+
+ public void scheduleHeresyChecker() {
+ Bukkit.getScheduler().scheduleSyncRepeatingTask(getPluginManager().getPlugin("fantasysmp"), this::checkHeretics, 0, 20);
+ Bukkit.getScheduler().scheduleSyncRepeatingTask(getPluginManager().getPlugin("fantasysmp"), () -> {
+ for (Player heretic : this.formerHeretics.keySet() ) {
+ this.formerHeretics.put(heretic, this.formerHeretics.get(heretic) - 1);
+ }
+ }, 0, 200);
+ }
+
+ public void checkHeretics() {
+ for ( Player player : Bukkit.getServer().getOnlinePlayers() ) {
+ if (player.getInventory().contains(Material.CHICKEN) || player.getInventory().contains(Material.COOKED_CHICKEN)) {
+ if (!this.heretics.containsKey(player)) {
+ this.heretics.put(player, this.formerHeretics.getOrDefault(player, 0));
+ }
+ } else if (this.heretics.containsKey(player)) {
+ this.formerHeretics.put(player, this.heretics.get(player));
+ this.heretics.remove(player);
+ }
+ }
+
+ for (Map.Entry entry : this.heretics.entrySet() ) {
+ entry.setValue(entry.getValue() + 1);
+ warnHeretic(entry.getKey());
+ if ( entry.getValue() >= 5 ) {
+ punishHeretic(entry.getKey());
+ }
+ }
+ }
+
+ public void punishHeretic(Player heretic) {
+ heretic.addPotionEffect(new PotionEffect(PotionEffectType.POISON, 20 * 2, 0));
+ heretic.addPotionEffect(new PotionEffect(PotionEffectType.WITHER, 20 * 2, 0));
+ heretic.addPotionEffect(new PotionEffect(PotionEffectType.SLOWNESS, 20 * 2, 3));
+ heretic.addPotionEffect(new PotionEffect(PotionEffectType.MINING_FATIGUE, 20 * 2, 3));
+ heretic.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 20 * 2, 3));
+ heretic.addPotionEffect(new PotionEffect(PotionEffectType.DARKNESS, 20 * 2, 3));
+ heretic.addPotionEffect(new PotionEffect(PotionEffectType.NAUSEA, 20 * 2, 3));
+ heretic.addPotionEffect(new PotionEffect(PotionEffectType.HUNGER, 20 * 2, 3));
+ heretic.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS, 20 * 2, 3));
+ heretic.addPotionEffect(new PotionEffect(PotionEffectType.INSTANT_DAMAGE, 20 * 2, 0));
+ }
+
+ public void warnHeretic(Player heretic) {
+ heretic.sendTitle(ChatColor.DARK_RED + "HOLDING CHICKEN IS HERESY!", ChatColor.YELLOW + "DROP IT IMMEDIATELY!", 5, 10, 5);
+ }
+
+ public void executeHeretic(Player heretic) {
+ Location coords = heretic.getLocation();
+ World world = coords.getWorld();
+ Plugin plugin = getPluginManager().getPlugin("fantasysmp");
+
+ heretic.sendTitle(ChatColor.DARK_RED + "HERESY!", ChatColor.YELLOW + "YOU SHALL PAY FOR YOUR CRIMES.", 5, 10, 5);
+ Bukkit.getScheduler().runTaskLater(plugin, () -> world.strikeLightning(coords), 0);
+ Bukkit.getScheduler().runTaskLater(plugin, () -> world.strikeLightning(coords), 1);
+ Bukkit.getScheduler().runTaskLater(plugin, () -> world.strikeLightning(coords), 2);
+ Bukkit.getScheduler().runTaskLater(plugin, () -> world.strikeLightning(coords), 3);
+ Bukkit.getScheduler().runTaskLater(plugin, () -> world.strikeLightning(coords), 4);
+ Bukkit.getScheduler().runTaskLater(plugin, () -> world.strikeLightning(coords), 5);
+ Bukkit.getScheduler().runTaskLater(plugin, () -> world.strikeLightning(coords), 6);
+ Bukkit.getScheduler().runTaskLater(plugin, () -> world.strikeLightning(coords), 7);
+ Bukkit.getScheduler().runTaskLater(plugin, () -> world.strikeLightning(coords), 8);
+ Bukkit.getScheduler().runTaskLater(plugin, () -> world.strikeLightning(coords), 9);
+ Bukkit.getScheduler().runTaskLater(plugin, () -> heretic.setHealth(0), 10);
+ }
+}
+
diff --git a/src/main/java/dev/zxq5/fantasysmp/events/HereticWarner.java b/src/main/java/dev/zxq5/fantasysmp/events/HereticWarner.java
deleted file mode 100644
index 5b4ac0f..0000000
--- a/src/main/java/dev/zxq5/fantasysmp/events/HereticWarner.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package dev.zxq5.fantasysmp.events;
-
-import org.bukkit.Bukkit;
-import org.bukkit.ChatColor;
-import org.bukkit.Material;
-import org.bukkit.entity.Player;
-import org.bukkit.potion.PotionEffect;
-import org.bukkit.potion.PotionEffectType;
-
-import static org.bukkit.Bukkit.getPluginManager;
-
-public class HereticWarner {
- int task;
-
- public void checkHereticInventory() {
- Bukkit.getScheduler().scheduleSyncRepeatingTask(getPluginManager().getPlugin("fantasysmp"), () -> {
- for ( Player heretic : Bukkit.getServer().getOnlinePlayers() ) {
- if (heretic.getInventory().contains(Material.CHICKEN) || heretic.getInventory().contains(Material.COOKED_CHICKEN)) {
- warnHeretic(heretic);
- }
- }
- }, 0, 20);
- }
-
- public void warnHeretic(Player heretic) {
- // apply poison to player
- heretic.sendMessage(ChatColor.DARK_RED + "HOLDING CHICKEN IS HERESY!");
- heretic.sendMessage(ChatColor.DARK_RED + "DROP IT IMMEDIATELY!");
- heretic.addPotionEffect(new PotionEffect(PotionEffectType.POISON, 20 * 2, 10));
- heretic.addPotionEffect(new PotionEffect(PotionEffectType.WITHER, 20 * 2, 10));
- heretic.addPotionEffect(new PotionEffect(PotionEffectType.SLOWNESS, 20 * 2, 3));
- heretic.addPotionEffect(new PotionEffect(PotionEffectType.MINING_FATIGUE, 20 * 2, 3));
- heretic.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 20 * 2, 3));
- heretic.addPotionEffect(new PotionEffect(PotionEffectType.DARKNESS, 20 * 2, 3));
- heretic.addPotionEffect(new PotionEffect(PotionEffectType.NAUSEA, 20 * 2, 3));
- heretic.addPotionEffect(new PotionEffect(PotionEffectType.HUNGER, 20 * 2, 3));
- heretic.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS, 20 * 2, 3));
- heretic.addPotionEffect(new PotionEffect(PotionEffectType.INSTANT_DAMAGE, 20 * 2, 0));
- }
-}
\ No newline at end of file
diff --git a/src/main/java/dev/zxq5/fantasysmp/events/StevenKillCheck.java b/src/main/java/dev/zxq5/fantasysmp/events/StevenKillCheck.java
deleted file mode 100644
index 2688c36..0000000
--- a/src/main/java/dev/zxq5/fantasysmp/events/StevenKillCheck.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package dev.zxq5.fantasysmp.events;
-
-import org.bukkit.*;
-import org.bukkit.entity.Chicken;
-import org.bukkit.entity.EntityType;
-import org.bukkit.entity.Player;
-import org.bukkit.entity.Wither;
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.Listener;
-import org.bukkit.event.entity.EntityDamageByEntityEvent;
-import org.bukkit.event.entity.EntityDamageEvent;
-import org.bukkit.event.entity.ProjectileHitEvent;
-import org.bukkit.plugin.Plugin;
-import org.bukkit.potion.PotionEffect;
-import org.bukkit.potion.PotionEffectType;
-import org.bukkit.scheduler.BukkitRunnable;
-
-import static org.bukkit.Bukkit.*;
-
-public class StevenKillCheck implements Listener {
-
- @EventHandler
- public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
- if (event.getEntity() instanceof Chicken) {
- event.setCancelled(true);
-
- if (event.getDamager() instanceof Player player) {
- destroyHeretic(player);
- }
- }
- }
-
- @EventHandler
- public void onEntityDamage(EntityDamageEvent event) {
- if (event.getEntity() instanceof Chicken) {
- event.setCancelled(true);
-
- if ( event.getDamageSource().getCausingEntity() instanceof Player player) {
- destroyHeretic(player);
- }
- }
- }
-
- @EventHandler
- public void onProjectileHit(ProjectileHitEvent event) {
- if (event.getHitEntity() instanceof Chicken && event.getEntity().getShooter() instanceof Player player) {
- if (event.getEntity().getType() == EntityType.EGG) return;
- if (event.getEntity().getType() == EntityType.SNOWBALL) return;
-
- event.setCancelled(true);
- destroyHeretic(player);
- }
- }
-
- @EventHandler
- public void onEntitySpawn(org.bukkit.event.entity.EntitySpawnEvent event) {
- if (event.getEntity() instanceof Chicken steven) {
- steven.setCustomName("Steven");
- }
- }
-
- public void destroyHeretic(Player heretic) {
- Location coords = heretic.getLocation();
- World world = coords.getWorld();
- Plugin plugin = getPluginManager().getPlugin("fantasysmp");
-
- broadcastMessage(ChatColor.DARK_RED + "HERESY!!!!");
- Bukkit.getScheduler().runTaskLater(plugin, () -> world.strikeLightning(coords), 0);
- Bukkit.getScheduler().runTaskLater(plugin, () -> world.strikeLightning(coords), 1);
- Bukkit.getScheduler().runTaskLater(plugin, () -> world.strikeLightning(coords), 2);
- Bukkit.getScheduler().runTaskLater(plugin, () -> world.strikeLightning(coords), 3);
- Bukkit.getScheduler().runTaskLater(plugin, () -> world.strikeLightning(coords), 4);
- Bukkit.getScheduler().runTaskLater(plugin, () -> world.strikeLightning(coords), 5);
- Bukkit.getScheduler().runTaskLater(plugin, () -> world.strikeLightning(coords), 6);
- Bukkit.getScheduler().runTaskLater(plugin, () -> world.strikeLightning(coords), 7);
- Bukkit.getScheduler().runTaskLater(plugin, () -> world.strikeLightning(coords), 8);
- Bukkit.getScheduler().runTaskLater(plugin, () -> world.strikeLightning(coords), 9);
- Bukkit.getScheduler().runTaskLater(plugin, () -> heretic.setHealth(0), 10);
- }
-}
-
diff --git a/src/main/java/dev/zxq5/fantasysmp/events/XrayDetector.java b/src/main/java/dev/zxq5/fantasysmp/events/XrayDetector.java
new file mode 100644
index 0000000..cf0f9fb
--- /dev/null
+++ b/src/main/java/dev/zxq5/fantasysmp/events/XrayDetector.java
@@ -0,0 +1,124 @@
+package dev.zxq5.fantasysmp.events;
+
+import com.google.gson.Gson;
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.block.BlockBreakEvent;
+import org.bukkit.plugin.Plugin;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.net.URI;
+import java.net.URL;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.bukkit.Bukkit.*;
+
+public class XrayDetector implements Listener {
+ private final HashMap> players = new HashMap<>();
+ private String token;
+
+ private final ArrayList trackedBlocks = new ArrayList<>(Arrays.asList(
+ Material.ANCIENT_DEBRIS,
+ Material.DIAMOND_ORE,
+ Material.EMERALD_ORE,
+ Material.GOLD_ORE,
+ Material.IRON_ORE,
+ Material.LAPIS_ORE,
+ Material.REDSTONE_ORE
+ ));
+
+ @EventHandler
+ public void onBlockBreak(BlockBreakEvent event) {
+ Player player = event.getPlayer();
+ HashMap blocks;
+ Material block = event.getBlock().getType();
+ Plugin plugin = getPluginManager().getPlugin("fantasysmp");
+
+ if (!this.players.containsKey(player)) this.players.put(player, new HashMap<>());
+ blocks = this.players.get(player);
+
+ if (this.trackedBlocks.contains(block)) {
+ if (!(blocks.containsKey(block))) blocks.put(block, 0);
+ blocks.put(block, blocks.get(block) + 1);
+
+ Bukkit.getScheduler().runTaskLater(plugin, () -> {
+ blocks.put(block, blocks.get(block) - 1);
+ }, 1200);
+ }
+ }
+
+ private void uploadData() {
+ HashMap> data = new HashMap<>();
+ for (Map.Entry> entry : players.entrySet()) {
+ HashMap materials = new HashMap<>();
+
+ for (Map.Entry materialEntry : entry.getValue().entrySet()) {
+ materials.put(materialEntry.getKey().toString(), materialEntry.getValue());
+ }
+
+ data.put(entry.getKey().getName(), materials);
+ }
+
+ Gson gson = new Gson();
+
+ HttpClient client = HttpClient.newHttpClient();
+ HttpRequest request = HttpRequest.newBuilder(URI.create("https://mcapi.zxq5.dev/xray?token=" + token))
+ .header("Content-Type", "application/json")
+ .POST(HttpRequest.BodyPublishers.ofString(gson.toJson(data)))
+ .build();
+
+ client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
+ .thenApply(HttpResponse::body)
+ .join();
+ }
+
+ public XrayDetector() {
+ File dataFolder = getServer().getPluginManager().getPlugin("Fantasysmp").getDataFolder();
+ File file = new File(dataFolder, "token.txt");
+
+ BufferedReader reader;
+ try {
+ reader = new BufferedReader(new FileReader(file));
+ this.token = reader.readLine();
+ } catch (Exception e) {
+ e.printStackTrace();
+ return;
+ }
+
+ Bukkit.getScheduler().runTaskTimerAsynchronously(getPluginManager().getPlugin("fantasysmp"), this::uploadData, 0, 20 * 60);
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/dev/zxq5/fantasysmp/groups/Commands.java b/src/main/java/dev/zxq5/fantasysmp/groups/Commands.java
new file mode 100644
index 0000000..cec0523
--- /dev/null
+++ b/src/main/java/dev/zxq5/fantasysmp/groups/Commands.java
@@ -0,0 +1,253 @@
+package dev.zxq5.fantasysmp.groups;
+
+import dev.zxq5.fantasysmp.chatutils.Chat;
+import dev.zxq5.fantasysmp.warps.Warp;
+import dev.zxq5.fantasysmp.warps.WarpType;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.entity.Player;
+
+import java.util.ArrayList;
+
+import static org.bukkit.Bukkit.getServer;
+
+/*
+ * Commands:
+ *
+ * ** PLAYER **
+ *
+ * team list => TODO
+ * team create => TODO
+ * team rename => TODO
+ * team transfer => TODO
+ * team join => TODO
+ * team invite => TODO
+ * team leave => TODO
+ * team disband => TODO
+ * team setwarp => TODO
+ * team delwarp => TODO
+ * team warp => TODO
+ * team kick => TODO
+ * team log => TODO
+ *
+ * ** ADMIN ONLY **
+ *
+ * rank create => TODO
+ * rank rename => TODO
+ * rank delete => TODO
+ * rank add => TODO
+ * rank remove => TODO
+ * */
+
+public class Commands implements CommandExecutor {
+
+ @Override
+ public boolean onCommand(org.bukkit.command.CommandSender sender, org.bukkit.command.Command command, String label, String[] args) {
+ if (!(sender instanceof Player player)) return false;
+
+ if (command.getName().equals("team")) handleTeamCommands(player, args);
+ if (command.getName().equals("rank")) handleRankCommands(player, args);
+ return true;
+ }
+
+ public void handleTeamCommands(Player player, String[] args) {
+ switch (args[0]) {
+ case "list" -> this.handleList(player, args);
+ case "create" -> this.handleCreate(player, args);
+ case "rename" -> this.handleRename(player, args);
+ case "tag" -> this.handleSetTag(player, args);
+ case "transfer" -> this.handleTransfer(player, args);
+ case "join" -> this.handleJoin(player, args);
+ case "invite" -> this.handleInvite(player, args);
+ case "leave" -> this.handleLeave(player, args);
+ case "disband" -> this.handleDisband(player, args);
+ case "setwarp" -> this.handleSetWarp(player, args);
+ case "delwarp" -> this.handleDelWarp(player, args);
+ case "colour" -> this.handleSetColour(player, args);
+ case "warp" -> this.handleWarp(player, args);
+ case "kick" -> this.handleKick(player, args);
+ case "log" -> this.handleLog(player, args);
+ }
+ }
+
+ public void handleRankCommands(Player player, String[] args) {
+ // check perms
+ if (!(player.hasPermission("fantasysmp.ranks"))) {
+ Chat.error(player, "You do not have permission to use this command.");
+ return;
+ }
+
+ switch (args[0]) {
+ case "create" -> this.handleCreateRank(player, args);
+ case "rename" -> this.handleRenameRank(player, args);
+ case "delete" -> this.handleDeleteRank(player, args);
+ case "add" -> this.handleAddRank(player, args);
+ case "remove" -> this.handleRemoveRank(player, args);
+ }
+ }
+
+ public void handleList(Player player, String[] args) {
+ String[] teams = Team.getTeams();
+ String result = "Teams: [\n " + String.join("\n ", teams) + "\n]";
+ Chat.info(player, result);
+ }
+
+ public void handleCreate(Player player, String[] args) {
+ if (args.length != 2) {
+ Chat.error(player, "Usage: /team create ");
+ return;
+ }
+
+ Team.createTeam(player, args[1]);
+ }
+
+ public void handleSetColour(Player player, String[] args) {
+ if (args.length != 2) {
+ Chat.error(player, "Usage: /team colour ");
+ return;
+ }
+
+ Team team = Team.fromMember(player);
+ if (team == null) return;
+
+ team.setColour(player, args[1]);
+ }
+
+ public void handleRename(Player player, String[] args) {
+ if (args.length != 2) {
+ Chat.error(player, "Usage: /team rename ");
+ return;
+ }
+
+ if (args[1].isEmpty() || args[1].contains(" ") || args[1].contains("\t")) {
+ Chat.error(player, "Invalid name!");
+ return;
+ }
+
+ Team team = Team.fromMember(player);
+ if (team == null) return;
+
+ team.renameTeam(player, args[1]);
+ }
+
+ public void handleSetTag(Player player, String[] args) {
+ if (args.length != 2) {
+ Chat.error(player, "Usage: /team tag ");
+ return;
+ }
+
+ if (args[1].length() < 3 || args[1].contains(" ") || args[1].contains("\t") || args[1].length() > 8) {
+ Chat.error(player, "Invalid tag!");
+ Chat.error(player, "tags should be 3-8 chars, alphanumeric and have no spaces");
+ return;
+ }
+
+ Team team = Team.fromMember(player);
+ if (team == null) return;
+
+ team.changeTeamTag(player, args[1]);
+ }
+
+ public void handleTransfer(Player player, String[] args) {
+ if (args.length != 2) {
+ Chat.error(player, "Usage: /team transfer ");
+ return;
+ }
+ }
+
+ public void handleJoin(Player player, String[] args) {
+ if (args.length != 2) {
+ Chat.error(player, "Usage: /team join ");
+ return;
+ }
+ }
+
+ public void handleInvite(Player player, String[] args) {
+ if (args.length != 2) {
+ Chat.error(player, "Usage: /team invite ");
+ return;
+ }
+ }
+
+ public void handleLeave(Player player, String[] args) {
+ if (args.length != 1) {
+ Chat.error(player, "Usage: /team leave");
+ return;
+ }
+ Team team = Team.fromMember(player);
+ if (team == null) return;
+
+ team.leaveTeam(player);
+ }
+
+ public void handleDisband(Player player, String[] args) {
+ if (args.length != 1) {
+ Chat.error(player, "Usage: /team disband");
+ return;
+ }
+ Team team = Team.fromMember(player);
+ if (team == null) return;
+
+ team.disbandTeam(player);
+ }
+
+ public void handleSetWarp(Player player, String[] args) {
+ if (args.length != 2) {
+ Chat.error(player, "Usage: /team setwarp ");
+ return;
+ }
+
+ Warp.setWarp(args[1], player, WarpType.TEAM);
+ }
+
+ public void handleDelWarp(Player player, String[] args) {
+
+ }
+
+ public void handleWarp(Player player, String[] args) {
+ if (args.length != 2) {
+ Chat.error(player, "Usage: /team warp ");
+ return;
+ }
+ Team team = Team.fromMember(player);
+ if (team == null) return;
+
+ Warp warp = Warp.getTeamWarp(team, args[1]);
+ }
+
+ public void handleKick(Player player, String[] args) {
+ if (args.length != 2) {
+ Chat.error(player, "Usage: /team kick ");
+ return;
+ }
+ Team team = Team.fromMember(player);
+ if (team == null) return;
+
+ team.removePlayer(player, args[1]);
+ }
+
+ public void handleLog(Player player, String[] args) {
+ if (args.length != 1) {
+ Chat.error(player, "Usage: /team log");
+ return;
+ }
+
+ Team team = Team.fromMember(player);
+ if (team == null) return;
+
+ ArrayList logs = team.getLogs(player);
+ String result = "Logs: [\n " + String.join("\n ", logs) + "\n]";
+ Chat.info(player, result);
+ }
+
+ public void handleCreateRank(Player player, String[] args) {}
+
+ public void handleRenameRank(Player player, String[] args) {}
+
+ public void handleDeleteRank(Player player, String[] args) {}
+
+ public void handleAddRank(Player player, String[] args) {}
+
+ public void handleRemoveRank(Player player, String[] args) {}
+
+ public Commands() {}
+}
diff --git a/src/main/java/dev/zxq5/fantasysmp/groups/Ranks.java b/src/main/java/dev/zxq5/fantasysmp/groups/Ranks.java
new file mode 100644
index 0000000..4f7fc01
--- /dev/null
+++ b/src/main/java/dev/zxq5/fantasysmp/groups/Ranks.java
@@ -0,0 +1,4 @@
+package dev.zxq5.fantasysmp.groups;
+
+public class Ranks {
+}
diff --git a/src/main/java/dev/zxq5/fantasysmp/groups/Team.java b/src/main/java/dev/zxq5/fantasysmp/groups/Team.java
new file mode 100644
index 0000000..2db1658
--- /dev/null
+++ b/src/main/java/dev/zxq5/fantasysmp/groups/Team.java
@@ -0,0 +1,308 @@
+package dev.zxq5.fantasysmp.groups;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import dev.zxq5.fantasysmp.chatutils.Chat;
+import org.bukkit.ChatColor;
+import org.bukkit.entity.Player;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.UUID;
+
+import static org.bukkit.Bukkit.broadcastMessage;
+import static org.bukkit.Bukkit.getServer;
+
+public class Team {
+ private static ArrayList teams;
+ private final static String FILENAME = "teams.json";
+
+ private String name;
+ private String ownerUUID;
+ private ArrayList members;
+ private ArrayList logs;
+ private String teamUUID;
+ private String tag;
+
+ public Team(Player creator, String name, String tag) {
+ this.name = name;
+ this.tag = tag;
+ this.teamUUID = UUID.randomUUID().toString();
+ this.ownerUUID = creator.getUniqueId().toString();
+ this.members = new ArrayList<>();
+ this.logs = new ArrayList<>();
+ members.add(creator.getUniqueId().toString());
+ }
+
+ public static Team createTeam(Player creator, String name) {
+ if (Team.fromMember(creator) != null) {
+ Team.error(creator, Error.SELF_IN_TEAM);
+ return null;
+ }
+
+ Team team = new Team(creator, name, name);
+ team.logs.add(creator.getName() + " created the team.");
+ teams.add(team);
+
+ Chat.success(creator, "You created " + team.name + ".");
+ return team;
+ }
+
+ public static Team fromMember(Player member) {
+ for (Team team : teams) {
+ if (team.members.contains(member.getUniqueId().toString())) return team;
+ }
+
+ Team.error(member, Error.TEAM_NOT_FOUND);
+ return null;
+ }
+
+ public static String[] getTeams() {
+ String[] names = new String[teams.size()];
+ for (int i = 0; i < teams.size(); i++) {
+ names[i] = teams.get(i).name;
+ }
+ return names;
+ }
+
+ public void renameTeam(Player player, String newName) {
+ if (!this.ownerUUID.equals(player.getUniqueId().toString())) {
+ Team.error(player, Error.NO_PERMISSION);
+ return;
+ }
+
+ String oldName = this.name;
+ this.name = newName;
+ this.log(player.getName() + " renamed the team to " + newName + ".");
+
+ Chat.success(player, "You renamed " + oldName + " to " + newName + ".");
+ }
+
+ public void changeTeamTag(Player player, String newTag) {
+ if (!this.ownerUUID.equals(player.getUniqueId().toString())) {
+ Team.error(player, Error.NO_PERMISSION);
+ return;
+ }
+
+ this.tag = newTag;
+ this.log(player.getName() + " changed the team tag to " + newTag + ".");
+
+ Chat.success(player, "You changed the tag of " + this.name + " to " + newTag + ".");
+ }
+
+ public void setColour (Player player, String colour) {
+ if (!this.ownerUUID.equals(player.getUniqueId().toString())) {
+ Team.error(player, Error.NO_PERMISSION);
+ return;
+ }
+
+ switch (colour) {
+ case "red" -> this.tag = ChatColor.RED + this.tag;
+ case "green" -> this.tag = ChatColor.GREEN + this.tag;
+ case "blue" -> this.tag = ChatColor.BLUE + this.tag;
+ case "yellow" -> this.tag = ChatColor.YELLOW + this.tag;
+ case "aqua" -> this.tag = ChatColor.AQUA + this.tag;
+ case "dark_aqua" -> this.tag = ChatColor.DARK_AQUA + this.tag;
+ case "dark_blue" -> this.tag = ChatColor.DARK_BLUE + this.tag;
+ case "dark_gray" -> this.tag = ChatColor.DARK_GRAY + this.tag;
+ case "dark_green" -> this.tag = ChatColor.DARK_GREEN + this.tag;
+ case "dark_purple" -> this.tag = ChatColor.DARK_PURPLE + this.tag;
+ case "gold" -> this.tag = ChatColor.GOLD + this.tag;
+ case "gray" -> this.tag = ChatColor.GRAY + this.tag;
+ case "light_purple" -> this.tag = ChatColor.LIGHT_PURPLE + this.tag;
+ case "white" -> this.tag = ChatColor.WHITE + this.tag;
+ case "black" -> this.tag = ChatColor.BLACK + this.tag;
+ }
+
+ this.log(player.getName() + " changed the team colour to " + colour + ".");
+ Chat.success(player, "You changed the colour of " + this.name + " to " + colour + ".");
+ }
+
+ public void transferTeam(Player player, String playerName) {
+ if (!this.ownerUUID.equals(player.getUniqueId().toString())) {
+ Team.error(player, Error.NO_PERMISSION);
+ return;
+ }
+
+ Player newOwner = getServer().getPlayer(playerName);
+ if (newOwner == null) {
+ Team.error(player, Error.PLAYER_NOT_FOUND);
+ return;
+ }
+
+ String newUUID = newOwner.getUniqueId().toString();
+ if (!this.members.contains(newUUID)) {
+ Team.error(player, Error.PLAYER_NOT_FOUND);
+ return;
+ }
+
+ this.ownerUUID = newUUID;
+ this.log(player.getName() + " transferred ownership to " + newOwner.getName() + ".");
+
+ Chat.success(player, "You transferred ownership of " + this.name + " to " + newOwner.getName() + ".");
+ }
+
+ public void removePlayer(Player remover, String playerName) {
+ Player removedPlayer = getServer().getPlayer(playerName);
+
+ if (removedPlayer == null) {
+ Team.error(remover, Error.PLAYER_NOT_FOUND);
+ return;
+ }
+
+ String removerUUID = remover.getUniqueId().toString();
+ String removedPlayerUUID = removedPlayer.getUniqueId().toString();
+
+ if (removedPlayerUUID.equals(this.ownerUUID)) {
+ Team.error(remover, Error.TEAM_OWNER);
+ return;
+ }
+
+ if (!this.ownerUUID.equals(removerUUID)) {
+ Team.error(remover, Error.NO_PERMISSION);
+ return;
+ }
+
+ if (!this.members.contains(removedPlayerUUID)) {
+ Team.error(remover, Error.PLAYER_NOT_FOUND);
+ return;
+ }
+
+ this.members.remove(removedPlayerUUID);
+ this.log(remover.getName() + " removed " + removedPlayer.getName() + " from the team.");
+
+ Chat.success(remover, "You removed " + removedPlayer.getName() + " from " + this.name + ".");
+ }
+
+ public void leaveTeam(Player member) {
+ if (this.ownerUUID.equals(member.getUniqueId().toString())) {
+ Team.error(member, Error.TEAM_OWNER);
+ return;
+ }
+
+ this.members.remove(member.getUniqueId().toString());
+ this.log(member.getName() + " left the team.");
+
+ Chat.success(member, "You left " + this.name + ".");
+ }
+
+ public void disbandTeam(Player member) {
+ if (!this.ownerUUID.equals(member.getUniqueId().toString())) {
+ Team.error(member, Error.NO_PERMISSION);
+ return;
+ }
+
+ teams.remove(this);
+ this.log(member.getName() + " disbanded the team.");
+
+ Chat.success(member, "You disbanded " + this.name + ".");
+ }
+
+ public void addMember(Player member) {
+ if (!this.ownerUUID.equals(member.getUniqueId().toString())) {
+ Team.error(member, Error.NO_PERMISSION);
+ return;
+ }
+
+ this.members.add(member.getUniqueId().toString());
+ this.log(member.getName() + " joined the team.");
+
+ Chat.success(member, "You joined " + this.name + ".");
+ }
+
+ public ArrayList getLogs(Player member) {
+ if (this.ownerUUID.equals(member.getUniqueId().toString())) return this.logs;
+
+ Team.error(member, Error.NO_PERMISSION);
+ return null;
+ }
+
+ public void log(String message) {
+ this.logs.add(message);
+ Team.saveTeams();
+ }
+
+ public static void loadTeams() throws Exception {
+ File dataFolder = getServer().getPluginManager().getPlugin("Fantasysmp").getDataFolder();
+ File file = new File(dataFolder, FILENAME);
+
+ if (!file.exists()) {
+ createTeamsFile();
+ }
+
+ BufferedReader reader;
+ reader = new BufferedReader(new FileReader(file));
+
+ Gson gson = new Gson();
+ teams = gson.fromJson(reader, new TypeToken>(){}.getType());
+
+ reader.close();
+ }
+
+ public static void saveTeams() {
+ File dataFolder = getServer().getPluginManager().getPlugin("Fantasysmp").getDataFolder();
+ File file = new File(dataFolder, FILENAME);
+
+ Gson gson = new Gson();
+ String json = gson.toJson(teams);
+
+ try {
+ Writer writer = new FileWriter(file);
+ writer.write(json);
+ writer.close();
+ } catch (Exception e) {
+ broadcastMessage("Error saving teams. Please contact an admin.");
+ e.printStackTrace();
+ }
+ }
+
+ public static void createTeamsFile() {
+ File dataFolder = getServer().getPluginManager().getPlugin("Fantasysmp").getDataFolder();
+ File file = new File(dataFolder, FILENAME);
+
+ if (!file.exists()) {
+ try {
+ Team[] t = new Team[0];
+ Gson gson = new Gson();
+ String json = gson.toJson(t);
+ Writer writer = new FileWriter(file);
+ writer.write(json);
+ writer.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public String getUUID() {
+ return this.teamUUID;
+ }
+
+ public String getTag() {
+ return this.tag;
+ }
+
+ public static void error(Player player, Error error) {
+ Chat.error(player, switch (error) {
+ case NO_PERMISSION -> "You do not have permission to do that!";
+ case SELF_IN_TEAM -> "You are already in a team!";
+ case NOT_IN_TEAM -> "You are not in a team!";
+ case TEAM_NOT_FOUND -> "Team not found!";
+ case PLAYER_NOT_FOUND -> "Player not found!";
+ case ALREADY_TAKEN -> "That name is already taken!";
+ case PLAYER_IN_TEAM -> "That player is already in a team!";
+ case TEAM_OWNER -> "You cannot do this to/as the owner!";
+ });
+ }
+}
+
+enum Error {
+ NO_PERMISSION,
+ TEAM_OWNER,
+ SELF_IN_TEAM,
+ NOT_IN_TEAM,
+ TEAM_NOT_FOUND,
+ PLAYER_NOT_FOUND,
+ ALREADY_TAKEN,
+ PLAYER_IN_TEAM,
+}
\ No newline at end of file
diff --git a/src/main/java/dev/zxq5/fantasysmp/items/Food.java b/src/main/java/dev/zxq5/fantasysmp/items/Food.java
new file mode 100644
index 0000000..b88474e
--- /dev/null
+++ b/src/main/java/dev/zxq5/fantasysmp/items/Food.java
@@ -0,0 +1,4 @@
+package dev.zxq5.fantasysmp.items;
+
+public class Food {
+}
diff --git a/src/main/java/dev/zxq5/fantasysmp/items/GenericGearSet.java b/src/main/java/dev/zxq5/fantasysmp/items/GenericGearSet.java
index 144dcb7..5195f91 100644
--- a/src/main/java/dev/zxq5/fantasysmp/items/GenericGearSet.java
+++ b/src/main/java/dev/zxq5/fantasysmp/items/GenericGearSet.java
@@ -1,22 +1,24 @@
package dev.zxq5.fantasysmp.items;
+import dev.zxq5.fantasysmp.util.LoreChecker;
+import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.attribute.Attribute;
import org.bukkit.attribute.AttributeModifier;
-import org.bukkit.entity.Item;
-import org.bukkit.inventory.EquipmentSlotGroup;
-import org.bukkit.inventory.ItemFlag;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.inventory.RecipeChoice;
+import org.bukkit.entity.Player;
+import org.bukkit.event.Listener;
+import org.bukkit.inventory.*;
import org.bukkit.inventory.meta.ItemMeta;
+import org.bukkit.inventory.meta.components.EquippableComponent;
+import org.bukkit.plugin.Plugin;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
-public abstract class GenericGearSet implements HasRecipes {
+public abstract class GenericGearSet implements HasRecipes, Listener {
protected ItemStats sword = new ItemStats();
protected ItemStats helmet = new ItemStats();
@@ -27,6 +29,10 @@ public abstract class GenericGearSet implements HasRecipes {
protected static RecipeChoice NETHERITE_UPGRADE = new RecipeChoice.MaterialChoice(Material.NETHERITE_UPGRADE_SMITHING_TEMPLATE);
protected static RecipeChoice WITHER_SKULL = new RecipeChoice.MaterialChoice(Material.WITHER_SKELETON_SKULL);
+ public void registerEvents(Plugin plugin) {
+ Bukkit.getServer().getPluginManager().registerEvents(this, plugin);
+ }
+
public void setTier1() {
sword.setMaterial(Material.WOODEN_SWORD);
helmet.setMaterial(Material.LEATHER_HELMET);
@@ -119,6 +125,14 @@ public abstract class GenericGearSet implements HasRecipes {
boots.knockbackResistance = 0.1;
}
+ public boolean hasGear(Player player) {
+ return (LoreChecker.itemLoreContains(player.getInventory().getHelmet(), this.helmet.lore)
+ && LoreChecker.itemLoreContains(player.getInventory().getChestplate(), this.chestplate.lore)
+ && LoreChecker.itemLoreContains(player.getInventory().getLeggings(), this.leggings.lore)
+ && LoreChecker.itemLoreContains(player.getInventory().getBoots(), this.boots.lore)
+ );
+ }
+
// this must be overridden by the child class.
public static void init() {}
@@ -143,13 +157,13 @@ public abstract class GenericGearSet implements HasRecipes {
meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
meta.setDisplayName(sword.name);
- if (!sword.customModel.isEmpty()) meta.setItemModel(NamespacedKey.fromString("fantasysmp:" + sword.customModel));
+ if (!sword.customItemModel.isEmpty()) meta.setItemModel(NamespacedKey.fromString("fantasysmp:" + sword.customItemModel));
ArrayList lore = new ArrayList<>(List.of(sword.lore));
lore.add("\n");
lore.add(ChatColor.GRAY + "When in Main Hand:" + ChatColor.RESET);
- if (sword.attackDamage > 0) lore.add(ChatColor.GREEN + " " + sword.attackDamage + " Attack Damage" + ChatColor.RESET);
- if (sword.attackSpeed > 0) lore.add(ChatColor.GREEN + " " + sword.attackSpeed + " Attack Speed" + ChatColor.RESET);
+ if (sword.attackDamage > 0) lore.add(ChatColor.GREEN + String.format(" %.1f Attack Damage", sword.attackDamage) + ChatColor.RESET);
+ if (sword.attackSpeed > 0) lore.add(ChatColor.GREEN + String.format(" %.1f Attack Speed", sword.attackSpeed) + ChatColor.RESET);
meta.setLore(lore);
item.setItemMeta(meta);
@@ -163,6 +177,7 @@ public abstract class GenericGearSet implements HasRecipes {
meta.setDisplayName(helmet.name);
meta.setLore(new ArrayList<>(List.of(helmet.lore)));
+
meta.addAttributeModifier(Attribute.ARMOR, new AttributeModifier(
UUID.randomUUID(),
"armour",
@@ -188,7 +203,11 @@ public abstract class GenericGearSet implements HasRecipes {
EquipmentSlotGroup.HEAD
));
}
- if (!helmet.customModel.isEmpty()) meta.setItemModel(NamespacedKey.fromString("fantasysmp:" + helmet.customModel));
+ if (!helmet.customItemModel.isEmpty()) meta.setItemModel(NamespacedKey.fromString("fantasysmp:" + helmet.customItemModel));
+ EquippableComponent equippable = meta.getEquippable();
+ equippable.setModel(NamespacedKey.fromString("fantasysmp:" + helmet.customEquipmentModel));
+ equippable.setSlot(EquipmentSlot.HEAD);
+ meta.setEquippable(equippable);
item.setItemMeta(meta);
return item;
@@ -227,7 +246,11 @@ public abstract class GenericGearSet implements HasRecipes {
));
}
- if (!chestplate.customModel.isEmpty()) meta.setItemModel(NamespacedKey.fromString("fantasysmp:" + chestplate.customModel));
+ if (!chestplate.customItemModel.isEmpty()) meta.setItemModel(NamespacedKey.fromString("fantasysmp:" + chestplate.customItemModel));
+ EquippableComponent equippable = meta.getEquippable();
+ equippable.setModel(NamespacedKey.fromString("fantasysmp:" + chestplate.customEquipmentModel));
+ equippable.setSlot(EquipmentSlot.CHEST);
+ meta.setEquippable(equippable);
item.setItemMeta(meta);
return item;
@@ -266,7 +289,12 @@ public abstract class GenericGearSet implements HasRecipes {
));
}
- if (!leggings.customModel.isEmpty()) meta.setItemModel(NamespacedKey.fromString("fantasysmp:" + leggings.customModel));
+ if (!leggings.customItemModel.isEmpty()) meta.setItemModel(NamespacedKey.fromString("fantasysmp:" + leggings.customItemModel));
+ EquippableComponent equippable = meta.getEquippable();
+ equippable.setModel(NamespacedKey.fromString("fantasysmp:" + leggings.customEquipmentModel));
+ equippable.setSlot(EquipmentSlot.LEGS);
+ meta.setEquippable(equippable);
+
item.setItemMeta(meta);
return item;
}
@@ -304,42 +332,17 @@ public abstract class GenericGearSet implements HasRecipes {
));
}
- if (!boots.customModel.isEmpty()) meta.setItemModel(NamespacedKey.fromString("fantasysmp:" + boots.customModel));
+ if (!boots.customItemModel.isEmpty()) meta.setItemModel(NamespacedKey.fromString("fantasysmp:" + boots.customItemModel));
+ EquippableComponent equippable = meta.getEquippable();
+ equippable.setModel(NamespacedKey.fromString("fantasysmp:" + boots.customEquipmentModel));
+ equippable.setSlot(EquipmentSlot.FEET);
+ meta.setEquippable(equippable);
+
item.setItemMeta(meta);
return item;
}
}
-class ItemStats {
- public double attackDamage;
- public double attackSpeed;
- public int durability;
- public int armour;
- public int armourToughness;
- public double knockbackResistance ;
- public String name;
- public String lore;
- public String customModel;
- public ItemStack material;
-
- public ItemStats() {
- this.attackDamage = 0;
- this.attackSpeed = 0;
- this.durability = 0;
- this.armour = 0;
- this.armourToughness = 0;
- this.knockbackResistance = 0;
- this.name = "";
- this.lore = "";
- this.customModel = "";
- this.material = new ItemStack(Material.AIR);
- }
-
- public void setMaterial(Material material) {
- this.material = new ItemStack(material);
- }
-}
-
diff --git a/src/main/java/dev/zxq5/fantasysmp/items/ItemStats.java b/src/main/java/dev/zxq5/fantasysmp/items/ItemStats.java
new file mode 100644
index 0000000..5acb73a
--- /dev/null
+++ b/src/main/java/dev/zxq5/fantasysmp/items/ItemStats.java
@@ -0,0 +1,36 @@
+package dev.zxq5.fantasysmp.items;
+
+import org.bukkit.Material;
+import org.bukkit.inventory.ItemStack;
+
+public class ItemStats {
+ public double attackDamage;
+ public double attackSpeed;
+ public int durability;
+ public int armour;
+ public int armourToughness;
+ public double knockbackResistance ;
+ public String name;
+ public String lore;
+ public String customItemModel;
+ public String customEquipmentModel;
+ public ItemStack material;
+
+ public ItemStats() {
+ this.attackDamage = 0;
+ this.attackSpeed = 0;
+ this.durability = 0;
+ this.armour = 0;
+ this.armourToughness = 0;
+ this.knockbackResistance = 0;
+ this.name = "";
+ this.lore = "";
+ this.customItemModel = "";
+ this.customEquipmentModel = "";
+ this.material = new ItemStack(Material.AIR);
+ }
+
+ public void setMaterial(Material material) {
+ this.material = new ItemStack(material);
+ }
+}
diff --git a/src/main/java/dev/zxq5/fantasysmp/items/Items.java b/src/main/java/dev/zxq5/fantasysmp/items/Items.java
index 0066e7d..96f0c03 100644
--- a/src/main/java/dev/zxq5/fantasysmp/items/Items.java
+++ b/src/main/java/dev/zxq5/fantasysmp/items/Items.java
@@ -1,15 +1,12 @@
package dev.zxq5.fantasysmp.items;
-import org.bukkit.Bukkit;
-import org.bukkit.block.data.type.Light;
+import dev.zxq5.fantasysmp.items.food.AppleCider;
+import dev.zxq5.fantasysmp.items.food.AppleJuice;
+import dev.zxq5.fantasysmp.items.gear.*;
import org.bukkit.command.CommandExecutor;
import org.bukkit.entity.Player;
-import org.bukkit.entity.Wither;
-import org.bukkit.event.EventHandler;
import org.bukkit.plugin.java.JavaPlugin;
-import static org.bukkit.Bukkit.getServer;
-
public class Items implements CommandExecutor {
@Override
@@ -36,7 +33,15 @@ public class Items implements CommandExecutor {
CommandExecutor handler;
switch (args[0]) {
- case "witherite" -> handler = new Witherite();
+ case "witherite" -> handler = new WitheriteGear();
+ case "lightning" -> handler = new LightningSword();
+ case "steven" -> handler = new StevensWrath();
+ case "blazing" -> handler = new BlazingGear();
+ case "dragon" -> handler = new DragonGear();
+ case "trueneth" -> handler = new TrueNetheriteGear();
+ case "ender" -> handler = new EnderGear();
+ case "poseidon" -> handler = new PoseidonGear();
+ case "crimson" -> handler = new CrimsonGear();
default -> { return false; }
}
@@ -46,10 +51,47 @@ public class Items implements CommandExecutor {
}
public Items(JavaPlugin plugin) {
- Witherite.init();
- Lightning.init();
- getServer().getPluginManager().registerEvents(new Witherite(), plugin);
- getServer().getPluginManager().registerEvents(new Lightning(), plugin);
- getServer().getPluginManager().registerEvents(new StevensWrath(), plugin);
+
+ WitheriteGear witherite = new WitheriteGear();
+ witherite.registerRecipes();
+ witherite.registerEvents(plugin);
+
+ LightningSword lightning = new LightningSword();
+ lightning.registerRecipes();
+ lightning.registerEvents(plugin);
+
+ StevensWrath stevensWrath = new StevensWrath();
+ stevensWrath.registerRecipes();
+ stevensWrath.registerEvents(plugin);
+
+ BlazingGear blazing = new BlazingGear();
+ blazing.registerRecipes();
+ blazing.registerEvents(plugin);
+
+ DragonGear dragon = new DragonGear();
+ dragon.registerRecipes();
+ dragon.registerEvents(plugin);
+
+ EnderGear ender = new EnderGear();
+ ender.registerRecipes();
+ ender.registerEvents(plugin);
+
+ TrueNetheriteGear trueNetherite = new TrueNetheriteGear();
+ trueNetherite.registerRecipes();
+ trueNetherite.registerEvents(plugin);
+
+ PoseidonGear poseidon = new PoseidonGear();
+ poseidon.registerRecipes();
+ poseidon.registerEvents(plugin);
+
+ CrimsonGear crimson = new CrimsonGear();
+ crimson.registerRecipes();
+ crimson.registerEvents(plugin);
+
+ AppleJuice appleJuice = new AppleJuice();
+ appleJuice.registerEvents(plugin);
+
+ AppleCider appleCider = new AppleCider();
+ appleCider.registerEvents(plugin);
}
}
diff --git a/src/main/java/dev/zxq5/fantasysmp/items/food/AppleCider.java b/src/main/java/dev/zxq5/fantasysmp/items/food/AppleCider.java
new file mode 100644
index 0000000..67de93e
--- /dev/null
+++ b/src/main/java/dev/zxq5/fantasysmp/items/food/AppleCider.java
@@ -0,0 +1,85 @@
+package dev.zxq5.fantasysmp.items.food;
+
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.PotionMeta;
+import org.bukkit.inventory.meta.components.FoodComponent;
+import org.bukkit.potion.PotionEffectType;
+
+public class AppleCider extends GenericDrink {
+
+ public boolean onCommand(org.bukkit.command.CommandSender sender, org.bukkit.command.Command command, String label, String[] args) {
+ Player player = (Player) sender;
+ player.getInventory().addItem(this.getDrink());
+ return true;
+ }
+
+ public AppleCider() {
+ this.name = "Apple Cider";
+ this.lore = "A stronger drink";
+
+ this.ingredients.put(new ItemStack(Material.APPLE, 1), 1);
+ this.ingredients.put(new AppleJuice().getDrink(), 1);
+ this.ingredients.put(new ItemStack(Material.SUGAR, 1), 1);
+ }
+
+ @Override
+ public ItemStack getDrink() {
+ ItemStack item = super.getDrink();
+ PotionMeta meta = (PotionMeta) item.getItemMeta();
+
+ if (meta == null) {
+ Bukkit.getConsoleSender().sendMessage("Meta is null on a drink!!!!! this should not happen!!!!");
+ return item;
+ }
+
+ meta.addCustomEffect(new org.bukkit.potion.PotionEffect(
+ PotionEffectType.SATURATION, 20, 5
+ ), true);
+ meta.addCustomEffect(new org.bukkit.potion.PotionEffect(
+ PotionEffectType.SPEED, 10 * 20, 1
+ ), true);
+
+ meta.setColor(org.bukkit.Color.fromRGB(255, 255, 0));
+ meta.setMaxStackSize(16);
+ FoodComponent food = meta.getFood();
+ food.setNutrition(8);
+ food.setSaturation(8);
+ food.setCanAlwaysEat(true);
+ meta.setFood(food);
+
+ item.setItemMeta(meta);
+ return item;
+ }
+
+ @Override
+ public void registerRecipes() {}
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/dev/zxq5/fantasysmp/items/food/AppleJuice.java b/src/main/java/dev/zxq5/fantasysmp/items/food/AppleJuice.java
new file mode 100644
index 0000000..d0cdac9
--- /dev/null
+++ b/src/main/java/dev/zxq5/fantasysmp/items/food/AppleJuice.java
@@ -0,0 +1,70 @@
+package dev.zxq5.fantasysmp.items.food;
+
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.PotionMeta;
+import org.bukkit.inventory.meta.components.FoodComponent;
+
+public class AppleJuice extends GenericDrink {
+
+ public boolean onCommand(org.bukkit.command.CommandSender sender, org.bukkit.command.Command command, String label, String[] args) {
+ Player player = (Player) sender;
+ player.getInventory().addItem(this.getDrink());
+ return true;
+ }
+
+ public AppleJuice() {
+ this.name = "Apple Juice";
+ this.lore = "A refreshing drink";
+
+ this.ingredients.put(new ItemStack(Material.APPLE, 1), 1);
+ this.ingredients.put(GenericDrink.WATER_BOTTLE, 1);
+ }
+
+ @Override
+ public ItemStack getDrink() {
+ ItemStack item = super.getDrink();
+ PotionMeta meta = (PotionMeta) item.getItemMeta();
+
+ meta.setColor(org.bukkit.Color.fromRGB(255, 255, 0));
+ meta.setMaxStackSize(16);
+ FoodComponent food = meta.getFood();
+ food.setNutrition(6);
+ food.setSaturation(6);
+ food.setCanAlwaysEat(true);
+ meta.setFood(food);
+
+ item.setItemMeta(meta);
+ return item;
+ }
+
+ @Override
+ public void registerRecipes() {}
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/dev/zxq5/fantasysmp/items/food/GenericDrink.java b/src/main/java/dev/zxq5/fantasysmp/items/food/GenericDrink.java
new file mode 100644
index 0000000..f1ea21a
--- /dev/null
+++ b/src/main/java/dev/zxq5/fantasysmp/items/food/GenericDrink.java
@@ -0,0 +1,67 @@
+package dev.zxq5.fantasysmp.items.food;
+
+import dev.zxq5.fantasysmp.items.HasRecipes;
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.PotionMeta;
+import org.bukkit.plugin.Plugin;
+
+import java.util.*;
+
+public abstract class GenericDrink implements Listener, CommandExecutor, HasRecipes {
+ protected static ItemStack WATER_BOTTLE = new ItemStack(Material.GLASS_BOTTLE, 1);
+ protected HashMap ingredients = new HashMap<>();
+
+ protected String name;
+ protected String lore;
+
+ public void registerEvents(Plugin plugin) {
+ Bukkit.getServer().getPluginManager().registerEvents(this, plugin);
+ }
+
+ @EventHandler
+ public void itemCraftingHandler(org.bukkit.event.inventory.PrepareItemCraftEvent event) {
+ ItemStack item = getDrink();
+ int sum = ingredients
+ .values()
+ .stream()
+ .mapToInt(Integer::intValue)
+ .sum();
+
+ long count = Arrays
+ .stream(event.getInventory().getMatrix())
+ .filter(Objects::nonNull)
+ .mapToInt(ItemStack::getAmount)
+ .sum();
+
+ if (sum != count) return;
+ for (ItemStack ingredient : ingredients.keySet()) {
+ if (!event.getInventory().containsAtLeast(ingredient, ingredients.get(ingredient))) return;
+ }
+ event.getInventory().setResult(item);
+ }
+
+ @Override
+ public abstract boolean onCommand(org.bukkit.command.CommandSender csender, org.bukkit.command.Command command, String label, String[] args);
+
+ public abstract void registerRecipes();
+
+ public ItemStack getDrink() {
+ ItemStack item = new ItemStack(Material.POTION, 1);
+
+ PotionMeta pm = (PotionMeta) item.getItemMeta();
+ pm.setBasePotionType(org.bukkit.potion.PotionType.WATER);
+
+ List lore = new ArrayList<>();
+ lore.add(this.lore);
+ pm.setLore(lore);
+ pm.setDisplayName(this.name);
+ item.setItemMeta(pm);
+ return item;
+ }
+
+}
diff --git a/src/main/java/dev/zxq5/fantasysmp/items/gear/BlazingGear.java b/src/main/java/dev/zxq5/fantasysmp/items/gear/BlazingGear.java
new file mode 100644
index 0000000..557f1a0
--- /dev/null
+++ b/src/main/java/dev/zxq5/fantasysmp/items/gear/BlazingGear.java
@@ -0,0 +1,136 @@
+package dev.zxq5.fantasysmp.items.gear;
+
+import dev.zxq5.fantasysmp.items.GenericGearSet;
+import dev.zxq5.fantasysmp.util.LoreChecker;
+import org.bukkit.*;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.damage.DamageType;
+import org.bukkit.entity.Fireball;
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.entity.Player;
+import org.bukkit.entity.SmallFireball;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.block.Action;
+import org.bukkit.event.entity.EntityDamageByEntityEvent;
+import org.bukkit.event.player.PlayerInteractEvent;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.RecipeChoice;
+import org.bukkit.inventory.SmithingTransformRecipe;
+import org.bukkit.plugin.Plugin;
+import org.bukkit.potion.PotionEffect;
+import org.bukkit.potion.PotionEffectType;
+import org.bukkit.util.Vector;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import static org.bukkit.Bukkit.*;
+
+public class BlazingGear extends GenericGearSet implements Listener, CommandExecutor {
+ private ArrayList cooldown = new ArrayList<>();
+
+ private final ArrayList damageTypes = new ArrayList<>(List.of(
+ DamageType.HOT_FLOOR,
+ DamageType.ON_FIRE,
+ DamageType.IN_FIRE,
+ DamageType.LAVA
+ ));
+
+ @Override
+ public boolean onCommand(org.bukkit.command.CommandSender sender, org.bukkit.command.Command command, String label, String[] args) {
+ Player player = (Player) sender;
+ player.getInventory().addItem(this.getSword());
+ player.getInventory().addItem(this.getHelmet());
+ player.getInventory().addItem(this.getChestplate());
+ player.getInventory().addItem(this.getLeggings());
+ player.getInventory().addItem(this.getBoots());
+
+ return true;
+ }
+
+ @Override
+ public void registerRecipes() {}
+
+ @EventHandler
+ public void onPlayerSetOnFire(org.bukkit.event.entity.EntityDamageEvent event) {
+ if (!(event.getEntity() instanceof Player player)) return;
+
+ if (!(LoreChecker.itemLoreContains(player.getInventory().getHelmet(), this.helmet.lore))) return;
+ if (!(LoreChecker.itemLoreContains(player.getInventory().getChestplate(), this.chestplate.lore))) return;
+ if (!(LoreChecker.itemLoreContains(player.getInventory().getLeggings(), this.leggings.lore))) return;
+ if (!(LoreChecker.itemLoreContains(player.getInventory().getBoots(), this.boots.lore))) return;
+
+ if (damageTypes.contains(event.getDamageSource().getDamageType())) event.setCancelled(true);
+
+ player.setFireTicks(0);
+ }
+
+ @EventHandler
+ public void onPlayerInteract(PlayerInteractEvent event) {
+ Player player = event.getPlayer();
+ ItemStack item = event.getItem(); // Get the item the player interacted with
+
+ if (!(event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK)) {
+ return;
+ }
+
+ if (!(LoreChecker.itemLoreContains(item, this.sword.lore))) return;
+ if (cooldown.contains(player)) return;
+
+ Plugin plugin = getPluginManager().getPlugin("fantasysmp");
+
+ cooldown.add(player);
+ Bukkit.getScheduler().runTaskLater(plugin, () -> cooldown.remove(player), 25);
+
+ shootFireball(player);
+ Bukkit.getScheduler().runTaskLater(plugin, () -> shootFireball(player), 4);
+ Bukkit.getScheduler().runTaskLater(plugin, () -> shootFireball(player), 8);
+ }
+
+ @EventHandler
+ public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
+ if (!(event.getDamager() instanceof Player player)) return;
+ if (!(LoreChecker.itemLoreContains(player.getInventory().getItemInMainHand(), this.sword.lore))) return;
+ if (event.getEntity().getFireTicks() < 240) event.getEntity().setFireTicks(240);
+ }
+
+ public void shootFireball(Player player) {
+ Location location = player.getLocation();
+ World world = player.getWorld();
+ player.launchProjectile(SmallFireball.class);
+ player.playSound(location, Sound.ENTITY_BLAZE_SHOOT, 1.0f, 1.0f);
+ world.spawnParticle(Particle.FLAME, location, 1);
+ }
+
+ public static void init() {}
+
+ public BlazingGear() {
+ this.setTier4();
+ this.sword.name = ChatColor.GOLD + "Blazing Sword" + ChatColor.RESET;
+ this.sword.customItemModel = "blazing_sword";
+
+ this.helmet.name = ChatColor.GOLD + "Blazing Helmet" + ChatColor.RESET;
+ this.helmet.customItemModel = "blazing_helmet";
+ this.helmet.customEquipmentModel = "blazing";
+
+ this.chestplate.name = ChatColor.GOLD + "Blazing Chestplate" + ChatColor.RESET;
+ this.chestplate.customItemModel = "blazing_chestplate";
+ this.chestplate.customEquipmentModel = "blazing";
+
+ this.leggings.name = ChatColor.GOLD + "Blazing Leggings" + ChatColor.RESET;
+ this.leggings.customItemModel = "blazing_leggings";
+ this.leggings.customEquipmentModel = "blazing";
+
+ this.boots.name = ChatColor.GOLD + "Blazing Boots" + ChatColor.RESET;
+ this.boots.customItemModel = "blazing_boots";
+ this.boots.customEquipmentModel = "blazing";
+
+ this.sword.lore = "Forged from molten lava and the essence of blazes";
+ this.helmet.lore = "Forged from molten lava and the essence of blazes";
+ this.chestplate.lore = "Forged from molten lava and the essence of blazes";
+ this.leggings.lore = "Forged from molten lava and the essence of blazes";
+ this.boots.lore = "Forged from molten lava and the essence of blazes";
+ }
+}
diff --git a/src/main/java/dev/zxq5/fantasysmp/items/gear/CrimsonGear.java b/src/main/java/dev/zxq5/fantasysmp/items/gear/CrimsonGear.java
new file mode 100644
index 0000000..8e6ca49
--- /dev/null
+++ b/src/main/java/dev/zxq5/fantasysmp/items/gear/CrimsonGear.java
@@ -0,0 +1,69 @@
+package dev.zxq5.fantasysmp.items.gear;
+
+import dev.zxq5.fantasysmp.items.GenericGearSet;
+import dev.zxq5.fantasysmp.util.LoreChecker;
+import org.bukkit.ChatColor;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+
+public class CrimsonGear extends GenericGearSet implements CommandExecutor, Listener {
+ @Override
+ public boolean onCommand(org.bukkit.command.CommandSender sender, org.bukkit.command.Command command, String label, String[] args) {
+ Player player = (Player) sender;
+
+ player.getInventory().addItem(this.getSword());
+ player.getInventory().addItem(this.getHelmet());
+ player.getInventory().addItem(this.getChestplate());
+ player.getInventory().addItem(this.getLeggings());
+ player.getInventory().addItem(this.getBoots());
+ return true;
+ }
+
+ @EventHandler
+ public void onEntityDamageByEntity(org.bukkit.event.entity.EntityDamageByEntityEvent event) {
+ if (!(event.getDamager() instanceof Player player)) return;
+ if (!(LoreChecker.itemLoreContains(player.getInventory().getItemInMainHand(), this.sword.lore))) return;
+
+ player.setHealth( Math.min(player.getHealth() + 1, player.getMaxHealth()) );
+
+ if (!(LoreChecker.itemLoreContains(player.getInventory().getHelmet(), this.helmet.lore))) return;
+ if (!(LoreChecker.itemLoreContains(player.getInventory().getChestplate(), this.chestplate.lore))) return;
+ if (!(LoreChecker.itemLoreContains(player.getInventory().getLeggings(), this.leggings.lore))) return;
+ if (!(LoreChecker.itemLoreContains(player.getInventory().getBoots(), this.boots.lore))) return;
+
+ player.setHealth( Math.min(player.getHealth() + 1, player.getMaxHealth()) );
+ player.setFoodLevel( Math.min(player.getFoodLevel() + 1, 20) );
+ }
+
+ @Override
+ public void registerRecipes() {}
+
+ public CrimsonGear() {
+ this.setTier5();
+ this.sword.name = ChatColor.DARK_RED + "Bloodlust" + ChatColor.RESET;
+ this.sword.customItemModel = "crimson_sword";
+ this.sword.lore = "Live off the blood of your enemies.";
+
+ this.helmet.name = ChatColor.DARK_RED + "Crimson Helmet" + ChatColor.RESET;
+ this.helmet.customItemModel = "crimson_helmet";
+ this.helmet.customEquipmentModel = "crimson";
+ this.helmet.lore = "A helmet that grants its wearer vampiric senses.";
+
+ this.chestplate.name = ChatColor.DARK_RED + "Crimson Chestplate" + ChatColor.RESET;
+ this.chestplate.customItemModel = "crimson_chestplate";
+ this.chestplate.customEquipmentModel = "crimson";
+ this.chestplate.lore = "A chestplate that strengthens the heart of the wearer.";
+
+ this.leggings.name = ChatColor.DARK_RED + "Crimson Leggings" + ChatColor.RESET;
+ this.leggings.customItemModel = "crimson_leggings";
+ this.leggings.customEquipmentModel = "crimson";
+ this.leggings.lore = "Leggings that enhance the wearer's speed and agility.";
+
+ this.boots.name = ChatColor.DARK_RED + "Crimson Boots" + ChatColor.RESET;
+ this.boots.customItemModel = "crimson_boots";
+ this.boots.customEquipmentModel = "crimson";
+ this.boots.lore = "Boots that allow the wearer to move silently and swiftly.";
+ }
+}
diff --git a/src/main/java/dev/zxq5/fantasysmp/items/gear/DragonGear.java b/src/main/java/dev/zxq5/fantasysmp/items/gear/DragonGear.java
new file mode 100644
index 0000000..dea0df8
--- /dev/null
+++ b/src/main/java/dev/zxq5/fantasysmp/items/gear/DragonGear.java
@@ -0,0 +1,175 @@
+package dev.zxq5.fantasysmp.items.gear;
+
+import dev.zxq5.fantasysmp.items.GenericGearSet;
+import dev.zxq5.fantasysmp.items.ItemStats;
+import dev.zxq5.fantasysmp.util.LoreChecker;
+import org.bukkit.*;
+import org.bukkit.attribute.Attribute;
+import org.bukkit.attribute.AttributeModifier;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.damage.DamageType;
+import org.bukkit.enchantments.Enchantment;
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.block.Action;
+import org.bukkit.event.player.PlayerInteractEvent;
+import org.bukkit.inventory.*;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.bukkit.inventory.meta.components.EquippableComponent;
+import org.bukkit.potion.PotionEffect;
+import org.bukkit.potion.PotionEffectType;
+import org.bukkit.util.Vector;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.UUID;
+
+import static org.bukkit.Bukkit.broadcastMessage;
+import static org.bukkit.Bukkit.getServer;
+
+public class DragonGear extends GenericGearSet implements Listener, CommandExecutor {
+ private ArrayList cooldown = new ArrayList<>();
+
+ @Override
+ public boolean onCommand(org.bukkit.command.CommandSender sender, org.bukkit.command.Command command, String label, String[] args) {
+ Player player = (Player) sender;
+ player.getInventory().addItem(this.getSword());
+ player.getInventory().addItem(this.getHelmet());
+ player.getInventory().addItem(this.getChestplate());
+ player.getInventory().addItem(this.getLeggings());
+ player.getInventory().addItem(this.getBoots());
+
+ return true;
+ }
+
+ @Override
+ public void registerRecipes() {}
+
+ @EventHandler
+ public void onEntityPotionEffectEvent(org.bukkit.event.entity.EntityPotionEffectEvent event) {
+ if (event.getEntity() instanceof Player player) {
+ if (event.getNewEffect() == null) return;
+
+ if (event.getNewEffect().getType() != PotionEffectType.LEVITATION) {
+ return;
+ }
+
+ try {
+ if (LoreChecker.itemLoreContains(player.getInventory().getHelmet(), this.helmet.lore)
+ && LoreChecker.itemLoreContains(player.getInventory().getChestplate(), this.chestplate.lore)
+ && LoreChecker.itemLoreContains(player.getInventory().getLeggings(), this.leggings.lore)
+ && LoreChecker.itemLoreContains(player.getInventory().getBoots(), this.boots.lore)
+ ) {
+ event.setCancelled(true);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ @EventHandler
+ public void onEntityDamage(org.bukkit.event.entity.EntityDamageEvent event) {
+ // check if fall damage
+ if (!(event.getEntity() instanceof Player player)) return;
+ if (!(LoreChecker.itemLoreContains(player.getInventory().getHelmet(), this.helmet.lore)
+ && LoreChecker.itemLoreContains(player.getInventory().getChestplate(), this.chestplate.lore)
+ && LoreChecker.itemLoreContains(player.getInventory().getLeggings(), this.leggings.lore)
+ && LoreChecker.itemLoreContains(player.getInventory().getBoots(), this.boots.lore)
+ )) return;
+ if (!(event.getDamageSource().getDamageType() == DamageType.FLY_INTO_WALL)) return;
+
+ event.setCancelled(true);
+ }
+
+ @EventHandler
+ public void onEntityDamageByEntity(org.bukkit.event.entity.EntityDamageByEntityEvent event) {
+ if (!(event.getDamager() instanceof Player player)) return;
+ if (!(LoreChecker.itemLoreContains(player.getInventory().getItemInMainHand(), this.sword.lore))) return;
+ if (!(player.isFlying() || player.isGliding())) return;
+
+ double baseDamage = event.getDamage();
+ double newDamage = baseDamage * Math.min(Math.max(player.getVelocity().length(), 1.0), 2.0);
+
+ broadcastMessage("damage " + baseDamage);
+ broadcastMessage("velocity " + player.getVelocity().length());
+ broadcastMessage("new damage " + newDamage);
+
+ event.setDamage(newDamage);
+ }
+
+ @EventHandler
+ public void onPlayerInteract(PlayerInteractEvent event) {
+ Player player = event.getPlayer();
+ ItemStack item = event.getItem(); // Get the item the player interacted with
+
+ if (!(event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK)) {
+ return;
+ }
+
+ if (!(LoreChecker.itemLoreContains(item, this.sword.lore))) return;
+ if (cooldown.contains(player)) return;
+
+ Location location = player.getLocation();
+ Vector direction = location.getDirection();
+
+ player.setVelocity(direction.multiply(2.0));
+ player.playSound(location, Sound.ENTITY_ENDER_DRAGON_FLAP, 1.0f, 1.0f);
+ World world = player.getWorld();
+ world.spawnParticle(Particle.DRAGON_BREATH, location, 100);
+
+ cooldown.add(player);
+ Bukkit.getScheduler().scheduleSyncDelayedTask(
+ Objects.requireNonNull(Bukkit.getPluginManager().getPlugin("fantasysmp")),
+ () -> cooldown.remove(player),
+ 25
+ );
+ }
+
+ @Override
+ public ItemStack getHelmet() {
+// helmet.setMaterial(Material.DRAGON_HEAD);
+ return super.getHelmet();
+ }
+
+ @Override
+ public ItemStack getChestplate() {
+ chestplate.setMaterial(Material.ELYTRA);
+ ItemStack item = super.getChestplate();
+ item.addUnsafeEnchantment(Enchantment.PROTECTION, 4);
+ return item;
+ }
+
+ public static void init() {}
+
+ public DragonGear() {
+ this.setTier5();
+ this.sword.name = ChatColor.DARK_PURPLE + "Dragon Sword" + ChatColor.RESET;
+ this.sword.customItemModel = "dragon_sword";
+
+ this.helmet.name = ChatColor.DARK_PURPLE + "Dragon Helmet" + ChatColor.RESET;
+ this.helmet.customItemModel = "dragon_helmet";
+ this.helmet.customEquipmentModel = "dragon";
+
+ this.chestplate.name = ChatColor.DARK_PURPLE + "Dragon Chestplate" + ChatColor.RESET;
+ this.chestplate.customItemModel = "dragon_chestplate";
+ this.chestplate.customEquipmentModel = "dragon";
+
+ this.leggings.name = ChatColor.DARK_PURPLE + "Dragon Leggings" + ChatColor.RESET;
+ this.leggings.customItemModel = "dragon_leggings";
+ this.leggings.customEquipmentModel = "dragon";
+
+ this.boots.name = ChatColor.DARK_PURPLE + "Dragon Boots" + ChatColor.RESET;
+ this.boots.customItemModel = "dragon_boots";
+ this.boots.customEquipmentModel = "dragon";
+
+ this.sword.lore = "A blade forged from dragon scales and chorus fruit";
+ this.helmet.lore = "Forged from dragon scales and chorus fruit";
+ this.chestplate.lore = "Forged from dragon scales and chorus fruit";
+ this.leggings.lore = "Forged from dragon scales and chorus fruit";
+ this.boots.lore = "Forged from dragon scales and chorus fruit";
+ }
+}
diff --git a/src/main/java/dev/zxq5/fantasysmp/items/gear/EnderGear.java b/src/main/java/dev/zxq5/fantasysmp/items/gear/EnderGear.java
new file mode 100644
index 0000000..3b1fe5a
--- /dev/null
+++ b/src/main/java/dev/zxq5/fantasysmp/items/gear/EnderGear.java
@@ -0,0 +1,109 @@
+package dev.zxq5.fantasysmp.items.gear;
+
+import dev.zxq5.fantasysmp.items.GenericGearSet;
+import dev.zxq5.fantasysmp.util.LoreChecker;
+import org.bukkit.*;
+import org.bukkit.block.Block;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.block.Action;
+import org.bukkit.event.player.PlayerInteractEvent;
+import org.bukkit.inventory.*;
+import org.bukkit.util.Vector;
+
+import java.util.ArrayList;
+import java.util.Objects;
+
+public class EnderGear extends GenericGearSet implements Listener, CommandExecutor {
+ private ArrayList cooldown = new ArrayList<>();
+
+ @Override
+ public boolean onCommand(org.bukkit.command.CommandSender sender, org.bukkit.command.Command command, String label, String[] args) {
+ Player player = (Player) sender;
+ player.getInventory().addItem(this.getSword());
+ player.getInventory().addItem(this.getHelmet());
+ player.getInventory().addItem(this.getChestplate());
+ player.getInventory().addItem(this.getLeggings());
+ player.getInventory().addItem(this.getBoots());
+
+ return true;
+ }
+
+ @Override
+ public void registerRecipes() {}
+
+ @EventHandler
+ public void onPlayerInteract(PlayerInteractEvent event) {
+ Player player = event.getPlayer();
+ ItemStack item = event.getItem(); // Get the item the player interacted with
+
+ if (!(event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK)) {
+ return;
+ }
+
+ if (!(LoreChecker.itemLoreContains(item, this.sword.lore))) return;
+ if (cooldown.contains(player)) return;
+
+ Location old_location = player.getLocation();
+ World world = player.getWorld();
+ Vector direction = old_location.getDirection();
+ // find nearest block in that direction
+
+ Block block = player.getTargetBlock(null, 64);
+
+ if (block.getType() == Material.AIR || block.getType() == Material.CAVE_AIR) {
+ return;
+ }
+
+ player.playSound(old_location, Sound.ENTITY_ENDERMAN_TELEPORT, 1.0f, 1.0f);
+ world.spawnParticle(Particle.PORTAL, old_location, 100);
+
+ Location new_location = block.getLocation();
+ new_location.setPitch(old_location.getPitch());
+ new_location.setYaw(old_location.getYaw());
+ player.setVelocity(new Vector(player.getVelocity().getX(), 0, player.getVelocity().getZ()));
+ player.teleport(new_location);
+
+ player.playSound(new_location, Sound.ENTITY_ENDERMAN_TELEPORT, 1.0f, 1.0f);
+ world.spawnParticle(Particle.PORTAL, new_location, 100);
+
+ cooldown.add(player);
+ Bukkit.getScheduler().scheduleSyncDelayedTask(
+ Objects.requireNonNull(Bukkit.getPluginManager().getPlugin("fantasysmp")),
+ () -> cooldown.remove(player),
+ 25
+ );
+ }
+
+ public static void init() {}
+
+ public EnderGear() {
+ this.setTier4();
+ this.sword.name = ChatColor.DARK_AQUA + "Ender Sword" + ChatColor.RESET;
+ this.sword.customItemModel = "ender_sword";
+
+ this.helmet.name = ChatColor.DARK_AQUA + "Ender Helmet" + ChatColor.RESET;
+ this.helmet.customItemModel = "ender_helmet";
+ this.helmet.customEquipmentModel = "ender";
+
+ this.chestplate.name = ChatColor.DARK_AQUA + "Ender Chestplate" + ChatColor.RESET;
+ this.chestplate.customItemModel = "ender_chestplate";
+ this.chestplate.customEquipmentModel = "ender";
+
+ this.leggings.name = ChatColor.DARK_AQUA + "Ender Leggings" + ChatColor.RESET;
+ this.leggings.customItemModel = "ender_leggings";
+ this.leggings.customEquipmentModel = "ender";
+
+ this.boots.name = ChatColor.DARK_AQUA + "Ender Boots" + ChatColor.RESET;
+ this.boots.customItemModel = "ender_boots";
+ this.boots.customEquipmentModel = "ender";
+
+ this.sword.lore = "A sword forged from the essence of ender pearls,";
+ this.helmet.lore = "A helmet forged from the essence of ender pearls,";
+ this.chestplate.lore = "A chestplate forged from the essence of ender pearls,";
+ this.leggings.lore = "Leggings forged from the essence of ender pearls,";
+ this.boots.lore = "Boots forged from the essence of ender pearls,";
+ }
+}
diff --git a/src/main/java/dev/zxq5/fantasysmp/items/Lightning.java b/src/main/java/dev/zxq5/fantasysmp/items/gear/LightningSword.java
similarity index 74%
rename from src/main/java/dev/zxq5/fantasysmp/items/Lightning.java
rename to src/main/java/dev/zxq5/fantasysmp/items/gear/LightningSword.java
index d797980..194de83 100644
--- a/src/main/java/dev/zxq5/fantasysmp/items/Lightning.java
+++ b/src/main/java/dev/zxq5/fantasysmp/items/gear/LightningSword.java
@@ -1,38 +1,27 @@
-package dev.zxq5.fantasysmp.items;
+package dev.zxq5.fantasysmp.items.gear;
+import dev.zxq5.fantasysmp.items.GenericGearSet;
import dev.zxq5.fantasysmp.util.LoreChecker;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.World;
import org.bukkit.command.CommandExecutor;
-import org.bukkit.entity.LightningStrike;
-import org.bukkit.entity.LivingEntity;
-import org.bukkit.entity.Player;
+import org.bukkit.entity.*;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.ShapedRecipe;
-import org.bukkit.inventory.meta.ItemMeta;
-import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
-import java.util.List;
-
-import static org.bukkit.Bukkit.broadcastMessage;
import static org.bukkit.Bukkit.getServer;
-public class Lightning extends GenericGearSet implements Listener, CommandExecutor {
+public class LightningSword extends GenericGearSet implements Listener, CommandExecutor {
@Override
public boolean onCommand(org.bukkit.command.CommandSender sender, org.bukkit.command.Command command, String label, String[] args) {
- if (!(args[0].equals("lightning"))) {
- return false;
- }
-
Player player = (Player) sender;
-
- player.getInventory().addItem(new Lightning().getSword());
+ player.getInventory().addItem(this.getSword());
return true;
}
@@ -77,7 +66,6 @@ public class Lightning extends GenericGearSet implements Listener, CommandExecut
@EventHandler
public void onEntityDamage(org.bukkit.event.entity.EntityDamageEvent event) {
if (event.getEntity() instanceof Player player) {
-
if (!(event
.getDamageSource()
.getDamageType()
@@ -88,16 +76,30 @@ public class Lightning extends GenericGearSet implements Listener, CommandExecut
if (LoreChecker.itemLoreContains(player.getInventory().getItemInMainHand(), this.sword.lore)) {
event.setCancelled(true);
+ return;
+ }
+ }
+ }
+
+ @EventHandler
+ public void onEntityDeath(org.bukkit.event.entity.EntityDeathEvent event) {
+ if (event.getEntity() instanceof Mob mob) {
+ if (
+ event.getDamageSource().getDamageType().getKey().toString().equals("minecraft:lightning_bolt")
+ || event.getDamageSource().getDamageType().getKey().toString().equals("minecraft:on_fire")
+ ) {
+ Entity e = event.getEntity();
+ ((ExperienceOrb) e.getLocation().getWorld().spawn(e.getLocation(), ExperienceOrb.class)).setExperience(10);
}
}
}
public static void init() {}
- public Lightning() {
+ public LightningSword() {
this.setTier5();
this.sword.name = "Lightning Sword";
- this.sword.customModel = "lightning_sword";
+ this.sword.customItemModel = "lightning_sword";
this.sword.lore = "All who oppose shall be smitten.";
}
}
diff --git a/src/main/java/dev/zxq5/fantasysmp/items/gear/PoseidonGear.java b/src/main/java/dev/zxq5/fantasysmp/items/gear/PoseidonGear.java
new file mode 100644
index 0000000..8ac0818
--- /dev/null
+++ b/src/main/java/dev/zxq5/fantasysmp/items/gear/PoseidonGear.java
@@ -0,0 +1,94 @@
+package dev.zxq5.fantasysmp.items.gear;
+
+import dev.zxq5.fantasysmp.items.GenericGearSet;
+import dev.zxq5.fantasysmp.items.ItemStats;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.Material;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.enchantments.Enchantment;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+import static org.bukkit.Bukkit.getPluginManager;
+
+public class PoseidonGear extends GenericGearSet implements CommandExecutor, Listener {
+ @Override
+ public boolean onCommand(org.bukkit.command.CommandSender sender, org.bukkit.command.Command command, String label, String[] args) {
+ Player player = (Player) sender;
+
+ player.getInventory().addItem(this.getTrident());
+ player.getInventory().addItem(this.getHelmet());
+ player.getInventory().addItem(this.getChestplate());
+ player.getInventory().addItem(this.getLeggings());
+ player.getInventory().addItem(this.getBoots());
+ return true;
+ }
+
+ public ItemStack getTrident() {
+ ItemStack item = super.getSword();
+ item.addUnsafeEnchantment(Enchantment.RIPTIDE, 5);
+ return item;
+ }
+
+ public ItemStack getHelmet() {
+ ItemStack item = super.getHelmet();
+ item.addUnsafeEnchantment(Enchantment.AQUA_AFFINITY, 3);
+ return item;
+ }
+
+ public ItemStack getBoots() {
+ ItemStack item = super.getBoots();
+ item.addUnsafeEnchantment(Enchantment.DEPTH_STRIDER, 5);
+ return item;
+ }
+
+ @Override
+ public void registerRecipes() {
+ Bukkit.getScheduler().scheduleSyncRepeatingTask(getPluginManager().getPlugin("fantasysmp"), this::checkPlayerAir, 0, 20);
+ }
+
+ public void checkPlayerAir() {
+ // any players wearing the armour will never run out of breath
+ for (Player player : Bukkit.getOnlinePlayers()) {
+ if (this.hasGear(player)) {
+ if (player.getRemainingAir() < player.getMaximumAir()) {
+ player.setRemainingAir(player.getMaximumAir());
+ }
+ }
+ }
+ }
+
+ public PoseidonGear() {
+ this.setTier5();
+ this.sword.setMaterial(Material.TRIDENT);
+ this.sword.attackDamage = 10;
+ this.sword.attackSpeed = 1.2f;
+ this.sword.name = ChatColor.AQUA + "Poseidon's Fury" + ChatColor.RESET;
+ this.sword.lore = "A powerful trident imbued with the power of the ocean.";
+ this.sword.customItemModel = "poseidons_trident";
+
+ this.helmet.name = ChatColor.AQUA + "Poseidon's Crown" + ChatColor.RESET;
+ this.helmet.lore = "A helmet granted to those who harness the power of the ocean.";
+ this.helmet.customItemModel = "poseidons_helmet";
+ this.helmet.customEquipmentModel = "poseidon";
+
+ this.chestplate.name = ChatColor.AQUA + "Poseidon's Chestplate" + ChatColor.RESET;
+ this.chestplate.lore = "A chestplate granted to those who harness the power of the ocean.";
+ this.chestplate.customItemModel = "poseidons_chestplate";
+ this.chestplate.customEquipmentModel = "poseidon";
+
+ this.leggings.name = ChatColor.AQUA + "Poseidon's Leggings" + ChatColor.RESET;
+ this.leggings.lore = "Leggings granted to those who harness the power of the ocean.";
+ this.leggings.customItemModel = "poseidons_leggings";
+ this.leggings.customEquipmentModel = "poseidon";
+
+ this.boots.name = ChatColor.AQUA + "Poseidon's Boots" + ChatColor.RESET;
+ this.boots.lore = "Boots granted to those who harness the power of the ocean.";
+ this.boots.customItemModel = "poseidons_boots";
+ this.boots.customEquipmentModel = "poseidon";
+ }
+}
diff --git a/src/main/java/dev/zxq5/fantasysmp/items/StevensWrath.java b/src/main/java/dev/zxq5/fantasysmp/items/gear/StevensWrath.java
similarity index 76%
rename from src/main/java/dev/zxq5/fantasysmp/items/StevensWrath.java
rename to src/main/java/dev/zxq5/fantasysmp/items/gear/StevensWrath.java
index b044eed..3369a31 100644
--- a/src/main/java/dev/zxq5/fantasysmp/items/StevensWrath.java
+++ b/src/main/java/dev/zxq5/fantasysmp/items/gear/StevensWrath.java
@@ -1,43 +1,26 @@
-package dev.zxq5.fantasysmp.items;
+package dev.zxq5.fantasysmp.items.gear;
+import dev.zxq5.fantasysmp.items.GenericGearSet;
import dev.zxq5.fantasysmp.util.LoreChecker;
import org.bukkit.*;
import org.bukkit.command.CommandExecutor;
-import org.bukkit.entity.LightningStrike;
-import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.inventory.ShapedRecipe;
-import org.bukkit.inventory.ShapelessRecipe;
-import org.bukkit.inventory.SmithingTransformRecipe;
-import org.bukkit.inventory.meta.ItemMeta;
-import org.bukkit.potion.PotionEffect;
-
-import java.util.List;
-
-import static org.bukkit.Bukkit.broadcastMessage;
-import static org.bukkit.Bukkit.getServer;
public class StevensWrath extends GenericGearSet implements Listener, CommandExecutor {
@Override
public boolean onCommand(org.bukkit.command.CommandSender sender, org.bukkit.command.Command command, String label, String[] args) {
- if (!(args[0].equals("wrath"))) {
- return false;
- }
-
Player player = (Player) sender;
-
- player.getInventory().addItem(new StevensWrath().getSword());
+ player.getInventory().addItem(this.getSword());
return true;
}
@EventHandler
public void onCraft(org.bukkit.event.inventory.PrepareItemCraftEvent event) {
if (!event.getInventory().contains(Material.NETHERITE_BLOCK)) return;
- if (!event.getInventory().contains(new Lightning().getSword())) return;
+ if (!event.getInventory().contains(new LightningSword().getSword())) return;
event.getInventory().setResult(new StevensWrath().getSword());
}
@@ -89,7 +72,7 @@ public class StevensWrath extends GenericGearSet implements Listener, CommandExe
public StevensWrath() {
this.setTier6();
this.sword.name = ChatColor.LIGHT_PURPLE + "Stevens Wrath" + ChatColor.RESET;
- this.sword.customModel = "stevens_wrath";
+ this.sword.customItemModel = "stevens_wrath";
this.sword.lore = ChatColor.LIGHT_PURPLE + "All who oppose the mighty Steven shall face his wrath of lightning.";
}
}
diff --git a/src/main/java/dev/zxq5/fantasysmp/items/gear/TrueNetheriteGear.java b/src/main/java/dev/zxq5/fantasysmp/items/gear/TrueNetheriteGear.java
new file mode 100644
index 0000000..147b35a
--- /dev/null
+++ b/src/main/java/dev/zxq5/fantasysmp/items/gear/TrueNetheriteGear.java
@@ -0,0 +1,52 @@
+package dev.zxq5.fantasysmp.items.gear;
+
+import dev.zxq5.fantasysmp.items.GenericGearSet;
+import org.bukkit.ChatColor;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.entity.Player;
+import org.bukkit.event.Listener;
+
+public class TrueNetheriteGear extends GenericGearSet implements CommandExecutor, Listener {
+ @Override
+ public boolean onCommand(org.bukkit.command.CommandSender sender, org.bukkit.command.Command command, String label, String[] args) {
+ Player player = (Player) sender;
+
+ player.getInventory().addItem(this.getSword());
+ player.getInventory().addItem(this.getHelmet());
+ player.getInventory().addItem(this.getChestplate());
+ player.getInventory().addItem(this.getLeggings());
+ player.getInventory().addItem(this.getBoots());
+ return true;
+ }
+
+ @Override
+ public void registerRecipes() {}
+
+ public TrueNetheriteGear() {
+ this.setTier6();
+ this.sword.name = ChatColor.WHITE + "True Netherite Sword" + ChatColor.RESET;
+ this.sword.lore = "A sword forged with the skulls of wither skeletons.";
+ this.sword.customItemModel = "true_netherite_sword";
+ this.sword.lore = "Destruction awaits.";
+
+ this.helmet.name = ChatColor.WHITE + "True Netherite Helmet" + ChatColor.RESET;
+ this.helmet.lore = "A helmet forged with the skulls of wither skeletons.";
+ this.helmet.customItemModel = "true_netherite_helmet";
+ this.helmet.customEquipmentModel = "true_netherite";
+
+ this.chestplate.name = ChatColor.WHITE + "True Netherite Chestplate" + ChatColor.RESET;
+ this.chestplate.lore = "A chestplate forged with the skulls of wither skeletons.";
+ this.chestplate.customItemModel = "true_netherite_chestplate";
+ this.chestplate.customEquipmentModel = "true_netherite";
+
+ this.leggings.name = ChatColor.WHITE + "True Netherite Leggings" + ChatColor.RESET;
+ this.leggings.lore = "Leggings forged with the skulls of wither skeletons.";
+ this.leggings.customItemModel = "true_netherite_leggings";
+ this.leggings.customEquipmentModel = "true_netherite";
+
+ this.boots.name = ChatColor.WHITE + "True Netherite Boots" + ChatColor.RESET;
+ this.boots.lore = "Boots forged with the skulls of wither skeletons.";
+ this.boots.customItemModel = "true_netherite_boots";
+ this.boots.customEquipmentModel = "true_netherite";
+ }
+}
diff --git a/src/main/java/dev/zxq5/fantasysmp/items/Witherite.java b/src/main/java/dev/zxq5/fantasysmp/items/gear/WitheriteGear.java
similarity index 64%
rename from src/main/java/dev/zxq5/fantasysmp/items/Witherite.java
rename to src/main/java/dev/zxq5/fantasysmp/items/gear/WitheriteGear.java
index 2aa5d67..e16094d 100644
--- a/src/main/java/dev/zxq5/fantasysmp/items/Witherite.java
+++ b/src/main/java/dev/zxq5/fantasysmp/items/gear/WitheriteGear.java
@@ -1,38 +1,38 @@
-package dev.zxq5.fantasysmp.items;
+package dev.zxq5.fantasysmp.items.gear;
+import dev.zxq5.fantasysmp.items.GenericGearSet;
import dev.zxq5.fantasysmp.util.LoreChecker;
-import org.bukkit.Material;
-import org.bukkit.NamespacedKey;
+import org.bukkit.*;
import org.bukkit.command.CommandExecutor;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
+import org.bukkit.entity.WitherSkull;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
+import org.bukkit.event.block.Action;
+import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.RecipeChoice;
import org.bukkit.inventory.SmithingTransformRecipe;
-import org.bukkit.inventory.meta.ItemMeta;
-import org.bukkit.inventory.meta.components.CustomModelDataComponent;
-import org.bukkit.inventory.meta.components.EquippableComponent;
import org.bukkit.potion.PotionEffect;
+import java.util.ArrayList;
+import java.util.Objects;
+
+import static org.bukkit.Bukkit.broadcastMessage;
import static org.bukkit.Bukkit.getServer;
-public class Witherite extends GenericGearSet implements Listener, CommandExecutor {
+public class WitheriteGear extends GenericGearSet implements Listener, CommandExecutor {
+ private ArrayList cooldown = new ArrayList<>();
@Override
public boolean onCommand(org.bukkit.command.CommandSender sender, org.bukkit.command.Command command, String label, String[] args) {
- if (!(args[0].equals("witherite"))) {
- return false;
- }
-
Player player = (Player) sender;
-
- player.getInventory().addItem(new Witherite().getSword());
- player.getInventory().addItem(new Witherite().getHelmet());
- player.getInventory().addItem(new Witherite().getChestplate());
- player.getInventory().addItem(new Witherite().getLeggings());
- player.getInventory().addItem(new Witherite().getBoots());
+ player.getInventory().addItem(this.getSword());
+ player.getInventory().addItem(this.getHelmet());
+ player.getInventory().addItem(this.getChestplate());
+ player.getInventory().addItem(this.getLeggings());
+ player.getInventory().addItem(this.getBoots());
return true;
}
@@ -91,6 +91,32 @@ public class Witherite extends GenericGearSet implements Listener, CommandExecut
}
+ @EventHandler
+ public void onPlayerInteract(PlayerInteractEvent event) {
+ Player player = event.getPlayer();
+ ItemStack item = event.getItem(); // Get the item the player interacted with
+
+ if (!(event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK)) {
+ return;
+ }
+
+ if (!(LoreChecker.itemLoreContains(item, this.sword.lore))) return;
+ if (cooldown.contains(player)) return;
+
+ Location location = player.getLocation();
+ player.launchProjectile(WitherSkull.class);
+ player.playSound(location, Sound.ENTITY_WITHER_SHOOT, 1.0f, 1.0f);
+ World world = player.getWorld();
+ world.spawnParticle(Particle.SOUL_FIRE_FLAME, location, 1);
+
+ cooldown.add(player);
+ Bukkit.getScheduler().scheduleSyncDelayedTask(
+ Objects.requireNonNull(Bukkit.getPluginManager().getPlugin("fantasysmp")),
+ () -> cooldown.remove(player),
+ 25
+ );
+ }
+
@EventHandler
public void onEntityPotionEffectEvent(org.bukkit.event.entity.EntityPotionEffectEvent event) {
if (event.getEntity() instanceof Player player) {
@@ -116,23 +142,30 @@ public class Witherite extends GenericGearSet implements Listener, CommandExecut
public static void init() {}
- public Witherite() {
+ public WitheriteGear() {
this.setTier5();
- this.sword.name = "Witherite Sword";
- this.sword.customModel = "witherite_sword";
- this.helmet.name = "Witherite Helmet";
- this.helmet.customModel = "witherite_helmet";
- this.chestplate.name = "Witherite Chestplate";
- this.chestplate.customModel = "witherite_chestplate";
- this.leggings.name = "Witherite Leggings";
- this.leggings.customModel = "witherite_leggings";
- this.boots.name = "Witherite Boots";
- this.boots.customModel = "witherite_boots";
-
+ this.sword.name = ChatColor.BLACK + "Witherite Sword" + ChatColor.RESET;
this.sword.lore = "A sword forged with the skulls of wither skeletons.";
+ this.sword.customItemModel = "witherite_sword";
+
+ this.helmet.name = ChatColor.BLACK + "Witherite Helmet" + ChatColor.RESET;
this.helmet.lore = "A helmet forged with the skulls of wither skeletons.";
+ this.helmet.customItemModel = "witherite_helmet";
+ this.helmet.customEquipmentModel = "witherite";
+
+ this.chestplate.name = ChatColor.BLACK + "Witherite Chestplate" + ChatColor.RESET;
this.chestplate.lore = "A chestplate forged with the skulls of wither skeletons.";
+ this.chestplate.customItemModel = "witherite_chestplate";
+ this.chestplate.customEquipmentModel = "witherite";
+
+ this.leggings.name = ChatColor.BLACK + "Witherite Leggings" + ChatColor.RESET;
this.leggings.lore = "Leggings forged with the skulls of wither skeletons.";
+ this.leggings.customItemModel = "witherite_leggings";
+ this.leggings.customEquipmentModel = "witherite";
+
+ this.boots.name = ChatColor.BLACK + "Witherite Boots" + ChatColor.RESET;
this.boots.lore = "Boots forged with the skulls of wither skeletons.";
+ this.boots.customItemModel = "witherite_boots";
+ this.boots.customEquipmentModel = "witherite";
}
}
diff --git a/src/main/java/dev/zxq5/fantasysmp/warps/Warp.java b/src/main/java/dev/zxq5/fantasysmp/warps/Warp.java
index 54ae113..c131eeb 100644
--- a/src/main/java/dev/zxq5/fantasysmp/warps/Warp.java
+++ b/src/main/java/dev/zxq5/fantasysmp/warps/Warp.java
@@ -1,6 +1,8 @@
package dev.zxq5.fantasysmp.warps;
import com.google.gson.Gson;
+import dev.zxq5.fantasysmp.groups.Team;
+import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.command.CommandExecutor;
@@ -15,11 +17,13 @@ import static org.bukkit.Bukkit.getServer;
public class Warp {
+ private static final String FILENAME = "warps.json";
private static Warp[] warps;
private String name;
private String setby;
private String world;
+ private String teamUUID;
private WarpType type;
private int x;
private int y;
@@ -35,7 +39,7 @@ public class Warp {
public static void loadWarps() throws Exception {
File dataFolder = getServer().getPluginManager().getPlugin("Fantasysmp").getDataFolder();
- File file = new File(dataFolder, "warps.json");
+ File file = new File(dataFolder, FILENAME);
if (!file.exists()) {
createWarpFile();
@@ -52,7 +56,7 @@ public class Warp {
public static void saveWarps() throws Exception {
File dataFolder = getServer().getPluginManager().getPlugin("Fantasysmp").getDataFolder();
- File file = new File(dataFolder, "warps.json");
+ File file = new File(dataFolder, FILENAME);
Gson gson = new Gson();
String json = gson.toJson(warps);
@@ -63,7 +67,7 @@ public class Warp {
public static void createWarpFile() {
File dataFolder = getServer().getPluginManager().getPlugin("Fantasysmp").getDataFolder();
- File file = new File(dataFolder, "warps.json");
+ File file = new File(dataFolder, FILENAME);
if (!file.exists()) {
try {
@@ -104,6 +108,29 @@ public class Warp {
return null;
}
+ public static Warp getTeamWarp(Team team, String name) {
+ for (Warp warp : warps) {
+ if (warp.type.equals(WarpType.TEAM)) {
+ if (warp.name.equals(name) && warp.setby.equals(team.getUUID())) {
+ return warp;
+ }
+ }
+ }
+ return null;
+ }
+
+ public static String listWarps(UUID player) {
+ String message = ChatColor.WHITE + "All Warps: [\n" + ChatColor.GREEN;
+
+ for (Warp warp : warps) {
+ if (warp.type.equals(WarpType.PUBLIC) || warp.setby.equals(player.toString())) {
+ message += " " + warp.name + "\n";
+ }
+ }
+
+ return message + ChatColor.WHITE + "]";
+ }
+
public static void setHome(Player player) {
setWarp("Home (" + player.getName() + ")", player, WarpType.HOME);
}
@@ -149,13 +176,6 @@ public class Warp {
}
}
-enum WarpType {
- HOME,
- PUBLIC,
- DEATH,
- TEAM,
-}
-
diff --git a/src/main/java/dev/zxq5/fantasysmp/warps/WarpType.java b/src/main/java/dev/zxq5/fantasysmp/warps/WarpType.java
new file mode 100644
index 0000000..c78b198
--- /dev/null
+++ b/src/main/java/dev/zxq5/fantasysmp/warps/WarpType.java
@@ -0,0 +1,8 @@
+package dev.zxq5.fantasysmp.warps;
+
+public enum WarpType {
+ HOME,
+ PUBLIC,
+ DEATH,
+ TEAM,
+}
diff --git a/src/main/java/dev/zxq5/fantasysmp/warps/Warper.java b/src/main/java/dev/zxq5/fantasysmp/warps/Warper.java
index cb26029..7bb290c 100644
--- a/src/main/java/dev/zxq5/fantasysmp/warps/Warper.java
+++ b/src/main/java/dev/zxq5/fantasysmp/warps/Warper.java
@@ -1,73 +1,121 @@
package dev.zxq5.fantasysmp.warps;
+import dev.zxq5.fantasysmp.chatutils.Chat;
+import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.entity.Player;
+/*
+* Commands:
+*
+* ** PLAYER **
+*
+* home => DONE
+* sethome => DONE
+* warp => DONE
+*
+* ** ADMIN ONLY **
+*
+* rewarps => DONE
+* setwarp => DONE
+* delwarp => TODO
+* */
+
public class Warper implements CommandExecutor {
@Override
- public boolean onCommand(org.bukkit.command.CommandSender sender, org.bukkit.command.Command command, String label, String[] args) {
+ public boolean onCommand(org.bukkit.command.CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player player)) {
return false;
}
- if (command.getName().equals("reloadwarps")) {
- // reply
- try {
- Warp.loadWarps();
- } catch (Exception e) {
- player.sendMessage("Failed to reload warps. please contact an admin.");
- e.printStackTrace();
- }
+ switch (command.getName()) {
+ case "home" -> this.handleHome(player, args);
+ case "sethome" -> this.handleSetHome(player, args);
+ case "warp" -> this.handleWarp(player, args);
+ case "setwarp" -> this.handleSetWarp(player, args);
+ case "delwarp" -> this.handleDelWarp(player, args);
+ case "rewarps" -> this.handleReWarps(player, args);
+ case "warps" -> this.handleWarpsOther(player, args);
}
- if (command.getName().equals("home")) {
- if (args.length != 0) {
- player.sendMessage("Usage: /home");
- return true;
- }
-
- Warp warp = Warp.getHome(player.getUniqueId());
-
- if (warp != null) {
- warp.execute(player);
- }
- }
-
- if (command.getName().equals("sethome")) {
- if (args.length != 0) {
- player.sendMessage("Usage: /sethome");
- return true;
- }
-
- Warp.setHome(player);
- }
-
- if (command.getName().equals("warp")) {
- if (args.length != 1) {
- player.sendMessage("Usage: /warp ");
- return true;
- }
-
- Warp warp = Warp.getWarp(args[0]);
-
- if (warp != null) {
- warp.execute(player);
- }
- }
-
- if (command.getName().equals("setwarp")) {
- if (!(player.hasPermission("fantasysmp.manage_warps"))) {
- player.sendMessage("You do not have permission to use this command.");
- return false;
- }
-
- if (args.length != 1) {
- player.sendMessage("Usage: /setwarp ");
- return true;
- }
-
- Warp.setWarp(args[0], player, WarpType.PUBLIC);
- }
return true;
}
+
+ public void handleHome(Player player, String[] args) {
+ if (args.length != 0) {
+ Chat.error(player,"Usage: /home");
+ return;
+ }
+
+ Warp warp = Warp.getHome(player.getUniqueId());
+
+ if (warp == null) {
+ Chat.error(player,"No home set! use /sethome to set one.");
+ return;
+ }
+
+ warp.execute(player);
+ Chat.success(player,"Warped Home!");
+ }
+
+ public void handleSetHome(Player player, String[] args) {
+ if (args.length != 0) {
+ Chat.error(player,"Usage: /sethome");
+ return;
+ }
+
+ Warp.setHome(player);
+ Chat.success(player,"Home set Successfully!");
+ }
+
+ public void handleWarp(Player player, String[] args) {
+ if (args.length != 1) {
+ Chat.error(player, "Usage: /warp ");
+ return;
+ }
+
+ Warp warp = Warp.getWarp(args[0]);
+
+ if (warp == null) {
+ Chat.error(player, "Location [" + args[0] + "] does not exist or is not accessible to you!");
+ return;
+ };
+ warp.execute(player);
+ Chat.success(player, "Warped!");
+ }
+
+ public void handleSetWarp(Player player, String[] args) {
+ if (!(player.hasPermission("fantasysmp.manage_warps"))) {
+ Chat.error(player, "You do not have permission to use this command.");
+ return;
+ }
+
+ if (args.length != 1) {
+ Chat.error(player, "Usage: /setwarp ");
+ return;
+ }
+
+ Warp.setWarp(args[0], player, WarpType.PUBLIC);
+ Chat.success(player, "Warp [" + args[0] + "] set Successfully!");
+ }
+
+ public void handleDelWarp(Player player, String[] args) {
+
+ }
+
+ public void handleReWarps(Player player, String[] args) {
+ try {
+ Warp.loadWarps();
+ } catch (Exception e) {
+ Chat.error(player, "Failed to reload warps. please contact zxq5.");
+ e.printStackTrace();
+ }
+ Chat.success(player, "Successfully reloaded warps from warps.json");
+ }
+
+ public void handleWarpsOther(Player player, String[] args) {
+ if (args.length == 0) {
+ Chat.info(player, Warp.listWarps(player.getUniqueId()));
+ }
+ }
}
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 2d73bfc..8ffc50d 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -27,36 +27,60 @@ commands:
usage: /setwarp
permission: fantasysmp.manage_warps
- reloadwarps:
+ delwarp:
+ description: delete a warp
+ usage: /delwarp
+ permission: fantasysmp.manage_warps
+
+ warps:
+ description: list all warps
+ usage: /warps
+ permission: fantasysmp.warps
+
+ rewarps:
description: reload warps
- usage: /reloadwarps
- permission: fantasysmp.admin
+ usage: /rewarps
+ permission: fantasysmp.manage_warps
warp:
description: teleport to a warp
usage: /warp
permission: fantasysmp.warps
+ team:
+ description: team commands
+ usage: /team
+ permission: fantasysmp.teams
+
permissions:
- fantasysmp.admin:
- description: Manage plugin
- default: op
- children:
- fantasysmp.*: true
-
fantasysmp.items:
description: create custom items from plugin
default: false
+ fantasysmp.teams:
+ description: team commands
+ default: true
+
fantasysmp.warps:
description: teleport to custom warps
default: true
fantasysmp.manage_warps:
description: commands for managing warps
- default: true
+ default: false
fantasysmp.home:
description: commands for teleporting home
- default: true
\ No newline at end of file
+ default: true
+
+ fantasysmp.admin:
+ description: Manage plugin
+ default: op
+ children:
+ fantasysmp.items: true
+ fantasysmp.manage_warps: true
+ fantasysmp.home: true
+ fantasysmp.warps: true
+ fantasysmp.teams: true
+