diff --git a/README.md b/README.md index 3212f77..74d6abf 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # aEventos -O ``aEventos`` é um plugin para servidores de Minecraft que traz vários eventos automáticos de forma fácil e rápida. O plugin foi testado apenas na 1.8.X, porém deve funcionar completamente até a 1.12.X. A maioria dos eventos deve funcionar nas versões mais atuais. +O ``aEventos`` é um plugin para servidores de Minecraft que traz vários eventos automáticos de forma fácil e rápida. O plugin foi testado apenas na 1.8.X, mas possui suporte para as versões mais recentes. ## Eventos: -O plugin conta atualmente com ``11`` eventos, que são: +O plugin conta atualmente com ``17`` eventos no total, sendo ``14`` presenciais: * Sign (Você ganha o evento ao clicar na placa. Com uma configuração, também pode ser usado para Parkour.) * Campo Minado * Spleef @@ -15,7 +15,14 @@ O plugin conta atualmente com ``11`` eventos, que são: * Sumo * Fall (Caso você ainda esteja vivo depois de X segundos do início do evento, você ganha. Pode ser usado para fazer um evento Astronauta, por exemplo.) * Paintball +* Hunter (Paintball com um sistema de pontos.) +* Quiz +* Anvil +e ``3`` no chat: +* Votação +* Loteria +* Bolão ## Comandos: |Comando |Descrição |Permissão | @@ -33,7 +40,7 @@ O plugin conta atualmente com ``11`` eventos, que são: ## Configurações: -Quando você carregar o plugin pela primeira vez, serão criadas ``12`` configurações de exemplo na pasta ``eventos`` com todos os eventos do plugin. Cada tipo de evento possui suas configurações únicas, mas neste exemplo será configurado o arquivo ``parkour.yml``. +Quando você carregar o plugin pela primeira vez, serão criadas ``18`` configurações de exemplo na pasta ``eventos`` com todos os eventos do plugin. Cada tipo de evento possui suas configurações únicas, mas neste exemplo será configurado o arquivo ``parkour.yml``. ```yml Evento: diff --git a/pom.xml b/pom.xml index 03d5ecb..45ac691 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ com.ars3ne aEventos https://github.com/ars3ne/aEventos - 1.1.0 + 1.2.0 8 @@ -31,6 +31,10 @@ bintray-roinujnosde-bukkit-plugins https://dl.bintray.com/roinujnosde/bukkit-plugins + + jitpack.io + https://jitpack.io + local-maven-repo file:///${project.basedir}/local-maven-repo @@ -57,6 +61,18 @@ 1.1.3 provided + + com.github.MilkBowl + VaultAPI + 1.7 + provided + + + com.google.code.findbugs + jsr305 + 3.0.2 + provided + @@ -70,5 +86,4 @@ - diff --git a/src/main/java/com/ars3ne/eventos/aEventos.java b/src/main/java/com/ars3ne/eventos/aEventos.java index a2539dc..ad404b4 100644 --- a/src/main/java/com/ars3ne/eventos/aEventos.java +++ b/src/main/java/com/ars3ne/eventos/aEventos.java @@ -34,10 +34,12 @@ import com.ars3ne.eventos.manager.*; import com.ars3ne.eventos.utils.ConfigFile; import com.ars3ne.eventos.utils.ConfigUpdater; +import net.milkbowl.vault.economy.Economy; import net.sacredlabyrinth.phaed.simpleclans.SimpleClans; import org.bukkit.Bukkit; import org.bukkit.event.HandlerList; import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.java.JavaPlugin; import java.io.File; @@ -54,6 +56,8 @@ public class aEventos extends JavaPlugin { private SimpleClans clan = null; private static final LegendChatHook lc_hook = new LegendChatHook(); + private Economy econ = null; + private final EventoListener setup_listener = new EventoListener(); @Override @@ -107,7 +111,6 @@ private void setupConfig() { if(!settings.exists()) { - // Presencial ConfigFile.create("parkour"); ConfigFile.create("campominado"); ConfigFile.create("spleef"); @@ -120,9 +123,12 @@ private void setupConfig() { ConfigFile.create("sumo"); ConfigFile.create("astronauta"); ConfigFile.create("paintball"); - - // Chat ConfigFile.create("votacao"); + ConfigFile.create("hunter"); + ConfigFile.create("quiz"); + ConfigFile.create("anvil"); + ConfigFile.create("loteria"); + ConfigFile.create("bolao"); } @@ -136,6 +142,9 @@ private void setupConfig() { e.printStackTrace(); } + // Tenta atualizar os eventos. + ConfigUpdater.updateEventos(); + } private void setupListener() { @@ -154,6 +163,9 @@ private void setupAddons() { if(!setupLegendChat()) { Bukkit.getConsoleSender().sendMessage("§e[aEventos] §cLegendChat não encontrado."); } + if(!setupEconomy()) { + Bukkit.getConsoleSender().sendMessage("§e[aEventos] §cVault não encontrado."); + } } private boolean setupLegendChat() { @@ -173,6 +185,17 @@ private boolean setupSimpleClans() { return true; } + private boolean setupEconomy() { + if (getServer().getPluginManager().getPlugin("Vault") == null) { + return false; + } + RegisteredServiceProvider rsp = getServer().getServicesManager().getRegistration(Economy.class); + if (rsp == null) { + return false; + } + econ = rsp.getProvider(); + return econ != null; + } public static EventosManager getEventoManager() { return manager; } @@ -185,6 +208,8 @@ public SimpleClans getSimpleClans() { return this.clan; } + public Economy getEconomy() { return this.econ; } + public static aEventos getInstance() { return (aEventos) Bukkit.getServer().getPluginManager().getPlugin("aEventos"); } diff --git a/src/main/java/com/ars3ne/eventos/api/Evento.java b/src/main/java/com/ars3ne/eventos/api/Evento.java index 5c93048..cc31a54 100644 --- a/src/main/java/com/ars3ne/eventos/api/Evento.java +++ b/src/main/java/com/ars3ne/eventos/api/Evento.java @@ -69,7 +69,7 @@ public Evento(YamlConfiguration config) { this.elimination = false; switch(type) { - case SPLEEF: case BATATA_QUENTE: case FIGHT: case KILLER: case SUMO: + case SPLEEF: case BATATA_QUENTE: case FIGHT: case KILLER: case SUMO: case ANVIL: this.elimination = true; break; } diff --git a/src/main/java/com/ars3ne/eventos/api/EventoChat.java b/src/main/java/com/ars3ne/eventos/api/EventoChat.java index e807c91..f68c210 100644 --- a/src/main/java/com/ars3ne/eventos/api/EventoChat.java +++ b/src/main/java/com/ars3ne/eventos/api/EventoChat.java @@ -34,6 +34,7 @@ import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; +import java.util.ArrayList; import java.util.List; public class EventoChat implements EventoInterface{ @@ -52,12 +53,15 @@ public EventoChat(YamlConfiguration config) { type = EventoType.getEventoType(config.getString("Evento.Type")); this.permission = config.getString("Evento.Permission"); - if (type == EventoType.VOTACAO) { - this.count_participation = false; - this.count_win = false; - } else { - this.count_participation = config.getBoolean("Evento.Count participation"); - this.count_win = config.getBoolean("Evento.Count victory"); + switch(type) { + case VOTACAO: + this.count_participation = false; + this.count_win = false; + break; + default: + this.count_participation = config.getBoolean("Evento.Count participation"); + this.count_win = config.getBoolean("Evento.Count victory"); + break; } } @@ -90,7 +94,6 @@ public void run() { List broadcast_messages = config.getStringList("Messages.Broadcast"); for(String s : broadcast_messages) { parseMessage(s, calls); - //aEventos.getInstance().getServer().broadcastMessage(s.replace("&", "§").replace("@broadcasts", String.valueOf(calls)).replace("@name", config.getString("Evento.Title"))); } calls--; @@ -99,6 +102,9 @@ public void run() { cancel(); start(); + EventoStartedEvent start = new EventoStartedEvent(config.getString("filename").substring(0, config.getString("filename").length() - 4), type); + Bukkit.getPluginManager().callEvent(start); + } } }.runTaskTimer(aEventos.getInstance(), 0, config.getInt("Evento.Calls interval") * 20L); @@ -116,10 +122,9 @@ public void setWinner(Player p) { if(!this.count_win) return; - /*List winners = new ArrayList<>(); + List winners = new ArrayList<>(); winners.add(p.getUniqueId().toString()); - this.win.add(p); - + aEventos.getConnectionManager().insertUser(p.getUniqueId()); aEventos.getConnectionManager().addWin(config.getString("filename").substring(0, config.getString("filename").length() - 4), p.getUniqueId()); @@ -129,7 +134,6 @@ public void setWinner(Player p) { PlayerWinEvent win = new PlayerWinEvent(p, config.getString("filename").substring(0, config.getString("filename").length() - 4), type); Bukkit.getPluginManager().callEvent(win); - */ } diff --git a/src/main/java/com/ars3ne/eventos/api/EventoType.java b/src/main/java/com/ars3ne/eventos/api/EventoType.java index 3642df8..7359f69 100644 --- a/src/main/java/com/ars3ne/eventos/api/EventoType.java +++ b/src/main/java/com/ars3ne/eventos/api/EventoType.java @@ -40,12 +40,15 @@ public enum EventoType { FALL, PAINTBALL, VOTACAO, + HUNTER, + QUIZ, + ANVIL, + LOTERIA, + BOLAO, NONE; public static EventoType getEventoType(String type) { - switch (type) { - - // Evento presencial + switch (type.toLowerCase()) { case "sign": return EventoType.SIGN; case "campominado": @@ -68,11 +71,18 @@ public static EventoType getEventoType(String type) { return EventoType.FALL; case "paintball": return EventoType.PAINTBALL; - - // Evento chat case "votacao": return EventoType.VOTACAO; - + case "hunter": + return EventoType.HUNTER; + case "quiz": + return EventoType.QUIZ; + case "anvil": + return EventoType.ANVIL; + case "loteria": + return EventoType.LOTERIA; + case "bolao": + return EventoType.BOLAO; default: return EventoType.NONE; } @@ -104,6 +114,16 @@ public static String getString(EventoType type) { return "paintball"; case VOTACAO: return "votacao"; + case HUNTER: + return "hunter"; + case QUIZ: + return "quiz"; + case ANVIL: + return "anvil"; + case LOTERIA: + return "loteria"; + case BOLAO: + return "bolao"; default: return "none"; } @@ -111,7 +131,7 @@ public static String getString(EventoType type) { public static boolean isEventoChat(EventoType type) { switch(type) { - case VOTACAO: + case VOTACAO: case LOTERIA: case BOLAO: return true; default: return false; diff --git a/src/main/java/com/ars3ne/eventos/commands/EventoCommand.java b/src/main/java/com/ars3ne/eventos/commands/EventoCommand.java index 05a4ed7..e810488 100644 --- a/src/main/java/com/ars3ne/eventos/commands/EventoCommand.java +++ b/src/main/java/com/ars3ne/eventos/commands/EventoCommand.java @@ -278,7 +278,10 @@ else if(args[0].equalsIgnoreCase("iniciar")) { YamlConfiguration config = ConfigFile.get(args[1].toLowerCase()); if(EventoType.isEventoChat(EventoType.getEventoType(config.getString("Evento.Type")))) { - aEventos.getEventoChatManager().startEvento(EventoType.getEventoType(config.getString("Evento.Type")), config); + boolean started = aEventos.getEventoChatManager().startEvento(EventoType.getEventoType(config.getString("Evento.Type")), config); + if(!started) { + sender.sendMessage(aEventos.getInstance().getConfig().getString("Messages.Missing dependency").replace("&", "§").replace("@dependency", "Vault")); + } }else { boolean started = aEventos.getEventoManager().startEvento(EventoType.getEventoType(config.getString("Evento.Type")), config); if(!started) { @@ -314,8 +317,10 @@ else if(args[0].equalsIgnoreCase("iniciar")) { return true; } - // Crie o arquivo de configuração. + // Crie o arquivo de configuração e atualize as tags. ConfigFile.create(args[1].toLowerCase()); + aEventos.updateTags(); + sender.sendMessage(aEventos.getInstance().getConfig().getString("Messages.Configuration created").replace("&", "§").replace("@file", args[1].toLowerCase() + ".yml")); return true; @@ -459,6 +464,21 @@ else if(args[1].equalsIgnoreCase("pos")) { axe.setItemMeta(meta); p.getInventory().addItem(axe); + if(setup.get(p).isSet("Locations.Pos3")) { + // De uma enxada para o jogador definir as posições. + ItemStack hoe = new ItemStack(Material.STONE_HOE, 1); + ItemMeta meta2 = hoe.getItemMeta(); + + meta2.setDisplayName("§6Enxada de Posições"); + ArrayList lore2 = new ArrayList<>(); + lore2.add("§7* Clique esquerdo para definir a terceira posição."); + lore2.add("§7* Clique direito para definir a quarta posição."); + meta2.setLore(lore2); + + hoe.setItemMeta(meta2); + p.getInventory().addItem(hoe); + } + sender.sendMessage(aEventos.getInstance().getConfig().getString("Messages.Give axe").replace("&", "§").replace("@name", settings.getString("Evento.Title"))); return true; @@ -516,6 +536,58 @@ else if(args[1].equalsIgnoreCase("pos2")) { } + else if(args[1].equalsIgnoreCase("pos3")) { + + // Se o evento não possui as configurações de pos, retorne um erro. + if(!setup.get(p).isSet("Locations.Pos3")) { + sender.sendMessage(aEventos.getInstance().getConfig().getString("Messages.Not needed").replace("&", "§").replace("@name", settings.getString("Evento.Title"))); + return true; + } + + settings.set("Locations.Pos3.world", p.getLocation().getWorld().getName()); + settings.set("Locations.Pos3.x", p.getLocation().getX()); + settings.set("Locations.Pos3.y", p.getLocation().getY()); + settings.set("Locations.Pos3.z", p.getLocation().getZ()); + + try { + ConfigFile.save(settings); + setup.replace(p, settings); + } catch (IOException e) { + sender.sendMessage(aEventos.getInstance().getConfig().getString("Messages.Error").replace("&", "§").replace("@name", settings.getString("Evento.Title")).replace("@pos", "")); + e.printStackTrace(); + } + + sender.sendMessage(aEventos.getInstance().getConfig().getString("Messages.Saved").replace("&", "§").replace("@name", settings.getString("Evento.Title")).replace("@pos", "pos3 ")); + return true; + + } + + else if(args[1].equalsIgnoreCase("pos4")) { + + // Se o evento não possui as configurações de pos, retorne um erro. + if(!setup.get(p).isSet("Locations.Pos3")) { + sender.sendMessage(aEventos.getInstance().getConfig().getString("Messages.Not needed").replace("&", "§").replace("@name", settings.getString("Evento.Title"))); + return true; + } + + settings.set("Locations.Pos4.world", p.getLocation().getWorld().getName()); + settings.set("Locations.Pos4.x", p.getLocation().getX()); + settings.set("Locations.Pos4.y", p.getLocation().getY()); + settings.set("Locations.Pos4.z", p.getLocation().getZ()); + + try { + ConfigFile.save(settings); + setup.replace(p, settings); + } catch (IOException e) { + sender.sendMessage(aEventos.getInstance().getConfig().getString("Messages.Error").replace("&", "§").replace("@name", settings.getString("Evento.Title")).replace("@pos", "")); + e.printStackTrace(); + } + + sender.sendMessage(aEventos.getInstance().getConfig().getString("Messages.Saved").replace("&", "§").replace("@name", settings.getString("Evento.Title")).replace("@pos", "pos4 ")); + return true; + + } + else if(args[1].equalsIgnoreCase("sair")) { // Remova o usuário da lista de setup. setup.remove(p); diff --git a/src/main/java/com/ars3ne/eventos/eventos/Anvil.java b/src/main/java/com/ars3ne/eventos/eventos/Anvil.java new file mode 100644 index 0000000..5d6f4a4 --- /dev/null +++ b/src/main/java/com/ars3ne/eventos/eventos/Anvil.java @@ -0,0 +1,215 @@ +/* + * + * This file is part of aEventos, licensed under the MIT License. + * + * Copyright (c) Ars3ne + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package com.ars3ne.eventos.eventos; + +import com.ars3ne.eventos.aEventos; +import com.ars3ne.eventos.api.Evento; +import com.ars3ne.eventos.listeners.eventos.AnvilListener; +import com.ars3ne.eventos.utils.Cuboid; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitScheduler; +import org.bukkit.scheduler.BukkitTask; + +import java.util.ArrayList; +import java.util.List; + +public class Anvil extends Evento { + + private final YamlConfiguration config; + private final AnvilListener listener = new AnvilListener(); + + private final List anvil = new ArrayList<>(); + + private final int height, time, delay; + + private final Cuboid cuboid; + + private BukkitTask runnable; + private final BukkitScheduler scheduler = aEventos.getInstance().getServer().getScheduler(); + + public Anvil(YamlConfiguration config) { + super(config); + this.config = config; + + this.height = config.getInt("Evento.Height"); + this.time = config.getInt("Evento.Time"); + this.delay = config.getInt("Evento.Delay"); + + // Obtenha o cuboid. + World world = aEventos.getInstance().getServer().getWorld(config.getString("Locations.Pos1.world")); + Location pos1 = new Location(world, config.getDouble("Locations.Pos1.x"), config.getDouble("Locations.Pos1.y"), config.getDouble("Locations.Pos1.z")); + Location pos2 = new Location(world, config.getDouble("Locations.Pos2.x"), config.getDouble("Locations.Pos2.y"), config.getDouble("Locations.Pos2.z")); + this.cuboid = new Cuboid(pos1, pos2); + + } + + @SuppressWarnings("deprecation") + @Override + public void start() { + // Registre o listener do evento + aEventos.getInstance().getServer().getPluginManager().registerEvents(listener, aEventos.getInstance()); + listener.setEvento(); + + // Remova as bigornas. + for(Block block: cuboid.getBlocks()) { + if(block.getType() == Material.ANVIL) { + block.setType(Material.AIR); + } + } + + // Envie a mensagem para todos os usuários no evento. + List starting_level = config.getStringList("Messages.Starting"); + for (Player player : getPlayers()) { + for(String s : starting_level) { + player.sendMessage(s.replace("&", "§").replace("@time", String.valueOf(time)).replace("@name", config.getString("Evento.Title"))); + } + } + + for (Player player : getSpectators()) { + for(String s : starting_level) { + player.sendMessage(s.replace("&", "§").replace("@time", String.valueOf(time)).replace("@name", config.getString("Evento.Title"))); + } + } + + // Adicione o efeito jump boost para não permitir que os jogadores pulem. + for(Player p: getPlayers()) { + p.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, Integer.MAX_VALUE, 200)); + } + + // Depois do tempo da config, inicie o evento. + runnable = scheduler.runTaskTimer(aEventos.getInstance(), () -> { + + if(!isHappening()) runnable.cancel(); + + if(anvil.size() < cuboid.getTotalBlockSize() - 1) { + + // Obtenha um bloco aleatório do cuboid. + Block anvil_block = cuboid.getRandomLocation().getBlock(); + while(anvil_block.getType() != Material.AIR || anvil.contains(anvil_block)) { + anvil_block = cuboid.getRandomLocation().getBlock(); + } + + anvil_block.getWorld().spawnFallingBlock(anvil_block.getLocation().add(0, height, 0), Material.ANVIL, (byte) 0).setDropItem(false); + anvil.add(anvil_block); + + }else { + win(); + runnable.cancel(); + } + + }, time * 20L, delay * 20L); + + } + + public void win() { + + List winners = new ArrayList<>(); + + // Adicionar vitória e dar a tag no LegendChat. + this.setWinners(); + + // Encerre o evento. + this.stop(); + + // Obtenha todos os jogadores restantes e os entregue as recompensas. + for(Player p: getPlayers()) { + + // Execute os comandos de vitória + List commands = this.config.getStringList("Rewards.Commands"); + for(String s : commands) { + aEventos.getInstance().getServer().dispatchCommand(aEventos.getInstance().getServer().getConsoleSender(), s.replace("@winner", p.getName())); + } + + // Adicione o nome á lista de vencedores. + winners.add(p.getName()); + } + + // Mande a mensagem de vitória para o servidor. + List broadcast_messages = this.config.getStringList("Messages.Winner"); + for(String s : broadcast_messages) { + aEventos.getInstance().getServer().broadcastMessage(s.replace("&", "§").replace("@winner", String.join(", ", winners)).replace("@name", config.getString("Evento.Title"))); + } + + } + + @Override + public void winner(Player p) { + + // Mande a mensagem de vitória. + List broadcast_messages = config.getStringList("Messages.Winner"); + for(String s : broadcast_messages) { + aEventos.getInstance().getServer().broadcastMessage(s.replace("&", "§").replace("@winner", p.getName()).replace("@name", getConfig().getString("Evento.Title"))); + } + + // Adicionar vitória e dar a tag no LegendChat. + this.setWinner(p); + + // Encerre o evento. + this.stop(); + + // Execute todos os comandos de vitória. + List commands = config.getStringList("Rewards.Commands"); + for(String s : commands) { + aEventos.getInstance().getServer().dispatchCommand(aEventos.getInstance().getServer().getConsoleSender(), s.replace("@winner", p.getName())); + } + + } + + @Override + public void stop() { + + // Remova o efeito. + for(Player p: getPlayers()) { + p.removePotionEffect(PotionEffectType.JUMP); + } + + // Remova as bigornas. + for(Block block: cuboid.getBlocks()) { + if(block.getType() == Material.ANVIL) { + block.setType(Material.AIR); + } + } + + // Remova o listener do evento e chame a função cancel. + HandlerList.unregisterAll(listener); + this.removePlayers(); + } + + public List getAnvils() { + return this.anvil; + } + +} diff --git a/src/main/java/com/ars3ne/eventos/eventos/BatataQuente.java b/src/main/java/com/ars3ne/eventos/eventos/BatataQuente.java index 3d16db7..27b6958 100644 --- a/src/main/java/com/ars3ne/eventos/eventos/BatataQuente.java +++ b/src/main/java/com/ars3ne/eventos/eventos/BatataQuente.java @@ -31,6 +31,7 @@ import com.ars3ne.eventos.api.Evento; import com.ars3ne.eventos.api.events.PlayerLoseEvent; import com.ars3ne.eventos.listeners.eventos.BatataQuenteListener; +import com.ars3ne.eventos.utils.XMaterial; import org.bukkit.*; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Firework; @@ -38,10 +39,13 @@ import org.bukkit.event.HandlerList; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.FireworkMeta; +import org.bukkit.scoreboard.Scoreboard; +import org.bukkit.scoreboard.Team; import java.util.List; import java.util.Random; +@SuppressWarnings("deprecation") public class BatataQuente extends Evento { private final YamlConfiguration config; @@ -51,11 +55,15 @@ public class BatataQuente extends Evento { private Player potato_holder; + Scoreboard board = Bukkit.getScoreboardManager().getMainScoreboard(); + Team potato_holder_team = board.registerNewTeam("potato_holder"); + public BatataQuente(YamlConfiguration config) { super(config); this.config = config; this.max_time = config.getInt("Evento.Time"); + potato_holder_team.setPrefix(ChatColor.RED.toString()); } @Override @@ -63,7 +71,6 @@ public void start() { // Registre o listener do evento aEventos.getInstance().getServer().getPluginManager().registerEvents(listener, aEventos.getInstance()); listener.setEvento(); - randomHolder(); } @@ -100,6 +107,9 @@ public void stop() { p.getInventory().clear(); } + // Remova o team. + potato_holder_team.unregister(); + // Remova o listener do evento e chame a função cancel. HandlerList.unregisterAll(listener); this.removePlayers(); @@ -120,6 +130,7 @@ public void leave(Player p) { // Se o jogador que saiu for o holder da batata, então pegue outro. if(potato_holder == p) { + potato_holder_team.removePlayer(p); potato_holder.getInventory().clear(); potato_holder.getInventory().setHelmet(null); potato_holder = null; @@ -147,9 +158,12 @@ public void setHolder(Player p) { // Dê a batata para o holder e o equipe com TNT. potato_holder.getInventory().setHelmet(new ItemStack(Material.TNT, 1)); for(int i = 0; i < 9; i++) { - potato_holder.getInventory().setItem(i, new ItemStack(Material.POTATO_ITEM, 1)); + potato_holder.getInventory().setItem(i, XMaterial.POTATO.parseItem()); } + // O adicione para o time do batata holder. + potato_holder_team.addPlayer(p); + // Spawne um foguete na localização do holder. Location loc = potato_holder.getLocation(); Firework firework = potato_holder.getWorld().spawn(loc, Firework.class); diff --git a/src/main/java/com/ars3ne/eventos/eventos/Fight.java b/src/main/java/com/ars3ne/eventos/eventos/Fight.java index bac8e80..4bde8de 100644 --- a/src/main/java/com/ars3ne/eventos/eventos/Fight.java +++ b/src/main/java/com/ars3ne/eventos/eventos/Fight.java @@ -31,10 +31,10 @@ import com.ars3ne.eventos.api.Evento; import com.ars3ne.eventos.api.events.PlayerLoseEvent; import com.ars3ne.eventos.listeners.eventos.FightListener; +import com.ars3ne.eventos.utils.XMaterial; import net.sacredlabyrinth.phaed.simpleclans.ClanPlayer; import org.bukkit.Bukkit; import org.bukkit.Location; -import org.bukkit.Material; import org.bukkit.World; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; @@ -43,9 +43,10 @@ import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.Random; -@SuppressWarnings("deprecation") +@SuppressWarnings("OptionalGetWithoutIsPresent") public class Fight extends Evento { private final YamlConfiguration config; @@ -136,6 +137,7 @@ public void stop() { p.getInventory().setChestplate(null); p.getInventory().setLeggings(null); p.getInventory().setBoots(null); + p.getInventory().clear(); } // Desative o friendly-fire dos jogadores. @@ -160,24 +162,27 @@ public void leave(Player p) { for (Player player : getSpectators()) { player.sendMessage(aEventos.getInstance().getConfig().getString("Messages.Leave").replace("&", "§").replace("@player", p.getName())); } - } - // Se o jogador que saiu foi um dos lutadores, então o defina como perdedor. - if(fighter1 == p || fighter2 == p) { - setFightLoser(p); - } + // Desative o friendly-fire do jogador. + if(aEventos.getInstance().getSimpleClans() != null) { + if(clans.contains(aEventos.getInstance().getSimpleClans().getClanManager().getClanPlayer(p))) { + clans.remove(aEventos.getInstance().getSimpleClans().getClanManager().getClanPlayer(p)); + aEventos.getInstance().getSimpleClans().getClanManager().getClanPlayer(p).setFriendlyFire(false); + } + } - // Desative o friendly-fire do jogador. - if(aEventos.getInstance().getSimpleClans() != null) { - if(clans.contains(aEventos.getInstance().getSimpleClans().getClanManager().getClanPlayer(p))) { - clans.remove(aEventos.getInstance().getSimpleClans().getClanManager().getClanPlayer(p)); - aEventos.getInstance().getSimpleClans().getClanManager().getClanPlayer(p).setFriendlyFire(false); + PlayerLoseEvent lose = new PlayerLoseEvent(p, config.getString("filename").substring(0, config.getString("filename").length() - 4), getType()); + Bukkit.getPluginManager().callEvent(lose); + + // Se o jogador que saiu foi um dos lutadores, então o defina como perdedor. + if(fighter1 == p || fighter2 == p) { + setFightLoser(p, true); } + + this.remove(p); + } - PlayerLoseEvent lose = new PlayerLoseEvent(p, config.getString("filename").substring(0, config.getString("filename").length() - 4), getType()); - Bukkit.getPluginManager().callEvent(lose); - this.remove(p); } @@ -230,70 +235,134 @@ private void fight() { } } - // Se for a última luta, de os itens especiais. + // Se for a última luta, de os Items especiais. if(getPlayers().size() == 2) { for(String s: config.getStringList("Items.Last fight.Inventory")) { + String[] separated = s.split("-"); - fighter1.getInventory().addItem(new ItemStack(Material.getMaterial(Integer.parseInt(separated[0])), Integer.parseInt(separated[1]))); - fighter2.getInventory().addItem(new ItemStack(Material.getMaterial(Integer.parseInt(separated[0])), Integer.parseInt(separated[1]))); + ItemStack is; + if(separated.length == 3) { + is = new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(separated[0]).get().parseMaterial()), Integer.parseInt(separated[2]), (byte) Integer.parseInt(separated[1])); + }else { + is = new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(separated[0]).get().parseMaterial()), Integer.parseInt(separated[1])); + } + + fighter1.getInventory().addItem(is); + fighter2.getInventory().addItem(is); } - if(config.getString("Itens.Last fight.Armor.Helmet") != null) { - String[] separated = config.getString("Itens.Last fight.Armor.Helmet").split("-"); - fighter1.getInventory().setHelmet(new ItemStack(Material.getMaterial(Integer.parseInt(separated[0])), Integer.parseInt(separated[1]))); - fighter2.getInventory().setHelmet(new ItemStack(Material.getMaterial(Integer.parseInt(separated[0])), Integer.parseInt(separated[1]))); + if(!config.getString("Items.Last fight.Armor.Helmet.Material").equalsIgnoreCase("air")) { + + if(config.getInt("Items.Last fight.Armor.Helmet.Data") != 0) { + fighter1.getInventory().setHelmet(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Last fight.Armor.Helmet.Material")).get().parseMaterial()), 1, (byte) config.getInt("Items.Last fight.Armor.Helmet.Data"))); + fighter2.getInventory().setHelmet(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Last fight.Armor.Helmet.Material")).get().parseMaterial()), 1, (byte) config.getInt("Items.Last fight.Armor.Helmet.Data"))); + }else { + fighter1.getInventory().setHelmet(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Last fight.Armor.Helmet.Material")).get().parseMaterial()), 1)); + fighter2.getInventory().setHelmet(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Last fight.Armor.Helmet.Material")).get().parseMaterial()), 1)); + } + } - if(config.getString("Itens.Last fight.Armor.Chestplate") != null) { - String[] separated = config.getString("Itens.Last fight.Armor.Chestplate").split("-"); - fighter1.getInventory().setChestplate(new ItemStack(Material.getMaterial(Integer.parseInt(separated[0])), Integer.parseInt(separated[1]))); - fighter2.getInventory().setChestplate(new ItemStack(Material.getMaterial(Integer.parseInt(separated[0])), Integer.parseInt(separated[1]))); + if(!config.getString("Items.Last fight.Armor.Chestplate.Material").equalsIgnoreCase("air")) { + + if(config.getInt("Items.Last fight.Armor.Chestplate.Data") != 0) { + fighter1.getInventory().setChestplate(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Last fight.Armor.Chestplate.Material")).get().parseMaterial()), 1, (byte) config.getInt("Items.Last fight.Armor.Chestplate.Data"))); + fighter2.getInventory().setChestplate(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Last fight.Armor.Chestplate.Material")).get().parseMaterial()), 1, (byte) config.getInt("Items.Last fight.Armor.Chestplate.Data"))); + }else { + fighter1.getInventory().setChestplate(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Last fight.Armor.Chestplate.Material")).get().parseMaterial()), 1)); + fighter2.getInventory().setChestplate(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Last fight.Armor.Chestplate.Material")).get().parseMaterial()), 1)); + } + } - if(config.getString("Itens.Last fight.Armor.Legging") != null) { - String[] separated = config.getString("Itens.Last fight.Armor.Legging").split("-"); - fighter1.getInventory().setLeggings(new ItemStack(Material.getMaterial(Integer.parseInt(separated[0])), Integer.parseInt(separated[1]))); - fighter2.getInventory().setLeggings(new ItemStack(Material.getMaterial(Integer.parseInt(separated[0])), Integer.parseInt(separated[1]))); + if(!config.getString("Items.Last fight.Armor.Legging.Material").equalsIgnoreCase("air")) { + + if(config.getInt("Items.Last fight.Armor.Legging.Data") != 0) { + fighter1.getInventory().setLeggings(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Last fight.Armor.Legging.Material")).get().parseMaterial()), 1, (byte) config.getInt("Items.Last fight.Armor.Legging.Data"))); + fighter2.getInventory().setLeggings(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Last fight.Armor.Legging.Material")).get().parseMaterial()), 1, (byte) config.getInt("Items.Last fight.Armor.Legging.Data"))); + }else { + fighter1.getInventory().setLeggings(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Last fight.Armor.Legging.Material")).get().parseMaterial()), 1)); + fighter2.getInventory().setLeggings(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Last fight.Armor.Legging.Material")).get().parseMaterial()), 1)); + } + } - if(config.getString("Itens.Last fight.Armor.Boots") != null) { - String[] separated = config.getString("Itens.Last fight.Armor.Boots").split("-"); - fighter1.getInventory().setBoots(new ItemStack(Material.getMaterial(Integer.parseInt(separated[0])), Integer.parseInt(separated[1]))); - fighter2.getInventory().setBoots(new ItemStack(Material.getMaterial(Integer.parseInt(separated[0])), Integer.parseInt(separated[1]))); + if(!config.getString("Items.Last fight.Armor.Boots.Material").equalsIgnoreCase("air")) { + + if(config.getInt("Items.Last fight.Armor.Boots.Data") != 0) { + fighter1.getInventory().setBoots(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Last fight.Armor.Boots.Material")).get().parseMaterial()), 1, (byte) config.getInt("Items.Last fight.Armor.Boots.Data"))); + fighter2.getInventory().setBoots(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Last fight.Armor.Boots.Material")).get().parseMaterial()), 1, (byte) config.getInt("Items.Last fight.Armor.Boots.Data"))); + }else { + fighter1.getInventory().setBoots(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Last fight.Armor.Boots.Material")).get().parseMaterial()), 1)); + fighter2.getInventory().setBoots(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Last fight.Armor.Boots.Material")).get().parseMaterial()), 1)); + } + } }else { - // Se não for, então de os itens comuns. + // Se não for, então de os Items comuns. for(String s: config.getStringList("Items.Normal.Inventory")) { + String[] separated = s.split("-"); - fighter1.getInventory().addItem(new ItemStack(Material.getMaterial(Integer.parseInt(separated[0])), Integer.parseInt(separated[1]))); - fighter2.getInventory().addItem(new ItemStack(Material.getMaterial(Integer.parseInt(separated[0])), Integer.parseInt(separated[1]))); + ItemStack is; + if(separated.length == 3) { + is = new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(separated[0]).get().parseMaterial()), Integer.parseInt(separated[2]), (byte) Integer.parseInt(separated[1])); + }else { + is = new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(separated[0]).get().parseMaterial()), Integer.parseInt(separated[1])); + } + + fighter1.getInventory().addItem(is); + fighter2.getInventory().addItem(is); } - if(config.getString("Itens.Normal.Armor.Helmet") != null) { - String[] separated = config.getString("Itens.Normal.Armor.Helmet").split("-"); - fighter1.getInventory().setHelmet(new ItemStack(Material.getMaterial(Integer.parseInt(separated[0])), Integer.parseInt(separated[1]))); - fighter2.getInventory().setHelmet(new ItemStack(Material.getMaterial(Integer.parseInt(separated[0])), Integer.parseInt(separated[1]))); + if(!config.getString("Items.Normal.Armor.Helmet.Material").equalsIgnoreCase("air")) { + + if(config.getInt("Items.Normal.Armor.Helmet.Data") != 0) { + fighter1.getInventory().setHelmet(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Normal.Armor.Helmet.Material")).get().parseMaterial()), 1, (byte) config.getInt("Items.Normal.Armor.Helmet.Data"))); + fighter2.getInventory().setHelmet(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Normal.Armor.Helmet.Material")).get().parseMaterial()), 1, (byte) config.getInt("Items.Normal.Armor.Helmet.Data"))); + }else { + fighter1.getInventory().setHelmet(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Normal.Armor.Helmet.Material")).get().parseMaterial()), 1)); + fighter2.getInventory().setHelmet(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Normal.Armor.Helmet.Material")).get().parseMaterial()), 1)); + } + } - if(config.getString("Itens.Normal.Armor.Chestplate") != null) { - String[] separated = config.getString("Itens.Normal.Armor.Chestplate").split("-"); - fighter1.getInventory().setChestplate(new ItemStack(Material.getMaterial(Integer.parseInt(separated[0])), Integer.parseInt(separated[1]))); - fighter2.getInventory().setChestplate(new ItemStack(Material.getMaterial(Integer.parseInt(separated[0])), Integer.parseInt(separated[1]))); + if(!config.getString("Items.Normal.Armor.Chestplate.Material").equalsIgnoreCase("air")) { + + if(config.getInt("Items.Normal.Armor.Chestplate.Data") != 0) { + fighter1.getInventory().setChestplate(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Normal.Armor.Chestplate.Material")).get().parseMaterial()), 1, (byte) config.getInt("Items.Normal.Armor.Chestplate.Data"))); + fighter2.getInventory().setChestplate(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Normal.Armor.Chestplate.Material")).get().parseMaterial()), 1, (byte) config.getInt("Items.Normal.Armor.Chestplate.Data"))); + }else { + fighter1.getInventory().setChestplate(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Normal.Armor.Chestplate.Material")).get().parseMaterial()), 1)); + fighter2.getInventory().setChestplate(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Normal.Armor.Chestplate.Material")).get().parseMaterial()), 1)); + } + } - if(config.getString("Itens.Normal.Armor.Legging") != null) { - String[] separated = config.getString("Itens.Normal.Armor.Legging").split("-"); - fighter1.getInventory().setLeggings(new ItemStack(Material.getMaterial(Integer.parseInt(separated[0])), Integer.parseInt(separated[1]))); - fighter2.getInventory().setLeggings(new ItemStack(Material.getMaterial(Integer.parseInt(separated[0])), Integer.parseInt(separated[1]))); + if(!config.getString("Items.Normal.Armor.Legging.Material").equalsIgnoreCase("air")) { + + if(config.getInt("Items.Normal.Armor.Legging.Data") != 0) { + fighter1.getInventory().setLeggings(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Normal.Armor.Legging.Material")).get().parseMaterial()), 1, (byte) config.getInt("Items.Normal.Armor.Legging.Data"))); + fighter2.getInventory().setLeggings(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Normal.Armor.Legging.Material")).get().parseMaterial()), 1, (byte) config.getInt("Items.Normal.Armor.Legging.Data"))); + }else { + fighter1.getInventory().setLeggings(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Normal.Armor.Legging.Material")).get().parseMaterial()), 1)); + fighter2.getInventory().setLeggings(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Normal.Armor.Legging.Material")).get().parseMaterial()), 1)); + } + } - if(config.getString("Itens.Normal.Armor.Boots") != null) { - String[] separated = config.getString("Itens.Normal.Armor.Boots").split("-"); - fighter1.getInventory().setBoots(new ItemStack(Material.getMaterial(Integer.parseInt(separated[0])), Integer.parseInt(separated[1]))); - fighter2.getInventory().setBoots(new ItemStack(Material.getMaterial(Integer.parseInt(separated[0])), Integer.parseInt(separated[1]))); + if(!config.getString("Items.Normal.Armor.Boots.Material").equalsIgnoreCase("air")) { + + if(config.getInt("Items.Normal.Armor.Boots.Data") != 0) { + fighter1.getInventory().setBoots(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Normal.Armor.Boots.Material")).get().parseMaterial()), 1, (byte) config.getInt("Items.Normal.Armor.Boots.Data"))); + fighter2.getInventory().setBoots(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Normal.Armor.Boots.Material")).get().parseMaterial()), 1, (byte) config.getInt("Items.Normal.Armor.Boots.Data"))); + }else { + fighter1.getInventory().setBoots(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Normal.Armor.Boots.Material")).get().parseMaterial()), 1)); + fighter2.getInventory().setBoots(new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(config.getString("Items.Normal.Armor.Boots.Material")).get().parseMaterial()), 1)); + } + } } @@ -312,7 +381,7 @@ private void fight() { if(!getPlayers().contains(current_fighter1) || !getPlayers().contains(current_fighter2)) return; if(fighter1 != current_fighter1 || fighter2 != current_fighter2) return; - setFightLoser(null); + setFightLoser(null, false); }, max_time * 20L); @@ -320,7 +389,7 @@ private void fight() { } - public void setFightLoser(Player p) { + public void setFightLoser(Player p, boolean leave) { // Se o player for null, significa que foi um empate. if(p == null) { @@ -413,10 +482,12 @@ public void setFightLoser(Player p) { } // Elimine o perdedor do evento. - p.sendMessage(aEventos.getInstance().getConfig().getString("Messages.Eliminated").replace("&", "§")); - remove(p); - PlayerLoseEvent lose = new PlayerLoseEvent(p, config.getString("filename").substring(0, config.getString("filename").length() - 4), getType()); - Bukkit.getPluginManager().callEvent(lose); + if(!leave) { + p.sendMessage(aEventos.getInstance().getConfig().getString("Messages.Eliminated").replace("&", "§")); + remove(p); + PlayerLoseEvent lose = new PlayerLoseEvent(p, config.getString("filename").substring(0, config.getString("filename").length() - 4), getType()); + Bukkit.getPluginManager().callEvent(lose); + } } diff --git a/src/main/java/com/ars3ne/eventos/eventos/Frog.java b/src/main/java/com/ars3ne/eventos/eventos/Frog.java index 3e67b45..f3a15a1 100644 --- a/src/main/java/com/ars3ne/eventos/eventos/Frog.java +++ b/src/main/java/com/ars3ne/eventos/eventos/Frog.java @@ -31,6 +31,7 @@ import com.ars3ne.eventos.api.Evento; import com.ars3ne.eventos.listeners.eventos.FrogListener; import com.ars3ne.eventos.utils.Cuboid; +import com.ars3ne.eventos.utils.XMaterial; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; @@ -91,7 +92,7 @@ public void start() { if(block.getType() != Material.AIR && block.getType() != Material.SNOW_BLOCK - && !(block.getType() == Material.WOOL && block.getData() == (byte) 14)) { + && !(block.getType() == XMaterial.RED_WOOL.parseMaterial() && block.getData() == XMaterial.RED_WOOL.getData())) { current_blocks.put(block, block.getType()); if(!remeaning_materials.contains(block.getType())) remeaning_materials.add(block.getType()); @@ -199,8 +200,8 @@ private void frog() { // Se tiver apenas um tipo de bloco, coloque a lã vermelha em um bloco deletado aleatório. List deleted_blocks_array = new ArrayList<>(deleted_blocks.keySet()); wool_block = deleted_blocks_array.get(random.nextInt(deleted_blocks_array.size())); - wool_block.setType(Material.WOOL); - wool_block.setData((byte) 14); + wool_block.setType(XMaterial.RED_WOOL.parseMaterial()); + wool_block.setData(XMaterial.RED_WOOL.getData()); listener.setWool(); // Troque os outros blocos deletados por neve. diff --git a/src/main/java/com/ars3ne/eventos/eventos/Hunter.java b/src/main/java/com/ars3ne/eventos/eventos/Hunter.java new file mode 100644 index 0000000..b99db5c --- /dev/null +++ b/src/main/java/com/ars3ne/eventos/eventos/Hunter.java @@ -0,0 +1,531 @@ +/* + * + * This file is part of aEventos, licensed under the MIT License. + * + * Copyright (c) Ars3ne + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package com.ars3ne.eventos.eventos; + +import com.ars3ne.eventos.aEventos; +import com.ars3ne.eventos.api.Evento; +import com.ars3ne.eventos.api.events.PlayerLoseEvent; +import com.ars3ne.eventos.listeners.eventos.HunterListener; +import net.sacredlabyrinth.phaed.simpleclans.ClanPlayer; +import org.bukkit.*; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.LeatherArmorMeta; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scoreboard.Scoreboard; +import org.bukkit.scoreboard.ScoreboardManager; +import org.bukkit.scoreboard.Team; + +import java.util.*; + +@SuppressWarnings("deprecation") +public class Hunter extends Evento { + + private final YamlConfiguration config; + private final HunterListener listener = new HunterListener(); + + private final Location blue, red; + + private final HashMap blue_team = new HashMap<>(); + private final HashMap red_team = new HashMap<>(); + private final List captured_players = new ArrayList<>(); + private int blue_points = 0; + private int red_points = 0; + private final List clans = new ArrayList<>(); + + private final int enable_pvp; + private final int kill_points; + private final int max_points; + private final int capture_time; + + private final String blue_name; + private final String red_name; + private boolean pvp_enabled; + + Scoreboard board = Bukkit.getScoreboardManager().getMainScoreboard(); + Team scoreboard_team_blue = board.registerNewTeam("blue_hunter"); + Team scoreboard_team_red = board.registerNewTeam("red_hunter"); + Team scoreboard_team_captured = board.registerNewTeam("captured_hunter"); + + public Hunter(YamlConfiguration config) { + super(config); + this.config = config; + this.blue_name = config.getString("Evento.Blue"); + this.red_name = config.getString("Evento.Red"); + this.enable_pvp = config.getInt("Evento.Enable PvP"); + this.kill_points = config.getInt("Evento.Points"); + this.max_points = config.getInt("Evento.Max points"); + this.capture_time = config.getInt("Evento.Capture time"); + this.pvp_enabled = false; + + World world = aEventos.getInstance().getServer().getWorld(config.getString("Locations.Pos1.world")); + this.blue = new Location(world, config.getDouble("Locations.Pos1.x"), config.getDouble("Locations.Pos1.y"), config.getDouble("Locations.Pos1.z")); + this.red = new Location(world, config.getDouble("Locations.Pos2.x"), config.getDouble("Locations.Pos2.y"), config.getDouble("Locations.Pos2.z")); + + scoreboard_team_blue.setPrefix(ChatColor.BLUE.toString()); + scoreboard_team_red.setPrefix(ChatColor.RED.toString()); + scoreboard_team_captured.setPrefix(ChatColor.BLACK.toString()); + + } + + @Override + public void start() { + + // Registre o listener do evento + aEventos.getInstance().getServer().getPluginManager().registerEvents(listener, aEventos.getInstance()); + listener.setEvento(); + + // Adicione os jogadores á times aleatórios. + Collections.shuffle(getPlayers()); + for(int i = 0; i < getPlayers().size(); i++) { + Player p = getPlayers().get(i); + if(i % 2 == 0) blue_team.put(p, 0); + else red_team.put(p, 0); + } + + List team_st = config.getStringList("Messages.Team"); + + ItemStack bow = new ItemStack(Material.BOW, 1); + ItemMeta meta = bow.getItemMeta(); + meta.addEnchant(Enchantment.ARROW_INFINITE, 1, true); + bow.setItemMeta(meta); + + // De itens aos jogadores. + for(Player p: getPlayers()) { + + if(blue_team.containsKey(p)) { + for(String s: team_st) { + p.sendMessage(s.replace("&", "§").replace("@name", config.getString("Evento.Title")).replace("@team", "§9" + blue_name).replace("@time", String.valueOf(enable_pvp))); + } + ItemStack helmet = new ItemStack(Material.LEATHER_HELMET, 1); + LeatherArmorMeta bl = (LeatherArmorMeta) helmet.getItemMeta(); + bl.setColor(Color.BLUE); + helmet.setItemMeta(bl); + ItemStack chestplate = new ItemStack(Material.LEATHER_CHESTPLATE, 1); + LeatherArmorMeta ch = (LeatherArmorMeta) chestplate.getItemMeta(); + ch.setColor(Color.BLUE); + chestplate.setItemMeta(ch); + ItemStack leggings = new ItemStack(Material.LEATHER_LEGGINGS, 1); + LeatherArmorMeta lg = (LeatherArmorMeta) leggings.getItemMeta(); + lg.setColor(Color.BLUE); + leggings.setItemMeta(ch); + ItemStack boots = new ItemStack(Material.LEATHER_BOOTS, 1); + LeatherArmorMeta bo = (LeatherArmorMeta) boots.getItemMeta(); + bo.setColor(Color.BLUE); + boots.setItemMeta(ch); + p.getInventory().setHelmet(helmet); + p.getInventory().setChestplate(chestplate); + p.getInventory().setLeggings(leggings); + p.getInventory().setBoots(boots); + + scoreboard_team_blue.addPlayer(p); + p.teleport(blue); + + } + + if(red_team.containsKey(p)) { + for(String s: team_st) { + p.sendMessage(s.replace("&", "§").replace("@name", config.getString("Evento.Title")).replace("@team", "§c" + red_name).replace("@time", String.valueOf(enable_pvp))); + } + ItemStack helmet = new ItemStack(Material.LEATHER_HELMET, 1); + LeatherArmorMeta bl = (LeatherArmorMeta) helmet.getItemMeta(); + bl.setColor(Color.RED); + helmet.setItemMeta(bl); + ItemStack chestplate = new ItemStack(Material.LEATHER_CHESTPLATE, 1); + LeatherArmorMeta ch = (LeatherArmorMeta) chestplate.getItemMeta(); + ch.setColor(Color.RED); + chestplate.setItemMeta(ch); + ItemStack leggings = new ItemStack(Material.LEATHER_LEGGINGS, 1); + LeatherArmorMeta lg = (LeatherArmorMeta) leggings.getItemMeta(); + lg.setColor(Color.RED); + leggings.setItemMeta(ch); + ItemStack boots = new ItemStack(Material.LEATHER_BOOTS, 1); + LeatherArmorMeta bo = (LeatherArmorMeta) boots.getItemMeta(); + bo.setColor(Color.RED); + boots.setItemMeta(ch); + p.getInventory().setHelmet(helmet); + p.getInventory().setChestplate(chestplate); + p.getInventory().setLeggings(leggings); + p.getInventory().setBoots(boots); + + scoreboard_team_red.addPlayer(p); + + p.teleport(red); + } + + p.getInventory().addItem(bow); + p.getInventory().addItem(new ItemStack(Material.ARROW, 1)); + + } + + // Se o servidor tiver SimpleClans, então ative o friendly fire. + if(aEventos.getInstance().getSimpleClans() != null) { + for(Player p: getPlayers()) { + if(aEventos.getInstance().getSimpleClans().getClanManager().getClanPlayer(p) != null) { + clans.add(aEventos.getInstance().getSimpleClans().getClanManager().getClanPlayer(p)); + aEventos.getInstance().getSimpleClans().getClanManager().getClanPlayer(p).setFriendlyFire(true); + } + } + } + + // Depois do tempo especificado na config, ative o PvP. + aEventos.getInstance().getServer().getScheduler().scheduleSyncDelayedTask(aEventos.getInstance(), () -> { + if(!isHappening()) return; + this.pvp_enabled = true; + // Mande a mensagem de que o PvP está ativado. + List enabled_st = config.getStringList("Messages.Enabled"); + for (Player player : getPlayers()) { + for(String s : enabled_st) { + player.sendMessage(s.replace("&", "§").replace("@name", config.getString("Evento.Title"))); + } + } + for (Player player : getSpectators()) { + for(String s : enabled_st) { + player.sendMessage(s.replace("&", "§").replace("@name", config.getString("Evento.Title"))); + } + } + }, enable_pvp * 20L); + + } + + public void win(String team) { + + List winners = new ArrayList<>(); + + // Adicionar vitória e dar a tag no LegendChat. + this.setWinners(); + + // Encerre o evento. + this.stop(); + + if(team.equals("blue")) { + + for (Player player : getPlayers()) { + player.sendMessage(aEventos.getInstance().getConfig().getString("Messages.Win").replace("&", "§").replace("@team", this.blue_name).replace("@points", String.valueOf(blue_points))); + } + for (Player player : getSpectators()) { + player.sendMessage(aEventos.getInstance().getConfig().getString("Messages.Win").replace("&", "§").replace("@team", this.blue_name).replace("@points", String.valueOf(blue_points))); + } + + // Obtenha todos os jogadores restantes e os entregue as recompensas. + for(Player p: blue_team.keySet()) { + List commands = this.config.getStringList("Rewards.Commands"); + for(String s : commands) { + aEventos.getInstance().getServer().dispatchCommand(aEventos.getInstance().getServer().getConsoleSender(), s.replace("@winner", p.getName())); + } + + // Adicione o nome á lista de vencedores. + winners.add(p.getName()); + } + + }else { + + for (Player player : getPlayers()) { + player.sendMessage(aEventos.getInstance().getConfig().getString("Messages.Win").replace("&", "§").replace("@team", this.red_name).replace("@points", String.valueOf(red_points))); + } + for (Player player : getSpectators()) { + player.sendMessage(aEventos.getInstance().getConfig().getString("Messages.Win").replace("&", "§").replace("@team", this.red_name).replace("@points", String.valueOf(red_points))); + } + + // Obtenha todos os jogadores restantes e os entregue as recompensas. + for(Player p: red_team.keySet()) { + List commands = this.config.getStringList("Rewards.Commands"); + for(String s : commands) { + aEventos.getInstance().getServer().dispatchCommand(aEventos.getInstance().getServer().getConsoleSender(), s.replace("@winner", p.getName())); + } + + // Adicione o nome á lista de vencedores. + winners.add(p.getName()); + } + + } + + // Mande a mensagem de vitória para o servidor. + List broadcast_messages = this.config.getStringList("Messages.Winner"); + for(String s : broadcast_messages) { + aEventos.getInstance().getServer().broadcastMessage(s.replace("&", "§").replace("@winner", String.join(", ", winners)).replace("@name", config.getString("Evento.Title"))); + } + + + } + + @Override + public void leave(Player p) { + + if(getPlayers().contains(p)) { + for (Player player : getPlayers()) { + player.sendMessage(aEventos.getInstance().getConfig().getString("Messages.Leave").replace("&", "§").replace("@player", p.getName())); + } + for (Player player : getSpectators()) { + player.sendMessage(aEventos.getInstance().getConfig().getString("Messages.Leave").replace("&", "§").replace("@player", p.getName())); + } + } + + // Desative o friendly-fire do jogador. + if(aEventos.getInstance().getSimpleClans() != null) { + if(clans.contains(aEventos.getInstance().getSimpleClans().getClanManager().getClanPlayer(p))) { + clans.remove(aEventos.getInstance().getSimpleClans().getClanManager().getClanPlayer(p)); + aEventos.getInstance().getSimpleClans().getClanManager().getClanPlayer(p).setFriendlyFire(false); + } + } + + if(blue_team.size() == 0) win("red"); + if(red_team.size() == 0) win("blue"); + + p.getInventory().setHelmet(null); + p.getInventory().setChestplate(null); + p.getInventory().setLeggings(null); + p.getInventory().setBoots(null); + + scoreboard_team_blue.removePlayer(p); + scoreboard_team_red.removePlayer(p); + scoreboard_team_captured.removePlayer(p); + + PlayerLoseEvent lose = new PlayerLoseEvent(p, config.getString("filename").substring(0, config.getString("filename").length() - 4), getType()); + Bukkit.getPluginManager().callEvent(lose); + this.remove(p); + } + + @Override + public void stop() { + + // Remova a armadura dos jogadores. + for(Player p: getPlayers()) { + p.getInventory().setHelmet(null); + p.getInventory().setChestplate(null); + p.getInventory().setLeggings(null); + p.getInventory().setBoots(null); + p.removePotionEffect(PotionEffectType.BLINDNESS); + p.removePotionEffect(PotionEffectType.SLOW); + scoreboard_team_blue.removePlayer(p); + scoreboard_team_red.removePlayer(p); + scoreboard_team_captured.removePlayer(p); + } + + // Remova os times. + scoreboard_team_blue.unregister(); + scoreboard_team_red.unregister(); + scoreboard_team_captured.unregister(); + + // Desative o friendly-fire dos jogadores. + Iterator iter = clans.iterator(); + while(iter.hasNext()) { + ClanPlayer p = iter.next(); + p.setFriendlyFire(false); + clans.remove(p); + } + + // Remova o listener do evento e chame a função cancel. + HandlerList.unregisterAll(listener); + this.removePlayers(); + } + + public void eliminate(Player captured, Player shooter) { + + // Mude a armadura do capturado e o paralize. + captured_players.add(captured); + captured.addPotionEffect((new PotionEffect(PotionEffectType.SLOW, 500000, 500))); + captured.addPotionEffect((new PotionEffect(PotionEffectType.BLINDNESS, 500000, 500))); + + ItemStack helmet = new ItemStack(Material.JACK_O_LANTERN, 1); + ItemStack chestplate = new ItemStack(Material.LEATHER_CHESTPLATE, 1); + LeatherArmorMeta ch = (LeatherArmorMeta) chestplate.getItemMeta(); + ch.setColor(Color.BLACK); + chestplate.setItemMeta(ch); + ItemStack leggings = new ItemStack(Material.LEATHER_LEGGINGS, 1); + LeatherArmorMeta lg = (LeatherArmorMeta) leggings.getItemMeta(); + lg.setColor(Color.BLACK); + leggings.setItemMeta(ch); + ItemStack boots = new ItemStack(Material.LEATHER_BOOTS, 1); + LeatherArmorMeta bo = (LeatherArmorMeta) boots.getItemMeta(); + bo.setColor(Color.BLACK); + boots.setItemMeta(ch); + captured.getInventory().setHelmet(helmet); + captured.getInventory().setChestplate(chestplate); + captured.getInventory().setLeggings(leggings); + captured.getInventory().setBoots(boots); + + scoreboard_team_blue.removePlayer(captured); + scoreboard_team_red.removePlayer(captured); + scoreboard_team_captured.addPlayer(captured); + + // Adicione um ponto para o shooter. + if(blue_team.containsKey(shooter)) { + blue_team.put(shooter, blue_team.get(shooter) + this.kill_points); + blue_points += this.kill_points; + } + + if(red_team.containsKey(shooter)) { + red_team.put(shooter, red_team.get(shooter) + this.kill_points); + red_points += this.kill_points; + } + + // Mande a mensagem no chat. + + List eliminated_st = config.getStringList("Messages.Eliminated"); + List capturated_st = config.getStringList("Messages.Capturated"); + + if(blue_team.containsKey(captured)) { + for (Player player : getPlayers()) { + for(String s: eliminated_st) { + player.sendMessage(s.replace("&", "§").replace("@name", config.getString("Evento.Title")).replace("@player", "§9" + captured.getName()).replace("@blueteam", "§9" + blue_points).replace("@redteam", "§c" + red_points).replace("@time", remeaningTime())); + } + } + for (Player player : getSpectators()) { + for(String s: eliminated_st) { + player.sendMessage(s.replace("&", "§").replace("@name", config.getString("Evento.Title")).replace("@player", "§9" + captured.getName()).replace("@blueteam", "§9" + blue_points).replace("@redteam", "§c" + red_points).replace("@time", remeaningTime())); + } + } + } + + if(red_team.containsKey(captured)) { + for (Player player : getPlayers()) { + for(String s: eliminated_st) { + player.sendMessage(s.replace("&", "§").replace("@name", config.getString("Evento.Title")).replace("@player", "§c" + captured.getName()).replace("@blueteam", "§9" + blue_points).replace("@redteam", "§c" + red_points).replace("@time", remeaningTime())); + } + } + for (Player player : getSpectators()) { + for(String s: eliminated_st) { + player.sendMessage(s.replace("&", "§").replace("@name", config.getString("Evento.Title")).replace("@player", "§c" + captured.getName()).replace("@blueteam", "§9" + blue_points).replace("@redteam", "§c" + red_points).replace("@time", remeaningTime())); + } + } + } + + for(String s: capturated_st) { + captured.sendMessage(s.replace("&", "§").replace("@name", config.getString("Evento.Title")).replace("@blueteam", "§9" + blue_points).replace("@redteam", "§c" + red_points).replace("@time", String.valueOf(this.capture_time))); + } + + // Verifique se algum time obteve os pontos necessários para a vitória. + if(this.max_points != 0) { + if(blue_points >= this.max_points) { + win("blue"); + } + + if(red_points >= this.max_points) { + win("red"); + } + } + + // Depois de alguns segundos, teleporte o capturado para o inicio. + aEventos.getInstance().getServer().getScheduler().scheduleSyncDelayedTask(aEventos.getInstance(), () -> { + + if(!isHappening()) return; + + captured_players.remove(captured); + scoreboard_team_captured.removePlayer(captured); + + if(blue_team.containsKey(captured)) { + ItemStack helmet2 = new ItemStack(Material.LEATHER_HELMET, 1); + LeatherArmorMeta bl = (LeatherArmorMeta) helmet2.getItemMeta(); + bl.setColor(Color.BLUE); + helmet2.setItemMeta(bl); + ItemStack chestplate2 = new ItemStack(Material.LEATHER_CHESTPLATE, 1); + LeatherArmorMeta ch2 = (LeatherArmorMeta) chestplate2.getItemMeta(); + ch2.setColor(Color.BLUE); + chestplate2.setItemMeta(ch2); + ItemStack leggings2 = new ItemStack(Material.LEATHER_LEGGINGS, 1); + LeatherArmorMeta lg2 = (LeatherArmorMeta) leggings2.getItemMeta(); + lg2.setColor(Color.BLUE); + leggings2.setItemMeta(ch2); + ItemStack boots2 = new ItemStack(Material.LEATHER_BOOTS, 1); + LeatherArmorMeta bo2 = (LeatherArmorMeta) boots2.getItemMeta(); + bo2.setColor(Color.BLUE); + boots.setItemMeta(ch2); + captured.getInventory().setHelmet(helmet2); + captured.getInventory().setChestplate(chestplate2); + captured.getInventory().setLeggings(leggings2); + captured.getInventory().setBoots(boots2); + + captured.removePotionEffect(PotionEffectType.BLINDNESS); + captured.removePotionEffect(PotionEffectType.SLOW); + + scoreboard_team_blue.addPlayer(captured); + captured.teleport(blue); + + } + + if(red_team.containsKey(captured)) { + ItemStack helmet2 = new ItemStack(Material.LEATHER_HELMET, 1); + LeatherArmorMeta bl = (LeatherArmorMeta) helmet2.getItemMeta(); + bl.setColor(Color.RED); + helmet2.setItemMeta(bl); + ItemStack chestplate2 = new ItemStack(Material.LEATHER_CHESTPLATE, 1); + LeatherArmorMeta ch2 = (LeatherArmorMeta) chestplate2.getItemMeta(); + ch2.setColor(Color.RED); + chestplate2.setItemMeta(ch2); + ItemStack leggings2 = new ItemStack(Material.LEATHER_LEGGINGS, 1); + LeatherArmorMeta lg2 = (LeatherArmorMeta) leggings2.getItemMeta(); + lg2.setColor(Color.RED); + leggings2.setItemMeta(ch2); + ItemStack boots2 = new ItemStack(Material.LEATHER_BOOTS, 1); + LeatherArmorMeta bo2 = (LeatherArmorMeta) boots2.getItemMeta(); + bo2.setColor(Color.RED); + boots.setItemMeta(ch2); + captured.getInventory().setHelmet(helmet2); + captured.getInventory().setChestplate(chestplate2); + captured.getInventory().setLeggings(leggings2); + captured.getInventory().setBoots(boots2); + + captured.removePotionEffect(PotionEffectType.BLINDNESS); + captured.removePotionEffect(PotionEffectType.SLOW); + + scoreboard_team_red.addPlayer(captured); + captured.teleport(red); + } + + + + }, capture_time * 20L); + + + } + public HashMap getBlueTeam() { + return this.blue_team; + } + public int getBluePoints() { return this.blue_points; } + + public HashMap getRedTeam() { + return this.red_team; + } + + public int getRedPoints() { return this.red_points; } + + public List getCaptured() { return this.captured_players; } + + public boolean isPvPEnabled() { return this.pvp_enabled; } + + public String remeaningTime() { + return "COLOCAR TEMPO DEPOIS"; + } + +} diff --git a/src/main/java/com/ars3ne/eventos/eventos/Paintball.java b/src/main/java/com/ars3ne/eventos/eventos/Paintball.java index 8a7ef02..72c441a 100644 --- a/src/main/java/com/ars3ne/eventos/eventos/Paintball.java +++ b/src/main/java/com/ars3ne/eventos/eventos/Paintball.java @@ -40,12 +40,15 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.LeatherArmorMeta; +import org.bukkit.scoreboard.Scoreboard; +import org.bukkit.scoreboard.Team; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; +@SuppressWarnings("deprecation") public class Paintball extends Evento { private final YamlConfiguration config; @@ -62,6 +65,10 @@ public class Paintball extends Evento { private final String red_name; private boolean pvp_enabled; + Scoreboard board = Bukkit.getScoreboardManager().getMainScoreboard(); + Team scoreboard_team_blue = board.registerNewTeam("blue_paintball"); + Team scoreboard_team_red = board.registerNewTeam("red_paintball"); + public Paintball(YamlConfiguration config) { super(config); this.config = config; @@ -74,6 +81,9 @@ public Paintball(YamlConfiguration config) { this.blue = new Location(world, config.getDouble("Locations.Pos1.x"), config.getDouble("Locations.Pos1.y"), config.getDouble("Locations.Pos1.z")); this.red = new Location(world, config.getDouble("Locations.Pos2.x"), config.getDouble("Locations.Pos2.y"), config.getDouble("Locations.Pos2.z")); + scoreboard_team_blue.setPrefix(ChatColor.BLUE.toString()); + scoreboard_team_red.setPrefix(ChatColor.RED.toString()); + } @Override @@ -126,6 +136,7 @@ public void start() { p.getInventory().setLeggings(leggings); p.getInventory().setBoots(boots); + scoreboard_team_blue.addPlayer(p); p.teleport(blue); } @@ -154,6 +165,7 @@ public void start() { p.getInventory().setLeggings(leggings); p.getInventory().setBoots(boots); + scoreboard_team_red.addPlayer(p); p.teleport(red); } @@ -255,8 +267,14 @@ public void stop() { p.getInventory().setChestplate(null); p.getInventory().setLeggings(null); p.getInventory().setBoots(null); + scoreboard_team_blue.removePlayer(p); + scoreboard_team_red.removePlayer(p); } + // Remova os times. + scoreboard_team_blue.unregister(); + scoreboard_team_red.unregister(); + // Desative o friendly-fire dos jogadores. Iterator iter = clans.iterator(); while(iter.hasNext()) { @@ -275,7 +293,10 @@ public void eliminate(Player p) { List eliminated_st = config.getStringList("Messages.Eliminated"); if(blue_team.contains(p)) { + blue_team.remove(p); + scoreboard_team_blue.removePlayer(p); + for (Player player : getPlayers()) { for(String s: eliminated_st) { player.sendMessage(s.replace("&", "§").replace("@name", config.getString("Evento.Title")).replace("@player", "§9" + p.getName()).replace("@remeaning", "§9" + blue_team.size()).replace("@team", "§9" + blue_name)); @@ -284,11 +305,15 @@ public void eliminate(Player p) { for (Player player : getSpectators()) { for(String s: eliminated_st) { player.sendMessage(s.replace("&", "§").replace("@name", config.getString("Evento.Title")).replace("@player", "§9" + p.getName()).replace("@remeaning", "§9" + blue_team.size()).replace("@team", "§9" + blue_name)); - } } + } + } } if(red_team.contains(p)) { + red_team.remove(p); + scoreboard_team_red.removePlayer(p); + for (Player player : getPlayers()) { for(String s: eliminated_st) { player.sendMessage(s.replace("&", "§").replace("@name", config.getString("Evento.Title")).replace("@player", "§c" + p.getName()).replace("@remeaning", "§c" + red_team.size()).replace("@team", "§c" + red_name)); diff --git a/src/main/java/com/ars3ne/eventos/eventos/Quiz.java b/src/main/java/com/ars3ne/eventos/eventos/Quiz.java new file mode 100644 index 0000000..6335c24 --- /dev/null +++ b/src/main/java/com/ars3ne/eventos/eventos/Quiz.java @@ -0,0 +1,287 @@ +/* + * + * This file is part of aEventos, licensed under the MIT License. + * + * Copyright (c) Ars3ne + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package com.ars3ne.eventos.eventos; + +import com.ars3ne.eventos.aEventos; +import com.ars3ne.eventos.api.Evento; +import com.ars3ne.eventos.api.events.PlayerLoseEvent; +import com.ars3ne.eventos.listeners.eventos.QuizListener; +import com.ars3ne.eventos.utils.Cuboid; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.scheduler.BukkitScheduler; +import org.bukkit.scheduler.BukkitTask; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Random; + +public class Quiz extends Evento { + + private final YamlConfiguration config; + private final QuizListener listener = new QuizListener(); + + private final HashMap questions = new HashMap<>(); + private final int time, delay, max_questions; + + private final Cuboid true_cuboid, false_cuboid; + + private BukkitTask runnable; + private final BukkitScheduler scheduler = aEventos.getInstance().getServer().getScheduler(); + + private boolean question_happening; + private int total_questions; + + public Quiz(YamlConfiguration config) { + + super(config); + this.config = config; + + time = this.config.getInt("Evento.Time"); + delay = this.config.getInt("Evento.Interval"); + max_questions = this.config.getInt("Evento.Max questions"); + + // Obtenha os cuboids. + World world = aEventos.getInstance().getServer().getWorld(this.config.getString("Locations.Pos1.world")); + Location pos1 = new Location(world, this.config.getDouble("Locations.Pos1.x"), this.config.getDouble("Locations.Pos1.y"), this.config.getDouble("Locations.Pos1.z")); + Location pos2 = new Location(world, this.config.getDouble("Locations.Pos2.x"), this.config.getDouble("Locations.Pos2.y"), this.config.getDouble("Locations.Pos2.z")); + true_cuboid = new Cuboid(pos1, pos2); + + Location pos3 = new Location(world, this.config.getDouble("Locations.Pos3.x"), this.config.getDouble("Locations.Pos3.y"), this.config.getDouble("Locations.Pos3.z")); + Location pos4 = new Location(world, this.config.getDouble("Locations.Pos4.x"), this.config.getDouble("Locations.Pos4.y"), this.config.getDouble("Locations.Pos4.z")); + false_cuboid = new Cuboid(pos3, pos4); + + // Obtenha as questões. + for(String s: config.getStringList("Questions")) { + String[] separated = s.split("-"); + if(separated.length == 1) { + questions.put(separated[0], null); + }else { + questions.put(separated[0], separated[1]); + } + } + + } + + @Override + public void start() { + + // Registre o listener do evento + aEventos.getInstance().getServer().getPluginManager().registerEvents(listener, aEventos.getInstance()); + listener.setEvento(); + + // Inicie a primeira questão + runnable = scheduler.runTaskTimer(aEventos.getInstance(), () -> { + + if(!isHappening()) runnable.cancel(); + if(!question_happening) { + + if(total_questions < max_questions) { + question(); + }else { + win(); + runnable.cancel(); + } + + } + }, 0, 20L); + + } + + @Override + public void winner(Player p) { + + // Mande a mensagem de vitória. + List broadcast_messages = config.getStringList("Messages.Winner"); + for(String s : broadcast_messages) { + aEventos.getInstance().getServer().broadcastMessage(s.replace("&", "§").replace("@winner", p.getName()).replace("@name", getConfig().getString("Evento.Title"))); + } + + // Adicionar vitória e dar a tag no LegendChat. + this.setWinner(p); + + // Encerre o evento. + this.stop(); + + // Execute todos os comandos de vitória. + List commands = config.getStringList("Rewards.Commands"); + for(String s : commands) { + aEventos.getInstance().getServer().dispatchCommand(aEventos.getInstance().getServer().getConsoleSender(), s.replace("@winner", p.getName())); + } + + } + + public void win() { + + List winners = new ArrayList<>(); + + // Adicionar vitória e dar a tag no LegendChat. + this.setWinners(); + + // Encerre o evento. + this.stop(); + + // Obtenha todos os jogadores restantes e os entregue as recompensas. + for(Player p: getPlayers()) { + + // Execute os comandos de vitória + List commands = this.config.getStringList("Rewards.Commands"); + for(String s : commands) { + aEventos.getInstance().getServer().dispatchCommand(aEventos.getInstance().getServer().getConsoleSender(), s.replace("@winner", p.getName())); + } + + // Adicione o nome á lista de vencedores. + winners.add(p.getName()); + } + + // Mande a mensagem de vitória para o servidor. + List broadcast_messages = this.config.getStringList("Messages.Winner"); + for(String s : broadcast_messages) { + aEventos.getInstance().getServer().broadcastMessage(s.replace("&", "§").replace("@winner", String.join(", ", winners)).replace("@name", config.getString("Evento.Title"))); + } + + } + + @Override + public void stop() { + // Remova o listener do evento e chame a função cancel. + HandlerList.unregisterAll(listener); + this.removePlayers(); + } + + private void question() { + + List question_values = new ArrayList<>(questions.keySet()); + List question_broadcast = config.getStringList("Messages.Question"); + List next_question = config.getStringList("Messages.Next question"); + + if(isHappening()) { + + total_questions++; + question_happening = true; + + // Obtenha uma questão aleatória. + int current_question = new Random().nextInt(question_values.size()); + + // Mande a pergunta para todos os participantes. + for (Player player : getPlayers()) { + for(String s : question_broadcast) { + player.sendMessage(s.replace("&", "§").replace("@currentquestion", String.valueOf(total_questions)).replace("@question", question_values.get(current_question)).replace("@name", this.config.getString("Evento.Title"))); + } + } + + for (Player player : getSpectators()) { + for(String s : question_broadcast) { + player.sendMessage(s.replace("&", "§").replace("@currentquestion", String.valueOf(total_questions)).replace("@question", question_values.get(current_question)).replace("@name", this.config.getString("Evento.Title"))); + } + } + + // Depois do tempo da config, verfique a resposta. + + aEventos.getInstance().getServer().getScheduler().scheduleSyncDelayedTask(aEventos.getInstance(), () -> { + + if(isHappening() && question_happening) { + + // Elimine todos os jogadores que não estão dentro dos cuboids. + for (Player p : getPlayers()) { + if (!true_cuboid.isInWithMargeY(p, 6) && !false_cuboid.isInWithMargeY(p, 6)) { + // Remova o jogador do evento e envie a mensagem de eliminação. + p.sendMessage(aEventos.getInstance().getConfig().getString("Messages.Eliminated").replace("&", "§")); + remove(p); + PlayerLoseEvent lose = new PlayerLoseEvent(p, config.getString("filename").substring(0, config.getString("filename").length() - 4), getType()); + Bukkit.getPluginManager().callEvent(lose); + } + } + + // Obtenha a resposta e elimine os jogadores que repsonderam incorretamente. + String answer = questions.get(question_values.get(current_question)); + + if(answer != null) { + + if(answer.equalsIgnoreCase("true")) { + + // Elimine todos os jogadores no cuboid false. + for (Player p : getPlayers()) { + if (false_cuboid.isInWithMargeY(p, 6)) { + // Remova o jogador do evento e envie a mensagem de eliminação. + p.sendMessage(aEventos.getInstance().getConfig().getString("Messages.Eliminated").replace("&", "§")); + remove(p); + PlayerLoseEvent lose = new PlayerLoseEvent(p, config.getString("filename").substring(0, config.getString("filename").length() - 4), getType()); + Bukkit.getPluginManager().callEvent(lose); + } + } + + }else { + + // Elimine todos os jogadores no cuboid true. + for (Player p : getPlayers()) { + if (true_cuboid.isInWithMargeY(p, 6)) { + // Remova o jogador do evento e envie a mensagem de eliminação. + p.sendMessage(aEventos.getInstance().getConfig().getString("Messages.Eliminated").replace("&", "§")); + remove(p); + PlayerLoseEvent lose = new PlayerLoseEvent(p, config.getString("filename").substring(0, config.getString("filename").length() - 4), getType()); + Bukkit.getPluginManager().callEvent(lose); + } + } + + } + } + + // Se tiver apenas um participante, então encerre o evento. + if(getPlayers().size() == 1) { + this.win(); + } + + // Mande a mensagem de início da próxima pergunta para todos os participantes. + for (Player player : getPlayers()) { + for(String s : next_question) { + player.sendMessage(s.replace("&", "§").replace("@time", String.valueOf(delay)).replace("@name", config.getString("Evento.Title"))); + } + } + + for (Player player : getSpectators()) { + for(String s : next_question) { + player.sendMessage(s.replace("&", "§").replace("@time", String.valueOf(delay)).replace("@name", config.getString("Evento.Title"))); + } + } + + aEventos.getInstance().getServer().getScheduler().scheduleSyncDelayedTask(aEventos.getInstance(), () -> question_happening = false, delay * 20L); + + } + + }, time * 20L); + + } + } + +} diff --git a/src/main/java/com/ars3ne/eventos/eventos/Semaforo.java b/src/main/java/com/ars3ne/eventos/eventos/Semaforo.java index 96c0717..32fa075 100644 --- a/src/main/java/com/ars3ne/eventos/eventos/Semaforo.java +++ b/src/main/java/com/ars3ne/eventos/eventos/Semaforo.java @@ -30,6 +30,7 @@ import com.ars3ne.eventos.aEventos; import com.ars3ne.eventos.api.Evento; import com.ars3ne.eventos.listeners.eventos.SemaforoListener; +import com.ars3ne.eventos.utils.XMaterial; import org.bukkit.Material; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; @@ -150,8 +151,9 @@ private void semaforo() { // Se a hotbar estiver ativada, limpe o inventário e coloque os blocos. if(this.hotbar && requireEmptyInventory()) { - ItemStack item = new ItemStack(Material.STAINED_CLAY, 1, (byte) 5); + ItemStack item = XMaterial.LIME_TERRACOTTA.parseItem(); + assert item != null; ItemMeta meta = item.getItemMeta(); meta.setDisplayName(this.green_name); item.setItemMeta(meta); @@ -188,8 +190,9 @@ private void semaforo() { // Se a hotbar estiver ativada, limpe o inventário e coloque os blocos. if(this.hotbar && requireEmptyInventory()) { - ItemStack item = new ItemStack(Material.STAINED_CLAY, 1, (byte) 4); + ItemStack item = XMaterial.YELLOW_TERRACOTTA.parseItem(); + assert item != null; ItemMeta meta = item.getItemMeta(); meta.setDisplayName(this.yellow_name); item.setItemMeta(meta); @@ -229,8 +232,9 @@ private void semaforo() { // Se a hotbar estiver ativada, limpe o inventário e coloque os blocos. if(this.hotbar && requireEmptyInventory()) { - ItemStack item = new ItemStack(Material.STAINED_CLAY, 1, (byte) 14); + ItemStack item = XMaterial.RED_TERRACOTTA.parseItem(); + assert item != null; ItemMeta meta = item.getItemMeta(); meta.setDisplayName(this.red_name); item.setItemMeta(meta); diff --git a/src/main/java/com/ars3ne/eventos/eventos/Spleef.java b/src/main/java/com/ars3ne/eventos/eventos/Spleef.java index 4494563..48f5c8a 100644 --- a/src/main/java/com/ars3ne/eventos/eventos/Spleef.java +++ b/src/main/java/com/ars3ne/eventos/eventos/Spleef.java @@ -32,6 +32,7 @@ import com.ars3ne.eventos.api.events.PlayerLoseEvent; import com.ars3ne.eventos.listeners.eventos.SpleefListener; import com.ars3ne.eventos.utils.Cuboid; +import com.ars3ne.eventos.utils.XMaterial; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; @@ -46,7 +47,9 @@ import java.util.Iterator; import java.util.List; +import java.util.Objects; +@SuppressWarnings("OptionalGetWithoutIsPresent") public class Spleef extends Evento { private final YamlConfiguration config; @@ -86,7 +89,6 @@ public Spleef(YamlConfiguration config) { } - @SuppressWarnings("deprecation") @Override public void start() { @@ -97,8 +99,15 @@ public void start() { String[] separated = s.split("-"); + ItemStack is; + if(separated.length == 3) { + is = new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(separated[0]).get().parseMaterial()), Integer.parseInt(separated[2]), (byte) Integer.parseInt(separated[1])); + }else { + is = new ItemStack(Objects.requireNonNull(XMaterial.matchXMaterial(separated[0]).get().parseMaterial()), Integer.parseInt(separated[1])); + } + for(Player p: getPlayers()) { - p.getInventory().addItem(new ItemStack(Material.getMaterial(Integer.parseInt(separated[0])), Integer.parseInt(separated[1]))); + p.getInventory().addItem(is); } } diff --git a/src/main/java/com/ars3ne/eventos/eventos/chat/Bolao.java b/src/main/java/com/ars3ne/eventos/eventos/chat/Bolao.java new file mode 100644 index 0000000..719efe8 --- /dev/null +++ b/src/main/java/com/ars3ne/eventos/eventos/chat/Bolao.java @@ -0,0 +1,142 @@ +/* + * + * This file is part of aEventos, licensed under the MIT License. + * + * Copyright (c) Ars3ne + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package com.ars3ne.eventos.eventos.chat; + +import com.ars3ne.eventos.aEventos; +import com.ars3ne.eventos.api.EventoChat; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class Bolao extends EventoChat { + + private final YamlConfiguration config; + + private final List players = new ArrayList<>(); + private long reward; + private final long cost; + + public Bolao(YamlConfiguration config) { + + super(config); + + this.config = config; + this.cost = config.getInt("Evento.Cost"); + this.reward = config.getInt("Evento.Reward"); + + } + + @Override + public void start() { + + // Se ninguém apostou no bolão, então encerre o evento sem vencedores. + if(players.size() == 0) { + + List broadcast_messages = config.getStringList("Messages.No winner"); + for(String s : broadcast_messages) { + aEventos.getInstance().getServer().broadcastMessage(s.replace("&", "§").replace("@name", config.getString("Evento.Title"))); + } + + stop(); + + }else { + // Pegue um jogador aleatório e o defina como vencedor. + Random random = new Random(); + winner(players.get(random.nextInt(players.size()))); + } + + } + + @Override + public void stop() { + players.clear(); // Pareçe redundante, mas não é. + removePlayers(); + } + + @Override + public void leave(Player p) { + players.remove(p); + } + + @Override + public void winner(Player p) { + + // Mande a mensagem de vitória. + List broadcast_messages = config.getStringList("Messages.Winner"); + for(String s : broadcast_messages) { + aEventos.getInstance().getServer().broadcastMessage(s.replace("&", "§").replace("@winner", p.getName()).replace("@name", config.getString("Evento.Title")).replace("@winner", p.getName())); + } + + // Adicionar vitória e dar a tag no LegendChat. + this.setWinner(p); + + // Encerre o evento. + this.stop(); + + // Execute todos os comandos de vitória. + List commands = config.getStringList("Rewards.Commands"); + for(String s : commands) { + aEventos.getInstance().getServer().dispatchCommand(aEventos.getInstance().getServer().getConsoleSender(), s.replace("@winner", p.getName())); + } + + // Deposite o valor na conta do vencedor. + aEventos.getInstance().getEconomy().depositPlayer(p, this.reward); + + } + + @Override + public void parseMessage(String s, int calls) { + s = s.replace("&", "§").replace("@broadcasts", String.valueOf(calls)).replace("@name", config.getString("Evento.Title")).replace("@reward", aEventos.getInstance().getEconomy().format(this.reward)).replace("@cost", aEventos.getInstance().getEconomy().format(this.cost)).replace("@players", String.valueOf(players.size())); + aEventos.getInstance().getServer().broadcastMessage(s); + } + + @Override + public void parseCommand(Player p, String[] args) { + + if(players.contains(p)) { + p.sendMessage(config.getString("Messages.Already joined").replace("&", "§").replace("@name", config.getString("Evento.Title"))); + return; + } + + if(aEventos.getInstance().getEconomy().getBalance(p) < this.cost) { + p.sendMessage(config.getString("Messages.No money").replace("&", "§").replace("@name", config.getString("Evento.Title")).replace("@cost", aEventos.getInstance().getEconomy().format(this.cost))); + return; + } + + aEventos.getInstance().getEconomy().withdrawPlayer(p, this.cost); + this.reward = this.reward + this.cost; + + players.add(p); + p.sendMessage(config.getString("Messages.Joined").replace("&", "§").replace("@name", config.getString("Evento.Title"))); + + } + +} diff --git a/src/main/java/com/ars3ne/eventos/eventos/chat/Loteria.java b/src/main/java/com/ars3ne/eventos/eventos/chat/Loteria.java new file mode 100644 index 0000000..2a44d93 --- /dev/null +++ b/src/main/java/com/ars3ne/eventos/eventos/chat/Loteria.java @@ -0,0 +1,138 @@ +/* + * + * This file is part of aEventos, licensed under the MIT License. + * + * Copyright (c) Ars3ne + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package com.ars3ne.eventos.eventos.chat; + +import com.ars3ne.eventos.aEventos; +import com.ars3ne.eventos.api.EventoChat; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; + +import java.util.List; + +public class Loteria extends EventoChat { + + private final YamlConfiguration config; + + private final int number, max_number; + private final long reward, cost; + + public Loteria(YamlConfiguration config) { + + super(config); + + this.config = config; + this.cost = config.getInt("Evento.Cost"); + this.max_number = config.getInt("Evento.Max number"); + this.reward = config.getInt("Evento.Reward"); + + this.number = (int) (Math.floor(Math.random() * this.max_number ) + 1); + + } + + @Override + public void start() { + + // Pare o evento sem vencedores. + List broadcast_messages = config.getStringList("Messages.No winner"); + for(String s : broadcast_messages) { + aEventos.getInstance().getServer().broadcastMessage(s.replace("&", "§").replace("@name", config.getString("Evento.Title")).replace("@number", String.valueOf(this.number))); + } + + stop(); + + } + + @Override + public void stop() { + removePlayers(); + } + + @Override + public void winner(Player p) { + + // Mande a mensagem de vitória. + List broadcast_messages = config.getStringList("Messages.Winner"); + for(String s : broadcast_messages) { + aEventos.getInstance().getServer().broadcastMessage(s.replace("&", "§").replace("@winner", p.getName()).replace("@name", config.getString("Evento.Title")).replace("@number", String.valueOf(this.number))); + } + + // Adicionar vitória e dar a tag no LegendChat. + this.setWinner(p); + + // Encerre o evento. + this.stop(); + + // Execute todos os comandos de vitória. + List commands = config.getStringList("Rewards.Commands"); + for(String s : commands) { + aEventos.getInstance().getServer().dispatchCommand(aEventos.getInstance().getServer().getConsoleSender(), s.replace("@winner", p.getName())); + } + + // Deposite o valor na conta do vencedor. + aEventos.getInstance().getEconomy().depositPlayer(p, this.reward); + + } + + @Override + public void parseMessage(String s, int calls) { + s = s.replace("&", "§").replace("@broadcasts", String.valueOf(calls)).replace("@name", config.getString("Evento.Title")).replace("@reward", aEventos.getInstance().getEconomy().format(this.reward)).replace("@cost", aEventos.getInstance().getEconomy().format(this.cost)).replace("@max", String.valueOf(this.max_number)); + aEventos.getInstance().getServer().broadcastMessage(s); + } + + @Override + public void parseCommand(Player p, String[] args) { + + if(aEventos.getInstance().getEconomy().getBalance(p) < this.cost) { + p.sendMessage(config.getString("Messages.No money").replace("&", "§").replace("@name", config.getString("Evento.Title")).replace("@cost", aEventos.getInstance().getEconomy().format(this.cost))); + return; + } + + try{ + + int player_number = Integer.parseInt(args[0]); + + if(player_number <= 0 || player_number > this.max_number) { + p.sendMessage(config.getString("Messages.Invalid").replace("&", "§").replace("@name", config.getString("Evento.Title")).replace("@max", String.valueOf(this.max_number))); + return; + } + + aEventos.getInstance().getEconomy().withdrawPlayer(p, this.cost); + + if(player_number == this.number) { + winner(p); + }else { + p.sendMessage(config.getString("Messages.Lose").replace("&", "§").replace("@name", config.getString("Evento.Title")).replace("@number", String.valueOf(player_number))); + } + + }catch(NumberFormatException e) { + p.sendMessage(config.getString("Messages.Invalid").replace("&", "§").replace("@name", config.getString("Evento.Title")).replace("@max", String.valueOf(this.max_number))); + } + + } + +} diff --git a/src/main/java/com/ars3ne/eventos/listeners/EventoListener.java b/src/main/java/com/ars3ne/eventos/listeners/EventoListener.java index 247f3ca..ddc1111 100644 --- a/src/main/java/com/ars3ne/eventos/listeners/EventoListener.java +++ b/src/main/java/com/ars3ne/eventos/listeners/EventoListener.java @@ -1,181 +1,232 @@ -/* - * - * This file is part of aEventos, licensed under the MIT License. - * - * Copyright (c) Ars3ne - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -package com.ars3ne.eventos.listeners; - -import com.ars3ne.eventos.aEventos; -import com.ars3ne.eventos.commands.EventoCommand; -import com.ars3ne.eventos.utils.ConfigFile; -import org.bukkit.Material; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.block.Action; -import org.bukkit.event.block.SignChangeEvent; -import org.bukkit.event.player.PlayerCommandPreprocessEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.player.PlayerQuitEvent; - -import java.io.IOException; -import java.util.List; -import java.util.Map; - -public class EventoListener implements Listener { - - // Bloquear comandos nos eventos - @EventHandler(priority = EventPriority.LOW) - public void onCommand(PlayerCommandPreprocessEvent e) { - - // Se não está ocorrendo um evento, ou o jogador não está nele, retorne. - if(aEventos.getEventoManager().getEvento() == null) return; - if(e.getPlayer().hasPermission("aeventos.admin")) return; - - if(!aEventos.getEventoManager().getEvento().getPlayers().contains(e.getPlayer()) - || aEventos.getEventoManager().getEvento().getSpectators().contains(e.getPlayer())) return; - - // Carregue a lista de comandos permitidos. Se não estiver na lista, cancele o evento e envie uma mensagem. - List allowed_commands = aEventos.getInstance().getConfig().getStringList("Allowed commands"); - - if(!allowed_commands.contains(e.getMessage().toLowerCase().split(" ")[0])) { - e.getPlayer().sendMessage(aEventos.getInstance().getConfig().getString("Messages.Blocked command").replace("&", "§")); - e.setCancelled(true); - } - - } - - // Remover jogador do evento se ele saiu do servidor. - @EventHandler - public void onLeave(PlayerQuitEvent e) { - - if(aEventos.getEventoManager().getEvento() == null) return; - - // Se o usuário estava no evento, remova-o. - if(aEventos.getEventoManager().getEvento().getPlayers().contains(e.getPlayer())) { - aEventos.getEventoManager().getEvento().leave(e.getPlayer()); - }else if(aEventos.getEventoManager().getEvento().getSpectators().contains(e.getPlayer())) { - // Se o usuário estava no modo espectador, remova-o. - aEventos.getEventoManager().getEvento().remove(e.getPlayer()); - } - - } - - // Listeners do modo setup - - // Ao escrever uma placa - @EventHandler - public void onSignChange(SignChangeEvent e) { - - Map setup = EventoCommand.getSetupList(); - - if(!setup.containsKey(e.getPlayer())) return; - if(setup.get(e.getPlayer()).getStringList("Messages.Sign") == null) return; - - if(e.getLine(0).equalsIgnoreCase("[evento]")) { - - if(e.getLine(1).equalsIgnoreCase("vitoria")) { - - e.setLine(0, setup.get(e.getPlayer()).getStringList("Messages.Sign").get(0).replace("&", "§")); - e.setLine(1, setup.get(e.getPlayer()).getStringList("Messages.Sign").get(1).replace("&", "§")); - e.setLine(2, setup.get(e.getPlayer()).getStringList("Messages.Sign").get(2).replace("&", "§")); - e.setLine(3, setup.get(e.getPlayer()).getStringList("Messages.Sign").get(3).replace("&", "§")); - - } - - if(e.getLine(1).equalsIgnoreCase("checkpoint")) { - - if(setup.get(e.getPlayer()).getStringList("Messages.Checkpoint") == null) return; - e.setLine(0, setup.get(e.getPlayer()).getStringList("Messages.Checkpoint").get(0).replace("&", "§")); - e.setLine(1, setup.get(e.getPlayer()).getStringList("Messages.Checkpoint").get(1).replace("&", "§")); - e.setLine(2, setup.get(e.getPlayer()).getStringList("Messages.Checkpoint").get(2).replace("&", "§")); - e.setLine(3, setup.get(e.getPlayer()).getStringList("Messages.Checkpoint").get(3).replace("&", "§")); - - } - } - - } - - @EventHandler - public void onInteract(PlayerInteractEvent e) { - - Map setup = EventoCommand.getSetupList(); - - if(!setup.containsKey(e.getPlayer())) return; - if(!setup.get(e.getPlayer()).isSet("Locations.Pos1")) return; - - if(e.getItem() == null || e.getItem().getType() != Material.STONE_AXE) return; - if(e.getItem().getItemMeta().getDisplayName() == null) return; - - if(e.getItem().getItemMeta().getDisplayName().equals("§6Machado de Posições")) { - - YamlConfiguration settings = setup.get(e.getPlayer()); - - // Se for um click com o machado de posições, então obtenha a posição dos blocos e detecte o click. - e.setCancelled(true); - - if(e.getAction() == Action.LEFT_CLICK_BLOCK) { - - settings.set("Locations.Pos1.world", e.getPlayer().getWorld().getName()); - settings.set("Locations.Pos1.x", e.getClickedBlock().getX()); - settings.set("Locations.Pos1.y", e.getClickedBlock().getY()); - settings.set("Locations.Pos1.z", e.getClickedBlock().getZ()); - - try { - ConfigFile.save(settings); - setup.replace(e.getPlayer(), settings); - } catch (IOException ex) { - e.getPlayer().sendMessage(aEventos.getInstance().getConfig().getString("Messages.Error").replace("&", "§").replace("@name", settings.getString("Evento.Title"))); - ex.printStackTrace(); - } - - e.getPlayer().sendMessage(aEventos.getInstance().getConfig().getString("Messages.Saved").replace("&", "§").replace("@name", settings.getString("Evento.Title")).replace("@pos", "pos1 ")); - - } - - if(e.getAction() == Action.RIGHT_CLICK_BLOCK) { - - settings.set("Locations.Pos2.world", e.getPlayer().getWorld().getName()); - settings.set("Locations.Pos2.x", e.getClickedBlock().getX()); - settings.set("Locations.Pos2.y", e.getClickedBlock().getY()); - settings.set("Locations.Pos2.z", e.getClickedBlock().getZ()); - - try { - ConfigFile.save(settings); - setup.replace(e.getPlayer(), settings); - } catch (IOException ex) { - e.getPlayer().sendMessage(aEventos.getInstance().getConfig().getString("Messages.Error").replace("&", "§").replace("@name", settings.getString("Evento.Title"))); - ex.printStackTrace(); - } - - e.getPlayer().sendMessage(aEventos.getInstance().getConfig().getString("Messages.Saved").replace("&", "§").replace("@name", settings.getString("Evento.Title")).replace("@pos", "pos2 ")); - - } - } - } - -} +/* + * + * This file is part of aEventos, licensed under the MIT License. + * + * Copyright (c) Ars3ne + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package com.ars3ne.eventos.listeners; + +import com.ars3ne.eventos.aEventos; +import com.ars3ne.eventos.commands.EventoCommand; +import com.ars3ne.eventos.utils.ConfigFile; +import org.bukkit.Material; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.SignChangeEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +public class EventoListener implements Listener { + + // Bloquear comandos nos eventos + @EventHandler(priority = EventPriority.LOW) + public void onCommand(PlayerCommandPreprocessEvent e) { + + // Se não está ocorrendo um evento, ou o jogador não está nele, retorne. + if(aEventos.getEventoManager().getEvento() == null) return; + if(e.getPlayer().hasPermission("aeventos.admin")) return; + + if(!aEventos.getEventoManager().getEvento().getPlayers().contains(e.getPlayer()) + || aEventos.getEventoManager().getEvento().getSpectators().contains(e.getPlayer())) return; + + // Carregue a lista de comandos permitidos. Se não estiver na lista, cancele o evento e envie uma mensagem. + List allowed_commands = aEventos.getInstance().getConfig().getStringList("Allowed commands"); + + if(!allowed_commands.contains(e.getMessage().toLowerCase().split(" ")[0])) { + e.getPlayer().sendMessage(aEventos.getInstance().getConfig().getString("Messages.Blocked command").replace("&", "§")); + e.setCancelled(true); + } + + } + + // Remover jogador do evento se ele saiu do servidor. + @EventHandler + public void onLeave(PlayerQuitEvent e) { + + if(aEventos.getEventoManager().getEvento() == null && aEventos.getEventoChatManager().getEvento() == null) return; + + if(aEventos.getEventoChatManager().getEvento() != null) { + aEventos.getEventoChatManager().getEvento().leave(e.getPlayer()); + }else { + // Se o usuário estava no evento, remova-o. + if(aEventos.getEventoManager().getEvento().getPlayers().contains(e.getPlayer())) { + aEventos.getEventoManager().getEvento().leave(e.getPlayer()); + }else if(aEventos.getEventoManager().getEvento().getSpectators().contains(e.getPlayer())) { + // Se o usuário estava no modo espectador, remova-o. + aEventos.getEventoManager().getEvento().remove(e.getPlayer()); + } + } + + } + + // Listeners do modo setup + + // Ao escrever uma placa + @EventHandler + public void onSignChange(SignChangeEvent e) { + + Map setup = EventoCommand.getSetupList(); + + if(!setup.containsKey(e.getPlayer())) return; + if(setup.get(e.getPlayer()).getStringList("Messages.Sign") == null) return; + + if(e.getLine(0).equalsIgnoreCase("[evento]")) { + + if(e.getLine(1).equalsIgnoreCase("vitoria")) { + + e.setLine(0, setup.get(e.getPlayer()).getStringList("Messages.Sign").get(0).replace("&", "§")); + e.setLine(1, setup.get(e.getPlayer()).getStringList("Messages.Sign").get(1).replace("&", "§")); + e.setLine(2, setup.get(e.getPlayer()).getStringList("Messages.Sign").get(2).replace("&", "§")); + e.setLine(3, setup.get(e.getPlayer()).getStringList("Messages.Sign").get(3).replace("&", "§")); + + } + + if(e.getLine(1).equalsIgnoreCase("checkpoint")) { + + if(setup.get(e.getPlayer()).getStringList("Messages.Checkpoint") == null) return; + e.setLine(0, setup.get(e.getPlayer()).getStringList("Messages.Checkpoint").get(0).replace("&", "§")); + e.setLine(1, setup.get(e.getPlayer()).getStringList("Messages.Checkpoint").get(1).replace("&", "§")); + e.setLine(2, setup.get(e.getPlayer()).getStringList("Messages.Checkpoint").get(2).replace("&", "§")); + e.setLine(3, setup.get(e.getPlayer()).getStringList("Messages.Checkpoint").get(3).replace("&", "§")); + + } + } + + } + + @EventHandler + public void onInteract(PlayerInteractEvent e) { + + Map setup = EventoCommand.getSetupList(); + + if(!setup.containsKey(e.getPlayer())) return; + if(!setup.get(e.getPlayer()).isSet("Locations.Pos1")) return; + + if(e.getItem() == null || (e.getItem().getType() != Material.STONE_AXE && e.getItem().getType() != Material.STONE_HOE)) return; + if(e.getItem().getItemMeta().getDisplayName() == null) return; + + if(e.getItem().getItemMeta().getDisplayName().equals("§6Machado de Posições")) { + + YamlConfiguration settings = setup.get(e.getPlayer()); + + // Se for um click com o machado de posições, então obtenha a posição dos blocos e detecte o click. + e.setCancelled(true); + + if(e.getAction() == Action.LEFT_CLICK_BLOCK) { + + settings.set("Locations.Pos1.world", e.getPlayer().getWorld().getName()); + settings.set("Locations.Pos1.x", e.getClickedBlock().getX()); + settings.set("Locations.Pos1.y", e.getClickedBlock().getY()); + settings.set("Locations.Pos1.z", e.getClickedBlock().getZ()); + + try { + ConfigFile.save(settings); + setup.replace(e.getPlayer(), settings); + } catch (IOException ex) { + e.getPlayer().sendMessage(aEventos.getInstance().getConfig().getString("Messages.Error").replace("&", "§").replace("@name", settings.getString("Evento.Title"))); + ex.printStackTrace(); + } + + e.getPlayer().sendMessage(aEventos.getInstance().getConfig().getString("Messages.Saved").replace("&", "§").replace("@name", settings.getString("Evento.Title")).replace("@pos", "pos1 ")); + + } + + if(e.getAction() == Action.RIGHT_CLICK_BLOCK) { + + settings.set("Locations.Pos2.world", e.getPlayer().getWorld().getName()); + settings.set("Locations.Pos2.x", e.getClickedBlock().getX()); + settings.set("Locations.Pos2.y", e.getClickedBlock().getY()); + settings.set("Locations.Pos2.z", e.getClickedBlock().getZ()); + + try { + ConfigFile.save(settings); + setup.replace(e.getPlayer(), settings); + } catch (IOException ex) { + e.getPlayer().sendMessage(aEventos.getInstance().getConfig().getString("Messages.Error").replace("&", "§").replace("@name", settings.getString("Evento.Title"))); + ex.printStackTrace(); + } + + e.getPlayer().sendMessage(aEventos.getInstance().getConfig().getString("Messages.Saved").replace("&", "§").replace("@name", settings.getString("Evento.Title")).replace("@pos", "pos2 ")); + + } + } + + if(e.getItem().getItemMeta().getDisplayName().equals("§6Enxada de Posições")) { + + YamlConfiguration settings = setup.get(e.getPlayer()); + + // Se for um click com o machado de posições, então obtenha a posição dos blocos e detecte o click. + e.setCancelled(true); + + if(e.getAction() == Action.LEFT_CLICK_BLOCK) { + + settings.set("Locations.Pos3.world", e.getPlayer().getWorld().getName()); + settings.set("Locations.Pos3.x", e.getClickedBlock().getX()); + settings.set("Locations.Pos3.y", e.getClickedBlock().getY()); + settings.set("Locations.Pos3.z", e.getClickedBlock().getZ()); + + try { + ConfigFile.save(settings); + setup.replace(e.getPlayer(), settings); + } catch (IOException ex) { + e.getPlayer().sendMessage(aEventos.getInstance().getConfig().getString("Messages.Error").replace("&", "§").replace("@name", settings.getString("Evento.Title"))); + ex.printStackTrace(); + } + + e.getPlayer().sendMessage(aEventos.getInstance().getConfig().getString("Messages.Saved").replace("&", "§").replace("@name", settings.getString("Evento.Title")).replace("@pos", "pos3 ")); + + } + + if(e.getAction() == Action.RIGHT_CLICK_BLOCK) { + + settings.set("Locations.Pos4.world", e.getPlayer().getWorld().getName()); + settings.set("Locations.Pos4.x", e.getClickedBlock().getX()); + settings.set("Locations.Pos4.y", e.getClickedBlock().getY()); + settings.set("Locations.Pos4.z", e.getClickedBlock().getZ()); + + try { + ConfigFile.save(settings); + setup.replace(e.getPlayer(), settings); + } catch (IOException ex) { + e.getPlayer().sendMessage(aEventos.getInstance().getConfig().getString("Messages.Error").replace("&", "§").replace("@name", settings.getString("Evento.Title"))); + ex.printStackTrace(); + } + + e.getPlayer().sendMessage(aEventos.getInstance().getConfig().getString("Messages.Saved").replace("&", "§").replace("@name", settings.getString("Evento.Title")).replace("@pos", "pos4 ")); + + } + } + + } + +} diff --git a/src/main/java/com/ars3ne/eventos/listeners/eventos/AnvilListener.java b/src/main/java/com/ars3ne/eventos/listeners/eventos/AnvilListener.java new file mode 100644 index 0000000..fece4e1 --- /dev/null +++ b/src/main/java/com/ars3ne/eventos/listeners/eventos/AnvilListener.java @@ -0,0 +1,93 @@ +/* + * + * This file is part of aEventos, licensed under the MIT License. + * + * Copyright (c) Ars3ne + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package com.ars3ne.eventos.listeners.eventos; + +import com.ars3ne.eventos.aEventos; +import com.ars3ne.eventos.api.events.PlayerLoseEvent; +import com.ars3ne.eventos.eventos.Anvil; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityChangeBlockEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; + +public class AnvilListener implements Listener { + + private Anvil evento; + + @EventHandler(priority = EventPriority.LOW) + public void onEntityChangeBlockEvent(EntityChangeBlockEvent e) { + + if(evento == null) return; + if(e.getEntityType() != EntityType.FALLING_BLOCK) return; + + FallingBlock fb = (FallingBlock) e.getEntity(); + if(fb.getMaterial() != Material.ANVIL) return; + if(!evento.getAnvils().contains(e.getBlock())) return; + + fb.setDropItem(false); + if(e.getBlock().getType() != Material.ANVIL) e.getBlock().setType(Material.ANVIL); + + for(Player p: evento.getPlayers()) { + + // Se o jogador estiver no mesmo bloco da bigorna, então o elimine. + if(Math.round(p.getLocation().getX()) != e.getBlock().getX() || Math.round(p.getLocation().getY()) != e.getBlock().getY() || Math.round(p.getLocation().getZ()) != e.getBlock().getZ() ) continue; + p.sendMessage(aEventos.getInstance().getConfig().getString("Messages.Eliminated").replace("&", "§")); + evento.remove(p); + PlayerLoseEvent lose = new PlayerLoseEvent(p, evento.getConfig().getString("filename").substring(0, evento.getConfig().getString("filename").length() - 4), evento.getType()); + Bukkit.getPluginManager().callEvent(lose); + + } + + } + + @EventHandler + public void onDrop(PlayerDropItemEvent e) { + if(evento == null) return; + if (!evento.getPlayers().contains(e.getPlayer())) return; + e.setCancelled(true); + } + + @EventHandler + public void onPickup(PlayerPickupItemEvent e) { + if(evento == null) return; + if (!evento.getPlayers().contains(e.getPlayer())) return; + e.setCancelled(true); + } + + public void setEvento() { + evento = (Anvil) aEventos.getEventoManager().getEvento(); + } + +} diff --git a/src/main/java/com/ars3ne/eventos/listeners/eventos/FightListener.java b/src/main/java/com/ars3ne/eventos/listeners/eventos/FightListener.java index 094d5e7..bc4467b 100644 --- a/src/main/java/com/ars3ne/eventos/listeners/eventos/FightListener.java +++ b/src/main/java/com/ars3ne/eventos/listeners/eventos/FightListener.java @@ -67,7 +67,7 @@ public void onDeath(PlayerDeathEvent e) { // Limpe os drops e defina o jogador como o perdedor. e.getDrops().clear(); - evento.setFightLoser(e.getEntity().getPlayer()); + evento.setFightLoser(e.getEntity().getPlayer(), false); } diff --git a/src/main/java/com/ars3ne/eventos/listeners/eventos/HunterListener.java b/src/main/java/com/ars3ne/eventos/listeners/eventos/HunterListener.java new file mode 100644 index 0000000..14fad50 --- /dev/null +++ b/src/main/java/com/ars3ne/eventos/listeners/eventos/HunterListener.java @@ -0,0 +1,89 @@ +/* + * + * This file is part of aEventos, licensed under the MIT License. + * + * Copyright (c) Ars3ne + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package com.ars3ne.eventos.listeners.eventos; + +import com.ars3ne.eventos.aEventos; +import com.ars3ne.eventos.eventos.Hunter; +import org.bukkit.entity.Arrow; +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.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; + +public class HunterListener implements Listener { + + Hunter evento; + + @EventHandler + public void onDamage(EntityDamageByEntityEvent e) { + + if(evento == null) return; + if(!(e.getEntity() instanceof Player)) return; + if(!(e.getDamager() instanceof Arrow)) return; + + Player p = (Player) e.getEntity(); + Arrow arrow = (Arrow) e.getDamager(); + Player shooter = (Player) arrow.getShooter(); + + if(!evento.getPlayers().contains(p) || !evento.getPlayers().contains(shooter)) return; + + if(!evento.isPvPEnabled()) { + e.setCancelled(true); + return; + } + + if(evento.getCaptured().contains(p)) return; + + if((evento.getBlueTeam().containsKey(p) && evento.getBlueTeam().containsKey(shooter)) + || (evento.getRedTeam().containsKey(p) && evento.getRedTeam().containsKey(shooter))) return; + + + evento.eliminate(p, shooter); + + } + + @EventHandler + public void onDrop(PlayerDropItemEvent e) { + if(evento == null) return; + if (!evento.getPlayers().contains(e.getPlayer())) return; + e.setCancelled(true); + } + + @EventHandler + public void onPickup(PlayerPickupItemEvent e) { + if(evento == null) return; + if (!evento.getPlayers().contains(e.getPlayer())) return; + e.setCancelled(true); + } + + public void setEvento() { + evento = (Hunter) aEventos.getEventoManager().getEvento(); + } +} diff --git a/src/main/java/com/ars3ne/eventos/listeners/eventos/QuizListener.java b/src/main/java/com/ars3ne/eventos/listeners/eventos/QuizListener.java new file mode 100644 index 0000000..5920967 --- /dev/null +++ b/src/main/java/com/ars3ne/eventos/listeners/eventos/QuizListener.java @@ -0,0 +1,82 @@ +/* + * + * This file is part of aEventos, licensed under the MIT License. + * + * Copyright (c) Ars3ne + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package com.ars3ne.eventos.listeners.eventos; + +import com.ars3ne.eventos.aEventos; +import com.ars3ne.eventos.api.events.PlayerLoseEvent; +import com.ars3ne.eventos.eventos.Quiz; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; + +public class QuizListener implements Listener { + + Quiz evento; + + @EventHandler + public void onMove(PlayerMoveEvent e) { + + if(evento == null) return; + if(!evento.getPlayers().contains(e.getPlayer())) return; + + if(e.getTo().getBlock().getType() == Material.WATER || e.getTo().getBlock().getType() == Material.STATIONARY_WATER) { + + // Se o jogador entrou na água, então o elimine. + e.getPlayer().sendMessage(aEventos.getInstance().getConfig().getString("Messages.Eliminated").replace("&", "§")); + evento.remove(e.getPlayer()); + PlayerLoseEvent lose = new PlayerLoseEvent(e.getPlayer(), evento.getConfig().getString("filename").substring(0, evento.getConfig().getString("filename").length() - 4), evento.getType()); + Bukkit.getPluginManager().callEvent(lose); + + } + + } + + @EventHandler + public void onDrop(PlayerDropItemEvent e) { + if(evento == null) return; + if (!evento.getPlayers().contains(e.getPlayer())) return; + e.setCancelled(true); + } + + @EventHandler + public void onPickup(PlayerPickupItemEvent e) { + if(evento == null) return; + if (!evento.getPlayers().contains(e.getPlayer())) return; + e.setCancelled(true); + } + + public void setEvento() { + evento = (Quiz) aEventos.getEventoManager().getEvento(); + } + +} diff --git a/src/main/java/com/ars3ne/eventos/manager/EventosChatManager.java b/src/main/java/com/ars3ne/eventos/manager/EventosChatManager.java index c1a4ab8..b3a89bd 100644 --- a/src/main/java/com/ars3ne/eventos/manager/EventosChatManager.java +++ b/src/main/java/com/ars3ne/eventos/manager/EventosChatManager.java @@ -27,6 +27,7 @@ package com.ars3ne.eventos.manager; +import com.ars3ne.eventos.aEventos; import com.ars3ne.eventos.api.EventoChat; import com.ars3ne.eventos.api.EventoType; import com.ars3ne.eventos.eventos.chat.*; @@ -43,11 +44,18 @@ public boolean startEvento(EventoType type, YamlConfiguration config) { return false; } + if(!verify(config)) return false; switch(type) { case VOTACAO: this.evento = new Votacao(config); break; + case LOTERIA: + this.evento = new Loteria(config); + break; + case BOLAO: + this.evento = new Bolao(config); + break; } this.evento.startCall(); @@ -55,6 +63,16 @@ public boolean startEvento(EventoType type, YamlConfiguration config) { } + private boolean verify(YamlConfiguration config) { + + switch(EventoType.getEventoType(config.getString("Evento.Type"))) { + case LOTERIA: case BOLAO: + return aEventos.getInstance().getEconomy() != null; + } + + return true; + + } public EventoChat getEvento() { return this.evento; } diff --git a/src/main/java/com/ars3ne/eventos/manager/EventosManager.java b/src/main/java/com/ars3ne/eventos/manager/EventosManager.java index 348b1d5..28f8b38 100644 --- a/src/main/java/com/ars3ne/eventos/manager/EventosManager.java +++ b/src/main/java/com/ars3ne/eventos/manager/EventosManager.java @@ -79,6 +79,15 @@ public boolean startEvento(EventoType type, YamlConfiguration config) { case PAINTBALL: this.evento = new Paintball(config); break; + case HUNTER: + this.evento = new Hunter(config); + break; + case QUIZ: + this.evento = new Quiz(config); + break; + case ANVIL: + this.evento = new Anvil(config); + break; } this.evento.startCall(); @@ -91,7 +100,7 @@ private boolean verify(YamlConfiguration config) { boolean require_pos = false; switch(EventoType.getEventoType(config.getString("Evento.Type"))) { - case CAMPO_MINADO: case SPLEEF: case FROG: case FIGHT: case PAINTBALL: + case CAMPO_MINADO: case SPLEEF: case FROG: case FIGHT: case PAINTBALL: case HUNTER: case QUIZ: case ANVIL: require_pos = true; break; } diff --git a/src/main/java/com/ars3ne/eventos/manager/TagManager.java b/src/main/java/com/ars3ne/eventos/manager/TagManager.java index 3821a84..96c10c6 100644 --- a/src/main/java/com/ars3ne/eventos/manager/TagManager.java +++ b/src/main/java/com/ars3ne/eventos/manager/TagManager.java @@ -46,6 +46,8 @@ public void setup() { // Leia todos os arquivos de configuração de eventos e adicione as suas tags a lista. for (File file : Objects.requireNonNull(ConfigFile.getAllFiles())) { + if(file.getName().contains("old")) continue; + // Adicione o evento á database. aEventos.getConnectionManager().createEvento(file.getName().substring(0, file.getName().length() - 4)); YamlConfiguration config = ConfigFile.get(file.getName().substring(0, file.getName().length() - 4)); diff --git a/src/main/java/com/ars3ne/eventos/manager/UpdateChecker.java b/src/main/java/com/ars3ne/eventos/manager/UpdateChecker.java index 60a18a8..8b6d708 100644 --- a/src/main/java/com/ars3ne/eventos/manager/UpdateChecker.java +++ b/src/main/java/com/ars3ne/eventos/manager/UpdateChecker.java @@ -82,13 +82,14 @@ public static void verify() { if(release.get("tag_name").equals(CURERNT_VERSION)) break; if((Boolean) release.get("draft") || (Boolean) release.get("prerelease")) continue; - Bukkit.getConsoleSender().sendMessage("§e[aEventos] §aUma nova atualização está disponível! (" + release.get("name") + ")."); + Bukkit.getConsoleSender().sendMessage("§e[aEventos] §aUma nova atualização está disponível! (" + release.get("name") + ")"); Bukkit.getConsoleSender().sendMessage("§e[aEventos] §aVocê pode baixar-la aqui: " + release.get("html_url")); - break; - + return; } } + Bukkit.getConsoleSender().sendMessage("§e[aEventos] §aVocê está usando a última versão. (" + CURERNT_VERSION + ")"); + } catch (IOException | ParseException e) { Bukkit.getConsoleSender().sendMessage("§e[aEventos] §cNão foi possível verificar por atualizações."); diff --git a/src/main/java/com/ars3ne/eventos/utils/ConfigUpdater.java b/src/main/java/com/ars3ne/eventos/utils/ConfigUpdater.java index 072a3e0..a1ea747 100644 --- a/src/main/java/com/ars3ne/eventos/utils/ConfigUpdater.java +++ b/src/main/java/com/ars3ne/eventos/utils/ConfigUpdater.java @@ -27,6 +27,9 @@ package com.ars3ne.eventos.utils; +import com.ars3ne.eventos.api.EventoType; +import org.bukkit.Bukkit; +import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; @@ -47,6 +50,7 @@ * If a key has an attached comment above it, it is written first. * @author tchristofferson */ +@SuppressWarnings("OptionalGetWithoutIsPresent") public class ConfigUpdater { /** @@ -341,4 +345,177 @@ private static String getPrefixSpaces(int indents) { private static void appendPrefixSpaces(StringBuilder builder, int indents) { builder.append(getPrefixSpaces(indents)); } + + // Atualiza as configurações dos eventos. + @SuppressWarnings("deprecation") + public static void updateEventos() { + + for (File file : Objects.requireNonNull(ConfigFile.getAllFiles())) { + + if(file.getName().contains("old")) continue; + YamlConfiguration config = ConfigFile.get(file.getName().substring(0, file.getName().length() - 4)); + + if(config.getString("Evento.Type") == null) continue; + if (EventoType.getEventoType(config.getString("Evento.Type")) == EventoType.FIGHT) { + + // Se for a config antiga, converta os items. + if(config.getString("Items.Normal.Armor.Helmet.Material") == null) { + + Bukkit.getConsoleSender().sendMessage("§e[aEventos] §aConvertendo o arquivo de configuração §f" + config.getString("filename") + " §apara a nova versão..."); + + // Luta normal + List normal_items = new ArrayList<>(); + for (String s : config.getStringList("Items.Normal.Inventory")) { + String[] separated = s.split("-"); + Material replace = XMaterial.matchXMaterial(Integer.parseInt(separated[0]), (byte) 0).get().parseMaterial(); + assert replace != null; + separated[0] = replace.toString(); + normal_items.add(String.join("-", separated)); + } + config.set("Items.Normal.Inventory", normal_items); + + if (config.getString("Items.Normal.Armor.Helmet") != null) { + String[] separated = config.getString("Items.Normal.Armor.Helmet").split("-"); + Material replace = XMaterial.matchXMaterial(Integer.parseInt(separated[0]), (byte) 0).get().parseMaterial(); + assert replace != null; + config.set("Items.Normal.Armor.Helmet.Material", replace.toString()); + }else { + config.set("Items.Normal.Armor.Helmet.Material", "null"); + } + config.set("Items.Normal.Armor.Helmet.Data", 0); + + if (config.getString("Items.Normal.Armor.Chestplate") != null) { + String[] separated = config.getString("Items.Normal.Armor.Chestplate").split("-"); + Material replace = XMaterial.matchXMaterial(Integer.parseInt(separated[0]), (byte) 0).get().parseMaterial(); + assert replace != null; + config.set("Items.Normal.Armor.Chestplate.Material", replace.toString()); + }else { + config.set("Items.Normal.Armor.Chestplate.Material", "null"); + } + config.set("Items.Normal.Armor.Chestplate.Data", 0); + + if (config.getString("Items.Normal.Armor.Legging") != null) { + String[] separated = config.getString("Items.Normal.Armor.Legging").split("-"); + Material replace = XMaterial.matchXMaterial(Integer.parseInt(separated[0]), (byte) 0).get().parseMaterial(); + assert replace != null; + config.set("Items.Normal.Armor.Legging.Material", replace.toString()); + }else { + config.set("Items.Normal.Armor.Legging.Material", "null"); + } + config.set("Items.Normal.Armor.Legging.Data", 0); + + if (config.getString("Items.Normal.Armor.Boots") != null) { + String[] separated = config.getString("Items.Normal.Armor.Boots").split("-"); + Material replace = XMaterial.matchXMaterial(Integer.parseInt(separated[0]), (byte) 0).get().parseMaterial(); + assert replace != null; + config.set("Items.Normal.Armor.Boots.Material", replace.toString()); + }else { + config.set("Items.Normal.Armor.Boots.Material", "null"); + } + config.set("Items.Normal.Armor.Boots.Data", 0); + + // Última luta + List last_items = new ArrayList<>(); + for (String s : config.getStringList("Items.Last fight.Inventory")) { + String[] separated = s.split("-"); + Material replace = XMaterial.matchXMaterial(Integer.parseInt(separated[0]), (byte) 0).get().parseMaterial(); + assert replace != null; + separated[0] = replace.toString(); + last_items.add(String.join("-", separated)); + } + config.set("Items.Last fight.Inventory", last_items); + + if (config.getString("Items.Last fight.Armor.Helmet") != null) { + String[] separated = config.getString("Items.Last fight.Armor.Helmet").split("-"); + Material replace = XMaterial.matchXMaterial(Integer.parseInt(separated[0]), (byte) 0).get().parseMaterial(); + assert replace != null; + config.set("Items.Last fight.Armor.Helmet.Material", replace.toString()); + }else { + config.set("Items.Last fight.Armor.Helmet.Material", "null"); + } + config.set("Items.Last fight.Armor.Helmet.Data", 0); + + if (config.getString("Items.Last fight.Armor.Chestplate") != null) { + String[] separated = config.getString("Items.Last fight.Armor.Chestplate").split("-"); + Material replace = XMaterial.matchXMaterial(Integer.parseInt(separated[0]), (byte) 0).get().parseMaterial(); + assert replace != null; + config.set("Items.Last fight.Armor.Chestplate.Material", replace.toString()); + }else { + config.set("Items.Last fight.Armor.Chestplate.Material", "null"); + } + config.set("Items.Last fight.Armor.Chestplate.Data", 0); + + if (config.getString("Items.Last fight.Armor.Legging") != null) { + String[] separated = config.getString("Items.Last fight.Armor.Legging").split("-"); + Material replace = XMaterial.matchXMaterial(Integer.parseInt(separated[0]), (byte) 0).get().parseMaterial(); + assert replace != null; + config.set("Items.Last fight.Armor.Legging.Material", replace.toString()); + }else { + config.set("Items.Last fight.Armor.Legging.Material", "null"); + } + config.set("Items.Last fight.Armor.Legging.Data", 0); + + if (config.getString("Items.Last fight.Armor.Boots") != null) { + String[] separated = config.getString("Items.Last fight.Armor.Boots").split("-"); + Material replace = XMaterial.matchXMaterial(Integer.parseInt(separated[0]), (byte) 0).get().parseMaterial(); + assert replace != null; + config.set("Items.Last fight.Armor.Boots.Material", replace.toString()); + }else { + config.set("Items.Last fight.Armor.Boots.Material", "null"); + } + config.set("Items.Last fight.Armor.Boots.Data", 0); + + try { + ConfigFile.save(config); + Bukkit.getConsoleSender().sendMessage("§e[aEventos] §aArquivo §f" + config.getString("filename") + " §aconvertido com sucesso!"); + } catch (IOException e) { + Bukkit.getConsoleSender().sendMessage("§e[aEventos] §cNão foi possível converter o arquivo de configuração."); + e.printStackTrace(); + } + + } + + + }else if(EventoType.getEventoType(config.getString("Evento.Type")) == EventoType.SPLEEF) { + + List items = config.getStringList("Items"); + if(items != null) { + + // Se for a config antiga, converta os items. + try{ + + Integer.parseInt(items.get(0).split("-")[0]); + + Bukkit.getConsoleSender().sendMessage("§e[aEventos] §aConvertendo o arquivo de configuração §f" + config.getString("filename") + " §apara a nova versão..."); + + List new_items = new ArrayList<>(); + for(String item: items) { + String[] separated = item.split("-"); + Material replace = XMaterial.matchXMaterial(Integer.parseInt(separated[0]), (byte) 0).get().parseMaterial(); + assert replace != null; + separated[0] = replace.toString(); + new_items.add(String.join("-", separated)); + } + + config.set("Items", new_items); + + try { + ConfigFile.save(config); + Bukkit.getConsoleSender().sendMessage("§e[aEventos] §aArquivo §f" + config.getString("filename") + " §aconvertido com sucesso!"); + } catch (IOException e) { + Bukkit.getConsoleSender().sendMessage("§e[aEventos] §cNão foi possível converter o arquivo de configuração."); + e.printStackTrace(); + } + + + }catch(NumberFormatException ignored) { } + + } + + } + + } + + } + } \ No newline at end of file diff --git a/src/main/java/com/ars3ne/eventos/utils/XMaterial.java b/src/main/java/com/ars3ne/eventos/utils/XMaterial.java new file mode 100644 index 0000000..6d983ab --- /dev/null +++ b/src/main/java/com/ars3ne/eventos/utils/XMaterial.java @@ -0,0 +1,2030 @@ +/* + * + * This file is part of aEventos, licensed under the MIT License. + * + * Copyright (c) Ars3ne + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package com.ars3ne.eventos.utils; + +import com.google.common.base.Enums; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.Validate; +import org.apache.commons.lang.WordUtils; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +/** + * XMaterial - Data Values/Pre-flattening
+ * 1.13 and above as priority. + *

