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 +