+ * This class is mainly designed to support {@link ItemStack}. If you want to use it on blocks, you'll have to use + * XBlock + *

+ * Pre-flattening: https://minecraft.gamepedia.com/Java_Edition_data_values/Pre-flattening + * Materials: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html + * Materials (1.12): https://helpch.at/docs/1.12.2/index.html?org/bukkit/Material.html + * Material IDs: https://minecraft-ids.grahamedgecombe.com/ + * Material Source Code: https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/browse/src/main/java/org/bukkit/Material.java + * XMaterial v1: https://www.spigotmc.org/threads/329630/ + *

+ * This class will throw a "unsupported material" error if someone tries to use an item with an invalid data value which can only happen in 1.12 servers and below or when the + * utility is missing a new material in that specific version. + * To get an invalid item, (aka Missing Texture Block) you can use the command + * /give @p minecraft:dirt 1 10 where 1 is the item amount, and 10 is the data value. The material {@link #DIRT} with a data value of {@code 10} doesn't exist. + * + * @author Crypto Morin + * @version 10.0.0 + * @see Material + * @see ItemStack + */ +public enum XMaterial { + ACACIA_BOAT("BOAT_ACACIA"), + ACACIA_BUTTON("WOOD_BUTTON"), + ACACIA_DOOR("ACACIA_DOOR", "ACACIA_DOOR_ITEM"), + ACACIA_FENCE, + ACACIA_FENCE_GATE, + ACACIA_LEAVES("LEAVES_2"), + ACACIA_LOG("LOG_2"), + ACACIA_PLANKS(4, "WOOD"), + ACACIA_PRESSURE_PLATE("WOOD_PLATE"), + ACACIA_SAPLING(4, "SAPLING"), + ACACIA_SIGN("SIGN_POST", "SIGN"), + ACACIA_SLAB(4, "WOOD_DOUBLE_STEP", "WOOD_STEP", "WOODEN_SLAB"), + ACACIA_STAIRS, + ACACIA_TRAPDOOR("TRAP_DOOR"), + ACACIA_WALL_SIGN("WALL_SIGN"), + ACACIA_WOOD("LOG_2"), + ACTIVATOR_RAIL, + AIR, + ALLIUM(2, "RED_ROSE"), + ANCIENT_DEBRIS(16), + ANDESITE(5, "STONE"), + ANDESITE_SLAB, + ANDESITE_STAIRS, + ANDESITE_WALL, + ANVIL, + APPLE, + ARMOR_STAND, + ARROW, + ATTACHED_MELON_STEM(7, "MELON_STEM"), + ATTACHED_PUMPKIN_STEM(7, "PUMPKIN_STEM"), + AZURE_BLUET(3, "RED_ROSE"), + BAKED_POTATO, + BAMBOO(0, 14), + BAMBOO_SAPLING(14), + BARREL(0, 14), + BARRIER, + BASALT(16), + BAT_SPAWN_EGG(65, "MONSTER_EGG"), + BEACON, + BEDROCK, + BEEF("RAW_BEEF"), + BEEHIVE(15), + /** + * Beetroot is a known material in pre-1.13 + */ + BEETROOT("BEETROOT_BLOCK"), + BEETROOTS("BEETROOT"), + BEETROOT_SEEDS, + BEETROOT_SOUP, + BEE_NEST(15), + BEE_SPAWN_EGG(15), + BELL(14), + BIRCH_BOAT("BOAT_BIRCH"), + BIRCH_BUTTON("WOOD_BUTTON"), + BIRCH_DOOR("BIRCH_DOOR", "BIRCH_DOOR_ITEM"), + BIRCH_FENCE, + BIRCH_FENCE_GATE, + BIRCH_LEAVES(2, "LEAVES"), + BIRCH_LOG(2, "LOG"), + BIRCH_PLANKS(2, "WOOD"), + BIRCH_PRESSURE_PLATE("WOOD_PLATE"), + BIRCH_SAPLING(2, "SAPLING"), + BIRCH_SIGN("SIGN_POST", "SIGN"), + BIRCH_SLAB(2, "WOOD_DOUBLE_STEP", "WOOD_STEP", "WOODEN_SLAB"), + BIRCH_STAIRS("BIRCH_WOOD_STAIRS"), + BIRCH_TRAPDOOR("TRAP_DOOR"), + BIRCH_WALL_SIGN("WALL_SIGN"), + BIRCH_WOOD(2, "LOG"), + BLACKSTONE(16), + BLACKSTONE_SLAB(16), + BLACKSTONE_STAIRS(16), + BLACKSTONE_WALL(16), + BLACK_BANNER("STANDING_BANNER", "BANNER"), + BLACK_BED(15, "BED_BLOCK", "BED"), + BLACK_CARPET(15, "CARPET"), + BLACK_CONCRETE(15, "CONCRETE"), + BLACK_CONCRETE_POWDER(15, "CONCRETE_POWDER"), + BLACK_DYE(0, 14, "INK_SACK", "INK_SAC"), + BLACK_GLAZED_TERRACOTTA(15, 12), + BLACK_SHULKER_BOX, + BLACK_STAINED_GLASS(15, "STAINED_GLASS"), + BLACK_STAINED_GLASS_PANE(15, "STAINED_GLASS_PANE"), + BLACK_TERRACOTTA(15, "STAINED_CLAY"), + BLACK_WALL_BANNER("WALL_BANNER"), + BLACK_WOOL(15, "WOOL"), + BLAST_FURNACE(0, 14), + BLAZE_POWDER, + BLAZE_ROD, + BLAZE_SPAWN_EGG(61, "MONSTER_EGG"), + BLUE_BANNER(4, "STANDING_BANNER", "BANNER"), + BLUE_BED(11, "BED_BLOCK", "BED"), + BLUE_CARPET(11, "CARPET"), + BLUE_CONCRETE(11, "CONCRETE"), + BLUE_CONCRETE_POWDER(11, "CONCRETE_POWDER"), + BLUE_DYE(4, "INK_SACK", "LAPIS_LAZULI"), + BLUE_GLAZED_TERRACOTTA(11, 12), + BLUE_ICE(0, 13), + BLUE_ORCHID(1, "RED_ROSE"), + BLUE_SHULKER_BOX, + BLUE_STAINED_GLASS(11, "STAINED_GLASS"), + BLUE_STAINED_GLASS_PANE(11, "THIN_GLASS", "STAINED_GLASS_PANE"), + BLUE_TERRACOTTA(11, "STAINED_CLAY"), + BLUE_WALL_BANNER(4, "WALL_BANNER"), + BLUE_WOOL(11, "WOOL"), + BONE, + BONE_BLOCK, + BONE_MEAL(15, "INK_SACK"), + BOOK, + BOOKSHELF, + BOW, + BOWL, + BRAIN_CORAL(13), + BRAIN_CORAL_BLOCK(13), + BRAIN_CORAL_FAN(13), + BRAIN_CORAL_WALL_FAN, + BREAD, + BREWING_STAND("BREWING_STAND", "BREWING_STAND_ITEM"), + BRICK("CLAY_BRICK"), + BRICKS("BRICKS", "BRICK"), + BRICK_SLAB(4, "STEP"), + BRICK_STAIRS, + BRICK_WALL, + BROWN_BANNER(3, "STANDING_BANNER", "BANNER"), + BROWN_BED(12, "BED_BLOCK", "BED"), + BROWN_CARPET(12, "CARPET"), + BROWN_CONCRETE(12, "CONCRETE"), + BROWN_CONCRETE_POWDER(12, "CONCRETE_POWDER"), + BROWN_DYE(3, "INK_SACK", "DYE", "COCOA_BEANS"), + BROWN_GLAZED_TERRACOTTA(12, 12), + BROWN_MUSHROOM, + BROWN_MUSHROOM_BLOCK("BROWN_MUSHROOM", "HUGE_MUSHROOM_1"), + BROWN_SHULKER_BOX, + BROWN_STAINED_GLASS(12, "STAINED_GLASS"), + BROWN_STAINED_GLASS_PANE(12, "THIN_GLASS", "STAINED_GLASS_PANE"), + BROWN_TERRACOTTA(12, "STAINED_CLAY"), + BROWN_WALL_BANNER(3, "WALL_BANNER"), + BROWN_WOOL(12, "WOOL"), + BUBBLE_COLUMN(13), + BUBBLE_CORAL(13), + BUBBLE_CORAL_BLOCK(13), + BUBBLE_CORAL_FAN(13), + BUBBLE_CORAL_WALL_FAN, + BUCKET, + CACTUS, + CAKE("CAKE_BLOCK"), + CAMPFIRE(14), + CARROT("CARROT_ITEM"), + CARROTS("CARROT"), + CARROT_ON_A_STICK("CARROT_STICK"), + CARTOGRAPHY_TABLE(0, 14), + CARVED_PUMPKIN(1, 13), + CAT_SPAWN_EGG, + CAULDRON("CAULDRON", "CAULDRON_ITEM"), + /** + * 1.13 tag is not added because it's the same thing as {@link #AIR} + * + * @see #VOID_AIR + */ + CAVE_AIR("AIR"), + CAVE_SPIDER_SPAWN_EGG(59, "MONSTER_EGG"), + CHAIN(16), + CHAINMAIL_BOOTS, + CHAINMAIL_CHESTPLATE, + CHAINMAIL_HELMET, + CHAINMAIL_LEGGINGS, + CHAIN_COMMAND_BLOCK("COMMAND", "COMMAND_CHAIN"), + CHARCOAL(1, "COAL"), + CHEST("LOCKED_CHEST"), + CHEST_MINECART("STORAGE_MINECART"), + CHICKEN("RAW_CHICKEN"), + CHICKEN_SPAWN_EGG(93, "MONSTER_EGG"), + CHIPPED_ANVIL(1, "ANVIL"), + CHISELED_NETHER_BRICKS(1, "NETHER_BRICKS"), + CHISELED_POLISHED_BLACKSTONE(0, 16, "POLISHED_BLACKSTONE"), + CHISELED_QUARTZ_BLOCK(1, "QUARTZ_BLOCK"), + CHISELED_RED_SANDSTONE(1, "RED_SANDSTONE"), + CHISELED_SANDSTONE(1, "SANDSTONE"), + CHISELED_STONE_BRICKS(3, "SMOOTH_BRICK"), + CHORUS_FLOWER(0, 9), + CHORUS_FRUIT(0, 9), + CHORUS_PLANT(0, 9), + CLAY("HARD_CLAY"), + CLAY_BALL, + CLOCK("WATCH"), + COAL, + COAL_BLOCK, + COAL_ORE, + COARSE_DIRT(1, "DIRT"), + COBBLESTONE, + COBBLESTONE_SLAB(3, "STEP"), + COBBLESTONE_STAIRS, + COBBLESTONE_WALL("COBBLE_WALL"), + COBWEB("WEB"), + COCOA(15), + COCOA_BEANS(3, "INK_SACK"), + COD("RAW_FISH"), + COD_BUCKET(0, 13), + COD_SPAWN_EGG(0, 13), + COMMAND_BLOCK("COMMAND"), + COMMAND_BLOCK_MINECART("COMMAND_MINECART"), + /** + * Unlike redstone torch and redstone lamp... neither REDTONE_COMPARATOR_OFF nor REDSTONE_COMPARATOR_ON + * are items. REDSTONE_COMPARATOR is. + * + * @see #REDSTONE_TORCH + * @see #REDSTONE_LAMP + */ + COMPARATOR("REDSTONE_COMPARATOR_OFF", "REDSTONE_COMPARATOR_ON", "REDSTONE_COMPARATOR"), + COMPASS, + COMPOSTER(0, 14), + CONDUIT(0, 13, "BEACON"), + COOKED_BEEF, + COOKED_CHICKEN, + COOKED_COD("COOKED_FISH"), + COOKED_MUTTON, + COOKED_PORKCHOP("PORK", "GRILLED_PORK"), + COOKED_RABBIT, + COOKED_SALMON(1, "COOKED_FISH"), + COOKIE, + CORNFLOWER(4, 14), + COW_SPAWN_EGG(92, "MONSTER_EGG"), + CRACKED_NETHER_BRICKS(2, "NETHER_BRICKS"), + CRACKED_POLISHED_BLACKSTONE_BRICKS(0, 16, "POLISHED_BLACKSTONE_BRICKS"), + CRACKED_STONE_BRICKS(2, "SMOOTH_BRICK"), + CRAFTING_TABLE("WORKBENCH"), + CREEPER_BANNER_PATTERN, + CREEPER_HEAD(4, "SKULL", "SKULL_ITEM"), + CREEPER_SPAWN_EGG(50, "MONSTER_EGG"), + CREEPER_WALL_HEAD(4, "SKULL", "SKULL_ITEM"), + CRIMSON_BUTTON(16), + CRIMSON_DOOR(16), + CRIMSON_FENCE(16), + CRIMSON_FENCE_GATE(16), + CRIMSON_FUNGUS(16), + CRIMSON_HYPHAE(16), + CRIMSON_NYLIUM(16), + CRIMSON_PLANKS(16), + CRIMSON_PRESSURE_PLATE(16), + CRIMSON_ROOTS(16), + CRIMSON_SIGN(0, 16, "SIGN_POST"), + CRIMSON_SLAB(16), + CRIMSON_STAIRS(16), + CRIMSON_STEM(16), + CRIMSON_TRAPDOOR(16), + CRIMSON_WALL_SIGN(0, 16, "WALL_SIGN"), + CROSSBOW, + CRYING_OBSIDIAN(16), + CUT_RED_SANDSTONE(13), + CUT_RED_SANDSTONE_SLAB("STONE_SLAB2"), + CUT_SANDSTONE(13), + CUT_SANDSTONE_SLAB("STEP"), + CYAN_BANNER(6, "STANDING_BANNER", "BANNER"), + CYAN_BED(9, "BED_BLOCK", "BED"), + CYAN_CARPET(9, "CARPET"), + CYAN_CONCRETE(9, "CONCRETE"), + CYAN_CONCRETE_POWDER(9, "CONCRETE_POWDER"), + CYAN_DYE(6, "INK_SACK"), + CYAN_GLAZED_TERRACOTTA(9, 12), + CYAN_SHULKER_BOX, + CYAN_STAINED_GLASS(9, "STAINED_GLASS"), + CYAN_STAINED_GLASS_PANE(9, "STAINED_GLASS_PANE"), + CYAN_TERRACOTTA(9, "STAINED_CLAY"), + CYAN_WALL_BANNER(6, "WALL_BANNER"), + CYAN_WOOL(9, "WOOL"), + DAMAGED_ANVIL(2, "ANVIL"), + DANDELION("YELLOW_FLOWER"), + DARK_OAK_BOAT("BOAT_DARK_OAK"), + DARK_OAK_BUTTON("WOOD_BUTTON"), + DARK_OAK_DOOR("DARK_OAK_DOOR", "DARK_OAK_DOOR_ITEM"), + DARK_OAK_FENCE, + DARK_OAK_FENCE_GATE, + DARK_OAK_LEAVES(4, "LEAVES", "LEAVES_2"), + DARK_OAK_LOG(1, "LOG_2"), + DARK_OAK_PLANKS(5, "WOOD"), + DARK_OAK_PRESSURE_PLATE("WOOD_PLATE"), + DARK_OAK_SAPLING(5, "SAPLING"), + DARK_OAK_SIGN("SIGN_POST", "SIGN"), + DARK_OAK_SLAB(5, "WOOD_DOUBLE_STEP", "WOOD_STEP", "WOODEN_SLAB"), + DARK_OAK_STAIRS, + DARK_OAK_TRAPDOOR("TRAP_DOOR"), + DARK_OAK_WALL_SIGN("WALL_SIGN"), + DARK_OAK_WOOD(1, "LOG_2"), + DARK_PRISMARINE(1, "PRISMARINE"), + DARK_PRISMARINE_SLAB(13), + DARK_PRISMARINE_STAIRS(13), + DAYLIGHT_DETECTOR("DAYLIGHT_DETECTOR_INVERTED"), + DEAD_BRAIN_CORAL(13), + DEAD_BRAIN_CORAL_BLOCK(13), + DEAD_BRAIN_CORAL_FAN(13), + DEAD_BRAIN_CORAL_WALL_FAN(13), + DEAD_BUBBLE_CORAL(13), + DEAD_BUBBLE_CORAL_BLOCK(13), + DEAD_BUBBLE_CORAL_FAN(13), + DEAD_BUBBLE_CORAL_WALL_FAN(13), + DEAD_BUSH, + DEAD_FIRE_CORAL(13), + DEAD_FIRE_CORAL_BLOCK(13), + DEAD_FIRE_CORAL_FAN(13), + DEAD_FIRE_CORAL_WALL_FAN(13), + DEAD_HORN_CORAL(13), + DEAD_HORN_CORAL_BLOCK(13), + DEAD_HORN_CORAL_FAN(13), + DEAD_HORN_CORAL_WALL_FAN(13), + DEAD_TUBE_CORAL(13), + DEAD_TUBE_CORAL_BLOCK(13), + DEAD_TUBE_CORAL_FAN(13), + DEAD_TUBE_CORAL_WALL_FAN(13), + DEBUG_STICK(0, 13), + DETECTOR_RAIL, + DIAMOND, + DIAMOND_AXE, + DIAMOND_BLOCK, + DIAMOND_BOOTS, + DIAMOND_CHESTPLATE, + DIAMOND_HELMET, + DIAMOND_HOE, + DIAMOND_HORSE_ARMOR("DIAMOND_BARDING"), + DIAMOND_LEGGINGS, + DIAMOND_ORE, + DIAMOND_PICKAXE, + DIAMOND_SHOVEL("DIAMOND_SPADE"), + DIAMOND_SWORD, + DIORITE(3, "STONE"), + DIORITE_SLAB, + DIORITE_STAIRS, + DIORITE_WALL, + DIRT, + DISPENSER, + DOLPHIN_SPAWN_EGG(0, 13), + DONKEY_SPAWN_EGG(32, "MONSTER_EGG"), + DRAGON_BREATH("DRAGONS_BREATH"), + DRAGON_EGG, + DRAGON_HEAD(5, 9, "SKULL", "SKULL_ITEM"), + DRAGON_WALL_HEAD(5, "SKULL", "SKULL_ITEM"), + DRIED_KELP(13), + DRIED_KELP_BLOCK(13), + DROPPER, + DROWNED_SPAWN_EGG(0, 13), + EGG, + ELDER_GUARDIAN_SPAWN_EGG(4, "MONSTER_EGG"), + ELYTRA, + EMERALD, + EMERALD_BLOCK, + EMERALD_ORE, + ENCHANTED_BOOK, + ENCHANTED_GOLDEN_APPLE(1, "GOLDEN_APPLE"), + ENCHANTING_TABLE("ENCHANTMENT_TABLE"), + ENDERMAN_SPAWN_EGG(58, "MONSTER_EGG"), + ENDERMITE_SPAWN_EGG(67, "MONSTER_EGG"), + ENDER_CHEST, + ENDER_EYE("EYE_OF_ENDER"), + ENDER_PEARL, + END_CRYSTAL, + END_GATEWAY(0, 9), + END_PORTAL("ENDER_PORTAL"), + END_PORTAL_FRAME("ENDER_PORTAL_FRAME"), + END_ROD(0, 9), + END_STONE("ENDER_STONE"), + END_STONE_BRICKS("END_BRICKS"), + END_STONE_BRICK_SLAB(6, "STEP"), + END_STONE_BRICK_STAIRS("SMOOTH_STAIRS"), + END_STONE_BRICK_WALL, + EVOKER_SPAWN_EGG(34, "MONSTER_EGG"), + EXPERIENCE_BOTTLE("EXP_BOTTLE"), + FARMLAND("SOIL"), + FEATHER, + FERMENTED_SPIDER_EYE, + FERN(2, "LONG_GRASS"), + /** + * For some reasons filled map items are really special. + * Their data value starts from 0 and every time a player + * creates a new map that maps data value increases. + * https://github.com/CryptoMorin/XSeries/issues/91 + */ + FILLED_MAP("MAP"), + FIRE, + FIREWORK_ROCKET("FIREWORK"), + FIREWORK_STAR("FIREWORK_CHARGE"), + FIRE_CHARGE("FIREBALL"), + FIRE_CORAL(13), + FIRE_CORAL_BLOCK(13), + FIRE_CORAL_FAN(13), + FIRE_CORAL_WALL_FAN, + FISHING_ROD, + FLETCHING_TABLE(0, 14), + FLINT, + FLINT_AND_STEEL, + FLOWER_BANNER_PATTERN, + FLOWER_POT("FLOWER_POT", "FLOWER_POT_ITEM"), + FOX_SPAWN_EGG(14), + /** + * This special material cannot be obtained as an item. + */ + FROSTED_ICE(0, 9), + FURNACE("BURNING_FURNACE"), + FURNACE_MINECART("POWERED_MINECART"), + GHAST_SPAWN_EGG(56, "MONSTER_EGG"), + GHAST_TEAR, + GILDED_BLACKSTONE(16), + GLASS, + GLASS_BOTTLE, + GLASS_PANE("THIN_GLASS"), + GLISTERING_MELON_SLICE("SPECKLED_MELON"), + GLOBE_BANNER_PATTERN, + GLOWSTONE, + GLOWSTONE_DUST, + GOLDEN_APPLE, + GOLDEN_AXE("GOLD_AXE"), + GOLDEN_BOOTS("GOLD_BOOTS"), + GOLDEN_CARROT, + GOLDEN_CHESTPLATE("GOLD_CHESTPLATE"), + GOLDEN_HELMET("GOLD_HELMET"), + GOLDEN_HOE("GOLD_HOE"), + GOLDEN_HORSE_ARMOR("GOLD_BARDING"), + GOLDEN_LEGGINGS("GOLD_LEGGINGS"), + GOLDEN_PICKAXE("GOLD_PICKAXE"), + GOLDEN_SHOVEL("GOLD_SPADE"), + GOLDEN_SWORD("GOLD_SWORD"), + GOLD_BLOCK, + GOLD_INGOT, + GOLD_NUGGET, + GOLD_ORE, + GRANITE(1, "STONE"), + GRANITE_SLAB, + GRANITE_STAIRS, + GRANITE_WALL, + GRASS(1, "LONG_GRASS"), + GRASS_BLOCK("GRASS"), + GRASS_PATH, + GRAVEL, + GRAY_BANNER(8, "STANDING_BANNER", "BANNER"), + GRAY_BED(7, "BED_BLOCK", "BED"), + GRAY_CARPET(7, "CARPET"), + GRAY_CONCRETE(7, "CONCRETE"), + GRAY_CONCRETE_POWDER(7, "CONCRETE_POWDER"), + GRAY_DYE(8, "INK_SACK"), + GRAY_GLAZED_TERRACOTTA(7, 12), + GRAY_SHULKER_BOX, + GRAY_STAINED_GLASS(7, "STAINED_GLASS"), + GRAY_STAINED_GLASS_PANE(7, "THIN_GLASS", "STAINED_GLASS_PANE"), + GRAY_TERRACOTTA(7, "STAINED_CLAY"), + GRAY_WALL_BANNER(8, "WALL_BANNER"), + GRAY_WOOL(7, "WOOL"), + GREEN_BANNER(2, "STANDING_BANNER", "BANNER"), + GREEN_BED(13, "BED_BLOCK", "BED"), + GREEN_CARPET(13, "CARPET"), + GREEN_CONCRETE(13, "CONCRETE"), + GREEN_CONCRETE_POWDER(13, "CONCRETE_POWDER"), + GREEN_DYE(2, "INK_SACK", "CACTUS_GREEN"), + GREEN_GLAZED_TERRACOTTA(13, 12), + GREEN_SHULKER_BOX, + GREEN_STAINED_GLASS(13, "STAINED_GLASS"), + GREEN_STAINED_GLASS_PANE(13, "THIN_GLASS", "STAINED_GLASS_PANE"), + GREEN_TERRACOTTA(13, "STAINED_CLAY"), + GREEN_WALL_BANNER(2, "WALL_BANNER"), + GREEN_WOOL(13, "WOOL"), + GRINDSTONE(0, 14), + GUARDIAN_SPAWN_EGG(68, "MONSTER_EGG"), + GUNPOWDER("SULPHUR"), + HAY_BLOCK, + HEART_OF_THE_SEA(13), + HEAVY_WEIGHTED_PRESSURE_PLATE("IRON_PLATE"), + HOGLIN_SPAWN_EGG(0, 16, "MONSTER_EGG"), + HONEYCOMB(15), + HONEYCOMB_BLOCK(15), + HONEY_BLOCK(0, 15), + HONEY_BOTTLE(0, 15), + HOPPER, + HOPPER_MINECART, + HORN_CORAL(13), + HORN_CORAL_BLOCK(13), + HORN_CORAL_FAN(13), + HORN_CORAL_WALL_FAN, + HORSE_SPAWN_EGG(100, "MONSTER_EGG"), + HUSK_SPAWN_EGG(23, "MONSTER_EGG"), + ICE, + INFESTED_CHISELED_STONE_BRICKS(5, "MONSTER_EGGS"), + INFESTED_COBBLESTONE(1, "MONSTER_EGGS"), + INFESTED_CRACKED_STONE_BRICKS(4, "MONSTER_EGGS"), + INFESTED_MOSSY_STONE_BRICKS(3, "MONSTER_EGGS"), + INFESTED_STONE("MONSTER_EGGS"), + INFESTED_STONE_BRICKS(2, "MONSTER_EGGS"), + /** + * We will only add "INK_SAC" for {@link #BLACK_DYE} since it's + * the only material (linked with this material) that is added + * after 1.13, which means it can use both INK_SACK and INK_SAC. + */ + INK_SAC("INK_SACK"), + IRON_AXE, + IRON_BARS("IRON_FENCE"), + IRON_BLOCK, + IRON_BOOTS, + IRON_CHESTPLATE, + IRON_DOOR("IRON_DOOR_BLOCK"), + IRON_HELMET, + IRON_HOE, + IRON_HORSE_ARMOR("IRON_BARDING"), + IRON_INGOT, + IRON_LEGGINGS, + IRON_NUGGET, + IRON_ORE, + IRON_PICKAXE, + IRON_SHOVEL("IRON_SPADE"), + IRON_SWORD, + IRON_TRAPDOOR, + ITEM_FRAME, + JACK_O_LANTERN, + JIGSAW(0, 14), + JUKEBOX, + JUNGLE_BOAT("BOAT_JUNGLE"), + JUNGLE_BUTTON("WOOD_BUTTON"), + JUNGLE_DOOR("JUNGLE_DOOR", "JUNGLE_DOOR_ITEM"), + JUNGLE_FENCE, + JUNGLE_FENCE_GATE, + JUNGLE_LEAVES(3, "LEAVES"), + JUNGLE_LOG(3, "LOG"), + JUNGLE_PLANKS(3, "WOOD"), + JUNGLE_PRESSURE_PLATE("WOOD_PLATE"), + JUNGLE_SAPLING(3, "SAPLING"), + JUNGLE_SIGN("SIGN_POST", "SIGN"), + JUNGLE_SLAB(3, "WOOD_DOUBLE_STEP", "WOOD_STEP", "WOODEN_SLAB"), + JUNGLE_STAIRS("JUNGLE_WOOD_STAIRS"), + JUNGLE_TRAPDOOR("TRAP_DOOR"), + JUNGLE_WALL_SIGN("WALL_SIGN"), + JUNGLE_WOOD(3, "LOG"), + KELP(13), + KELP_PLANT(13), + KNOWLEDGE_BOOK(0, 12, "BOOK"), + LADDER, + LANTERN(0, 14), + LAPIS_BLOCK, + LAPIS_LAZULI(4, "INK_SACK"), + LAPIS_ORE, + LARGE_FERN(3, "DOUBLE_PLANT"), + LAVA("STATIONARY_LAVA"), + LAVA_BUCKET, + LEAD("LEASH"), + LEATHER, + LEATHER_BOOTS, + LEATHER_CHESTPLATE, + LEATHER_HELMET, + LEATHER_HORSE_ARMOR(0, 14, "IRON_HORSE_ARMOR"), + LEATHER_LEGGINGS, + LECTERN(0, 14), + LEVER, + LIGHT_BLUE_BANNER(12, "STANDING_BANNER", "BANNER"), + LIGHT_BLUE_BED(3, "BED_BLOCK", "BED"), + LIGHT_BLUE_CARPET(3, "CARPET"), + LIGHT_BLUE_CONCRETE(3, "CONCRETE"), + LIGHT_BLUE_CONCRETE_POWDER(3, "CONCRETE_POWDER"), + LIGHT_BLUE_DYE(12, "INK_SACK"), + LIGHT_BLUE_GLAZED_TERRACOTTA(3, 12), + LIGHT_BLUE_SHULKER_BOX, + LIGHT_BLUE_STAINED_GLASS(3, "STAINED_GLASS"), + LIGHT_BLUE_STAINED_GLASS_PANE(3, "THIN_GLASS", "STAINED_GLASS_PANE"), + LIGHT_BLUE_TERRACOTTA(3, "STAINED_CLAY"), + LIGHT_BLUE_WALL_BANNER(12, "WALL_BANNER", "STANDING_BANNER", "BANNER"), + LIGHT_BLUE_WOOL(3, "WOOL"), + LIGHT_GRAY_BANNER(7, "STANDING_BANNER", "BANNER"), + LIGHT_GRAY_BED(8, "BED_BLOCK", "BED"), + LIGHT_GRAY_CARPET(8, "CARPET"), + LIGHT_GRAY_CONCRETE(8, "CONCRETE"), + LIGHT_GRAY_CONCRETE_POWDER(8, "CONCRETE_POWDER"), + LIGHT_GRAY_DYE(7, "INK_SACK"), + /** + * Renamed to SILVER_GLAZED_TERRACOTTA in 1.12 + * Renamed to LIGHT_GRAY_GLAZED_TERRACOTTA in 1.14 + */ + LIGHT_GRAY_GLAZED_TERRACOTTA(0, 12, "STAINED_CLAY", "LIGHT_GRAY_TERRACOTTA", "SILVER_GLAZED_TERRACOTTA"), + LIGHT_GRAY_SHULKER_BOX("SILVER_SHULKER_BOX"), + LIGHT_GRAY_STAINED_GLASS(8, "STAINED_GLASS"), + LIGHT_GRAY_STAINED_GLASS_PANE(8, "THIN_GLASS", "STAINED_GLASS_PANE"), + LIGHT_GRAY_TERRACOTTA(8, "STAINED_CLAY"), + LIGHT_GRAY_WALL_BANNER(7, "WALL_BANNER"), + LIGHT_GRAY_WOOL(8, "WOOL"), + LIGHT_WEIGHTED_PRESSURE_PLATE("GOLD_PLATE"), + LILAC(1, "DOUBLE_PLANT"), + LILY_OF_THE_VALLEY(15, 14), + LILY_PAD("WATER_LILY"), + LIME_BANNER(10, "STANDING_BANNER", "BANNER"), + LIME_BED(5, "BED_BLOCK", "BED"), + LIME_CARPET(5, "CARPET"), + LIME_CONCRETE(5, "CONCRETE"), + LIME_CONCRETE_POWDER(5, "CONCRETE_POWDER"), + LIME_DYE(10, "INK_SACK"), + LIME_GLAZED_TERRACOTTA(5, 12), + LIME_SHULKER_BOX, + LIME_STAINED_GLASS(5, "STAINED_GLASS"), + LIME_STAINED_GLASS_PANE(5, "STAINED_GLASS_PANE"), + LIME_TERRACOTTA(5, "STAINED_CLAY"), + LIME_WALL_BANNER(10, "WALL_BANNER"), + LIME_WOOL(5, "WOOL"), + LINGERING_POTION, + LLAMA_SPAWN_EGG(103, "MONSTER_EGG"), + LODESTONE(16), + LOOM(14), + MAGENTA_BANNER(13, "STANDING_BANNER", "BANNER"), + MAGENTA_BED(2, "BED_BLOCK", "BED"), + MAGENTA_CARPET(2, "CARPET"), + MAGENTA_CONCRETE(2, "CONCRETE"), + MAGENTA_CONCRETE_POWDER(2, "CONCRETE_POWDER"), + MAGENTA_DYE(13, "INK_SACK"), + MAGENTA_GLAZED_TERRACOTTA(2, 12), + MAGENTA_SHULKER_BOX, + MAGENTA_STAINED_GLASS(2, "STAINED_GLASS"), + MAGENTA_STAINED_GLASS_PANE(2, "THIN_GLASS", "STAINED_GLASS_PANE"), + MAGENTA_TERRACOTTA(2, "STAINED_CLAY"), + MAGENTA_WALL_BANNER(13, "WALL_BANNER"), + MAGENTA_WOOL(2, "WOOL"), + MAGMA_BLOCK(0, 10, "MAGMA"), + MAGMA_CREAM, + MAGMA_CUBE_SPAWN_EGG(62, "MONSTER_EGG"), + /** + * Adding this to the duplicated list will give you a filled map + * for 1.13+ versions and removing it from duplicated list will + * still give you a filled map in -1.12 versions. + * Since higher versions are our priority I'll keep 1.13+ support + * until I can come up with something to fix it. + */ + MAP("EMPTY_MAP"), + MELON("MELON_BLOCK"), + MELON_SEEDS, + MELON_SLICE("MELON"), + MELON_STEM, + MILK_BUCKET, + MINECART, + MOJANG_BANNER_PATTERN, + MOOSHROOM_SPAWN_EGG(96, "MONSTER_EGG"), + MOSSY_COBBLESTONE, + MOSSY_COBBLESTONE_SLAB(3, "STEP"), + MOSSY_COBBLESTONE_STAIRS, + MOSSY_COBBLESTONE_WALL(1, "COBBLE_WALL", "COBBLESTONE_WALL"), + MOSSY_STONE_BRICKS(1, "SMOOTH_BRICK"), + MOSSY_STONE_BRICK_SLAB(5, "STEP"), + MOSSY_STONE_BRICK_STAIRS("SMOOTH_STAIRS"), + MOSSY_STONE_BRICK_WALL, + MOVING_PISTON("PISTON_MOVING_PIECE"), + MULE_SPAWN_EGG(32, "MONSTER_EGG"), + MUSHROOM_STEM("BROWN_MUSHROOM"), + MUSHROOM_STEW("MUSHROOM_SOUP"), + MUSIC_DISC_11("GOLD_RECORD"), + MUSIC_DISC_13("GREEN_RECORD"), + MUSIC_DISC_BLOCKS("RECORD_3"), + MUSIC_DISC_CAT("RECORD_4"), + MUSIC_DISC_CHIRP("RECORD_5"), + MUSIC_DISC_FAR("RECORD_6"), + MUSIC_DISC_MALL("RECORD_7"), + MUSIC_DISC_MELLOHI("RECORD_8"), + MUSIC_DISC_PIGSTEP(16), + MUSIC_DISC_STAL("RECORD_9"), + MUSIC_DISC_STRAD("RECORD_10"), + MUSIC_DISC_WAIT("RECORD_11"), + MUSIC_DISC_WARD("RECORD_12"), + MUTTON, + MYCELIUM("MYCEL"), + NAME_TAG, + NAUTILUS_SHELL(13), + NETHERITE_AXE(16), + NETHERITE_BLOCK(16), + NETHERITE_BOOTS(16), + NETHERITE_CHESTPLATE(16), + NETHERITE_HELMET(16), + NETHERITE_HOE(16), + NETHERITE_INGOT(16), + NETHERITE_LEGGINGS(16), + NETHERITE_PICKAXE(16), + NETHERITE_SCRAP(16), + NETHERITE_SHOVEL(16), + NETHERITE_SWORD(16), + NETHERRACK, + NETHER_BRICK("NETHER_BRICK_ITEM"), + NETHER_BRICKS("NETHER_BRICK"), + NETHER_BRICK_FENCE("NETHER_FENCE"), + NETHER_BRICK_SLAB(6, "STEP"), + NETHER_BRICK_STAIRS, + NETHER_BRICK_WALL, + NETHER_GOLD_ORE(16), + NETHER_PORTAL("PORTAL"), + NETHER_QUARTZ_ORE("QUARTZ_ORE"), + NETHER_SPROUTS(16), + NETHER_STAR, + /** + * Just like mentioned in https://minecraft.gamepedia.com/Nether_Wart + * Nether wart is also known as nether stalk in the code. + * NETHER_STALK is the planted state of nether warts. + */ + NETHER_WART("NETHER_WARTS", "NETHER_STALK"), + NETHER_WART_BLOCK, + NOTE_BLOCK, + OAK_BOAT("BOAT"), + OAK_BUTTON("WOOD_BUTTON"), + OAK_DOOR("WOODEN_DOOR", "WOOD_DOOR"), + OAK_FENCE("FENCE"), + OAK_FENCE_GATE("FENCE_GATE"), + OAK_LEAVES("LEAVES"), + OAK_LOG("LOG"), + OAK_PLANKS("WOOD"), + OAK_PRESSURE_PLATE("WOOD_PLATE"), + OAK_SAPLING("SAPLING"), + OAK_SIGN("SIGN_POST", "SIGN"), + OAK_SLAB("WOOD_DOUBLE_STEP", "WOOD_STEP", "WOODEN_SLAB"), + OAK_STAIRS("WOOD_STAIRS"), + OAK_TRAPDOOR("TRAP_DOOR"), + OAK_WALL_SIGN("WALL_SIGN"), + OAK_WOOD("LOG"), + OBSERVER, + OBSIDIAN, + OCELOT_SPAWN_EGG(98, "MONSTER_EGG"), + ORANGE_BANNER(14, "STANDING_BANNER", "BANNER"), + ORANGE_BED(1, "BED_BLOCK", "BED"), + ORANGE_CARPET(1, "CARPET"), + ORANGE_CONCRETE(1, "CONCRETE"), + ORANGE_CONCRETE_POWDER(1, "CONCRETE_POWDER"), + ORANGE_DYE(14, "INK_SACK"), + ORANGE_GLAZED_TERRACOTTA(1, 12), + ORANGE_SHULKER_BOX, + ORANGE_STAINED_GLASS(1, "STAINED_GLASS"), + ORANGE_STAINED_GLASS_PANE(1, "STAINED_GLASS_PANE"), + ORANGE_TERRACOTTA(1, "STAINED_CLAY"), + ORANGE_TULIP(5, "RED_ROSE"), + ORANGE_WALL_BANNER(14, "WALL_BANNER"), + ORANGE_WOOL(1, "WOOL"), + OXEYE_DAISY(8, "RED_ROSE"), + PACKED_ICE, + PAINTING, + PANDA_SPAWN_EGG(14), + PAPER, + PARROT_SPAWN_EGG(105, "MONSTER_EGG"), + PEONY(5, "DOUBLE_PLANT"), + PETRIFIED_OAK_SLAB("WOOD_STEP"), + PHANTOM_MEMBRANE(13), + PHANTOM_SPAWN_EGG(0, 13), + PIGLIN_BANNER_PATTERN(16), + PIGLIN_BRUTE_SPAWN_EGG(16), + PIGLIN_SPAWN_EGG(57, "MONSTER_EGG"), + PIG_SPAWN_EGG(90, "MONSTER_EGG"), + PILLAGER_SPAWN_EGG(14), + PINK_BANNER(9, "STANDING_BANNER", "BANNER"), + PINK_BED(6, "BED_BLOCK", "BED"), + PINK_CARPET(6, "CARPET"), + PINK_CONCRETE(6, "CONCRETE"), + PINK_CONCRETE_POWDER(6, "CONCRETE_POWDER"), + PINK_DYE(9, "INK_SACK"), + PINK_GLAZED_TERRACOTTA(6, 12), + PINK_SHULKER_BOX, + PINK_STAINED_GLASS(6, "STAINED_GLASS"), + PINK_STAINED_GLASS_PANE(6, "THIN_GLASS", "STAINED_GLASS_PANE"), + PINK_TERRACOTTA(6, "STAINED_CLAY"), + PINK_TULIP(7, "RED_ROSE"), + PINK_WALL_BANNER(9, "WALL_BANNER"), + PINK_WOOL(6, "WOOL"), + PISTON("PISTON_BASE"), + PISTON_HEAD("PISTON_EXTENSION"), + PLAYER_HEAD(3, "SKULL", "SKULL_ITEM"), + PLAYER_WALL_HEAD(3, "SKULL", "SKULL_ITEM"), + PODZOL(2, "DIRT"), + POISONOUS_POTATO, + POLAR_BEAR_SPAWN_EGG(102, "MONSTER_EGG"), + POLISHED_ANDESITE(6, "STONE"), + POLISHED_ANDESITE_SLAB, + POLISHED_ANDESITE_STAIRS, + POLISHED_BASALT(16), + POLISHED_BLACKSTONE(16), + POLISHED_BLACKSTONE_BRICKS(16), + POLISHED_BLACKSTONE_BRICK_SLAB(16), + POLISHED_BLACKSTONE_BRICK_STAIRS(16), + POLISHED_BLACKSTONE_BRICK_WALL(16), + POLISHED_BLACKSTONE_BUTTON(16), + POLISHED_BLACKSTONE_PRESSURE_PLATE(16), + POLISHED_BLACKSTONE_SLAB(16), + POLISHED_BLACKSTONE_STAIRS(16), + POLISHED_BLACKSTONE_WALL(16), + POLISHED_DIORITE(4, "STONE"), + POLISHED_DIORITE_SLAB, + POLISHED_DIORITE_STAIRS, + POLISHED_GRANITE(2, "STONE"), + POLISHED_GRANITE_SLAB, + POLISHED_GRANITE_STAIRS, + POPPED_CHORUS_FRUIT("CHORUS_FRUIT_POPPED"), + POPPY("RED_ROSE"), + PORKCHOP("PORK"), + POTATO("POTATO_ITEM"), + POTATOES("POTATO"), + POTION, + POTTED_ACACIA_SAPLING(4, "SAPLING", "FLOWER_POT"), + POTTED_ALLIUM(2, "RED_ROSE", "FLOWER_POT"), + POTTED_AZURE_BLUET(3, "RED_ROSE", "FLOWER_POT"), + POTTED_BAMBOO, + POTTED_BIRCH_SAPLING(2, "SAPLING", "FLOWER_POT"), + POTTED_BLUE_ORCHID(1, "RED_ROSE", "FLOWER_POT"), + POTTED_BROWN_MUSHROOM("FLOWER_POT"), + POTTED_CACTUS("FLOWER_POT"), + POTTED_CORNFLOWER, + POTTED_CRIMSON_FUNGUS(16), + POTTED_CRIMSON_ROOTS(16), + POTTED_DANDELION("YELLOW_FLOWER", "FLOWER_POT"), + POTTED_DARK_OAK_SAPLING(5, "SAPLING", "FLOWER_POT"), + POTTED_DEAD_BUSH("FLOWER_POT"), + POTTED_FERN(2, "LONG_GRASS", "FLOWER_POT"), + POTTED_JUNGLE_SAPLING(3, "SAPLING", "FLOWER_POT"), + POTTED_LILY_OF_THE_VALLEY, + POTTED_OAK_SAPLING("SAPLING", "FLOWER_POT"), + POTTED_ORANGE_TULIP(5, "RED_ROSE", "FLOWER_POT"), + POTTED_OXEYE_DAISY(8, "RED_ROSE", "FLOWER_POT"), + POTTED_PINK_TULIP(7, "RED_ROSE", "FLOWER_POT"), + POTTED_POPPY("RED_ROSE", "FLOWER_POT"), + POTTED_RED_MUSHROOM("FLOWER_POT"), + POTTED_RED_TULIP(4, "RED_ROSE", "FLOWER_POT"), + POTTED_SPRUCE_SAPLING(1, "SAPLING", "FLOWER_POT"), + POTTED_WARPED_FUNGUS(16), + POTTED_WARPED_ROOTS(16), + POTTED_WHITE_TULIP(6, "RED_ROSE", "FLOWER_POT"), + POTTED_WITHER_ROSE, + POWERED_RAIL, + PRISMARINE, + PRISMARINE_BRICKS(2, "PRISMARINE"), + PRISMARINE_BRICK_SLAB(4, "STEP"), + PRISMARINE_BRICK_STAIRS(13), + PRISMARINE_CRYSTALS, + PRISMARINE_SHARD, + PRISMARINE_SLAB(13), + PRISMARINE_STAIRS(13), + PRISMARINE_WALL, + PUFFERFISH(3, "RAW_FISH"), + PUFFERFISH_BUCKET(0, 13), + PUFFERFISH_SPAWN_EGG(0, 13), + PUMPKIN, + PUMPKIN_PIE, + PUMPKIN_SEEDS, + PUMPKIN_STEM, + PURPLE_BANNER(5, "STANDING_BANNER", "BANNER"), + PURPLE_BED(10, "BED_BLOCK", "BED"), + PURPLE_CARPET(10, "CARPET"), + PURPLE_CONCRETE(10, "CONCRETE"), + PURPLE_CONCRETE_POWDER(10, "CONCRETE_POWDER"), + PURPLE_DYE(5, "INK_SACK"), + PURPLE_GLAZED_TERRACOTTA(10, 12), + PURPLE_SHULKER_BOX, + PURPLE_STAINED_GLASS(10, "STAINED_GLASS"), + PURPLE_STAINED_GLASS_PANE(10, "THIN_GLASS", "STAINED_GLASS_PANE"), + PURPLE_TERRACOTTA(10, "STAINED_CLAY"), + PURPLE_WALL_BANNER(5, "WALL_BANNER"), + PURPLE_WOOL(10, "WOOL"), + PURPUR_BLOCK, + PURPUR_PILLAR, + PURPUR_SLAB("PURPUR_DOUBLE_SLAB"), + PURPUR_STAIRS, + QUARTZ, + QUARTZ_BLOCK, + QUARTZ_BRICKS(16), + QUARTZ_PILLAR(2, "QUARTZ_BLOCK"), + QUARTZ_SLAB(7, "STEP"), + QUARTZ_STAIRS, + RABBIT, + RABBIT_FOOT, + RABBIT_HIDE, + RABBIT_SPAWN_EGG(101, "MONSTER_EGG"), + RABBIT_STEW, + RAIL("RAILS"), + RAVAGER_SPAWN_EGG(14), + REDSTONE, + REDSTONE_BLOCK, + /** + * Unlike redstone torch, REDSTONE_LAMP_ON isn't an item. + * The name is just here on the list for matching. + * + * @see #REDSTONE_TORCH + */ + REDSTONE_LAMP("REDSTONE_LAMP_ON", "REDSTONE_LAMP_OFF"), + REDSTONE_ORE("GLOWING_REDSTONE_ORE"), + /** + * REDSTONE_TORCH_OFF isn't an item, but a block. + * But REDSTONE_TORCH_ON is the item. + * The name is just here on the list for matching. + */ + REDSTONE_TORCH("REDSTONE_TORCH_OFF", "REDSTONE_TORCH_ON"), + REDSTONE_WALL_TORCH, + REDSTONE_WIRE, + RED_BANNER(1, "STANDING_BANNER", "BANNER"), + /** + * Data value 14 or 0 + */ + RED_BED(14, "BED_BLOCK", "BED"), + RED_CARPET(14, "CARPET"), + RED_CONCRETE(14, "CONCRETE"), + RED_CONCRETE_POWDER(14, "CONCRETE_POWDER"), + RED_DYE(1, "INK_SACK", "ROSE_RED"), + RED_GLAZED_TERRACOTTA(14, 12), + RED_MUSHROOM, + RED_MUSHROOM_BLOCK("RED_MUSHROOM", "HUGE_MUSHROOM_2"), + RED_NETHER_BRICKS("RED_NETHER_BRICK"), + RED_NETHER_BRICK_SLAB(4, "STEP"), + RED_NETHER_BRICK_STAIRS, + RED_NETHER_BRICK_WALL, + RED_SAND(1, "SAND"), + RED_SANDSTONE, + RED_SANDSTONE_SLAB("DOUBLE_STONE_SLAB2", "STONE_SLAB2"), + RED_SANDSTONE_STAIRS, + RED_SANDSTONE_WALL, + RED_SHULKER_BOX, + RED_STAINED_GLASS(14, "STAINED_GLASS"), + RED_STAINED_GLASS_PANE(14, "THIN_GLASS", "STAINED_GLASS_PANE"), + RED_TERRACOTTA(14, "STAINED_CLAY"), + RED_TULIP(4, "RED_ROSE"), + RED_WALL_BANNER(1, "WALL_BANNER"), + RED_WOOL(14, "WOOL"), + REPEATER("DIODE_BLOCK_ON", "DIODE_BLOCK_OFF", "DIODE"), + REPEATING_COMMAND_BLOCK("COMMAND", "COMMAND_REPEATING"), + RESPAWN_ANCHOR(16), + ROSE_BUSH(4, "DOUBLE_PLANT"), + ROTTEN_FLESH, + SADDLE, + SALMON(1, "RAW_FISH"), + SALMON_BUCKET(0, 13), + SALMON_SPAWN_EGG(0, 13), + SAND, + SANDSTONE, + SANDSTONE_SLAB(1, "DOUBLE_STEP", "STEP", "STONE_SLAB"), + SANDSTONE_STAIRS, + SANDSTONE_WALL, + SCAFFOLDING(0, 14), + SCUTE(13), + SEAGRASS(0, 13), + SEA_LANTERN, + SEA_PICKLE(13), + SHEARS, + SHEEP_SPAWN_EGG(91, "MONSTER_EGG"), + SHIELD, + SHROOMLIGHT(16), + SHULKER_BOX("PURPLE_SHULKER_BOX"), + SHULKER_SHELL, + SHULKER_SPAWN_EGG(69, "MONSTER_EGG"), + SILVERFISH_SPAWN_EGG(60, "MONSTER_EGG"), + SKELETON_HORSE_SPAWN_EGG(28, "MONSTER_EGG"), + SKELETON_SKULL("SKULL", "SKULL_ITEM"), + SKELETON_SPAWN_EGG(51, "MONSTER_EGG"), + SKELETON_WALL_SKULL("SKULL", "SKULL_ITEM"), + SKULL_BANNER_PATTERN, + SLIME_BALL, + SLIME_BLOCK, + SLIME_SPAWN_EGG(55, "MONSTER_EGG"), + SMITHING_TABLE, + SMOKER(0, 14), + SMOOTH_QUARTZ(0, 13), + SMOOTH_QUARTZ_SLAB(7, "STEP"), + SMOOTH_QUARTZ_STAIRS, + SMOOTH_RED_SANDSTONE(2, "RED_SANDSTONE"), + SMOOTH_RED_SANDSTONE_SLAB("STONE_SLAB2"), + SMOOTH_RED_SANDSTONE_STAIRS, + SMOOTH_SANDSTONE(2, "SANDSTONE"), + SMOOTH_SANDSTONE_SLAB("STEP"), + SMOOTH_SANDSTONE_STAIRS, + SMOOTH_STONE("STEP"), + SMOOTH_STONE_SLAB("STEP"), + SNOW, + SNOWBALL("SNOW_BALL"), + SNOW_BLOCK, + SOUL_CAMPFIRE(16), + SOUL_FIRE(16), + SOUL_LANTERN(16), + SOUL_SAND, + SOUL_SOIL(16), + SOUL_TORCH(16), + SOUL_WALL_TORCH(16), + SPAWNER("MOB_SPAWNER"), + SPECTRAL_ARROW(0, 9), + SPIDER_EYE, + SPIDER_SPAWN_EGG(52, "MONSTER_EGG"), + SPLASH_POTION, + SPONGE, + SPRUCE_BOAT("BOAT_SPRUCE"), + SPRUCE_BUTTON("WOOD_BUTTON"), + SPRUCE_DOOR("SPRUCE_DOOR", "SPRUCE_DOOR_ITEM"), + SPRUCE_FENCE, + SPRUCE_FENCE_GATE, + SPRUCE_LEAVES(1, "LEAVES", "LEAVES_2"), + SPRUCE_LOG(1, "LOG"), + SPRUCE_PLANKS(1, "WOOD"), + SPRUCE_PRESSURE_PLATE("WOOD_PLATE"), + SPRUCE_SAPLING(1, "SAPLING"), + SPRUCE_SIGN("SIGN_POST", "SIGN"), + SPRUCE_SLAB(1, "WOOD_DOUBLE_STEP", "WOOD_STEP", "WOODEN_SLAB"), + SPRUCE_STAIRS("SPRUCE_WOOD_STAIRS"), + SPRUCE_TRAPDOOR("TRAP_DOOR"), + SPRUCE_WALL_SIGN("WALL_SIGN"), + SPRUCE_WOOD(1, "LOG"), + SQUID_SPAWN_EGG(94, "MONSTER_EGG"), + STICK, + STICKY_PISTON("PISTON_BASE", "PISTON_STICKY_BASE"), + STONE, + STONECUTTER(14), + STONE_AXE, + STONE_BRICKS("SMOOTH_BRICK"), + STONE_BRICK_SLAB(4, "DOUBLE_STEP", "STEP", "STONE_SLAB"), + STONE_BRICK_STAIRS("SMOOTH_STAIRS"), + STONE_BRICK_WALL, + STONE_BUTTON, + STONE_HOE, + STONE_PICKAXE, + STONE_PRESSURE_PLATE("STONE_PLATE"), + STONE_SHOVEL("STONE_SPADE"), + STONE_SLAB("DOUBLE_STEP", "STEP"), + STONE_STAIRS, + STONE_SWORD, + STRAY_SPAWN_EGG(6, "MONSTER_EGG"), + STRIDER_SPAWN_EGG(16), + STRING, + STRIPPED_ACACIA_LOG("LOG_2"), + STRIPPED_ACACIA_WOOD("LOG_2"), + STRIPPED_BIRCH_LOG(2, "LOG"), + STRIPPED_BIRCH_WOOD(2, "LOG"), + STRIPPED_CRIMSON_HYPHAE(16), + STRIPPED_CRIMSON_STEM(16), + STRIPPED_DARK_OAK_LOG("LOG"), + STRIPPED_DARK_OAK_WOOD("LOG"), + STRIPPED_JUNGLE_LOG(3, "LOG"), + STRIPPED_JUNGLE_WOOD(3, "LOG"), + STRIPPED_OAK_LOG("LOG"), + STRIPPED_OAK_WOOD("LOG"), + STRIPPED_SPRUCE_LOG(1, "LOG"), + STRIPPED_SPRUCE_WOOD(1, "LOG"), + STRIPPED_WARPED_HYPHAE(16), + STRIPPED_WARPED_STEM(16), + STRUCTURE_BLOCK, + /** + * Originally developers used barrier blocks for its purpose. + * So technically this isn't really considered as a suggested material. + */ + STRUCTURE_VOID(10, "BARRIER"), + SUGAR, + /** + * Sugar Cane is a known material in pre-1.13 + */ + SUGAR_CANE("SUGAR_CANE_BLOCK"), + SUNFLOWER("DOUBLE_PLANT"), + SUSPICIOUS_STEW(0, 14), + SWEET_BERRIES(14), + SWEET_BERRY_BUSH(0, 14), + TALL_GRASS(2, "DOUBLE_PLANT"), + TALL_SEAGRASS(2, 13), + TARGET(16), + TERRACOTTA("STAINED_CLAY"), + TIPPED_ARROW(0, 9), + TNT, + TNT_MINECART("EXPLOSIVE_MINECART"), + TORCH, + TOTEM_OF_UNDYING("TOTEM"), + TRADER_LLAMA_SPAWN_EGG(103, 14), + TRAPPED_CHEST, + TRIDENT(13), + TRIPWIRE, + TRIPWIRE_HOOK, + TROPICAL_FISH(2, "RAW_FISH"), + TROPICAL_FISH_BUCKET(0, 13, "BUCKET", "WATER_BUCKET"), + TROPICAL_FISH_SPAWN_EGG(0, 13, "MONSTER_EGG"), + TUBE_CORAL(13), + TUBE_CORAL_BLOCK(13), + TUBE_CORAL_FAN(13), + TUBE_CORAL_WALL_FAN, + TURTLE_EGG(0, 13), + TURTLE_HELMET(0, 13), + TURTLE_SPAWN_EGG(0, 13), + TWISTING_VINES(16), + TWISTING_VINES_PLANT(16), + VEX_SPAWN_EGG(35, "MONSTER_EGG"), + VILLAGER_SPAWN_EGG(120, "MONSTER_EGG"), + VINDICATOR_SPAWN_EGG(36, "MONSTER_EGG"), + VINE, + /** + * 1.13 tag is not added because it's the same thing as {@link #AIR} + * + * @see #CAVE_AIR + */ + VOID_AIR("AIR"), + WALL_TORCH("TORCH"), + WANDERING_TRADER_SPAWN_EGG(0, 14), + WARPED_BUTTON(16), + WARPED_DOOR(16), + WARPED_FENCE(16), + WARPED_FENCE_GATE(16), + WARPED_FUNGUS(16), + WARPED_FUNGUS_ON_A_STICK(16), + WARPED_HYPHAE(16), + WARPED_NYLIUM(16), + WARPED_PLANKS(16), + WARPED_PRESSURE_PLATE(16), + WARPED_ROOTS(16), + WARPED_SIGN(0, 16, "SIGN_POST"), + WARPED_SLAB(16), + WARPED_STAIRS(16), + WARPED_STEM(16), + WARPED_TRAPDOOR(16), + WARPED_WALL_SIGN(0, 16, "WALL_SIGN"), + WARPED_WART_BLOCK(16), + /** + * This is used for blocks only. + * In 1.13- WATER will turn into STATIONARY_WATER after it finished spreading. + * After 1.13+ this uses + * https://hub.spigotmc.org/javadocs/spigot/org/bukkit/block/data/Levelled.html water flowing system. + */ + WATER("STATIONARY_WATER"), + WATER_BUCKET, + WEEPING_VINES(16), + WEEPING_VINES_PLANT(16), + WET_SPONGE(1, "SPONGE"), + /** + * Wheat is a known material in pre-1.13 + */ + WHEAT("CROPS"), + WHEAT_SEEDS("SEEDS"), + WHITE_BANNER(15, "STANDING_BANNER", "BANNER"), + WHITE_BED("BED_BLOCK", "BED"), + WHITE_CARPET("CARPET"), + WHITE_CONCRETE("CONCRETE"), + WHITE_CONCRETE_POWDER("CONCRETE_POWDER"), + WHITE_DYE(15, 14, "INK_SACK", "BONE_MEAL"), + WHITE_GLAZED_TERRACOTTA(0, 12, "STAINED_CLAY"), + WHITE_SHULKER_BOX, + WHITE_STAINED_GLASS("STAINED_GLASS"), + WHITE_STAINED_GLASS_PANE("THIN_GLASS", "STAINED_GLASS_PANE"), + WHITE_TERRACOTTA("STAINED_CLAY", "TERRACOTTA"), + WHITE_TULIP(6, "RED_ROSE"), + WHITE_WALL_BANNER(15, "WALL_BANNER"), + WHITE_WOOL("WOOL"), + WITCH_SPAWN_EGG(66, "MONSTER_EGG"), + WITHER_ROSE(0, 14), + WITHER_SKELETON_SKULL(1, "SKULL", "SKULL_ITEM"), + WITHER_SKELETON_SPAWN_EGG(5, "MONSTER_EGG"), + WITHER_SKELETON_WALL_SKULL(1, "SKULL", "SKULL_ITEM"), + WOLF_SPAWN_EGG(95, "MONSTER_EGG"), + WOODEN_AXE("WOOD_AXE"), + WOODEN_HOE("WOOD_HOE"), + WOODEN_PICKAXE("WOOD_PICKAXE"), + WOODEN_SHOVEL("WOOD_SPADE"), + WOODEN_SWORD("WOOD_SWORD"), + WRITABLE_BOOK("BOOK_AND_QUILL"), + WRITTEN_BOOK, + YELLOW_BANNER(11, "STANDING_BANNER", "BANNER"), + YELLOW_BED(4, "BED_BLOCK", "BED"), + YELLOW_CARPET(4, "CARPET"), + YELLOW_CONCRETE(4, "CONCRETE"), + YELLOW_CONCRETE_POWDER(4, "CONCRETE_POWDER"), + YELLOW_DYE(11, "INK_SACK", "DANDELION_YELLOW"), + YELLOW_GLAZED_TERRACOTTA(4, 12, "STAINED_CLAY", "YELLOW_TERRACOTTA"), + YELLOW_SHULKER_BOX, + YELLOW_STAINED_GLASS(4, "STAINED_GLASS"), + YELLOW_STAINED_GLASS_PANE(4, "THIN_GLASS", "STAINED_GLASS_PANE"), + YELLOW_TERRACOTTA(4, "STAINED_CLAY"), + YELLOW_WALL_BANNER(11, "WALL_BANNER"), + YELLOW_WOOL(4, "WOOL"), + ZOGLIN_SPAWN_EGG(16), + ZOMBIE_HEAD(2, "SKULL", "SKULL_ITEM"), + ZOMBIE_HORSE_SPAWN_EGG(29, "MONSTER_EGG"), + ZOMBIE_SPAWN_EGG(54, "MONSTER_EGG"), + ZOMBIE_VILLAGER_SPAWN_EGG(27, "MONSTER_EGG"), + ZOMBIE_WALL_HEAD(2, "SKULL", "SKULL_ITEM"), + ZOMBIFIED_PIGLIN_SPAWN_EGG(57, "MONSTER_EGG", "ZOMBIE_PIGMAN_SPAWN_EGG"); + + + /** + * Cached array of {@link XMaterial#values()} to avoid allocating memory for + * calling the method every time. + * + * @since 2.0.0 + */ + public static final XMaterial[] VALUES = values(); + + /** + * We don't want to use {@link Enums#getIfPresent(Class, String)} to avoid a few checks. + * + * @since 5.1.0 + */ + private static final Map NAMES = new HashMap<>(); + + /** + * Guava (Google Core Libraries for Java)'s cache for performance and timed caches. + * For strings that match a certain XMaterial. Mostly cached for configs. + * + * @since 1.0.0 + */ + private static final Cache NAME_CACHE = CacheBuilder.newBuilder() + .expireAfterAccess(1, TimeUnit.HOURS) + .build(); + + /** + * This is used for {@link #isOneOf(Collection)} + * + * @since 3.4.0 + */ + private static final LoadingCache CACHED_REGEX = CacheBuilder.newBuilder() + .expireAfterAccess(3, TimeUnit.HOURS) + .build(new CacheLoader() { + @Override + public Pattern load(@Nonnull String str) { + try { + return Pattern.compile(str); + } catch (PatternSyntaxException ex) { + ex.printStackTrace(); + return null; + } + } + }); + /** + * The maximum data value in the pre-flattening update which belongs to {@link #VILLAGER_SPAWN_EGG}
+ * https://minecraftitemids.com/types/spawn-egg + * + * @see #matchXMaterialWithData(String) + * @since 8.0.0 + */ + private static final byte MAX_DATA_VALUE = 120; + /** + * Used to tell the system that the passed object's (name or material) data value + * is not provided or is invalid. + * + * @since 8.0.0 + */ + private static final byte UNKNOWN_DATA_VALUE = -1; + /** + * The maximum material ID before the pre-flattening update which belongs to {@link #MUSIC_DISC_WAIT} + * + * @since 8.1.0 + */ + private static final short MAX_ID = 2267; + /** + * XMaterial Paradox (Duplication Check) + *

+ * A set of duplicated material names in 1.13 and 1.12 that will conflict with the legacy names. + * Values are the new material names. This map also contains illegal elements. Check the static initializer for more info. + *

+ * Duplications are not useful at all in versions above the flattening update {@link Data#ISFLAT} + * This set is only used for matching materials, for parsing refer to {@link #isDuplicated()} + * + * @since 3.0.0 + */ + private static final Set DUPLICATED; + + static { + for (XMaterial material : VALUES) NAMES.put(material.name(), material); + } + + static { + if (Data.ISFLAT) { + // It's not needed at all if it's the newer version. We can save some memory. + DUPLICATED = null; + } else { + // MELON_SLICE, CARROTS, POTATOES, BEETROOTS, GRASS_BLOCK, BRICKS, NETHER_BRICKS, BROWN_MUSHROOM + // Using the constructor to add elements will decide to allocate more size which we don't need. + DUPLICATED = new HashSet<>(4); + DUPLICATED.add(GRASS.name()); + DUPLICATED.add(MELON.name()); + DUPLICATED.add(BRICK.name()); + DUPLICATED.add(NETHER_BRICK.name()); + } + } + + /** + * The data value of this material https://minecraft.gamepedia.com/Java_Edition_data_values/Pre-flattening + * It's never a negative number. + * + * @see #getData() + */ + private final byte data; + /** + * The version that this material was added in, otherwise 0 if the version is not recorded. + * + * @see #getMaterialVersion() + * @since 7.0.0 + */ + private final byte version; + /** + * A list of material names that was being used for older verions. + * + * @see #getLegacy() + */ + @Nonnull + private final String[] legacy; + /** + * The cached Bukkit parsed material. + * + * @see #parseMaterial() + * @since 9.0.0 + */ + @Nullable + private final Material material; + + XMaterial(int data, int version, @Nonnull String... legacy) { + this.data = (byte) data; + this.version = (byte) version; + this.legacy = legacy; + + Material mat = null; + if ((!Data.ISFLAT && this.isDuplicated()) || (mat = Material.getMaterial(this.name())) == null) { + for (int i = legacy.length - 1; i >= 0; i--) { + mat = Material.getMaterial(legacy[i]); + if (mat != null) break; + } + } + this.material = mat; + } + + XMaterial(int data, @Nonnull String... legacy) { + this(data, 0, legacy); + } + + XMaterial(int version) { + this(0, version); + } + + XMaterial() { + this(0, 0); + } + + XMaterial(String... legacy) { + this(0, 0, legacy); + } + + /** + * Checks if the version is 1.13 Aquatic Update or higher. + * An invocation of this method yields the cached result from the expression: + *

+ *

+ * {@link #supports(int) 13}} + *
+ * + * @return true if 1.13 or higher. + * @see #getVersion() + * @see #supports(int) + * @since 1.0.0 + */ + public static boolean isNewVersion() { + return Data.ISFLAT; + } + + /** + * This is just an extra method that can be used for many cases. + * It can be used in {@link org.bukkit.event.player.PlayerInteractEvent} + * or other compatibility related methods. + *

+ * An invocation of this method yields exactly the same result as the expression: + *

+ *

+ * !{@link #supports(int)} 9 + *
+ * + * @since 2.0.0 + */ + public static boolean isOneEight() { + return !supports(9); + } + + /** + * Gets the XMaterial with this name similar to {@link #valueOf(String)} + * without throwing an exception. + * + * @param name the name of the material. + * + * @return an optional that can be empty. + * @since 5.1.0 + */ + @Nonnull + private static Optional getIfPresent(@Nonnull String name) { + return Optional.ofNullable(NAMES.get(name)); + } + + /** + * The current version of the server. + * + * @return the current server version minor number. + * @see #isNewVersion() + * @since 2.0.0 + */ + public static int getVersion() { + return Data.VERSION; + } + + /** + * When using newer versions of Minecraft ({@link #isNewVersion()}), helps + * to find the old material name with its data value using a cached search for optimization. + * + * @see #matchDefinedXMaterial(String, byte) + * @since 1.0.0 + */ + @Nullable + private static XMaterial requestOldXMaterial(@Nonnull String name, byte data) { + String holder = name + data; + XMaterial cache = NAME_CACHE.getIfPresent(holder); + if (cache != null) return cache; + + for (XMaterial material : VALUES) { + // Not using material.name().equals(name) check is intended. + if ((data == UNKNOWN_DATA_VALUE || data == material.data) && material.anyMatchLegacy(name)) { + NAME_CACHE.put(holder, material); + return material; + } + } + + return null; + } + + /** + * Parses the given material name as an XMaterial with a given data + * value in the string if attached. Check {@link #matchXMaterialWithData(String)} for more info. + * + * @see #matchXMaterialWithData(String) + * @see #matchDefinedXMaterial(String, byte) + * @since 2.0.0 + */ + @Nonnull + public static Optional matchXMaterial(@Nonnull String name) { + Validate.notEmpty(name, "Cannot match a material with null or empty material name"); + Optional oldMatch = matchXMaterialWithData(name); + return oldMatch.isPresent() ? oldMatch : matchDefinedXMaterial(format(name), UNKNOWN_DATA_VALUE); + } + + /** + * Parses material name and data value from the specified string. + * The separator for the material name and its data value is {@code :} + * Spaces are allowed. Mostly used when getting materials from config for old school minecrafters. + *

+ * Examples + *

+     *     {@code INK_SACK:1 -> RED_DYE}
+     *     {@code WOOL: 14  -> RED_WOOL}
+     * 
+ * + * @param name the material string that consists of the material name, data and separator character. + * + * @return the parsed XMaterial. + * @see #matchXMaterial(String) + * @since 3.0.0 + */ + @Nonnull + private static Optional matchXMaterialWithData(@Nonnull String name) { + int index = name.indexOf(':'); + if (index != -1) { + String mat = format(name.substring(0, index)); + try { + // We don't use Byte.parseByte because we have our own range check. + byte data = (byte) Integer.parseInt(StringUtils.deleteWhitespace(name.substring(index + 1))); + return data >= 0 && data < MAX_DATA_VALUE ? matchDefinedXMaterial(mat, data) : matchDefinedXMaterial(mat, UNKNOWN_DATA_VALUE); + } catch (NumberFormatException ignored) { + return matchDefinedXMaterial(mat, UNKNOWN_DATA_VALUE); + } + } + + return Optional.empty(); + } + + /** + * Parses the given material as an XMaterial. + * + * @throws IllegalArgumentException may be thrown as an unexpected exception. + * @see #matchDefinedXMaterial(String, byte) + * @see #matchXMaterial(ItemStack) + * @since 2.0.0 + */ + @Nonnull + public static XMaterial matchXMaterial(@Nonnull Material material) { + Objects.requireNonNull(material, "Cannot match null material"); + return matchDefinedXMaterial(material.name(), UNKNOWN_DATA_VALUE) + .orElseThrow(() -> new IllegalArgumentException("Unsupported material with no data value: " + material.name())); + } + + /** + * Parses the given item as an XMaterial using its material and data value (durability) + * if not a damageable item {@link ItemStack#getDurability()}. + * + * @param item the ItemStack to match. + * + * @return an XMaterial if matched any. + * @throws IllegalArgumentException may be thrown as an unexpected exception. + * @see #matchXMaterial(Material) + * @since 2.0.0 + */ + @Nonnull + @SuppressWarnings("deprecation") + public static XMaterial matchXMaterial(@Nonnull ItemStack item) { + Objects.requireNonNull(item, "Cannot match null ItemStack"); + String material = item.getType().name(); + byte data = (byte) (Data.ISFLAT || item.getType().getMaxDurability() > 0 ? 0 : item.getDurability()); + + // Check FILLED_MAP enum for more info. + //if (!Data.ISFLAT && item.hasItemMeta() && item.getItemMeta() instanceof org.bukkit.inventory.meta.MapMeta) return FILLED_MAP; + + return matchDefinedXMaterial(material, data) + .orElseThrow(() -> new IllegalArgumentException("Unsupported material from item: " + material + " (" + data + ')')); + } + + /** + * The main method that parses the given material name and data value as an XMaterial. + * All the values passed to this method will not be null or empty and are formatted correctly. + * + * @param name the formatted name of the material. + * @param data the data value of the material. Is always 0 or {@link #UNKNOWN_DATA_VALUE} when {@link Data#ISFLAT} + * + * @return an XMaterial (with the same data value if specified) + * @see #matchXMaterial(Material) + * @see #matchXMaterial(int, byte) + * @see #matchXMaterial(ItemStack) + * @since 3.0.0 + */ + @Nonnull + protected static Optional matchDefinedXMaterial(@Nonnull String name, byte data) { + // if (!Boolean.valueOf(Boolean.getBoolean(Boolean.TRUE.toString())).equals(Boolean.FALSE.booleanValue())) return null; + Boolean duplicated = null; + boolean isAMap = name.equalsIgnoreCase("MAP"); + + // Do basic number and boolean checks before accessing more complex enum stuff. + if (Data.ISFLAT || (!isAMap && data <= 0 && !(duplicated = isDuplicated(name)))) { + Optional xMaterial = getIfPresent(name); + if (xMaterial.isPresent()) return xMaterial; + } + // Usually flat versions wouldn't pass this point, but some special materials do. + + XMaterial oldXMaterial = requestOldXMaterial(name, data); + if (oldXMaterial == null) { + // Special case. Refer to FILLED_MAP for more info. + return (data >= 0 && isAMap) ? Optional.of(FILLED_MAP) : Optional.empty(); + } + + if (!Data.ISFLAT && oldXMaterial.isPlural() && (duplicated == null ? isDuplicated(name) : duplicated)) return getIfPresent(name); + return Optional.of(oldXMaterial); + } + + /** + * XMaterial Paradox (Duplication Check) + * Checks if the material has any duplicates. + *

+ * Example: + *

{@code MELON, CARROT, POTATO, BEETROOT -> true} + * + * @param name the name of the material to check. + * + * @return true if there's a duplicated material for this material, otherwise false. + * @since 2.0.0 + */ + private static boolean isDuplicated(@Nonnull String name) { + // Don't use matchXMaterial() since this method is being called from matchXMaterial() itself and will cause a StackOverflowError. + return DUPLICATED.contains(name); + } + + /** + * Gets the XMaterial based on the material's ID (Magic Value) and data value.
+ * You should avoid using this for performance issues. + * + * @param id the ID (Magic value) of the material. + * @param data the data value of the material. + * + * @return a parsed XMaterial with the same ID and data value. + * @see #matchXMaterial(ItemStack) + * @since 2.0.0 + * @deprecated this method loops through all the available materials and matches their ID using {@link #getId()} + * which takes a really long time. Plugins should no longer support IDs. If you want, you can make a {@link Map} cache yourself. + * This method obviously doesn't work for 1.13+ and will not be supported. This is only here for debugging purposes. + */ + @Nonnull + @Deprecated + public static Optional matchXMaterial(int id, byte data) { + if (id < 0 || id > MAX_ID || data < 0) return Optional.empty(); + for (XMaterial materials : VALUES) { + if (materials.data == data && materials.getId() == id) return Optional.of(materials); + } + return Optional.empty(); + } + + /** + * Attempts to build the string like an enum name. + * Removes all the spaces, and extra non-English characters. Also removes some config/in-game based strings. + * While this method is hard to maintain, it's extremely efficient. It's approximately more than x5 times faster than + * the normal RegEx + String Methods approach for both formatted and unformatted material names. + * + * @param name the material name to modify. + * + * @return an enum name. + * @since 2.0.0 + */ + @Nonnull + protected static String format(@Nonnull String name) { + int len = name.length(); + char[] chs = new char[len]; + int count = 0; + boolean appendUnderline = false; + + for (int i = 0; i < len; i++) { + char ch = name.charAt(i); + + if (!appendUnderline && count != 0 && (ch == '-' || ch == ' ' || ch == '_') && chs[count] != '_') + appendUnderline = true; + else { + boolean number = false; + // Old materials have numbers in them. + if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (number = (ch >= '0' && ch <= '9'))) { + if (appendUnderline) { + chs[count++] = '_'; + appendUnderline = false; + } + + if (number) chs[count++] = ch; + else chs[count++] = (char) (ch & 0x5f); + } + } + } + + return new String(chs, 0, count); + } + + /** + * Checks if the specified version is the same version or higher than the current server version. + * + * @param version the major version to be checked. "1." is ignored. E.g. 1.12 = 12 | 1.9 = 9 + * + * @return true of the version is equal or higher than the current version. + * @since 2.0.0 + */ + public static boolean supports(int version) { + return Data.VERSION >= version; + } + + /** + * Gets the exact major version (..., 1.9, 1.10, ..., 1.14) + * In most cases, you shouldn't be using this method. + * + * @param version Supports {@link Bukkit#getVersion()}, {@link Bukkit#getBukkitVersion()} and normal formats such as "1.14" + * + * @return the exact major version. + * @see #supports(int) + * @see #getVersion() + * @see #getMaterialVersion() + * @since 2.0.0 + */ + @Nonnull + public static String getMajorVersion(@Nonnull String version) { + Validate.notEmpty(version, "Cannot get major Minecraft version from null or empty string"); + + // getVersion() + int index = version.lastIndexOf("MC:"); + if (index != -1) { + version = version.substring(index + 4, version.length() - 1); + } else if (version.endsWith("SNAPSHOT")) { + // getBukkitVersion() + index = version.indexOf('-'); + version = version.substring(0, index); + } + + // 1.13.2, 1.14.4, etc... + int lastDot = version.lastIndexOf('.'); + if (version.indexOf('.') != lastDot) version = version.substring(0, lastDot); + + return version; + } + + public String[] getLegacy() { + return this.legacy; + } + + /** + * XMaterial Paradox (Duplication Check) + * I've concluded that this is just an infinite loop that keeps + * going around the Singular Form and the Plural Form materials. A waste of brain cells and a waste of time. + * This solution works just fine anyway. + *

+ * A solution for XMaterial Paradox. + * Manually parses the duplicated materials to find the exact material based on the server version. + * If the name ends with "S" -> Plural Form Material. + * Plural methods are only plural if they're also {@link #DUPLICATED} + *

+ * The only special exceptions are {@link #BRICKS} and {@link #NETHER_BRICKS} + * + * @return true if this material is a plural form material, otherwise false. + * @since 8.0.0 + */ + private boolean isPlural() { + // this.name().charAt(this.name().length() - 1) == 'S' + return this == CARROTS || this == POTATOES; + } + + /** + * Checks if the list of given material names matches the given base material. + * Mostly used for configs. + *

+ * Supports {@link String#contains} {@code CONTAINS:NAME} and Regular Expression {@code REGEX:PATTERN} formats. + *

+ * Example: + *

+     *     XMaterial material = {@link #matchXMaterial(ItemStack)};
+     *     if (material.isOneOf(plugin.getConfig().getStringList("disabled-items")) return;
+     * 
+ *
+ * {@code CONTAINS} Examples: + *
+     *     {@code "CONTAINS:CHEST" -> CHEST, ENDERCHEST, TRAPPED_CHEST -> true}
+     *     {@code "cOnTaINS:dYe" -> GREEN_DYE, YELLOW_DYE, BLUE_DYE, INK_SACK -> true}
+     * 
+ *

+ * {@code REGEX} Examples + *

+     *     {@code "REGEX:^.+_.+_.+$" -> Every Material with 3 underlines or more: SHULKER_SPAWN_EGG, SILVERFISH_SPAWN_EGG, SKELETON_HORSE_SPAWN_EGG}
+     *     {@code "REGEX:^.{1,3}$" -> Material names that have 3 letters only: BED, MAP, AIR}
+     * 
+ *

+ * The reason that there are tags for {@code CONTAINS} and {@code REGEX} is for the performance. + * Although RegEx patterns are cached in this method, + * please avoid using the {@code REGEX} tag if you can use the {@code CONTAINS} tag instead. + * It'll have a huge impact on performance. + * Please avoid using {@code (capturing groups)} there's no use for them in this case. + * If you want to use groups, use {@code (?: non-capturing groups)}. It's faster. + *

+ * Want to learn RegEx? You can mess around in RegExr website. + * + * @param materials the material names to check base material on. + * + * @return true if one of the given material names is similar to the base material. + * @since 3.1.1 + */ + public boolean isOneOf(@Nullable Collection materials) { + if (materials == null || materials.isEmpty()) return false; + String name = this.name(); + + for (String comp : materials) { + String checker = comp.toUpperCase(Locale.ENGLISH); + if (checker.startsWith("CONTAINS:")) { + comp = format(checker.substring(9)); + if (name.contains(comp)) return true; + continue; + } + if (checker.startsWith("REGEX:")) { + comp = comp.substring(6); + Pattern pattern = CACHED_REGEX.getUnchecked(comp); + if (pattern != null && pattern.matcher(name).matches()) return true; + continue; + } + + // Direct Object Equals + Optional xMat = matchXMaterial(comp); + if (xMat.isPresent() && xMat.get() == this) return true; + } + return false; + } + + /** + * Sets the {@link Material} (and data value on older versions) of an item. + * Damageable materials will not have their durability changed. + *

+ * Use {@link #parseItem()} instead when creating new ItemStacks. + * + * @param item the item to change its type. + * + * @see #parseItem() + * @since 3.0.0 + */ + @Nonnull + @SuppressWarnings("deprecation") + public ItemStack setType(@Nonnull ItemStack item) { + Objects.requireNonNull(item, "Cannot set material for null ItemStack"); + Material material = this.parseMaterial(); + Objects.requireNonNull(material, () -> "Unsupported material: " + this.name()); + + item.setType(material); + if (!Data.ISFLAT && material.getMaxDurability() <= 0) item.setDurability(this.data); + return item; + } + + /** + * Checks if the given material name matches any of this xmaterial's legacy material names. + * All the values passed to this method will not be null or empty and are formatted correctly. + * + * @param name the material name to check. + * + * @return true if it's one of the legacy names, otherwise false. + * @since 2.0.0 + */ + private boolean anyMatchLegacy(@Nonnull String name) { + for (int i = this.legacy.length - 1; i >= 0; i--) { + if (name.equals(this.legacy[i])) return true; + } + return false; + } + + /** + * Parses an enum name to a user-friendly name. + * These names will have underlines removed and with each word capitalized. + *

+ * Examples: + *

+     *     {@literal EMERALD                 -> Emerald}
+     *     {@literal EMERALD_BLOCK           -> Emerald Block}
+     *     {@literal ENCHANTED_GOLDEN_APPLE  -> Enchanted Golden Apple}
+     * 
+ * + * @return a more user-friendly enum name. + * @since 3.0.0 + */ + @Override + @Nonnull + public String toString() { + return WordUtils.capitalize(this.name().replace('_', ' ').toLowerCase(Locale.ENGLISH)); + } + + /** + * Gets the ID (Magic value) of the material. + * https://www.minecraftinfo.com/idlist.htm + * + * @return the ID of the material or -1 if it's not a legacy material or the server doesn't support the material. + * @see #matchXMaterial(int, byte) + * @since 2.2.0 + */ + @SuppressWarnings("deprecation") + public int getId() { + if (this.data != 0 || this.version >= 13) return -1; + Material material = this.parseMaterial(); + if (material == null) return -1; + if (Data.ISFLAT) return -1; + return material.getId(); + } + + /** + * The data value of this material pre-flattening. + *

+ * Can be accessed with {@link ItemStack#getData()} then {@code MaterialData#getData()} + * or {@link ItemStack#getDurability()} if not damageable. + * + * @return data of this material, or 0 if none. + * @since 1.0.0 + */ + @SuppressWarnings("deprecation") + public byte getData() { + return data; + } + + /** + * Parses an item from this XMaterial. + * Uses data values on older versions. + * + * @return an ItemStack with the same material (and data value if in older versions.) + * @see #setType(ItemStack) + * @since 2.0.0 + */ + @Nullable + @SuppressWarnings("deprecation") + public ItemStack parseItem() { + Material material = this.parseMaterial(); + if (material == null) return null; + return Data.ISFLAT ? new ItemStack(material) : new ItemStack(material, 1, this.data); + } + + /** + * Parses the material of this XMaterial. + * + * @return the material related to this XMaterial based on the server version. + * @since 1.0.0 + */ + @Nullable + public Material parseMaterial() { + return this.material; + } + + /** + * Checks if an item has the same material (and data value on older versions). + * + * @param item item to check. + * + * @return true if the material is the same as the item's material (and data value if on older versions), otherwise false. + * @since 1.0.0 + */ + @SuppressWarnings("deprecation") + public boolean isSimilar(@Nonnull ItemStack item) { + Objects.requireNonNull(item, "Cannot compare with null ItemStack"); + if (item.getType() != this.parseMaterial()) return false; + return Data.ISFLAT || item.getDurability() == this.data || item.getType().getMaxDurability() <= 0; + } + + /** + * Checks if this material is supported in the current version. + * Suggested materials will be ignored. + *

+ * Note that you should use {@link #parseMaterial()} or {@link #parseItem()} and check if it's null + * if you're going to parse and use the material/item later. + * + * @return true if the material exists in {@link Material} list. + * @since 2.0.0 + */ + public boolean isSupported() { + return this.material != null; + } + + /** + * The version this material was added in. This will return the minor number in the version scheme. + * For example, if it was added in 1.16, it'll return 16 + * + * @return the version number of 0 if the version was not recorded. + * @since 7.0.0 + */ + public byte getMaterialVersion() { + return version; + } + + /** + * This method is needed due to Java enum initialization limitations. + * It's really inefficient yes, but it's only used for initialization. + *

+ * Yes there are many other ways like comparing the hardcoded ordinal or using a boolean in the enum constructor, + * but it's not really a big deal. + *

+ * This method should not be called if the version is after the flattening update {@link Data#ISFLAT} + * and is only used for parsing materials, not matching, for matching check {@link #DUPLICATED} + */ + private boolean isDuplicated() { + switch (this.name()) { + case "MELON": + case "CARROT": + case "POTATO": + case "GRASS": + case "BRICK": + case "NETHER_BRICK": + + // Illegal Elements + // Since both 1.12 and 1.13 have _DOOR XMaterial will use it + // for 1.12 to parse the material, but it needs _DOOR_ITEM. + // We'll trick XMaterial into thinking this needs to be parsed + // using the old methods. + // Some of these materials have their enum name added to the legacy list as well. + case "DARK_OAK_DOOR": + case "ACACIA_DOOR": + case "BIRCH_DOOR": + case "JUNGLE_DOOR": + case "SPRUCE_DOOR": + case "MAP": + case "CAULDRON": + case "BREWING_STAND": + case "FLOWER_POT": + return true; + default: + return false; + } + } + + /** + * Used for datas that need to be accessed during enum initilization. + * + * @since 9.0.0 + */ + private static final class Data { + /** + * The current version of the server in the a form of a major version. + * If the static initialization for this fails, you know something's wrong with the server software. + * + * @since 1.0.0 + */ + private static final int VERSION = Integer.parseInt(getMajorVersion(Bukkit.getVersion()).substring(2)); + /** + * Cached result if the server version is after the v1.13 flattening update. + * + * @since 3.0.0 + */ + private static final boolean ISFLAT = supports(13); + } +} \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index ea20142..fd1ba75 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -70,6 +70,8 @@ Messages: Not needed: "&3[Evento] &bVocê não precisa do machado para definir posições nesse evento." Not enough alternatives: "&3[Evento] &bO número mínimo de alternativas é maior que o número total de alternativas possíveis." Unknown argument: "&3[Evento] &bArgumento inválido. Digite &f/evento setup&b para ver a lista de argumentos." + Missing dependency: "&3[Evento] &bEste evento não pode funcionar sem o plugin &f@dependency&b." + Default: - "&3[Evento] &bLista de Comandos:" - "&b/evento &f- Entrar no evento" @@ -94,4 +96,6 @@ Messages: - "&c/evento setup pos &4- Obtenha um machado para definir as posições." - "&c/evento setup pos1 &4- Defina a primeira posição." - "&c/evento setup pos2 &4- Defina a segunda posição." + - "&c/evento setup pos3 &4- Defina a terceira posição." + - "&c/evento setup pos4 &4- Defina a quarta posição." - "&c/evento setup sair &4- Saia das configurações do evento &f@name&c." \ No newline at end of file diff --git a/src/main/resources/eventos/anvil.yml b/src/main/resources/eventos/anvil.yml new file mode 100644 index 0000000..f60da2d --- /dev/null +++ b/src/main/resources/eventos/anvil.yml @@ -0,0 +1,69 @@ +Evento: + # Configurações do evento. + Title: "Anvil" # O nome do evento. Será usado na placeholder @name. + Type: "anvil" # O tipo do evento. Não modifique! + Calls: 5 # Quantas chamadas o evento terá. + Calls interval: 15 # O intervalo (em segundos) entre as chamadas. + Mininum players: 2 # O mínimo de jogadores para iniciar o evento. + Spectator mode: true # Este evento possui camarote? + Empty inventory: false # Esse evento requer que você esteja com o inventário vazio? + Permission: "aeventos.evento" # A permissão necessária para participar do evento. + Count participation: true # Esse evento contará participação? + Count victory: true # Esse evento contará vitória? + Height: 20 # As bigornas devem ser invocadas de quantos blocos de altura? + Time: 10 # Tempo antes das bigornas começarem a cair. + Delay: 2 # Tempo de delay para cair uma bigorna. + +# Mensagens +Messages: + Broadcast: + - "" + - "&3[@name] &bIniciando evento &f@name" + - "&3[@name] &bPara participar, digite &f/evento" + - "&3[@name] &bPrêmio: &2$&f10.485,96 &b+ &8[Anvil]" + - "&3[@name] &bJogadores no evento: &f@players" + - "&3[@name] &bChamadas restantes: &f@broadcasts" + - "" + Start: + - "" + - "&3[@name] &bIniciando evento..." + - "" + Winner: + - "" + - "&3[@name] &bO evento &f@name &bfoi finalizado!" + - "&3[@name] &bO vencedor foi &f@winner&b!" + - "" + No winner: + - "" + - "&3[@name] &bO evento &f@name &bfoi finalizado!" + - "&3[@name] &bNão houveram vencedores." + - "" + No players: + - "" + - "&3[@name] &bEvento cancelado." + - "&3[@name] &bA quantidade mínima de jogadores não foi atingida." + - "" + Cancelled: + - "" + - "&3[@name] &bO evento foi cancelado manualmente." + - "" + Starting: + - "&3[@name] &bAs bigornas começarão a cair em &f@time &bsegundos." + +# Recompensas. Elas serão dadas ao vencedor. +Rewards: + Tag: # Tag do LegendChat. + Enabled: true # Ativar a tag do evento? + Name: "aeventos_anvil" # O nome da tag. Você a colocará na configuração do LegendChat. Nesse caso, {aeventos_anvil} + Style: "&8[Anvil] " # A aparência da tag. + Commands: # Lista de comandos que serão executados no vencedor. + - "give @winner diamond 1" + +# Localizações. Você configurará essa seção usando o comando /evento setup anvil +Locations: + Lobby: [] + Entrance: [] + Spectator: [] + Exit: [] + Pos1: [] + Pos2: [] \ No newline at end of file diff --git a/src/main/resources/eventos/bolao.yml b/src/main/resources/eventos/bolao.yml new file mode 100644 index 0000000..90d3d1b --- /dev/null +++ b/src/main/resources/eventos/bolao.yml @@ -0,0 +1,47 @@ +Evento: + # Configurações do evento. + Title: "Bolão" # O nome do evento. Será usado na placeholder @name. + Type: "bolao" # O tipo do evento. Não modifique! + Calls: 5 # Quantas chamadas o evento terá? + Calls interval: 15 # O intervalo (em segundos) entre as chamadas. + Permission: "aeventos.evento" # A permissão necessária para poder participar do evento. + Reward: 10000 # A recompensa do evento. + Cost: 10000 # O custo para apostar em um número. + +# Mensagens +Messages: + Broadcast: + - "" + - "&3[@name] &bIniciando evento &f@name" + - "&3[@name] &bPara participar, digite &f/evento entrar" + - "&3[@name] &bPrêmio: &2$&f@reward &b+ &5[Bolão]" + - "&3[@name] &bCusto: &2$&f@cost" + - "&3[@name] &bJogadores no evento: &f@players" + - "&3[@name] &bChamadas restantes: &f@broadcasts" + - "" + Winner: + - "" + - "&3[@name] &bO evento &f@name &bfoi finalizado!" + - "&3[@name] &bO vencedor foi &f@winner&b!" + - "" + No winner: + - "" + - "&3[@name] &bO evento &f@name &bfoi finalizado!" + - "&3[@name] &bNão houveram vencedores." + - "" + Cancelled: + - "" + - "&3[@name] &bO evento foi cancelado manualmente." + - "" + No money: "&3[@name] &bVocê não tem dinheiro suficiente para entrar no Bolão. &f(@cost)" + Joined: "&3[@name] &bVocê entrou no Bolão. Que a sorte esteja ao seu lado." + Already joined: "&3[@name] &bVocê já está no bolão." + +# Recompensas. Elas serão dadas ao vencedor. +Rewards: + Tag: # Tag do LegendChat. + Enabled: true # Ativar a tag do evento? + Name: "aeventos_bolao" # O nome da tag. Você a colocará na configuração do LegendChat. Nesse caso, {aeventos_bolao} + Style: "&5[Bolão] " # A aparência da tag. + Commands: # Lista de comandos que serão executados no vencedor. + - "give @winner diamond 1" \ No newline at end of file diff --git a/src/main/resources/eventos/fight.yml b/src/main/resources/eventos/fight.yml index defb0bf..5535f40 100644 --- a/src/main/resources/eventos/fight.yml +++ b/src/main/resources/eventos/fight.yml @@ -1,99 +1,122 @@ -Evento: - # Configurações do evento. - Title: "Fight" # O nome do evento. Será usado na placeholder @name. - Type: "fight" # O tipo do evento. Não modifique! - Calls: 5 # Quantas chamadas o evento terá. - Calls interval: 15 # O intervalo (em segundos) entre as chamadas. - Mininum players: 2 # O mínimo de jogadores para iniciar o evento. - Spectator mode: true # Este evento possui camarote? - Empty inventory: true # Esse evento requer que você esteja com o inventário vazio? - Permission: "aeventos.evento" # A permissão necessária para participar do evento. - Count participation: true # Esse evento contará participação? - Count victory: true # Esse evento contará vitória? - Time: 5 # Tempo em segundos de intervalo entre as lutas. - Fight time: 180 # Tempo máximo em segundos que uma luta pode ter. - -Items: - # FORMATO: ID-QUANTIDADE. - # Itens para todas as lutas, exceto a final. - Normal: - Armor: - Helmet: null - Chestplate: null - Legging: null - Boots: null - Inventory: - - "268-1" - # Itens para a última luta. - Last fight: - Armor: - Helmet: "306-1" - Chestplate: "307-1" - Legging: "308-1" - Boots: "309-1" - Inventory: - - "267-1" - -# Mensagens -Messages: - Broadcast: - - "" - - "&3[@name] &bIniciando evento &f@name" - - "&3[@name] &bPara participar, digite &f/evento" - - "&3[@name] &bPrêmio: &2$&f12,345.67 &b+ &5[Fight]" - - "&3[@name] &bJogadores no evento: &f@players" - - "&3[@name] &bChamadas restantes: &f@broadcasts" - - "" - Start: - - "" - - "&3[@name] &bIniciando evento..." - - "" - Winner: - - "" - - "&3[@name] &bO evento &f@name &bfoi finalizado!" - - "&3[@name] &bO vencedor foi &f@winner&b!" - - "" - No winner: - - "" - - "&3[@name] &bO evento &f@name &bfoi finalizado!" - - "&3[@name] &bNão houveram vencedores." - - "" - No players: - - "" - - "&3[@name] &bEvento cancelado." - - "&3[@name] &bA quantidade mínima de jogadores não foi atingida." - - "" - Cancelled: - - "" - - "&3[@name] &bO evento foi cancelado manualmente." - - "" - Next fight: - - "" - - "&3[@name] &bIniciando próxima luta em &f@time &bsegundos." - - "" - Fight: - - "" - - "&3[@name] &f@player1 &bVS &f@player2&b!" - - "" - Fight winner: - - "&3[@name] &f@winner &bvenceu a luta!" - Fight no winner: - - "&3[@name] &bEmpate!" - -# Recompensas. Elas serão dadas ao(s) vencedor(es). -Rewards: - Tag: # Tag do LegendChat. - Enabled: true # Ativar a tag do evento? - Name: "aeventos_fight" # O nome da tag. Você a colocará na configuração do LegendChat. Nesse caso, {aeventos_fight} - Style: "&5[Fight] " # A aparência da tag. - Commands: # Lista de comandos que serão executados no(s) vencedor(es). - - "give @winner diamond 1" - -# Localizações. Você configurará essa seção usando o comando /evento setup fight -Locations: - Lobby: [] - Entrance: [] - Spectator: [] - Exit: [] - Pos1: [] +Evento: + # Configurações do evento. + Title: "Fight" # O nome do evento. Será usado na placeholder @name. + Type: "fight" # O tipo do evento. Não modifique! + Calls: 5 # Quantas chamadas o evento terá. + Calls interval: 15 # O intervalo (em segundos) entre as chamadas. + Mininum players: 2 # O mínimo de jogadores para iniciar o evento. + Spectator mode: true # Este evento possui camarote? + Empty inventory: true # Esse evento requer que você esteja com o inventário vazio? + Permission: "aeventos.evento" # A permissão necessária para participar do evento. + Count participation: true # Esse evento contará participação? + Count victory: true # Esse evento contará vitória? + Time: 5 # Tempo em segundos de intervalo entre as lutas. + Fight time: 180 # Tempo máximo em segundos que uma luta pode ter. + +Items: + # Lista de materiais: + # 1.8.X - 1.12.X: https://www.digminecraft.com/lists/item_id_list_pc_1_12.php + # 1.13.X em diante: https://www.digminecraft.com/lists/item_id_list_pc.php + # Itens para todas as lutas, exceto a final. + Normal: + Armor: + Helmet: + Material: 'AIR' + Data: 0 + Chestplate: + Material: 'AIR' + Data: 0 + Legging: + Material: 'AIR' + Data: 0 + Boots: + Material: 'AIR' + Data: 0 + Inventory: + # FORMATO: -(data)- + # O campo data é opicional, porém o material e a quantidade são obrigatórios. + - "WOOD_SWORD-1" + + # Itens para a última luta. + Last fight: + Armor: + Helmet: + Material: "IRON_HELMET" + Data: 0 + Chestplate: + Material: "IRON_CHESTPLATE" + Data: 0 + Legging: + Material: "IRON_LEGGINGS" + Data: 0 + Boots: + Material: "IRON_BOOTS" + Data: 0 + Inventory: + # FORMATO: -(data)- + # O campo data é opicional, porém o material e a quantidade são obrigatórios. + - "IRON_SWORD-1" + +# Mensagens +Messages: + Broadcast: + - "" + - "&3[@name] &bIniciando evento &f@name" + - "&3[@name] &bPara participar, digite &f/evento" + - "&3[@name] &bPrêmio: &2$&f12,345.67 &b+ &5[Fight]" + - "&3[@name] &bJogadores no evento: &f@players" + - "&3[@name] &bChamadas restantes: &f@broadcasts" + - "" + Start: + - "" + - "&3[@name] &bIniciando evento..." + - "" + Winner: + - "" + - "&3[@name] &bO evento &f@name &bfoi finalizado!" + - "&3[@name] &bO vencedor foi &f@winner&b!" + - "" + No winner: + - "" + - "&3[@name] &bO evento &f@name &bfoi finalizado!" + - "&3[@name] &bNão houveram vencedores." + - "" + No players: + - "" + - "&3[@name] &bEvento cancelado." + - "&3[@name] &bA quantidade mínima de jogadores não foi atingida." + - "" + Cancelled: + - "" + - "&3[@name] &bO evento foi cancelado manualmente." + - "" + Next fight: + - "" + - "&3[@name] &bIniciando próxima luta em &f@time &bsegundos." + - "" + Fight: + - "" + - "&3[@name] &f@player1 &bVS &f@player2&b!" + - "" + Fight winner: + - "&3[@name] &f@winner &bvenceu a luta!" + Fight no winner: + - "&3[@name] &bEmpate!" + +# Recompensas. Elas serão dadas ao(s) vencedor(es). +Rewards: + Tag: # Tag do LegendChat. + Enabled: true # Ativar a tag do evento? + Name: "aeventos_fight" # O nome da tag. Você a colocará na configuração do LegendChat. Nesse caso, {aeventos_fight} + Style: "&5[Fight] " # A aparência da tag. + Commands: # Lista de comandos que serão executados no(s) vencedor(es). + - "give @winner diamond 1" + +# Localizações. Você configurará essa seção usando o comando /evento setup fight +Locations: + Lobby: [] + Entrance: [] + Spectator: [] + Exit: [] + Pos1: [] Pos2: [] \ No newline at end of file diff --git a/src/main/resources/eventos/hunter.yml b/src/main/resources/eventos/hunter.yml new file mode 100644 index 0000000..96ba1f5 --- /dev/null +++ b/src/main/resources/eventos/hunter.yml @@ -0,0 +1,84 @@ +Evento: + # Configurações do evento. + Title: "Hunter" # O nome do evento. Será usado na placeholder @name. + Type: "hunter" # O tipo do evento. Não modifique! + Calls: 5 # Quantas chamadas o evento terá. + Calls interval: 15 # O intervalo (em segundos) entre as chamadas. + Mininum players: 2 # O mínimo de jogadores para iniciar o evento. + Spectator mode: true # Este evento possui camarote? + Empty inventory: true # Esse evento requer que você esteja com o inventário vazio? + Permission: "aeventos.evento" # A permissão necessária para participar do evento. + Count participation: true # Esse evento contará participação? + Count victory: true # Esse evento contará vitória? + Blue: "Time Azul" # O nome do time azul. + Red: "Time Vermelho" # O nome do time vermelho. + Enable PvP: 10 # Tempo em segundos antes do PvP ser ativado. + Points: 1 # Quantos pontos um time ganhará ao capturar um jogador do time oposto? + Max points: 30 # Caso um time obtenha essa quantidade de pontos, ele vence. Para desativar, basta definir como 0. + Capture time: 5 # Quanto tempo, em segundos, um jogador capturado deve esperar para poder voltar a jogar? + +# Mensagens +Messages: + Broadcast: + - "" + - "&3[@name] &bIniciando evento &f@name" + - "&3[@name] &bPara participar, digite &f/evento" + - "&3[@name] &bPrêmio: &2$&f10.485,96 &b+ &6[Hunter]" + - "&3[@name] &bJogadores no evento: &f@players" + - "&3[@name] &bChamadas restantes: &f@broadcasts" + - "" + Start: + - "" + - "&3[@name] &bIniciando evento..." + - "" + Winner: + - "" + - "&3[@name] &bO evento &f@name &bfoi finalizado!" + - "&3[@name] &bO vencedor foi &f@winner&b!" + - "" + No winner: + - "" + - "&3[@name] &bO evento &f@name &bfoi finalizado!" + - "&3[@name] &bNão houveram vencedores." + - "" + No players: + - "" + - "&3[@name] &bEvento cancelado." + - "&3[@name] &bA quantidade mínima de jogadores não foi atingida." + - "" + Cancelled: + - "" + - "&3[@name] &bO evento foi cancelado manualmente." + - "" + Team: + - "" + - "&3[@name] &bVocê faz parte do &f@team&b." + - "&3[@name] &bAtivando PvP em &f@time &bsegundos." + - "" + Enabled: + - "&3[@name] &bPvP ativado! Boa sorte á todos." + Eliminated: + - "&3[@name] @player &bfoi capturado!" + - "&3[@name] &bPontuação: @blueteam&b á @readteam&b." + Capturated: + - "&3[@name] &bVocê foi capturado! Aguarde &f@time&b segundos para voltar a jogar." + Win: + - "&3[@name] &bCom @points &bpontos, o @team &bvenceu!" + +# Recompensas. Elas serão dadas ao vencedor. +Rewards: + Tag: # Tag do LegendChat. + Enabled: true # Ativar a tag do evento? + Name: "aeventos_hunter" # O nome da tag. Você a colocará na configuração do LegendChat. Nesse caso, {aeventos_hunter} + Style: "&6[Hunter] " # A aparência da tag. + Commands: # Lista de comandos que serão executados no vencedor. + - "give @winner diamond 1" + +# Localizações. Você configurará essa seção usando o comando /evento setup hunter +Locations: + Lobby: [] + Entrance: [] + Spectator: [] + Exit: [] + Pos1: [] + Pos2: [] \ No newline at end of file diff --git a/src/main/resources/eventos/loteria.yml b/src/main/resources/eventos/loteria.yml new file mode 100644 index 0000000..924f4af --- /dev/null +++ b/src/main/resources/eventos/loteria.yml @@ -0,0 +1,49 @@ +Evento: + # Configurações do evento. + Title: "Loteria" # O nome do evento. Será usado na placeholder @name. + Type: "loteria" # O tipo do evento. Não modifique! + Calls: 5 # Quantas chamadas o evento terá? + Calls interval: 15 # O intervalo (em segundos) entre as chamadas. + Permission: "aeventos.evento" # A permissão necessária para poder participar do evento. + Reward: 10000 # A recompensa do evento. + Cost: 0 # O custo para apostar em um número. + Max number: 100 # O número máximo que o plugin pode sortear. Nesse caso, será sorteado um número de 0 á 100. + +# Mensagens +Messages: + Broadcast: + - "" + - "&3[@name] &bIniciando evento &f@name" + - "&3[@name] &bPara apostar, digite &f/evento " + - "&3[@name] &bPrêmio: &2$&f@reward &b+ &2[Loteria]" + - "&3[@name] &bCusto por aposta: &2$&f@cost" + - "&3[@name] &bChamadas restantes: &f@broadcasts" + - "" + Winner: + - "" + - "&3[@name] &bO evento &f@name &bfoi finalizado!" + - "&3[@name] &bO vencedor foi &f@winner&b!" + - "&3[@name] &bO número sorteado foi &f@number&b." + - "" + No winner: + - "" + - "&3[@name] &bO evento &f@name &bfoi finalizado!" + - "&3[@name] &bNão houveram vencedores." + - "&3[@name] &bO número sorteado foi &f@number&b." + - "" + Cancelled: + - "" + - "&3[@name] &bO evento foi cancelado manualmente." + - "" + No money: "&3[@name] &bVocê não tem dinheiro suficiente para apostar. &f(@cost)" + Lose: "&3[@name] &bVocê apostou no número &f@number&b, mas infelizmente não venceu." + Invalid: "&3[@name] &bUso correto: &f/evento " + +# Recompensas. Elas serão dadas ao vencedor. +Rewards: + Tag: # Tag do LegendChat. + Enabled: true # Ativar a tag do evento? + Name: "aeventos_loteria" # O nome da tag. Você a colocará na configuração do LegendChat. Nesse caso, {aeventos_loteria} + Style: "&2[Loteria] " # A aparência da tag. + Commands: # Lista de comandos que serão executados no vencedor. + - "give @winner diamond 1" \ No newline at end of file diff --git a/src/main/resources/eventos/quiz.yml b/src/main/resources/eventos/quiz.yml new file mode 100644 index 0000000..485c5b6 --- /dev/null +++ b/src/main/resources/eventos/quiz.yml @@ -0,0 +1,84 @@ +Evento: + # Configurações do evento. + Title: "Quiz" # O nome do evento. Será usado na placeholder @name. + Type: "quiz" # O tipo do evento. Não modifique! + Calls: 5 # Quantas chamadas o evento terá. + Calls interval: 15 # O intervalo (em segundos) entre as chamadas. + Mininum players: 2 # O mínimo de jogadores para iniciar o evento. + Spectator mode: true # Este evento possui camarote? + Empty inventory: false # Esse evento requer que você esteja com o inventário vazio? + Permission: "aeventos.evento" # A permissão necessária para participar do evento. + Count participation: true # Esse evento contará participação? + Count victory: true # Esse evento contará vitória? + Time: 10 # Quanto tempo, em segundos, os jogadores terão para responder a pergunta? + Interval: 5 # O tempo, em segundos, de intervalo entre as perguntas. + Max questions: 50 # Caso tenham sido feitas mais perguntas que o limite, então todos os jogadores restantes vencem. + +# Mensagens +Messages: + Broadcast: + - "" + - "&3[@name] &bIniciando evento &f@name" + - "&3[@name] &bPara participar, digite &f/evento" + - "&3[@name] &bPrêmio: &2$&f10.485,96 &b+ &d[Quiz]" + - "&3[@name] &bJogadores no evento: &f@players" + - "&3[@name] &bChamadas restantes: &f@broadcasts" + - "" + Start: + - "" + - "&3[@name] &bIniciando evento..." + - "" + Winner: + - "" + - "&3[@name] &bO evento &f@name &bfoi finalizado!" + - "&3[@name] &bO vencedor foi &f@winner&b!" + - "" + No winner: + - "" + - "&3[@name] &bO evento &f@name &bfoi finalizado!" + - "&3[@name] &bNão houveram vencedores." + - "" + No players: + - "" + - "&3[@name] &bEvento cancelado." + - "&3[@name] &bA quantidade mínima de jogadores não foi atingida." + - "" + Cancelled: + - "" + - "&3[@name] &bO evento foi cancelado manualmente." + - "" + Question: + - "&3[@name] &bPergunta @currentquestion: &f@question" + Next question: + - "&3[@name] &bPróxima pergunta em &f@time &bsegundos." + +# Questões. +Questions: + # Formato: -(true ou false) + # Caso o segundo argumento esteja como true, a resposta será verdadeiro. + # Caso esteja false, a resposta será falsa. + # Se o segundo argumento não for colocado, então as duas respostas serão válidas. + - "O aEventos é um bom plugin?-true" + - "A resposta dessa pergunta é o oposto de falso?-true" + - "É verdade que essas perguntas não são de teste?-false" + - "Qual é o sentido da vida?" + +# Recompensas. Elas serão dadas ao vencedor. +Rewards: + Tag: # Tag do LegendChat. + Enabled: true # Ativar a tag do evento? + Name: "aeventos_quiz" # O nome da tag. Você a colocará na configuração do LegendChat. Nesse caso, {aeventos_quiz} + Style: "&d[Quiz] " # A aparência da tag. + Commands: # Lista de comandos que serão executados no vencedor. + - "give @winner diamond 1" + +# Localizações. Você configurará essa seção usando o comando /evento setup quiz +Locations: + Lobby: [] + Entrance: [] + Spectator: [] + Exit: [] + Pos1: [] + Pos2: [] + Pos3: [] + Pos4: [] \ No newline at end of file diff --git a/src/main/resources/eventos/spleef.yml b/src/main/resources/eventos/spleef.yml index 049f5dc..ef48eed 100644 --- a/src/main/resources/eventos/spleef.yml +++ b/src/main/resources/eventos/spleef.yml @@ -1,79 +1,83 @@ -Evento: - # Configurações do evento. - Title: "Spleef" # O nome do evento. Será usado na placeholder @name. - Type: "spleef" # O tipo do evento. Não modifique! - Calls: 5 # Quantas chamadas o evento terá. - Calls interval: 15 # O intervalo (em segundos) entre as chamadas. - Mininum players: 2 # O mínimo de jogadores para iniciar o evento. - Spectator mode: true # Este evento possui camarote? - Empty inventory: true # Esse evento requer que você esteja com o inventário vazio? - Permission: "aeventos.evento" # A permissão necessária para participar do evento. - Count participation: true # Esse evento contará participação? - Count victory: true # Esse evento contará vitória? - Delay: 5 # O tempo em segundos de delay antes do início da quebra de blocos. - Kick: true # Caso esteja ativado, jogadores que estiverem parados por X segundos serão expulsos do evento. - Kick time: 20 # O tempo limite para ficar parado em segundos. - -# Os itens que serão dados para os jogadores no início do evento. -Items: - # Formato: ID-QUANTIDADE. - - "273-1" - - "332-15" - -# Mensagens -Messages: - Broadcast: - - "" - - "&3[@name] &bIniciando evento &f@name" - - "&3[@name] &bPara participar, digite &f/evento" - - "&3[@name] &bPrêmio: &2$&f10.485,96 &b+ &3[Spleef]" - - "&3[@name] &bJogadores no evento: &f@players" - - "&3[@name] &bChamadas restantes: &f@broadcasts" - - "" - Start: - - "" - - "&3[@name] &bIniciando evento..." - - "" - Winner: - - "" - - "&3[@name] &bO evento &f@name &bfoi finalizado!" - - "&3[@name] &bO vencedor foi &f@winner&b!" - - "" - No winner: - - "" - - "&3[@name] &bO evento &f@name &bfoi finalizado!" - - "&3[@name] &bNão houveram vencedores." - - "" - No players: - - "" - - "&3[@name] &bEvento cancelado." - - "&3[@name] &bA quantidade mínima de jogadores não foi atingida." - - "" - Cancelled: - - "" - - "&3[@name] &bO evento foi cancelado manualmente." - - "" - Enabling breaking: - - "&3[@name] &bAtivando quebra de blocos em &f@time&b segundos..." - Breaking allowed: - - "&3[@name] &bAgora vocês podem quebrar blocos!" - Kick: "&3[@name] &bComo você está parado, você será eliminado do evento em &f@time &bsegundos." - -# Recompensas. Elas serão dadas ao vencedor. -Rewards: - Tag: # Tag do LegendChat. - Enabled: true # Ativar a tag do evento? - Name: "aeventos_spleef" # O nome da tag. Você a colocará na configuração do LegendChat. Nesse caso, {aeventos_spleef} - Style: "&3[Spleef] " # A aparência da tag. - Commands: # Lista de comandos que serão executados no vencedor. - - "give @winner diamond 1" - - -# Localizações. Você configurará essa seção usando o comando /evento setup spleef -Locations: - Lobby: [] - Entrance: [] - Spectator: [] - Exit: [] - Pos1: [] +Evento: + # Configurações do evento. + Title: "Spleef" # O nome do evento. Será usado na placeholder @name. + Type: "spleef" # O tipo do evento. Não modifique! + Calls: 5 # Quantas chamadas o evento terá. + Calls interval: 15 # O intervalo (em segundos) entre as chamadas. + Mininum players: 2 # O mínimo de jogadores para iniciar o evento. + Spectator mode: true # Este evento possui camarote? + Empty inventory: true # Esse evento requer que você esteja com o inventário vazio? + Permission: "aeventos.evento" # A permissão necessária para participar do evento. + Count participation: true # Esse evento contará participação? + Count victory: true # Esse evento contará vitória? + Delay: 5 # O tempo em segundos de delay antes do início da quebra de blocos. + Kick: true # Caso esteja ativado, jogadores que estiverem parados por X segundos serão expulsos do evento. + Kick time: 20 # O tempo limite para ficar parado em segundos. + +# Os itens que serão dados para os jogadores no início do evento. +Items: + # Lista de materiais: + # 1.8.X - 1.12.X: https://www.digminecraft.com/lists/item_id_list_pc_1_12.php + # 1.13.X em diante: https://www.digminecraft.com/lists/item_id_list_pc.php + # FORMATO: -(data)- + # O campo data é opicional, porém o material e a quantidade são obrigatórios. + - "STONE_SPADE-1" + - "SNOW_BALL-15" + +# Mensagens +Messages: + Broadcast: + - "" + - "&3[@name] &bIniciando evento &f@name" + - "&3[@name] &bPara participar, digite &f/evento" + - "&3[@name] &bPrêmio: &2$&f10.485,96 &b+ &3[Spleef]" + - "&3[@name] &bJogadores no evento: &f@players" + - "&3[@name] &bChamadas restantes: &f@broadcasts" + - "" + Start: + - "" + - "&3[@name] &bIniciando evento..." + - "" + Winner: + - "" + - "&3[@name] &bO evento &f@name &bfoi finalizado!" + - "&3[@name] &bO vencedor foi &f@winner&b!" + - "" + No winner: + - "" + - "&3[@name] &bO evento &f@name &bfoi finalizado!" + - "&3[@name] &bNão houveram vencedores." + - "" + No players: + - "" + - "&3[@name] &bEvento cancelado." + - "&3[@name] &bA quantidade mínima de jogadores não foi atingida." + - "" + Cancelled: + - "" + - "&3[@name] &bO evento foi cancelado manualmente." + - "" + Enabling breaking: + - "&3[@name] &bAtivando quebra de blocos em &f@time&b segundos..." + Breaking allowed: + - "&3[@name] &bAgora vocês podem quebrar blocos!" + Kick: "&3[@name] &bComo você está parado, você será eliminado do evento em &f@time &bsegundos." + +# Recompensas. Elas serão dadas ao vencedor. +Rewards: + Tag: # Tag do LegendChat. + Enabled: true # Ativar a tag do evento? + Name: "aeventos_spleef" # O nome da tag. Você a colocará na configuração do LegendChat. Nesse caso, {aeventos_spleef} + Style: "&3[Spleef] " # A aparência da tag. + Commands: # Lista de comandos que serão executados no vencedor. + - "give @winner diamond 1" + + +# Localizações. Você configurará essa seção usando o comando /evento setup spleef +Locations: + Lobby: [] + Entrance: [] + Spectator: [] + Exit: [] + Pos1: [] Pos2: [] \ No newline at end of file diff --git a/src/main/resources/eventos/votacao.yml b/src/main/resources/eventos/votacao.yml index 8acd966..c8dce07 100644 --- a/src/main/resources/eventos/votacao.yml +++ b/src/main/resources/eventos/votacao.yml @@ -64,4 +64,10 @@ Alternatives: astronauta: Name: "Astronauta" paintball: - Name: "Paintball" \ No newline at end of file + Name: "Paintball" + hunter: + Name: "Hunter" + quiz: + Name: "Quiz" + anvil: + Name: "Anvil" \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 898af7b..bd56e33 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -6,7 +6,7 @@ author: Ars3ne website: ${project.url} main: com.ars3ne.eventos.aEventos -softdepend: [LegendChat, SimpleClans] +softdepend: [LegendChat, SimpleClans, Vault] commands: evento: