diff --git a/pom.xml b/pom.xml index 65cbb9e..f5b22b2 100644 --- a/pom.xml +++ b/pom.xml @@ -55,5 +55,10 @@ SpigotCore 2.0 + + steamwar + WorldEdit + 1.15 + \ No newline at end of file diff --git a/src/Doku.txt b/src/Doku.txt deleted file mode 100644 index 231b2d0..0000000 --- a/src/Doku.txt +++ /dev/null @@ -1,4 +0,0 @@ -Rot ist im süden -SpawnEgg name == MissleName (Config) - incl Color-Tags, ect -Missle-Configs sind für Team Rot \ No newline at end of file diff --git a/src/ToDo.txt b/src/ToDo.txt deleted file mode 100644 index 5d7995d..0000000 --- a/src/ToDo.txt +++ /dev/null @@ -1,14 +0,0 @@ -Config: - Timeout-Time - Runden max length - shield / platform / ect item on/off - give-speed (default: 11) -Features - Items: - shield - platform - fireball - pfeile - bridge - Item-giver - am anfang bogen geben \ No newline at end of file diff --git a/src/config.yml b/src/config.yml index d76b417..89c30fd 100644 --- a/src/config.yml +++ b/src/config.yml @@ -1,3 +1,23 @@ -portal: - red: -60 - blue: 60 \ No newline at end of file +WaitingTime: 600 +ItemTime: 300 +ShieldFlyTime: 100 +EndTime: 100 + +Arena: + MinX: 0 + MaxX: 0 + MinY: 0 + MinZ: 0 + MaxZ: 0 + +Red: + PortalZ: -60 + SpawnX: 0 + SpawnY: 0 + SpawnZ: 0 + +Blue: + PortalZ: 60 + SpawnX: 0 + SpawnY: 0 + SpawnZ: 0 diff --git a/src/de/steamwar/misslewars/Config.java b/src/de/steamwar/misslewars/Config.java new file mode 100644 index 0000000..278b07a --- /dev/null +++ b/src/de/steamwar/misslewars/Config.java @@ -0,0 +1,61 @@ +package de.steamwar.misslewars; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; + +import java.io.File; +import java.util.logging.Level; + +public class Config { + private Config(){} + + public static final int ArenaMinX; + public static final int ArenaMaxX; + public static final int ArenaMinY; + public static final int ArenaMinZ; + public static final int ArenaMaxZ; + + public static final Location RedSpawn; + public static final int RedPortalZ; + public static final Location BlueSpawn; + public static final int BluePortalZ; + + public static final int WaitingTime; + public static final int ItemTime; + public static final int ShieldFlyTime; + public static final int EndTime; + + static{ + if(!new File(MissileWars.getPlugin().getDataFolder(), "config.yml").exists()){ + MissileWars.getPlugin().saveDefaultConfig(); + Bukkit.getLogger().log(Level.SEVERE, "Config fehlt!"); + Bukkit.shutdown(); + } + + FileConfiguration config = MissileWars.getPlugin().getConfig(); + WaitingTime = config.getInt("WaitingTime"); + ItemTime = config.getInt("ItemTime"); + ShieldFlyTime = config.getInt("ShieldFlyTime"); + EndTime = config.getInt("EndTime"); + + ConfigurationSection arena = config.getConfigurationSection("Arena"); + assert arena != null; + ArenaMinX = arena.getInt("MinX"); + ArenaMaxX = arena.getInt("MaxX"); + ArenaMinY = arena.getInt("MinY"); + ArenaMinZ = arena.getInt("MinZ"); + ArenaMaxZ = arena.getInt("MaxZ"); + + ConfigurationSection red = config.getConfigurationSection("Red"); + assert red != null; + RedPortalZ = red.getInt("PortalZ"); + RedSpawn = new Location(Bukkit.getWorlds().get(0), red.getDouble("SpawnX"), red.getDouble("SpawnY"), red.getDouble("SpawnZ")); + + ConfigurationSection blue = config.getConfigurationSection("Blue"); + assert blue != null; + BluePortalZ = blue.getInt("PortalZ"); + BlueSpawn = new Location(Bukkit.getWorlds().get(0), blue.getDouble("SpawnX"), blue.getDouble("SpawnY"), blue.getDouble("SpawnZ")); + } +} diff --git a/src/de/steamwar/misslewars/FightScoreboard.java b/src/de/steamwar/misslewars/FightScoreboard.java index f6e6ef2..dcd7fd6 100644 --- a/src/de/steamwar/misslewars/FightScoreboard.java +++ b/src/de/steamwar/misslewars/FightScoreboard.java @@ -20,7 +20,6 @@ public class FightScoreboard { static{ if(scoreboard.getObjective("AAA") == null) - //noinspection deprecation objective = scoreboard.registerNewObjective("AAA", "BBB", "MissleWars"); else objective = scoreboard.getObjective("AAA"); @@ -29,7 +28,6 @@ public class FightScoreboard { public static void init(){ Bukkit.getScheduler().scheduleSyncRepeatingTask(MissileWars.getPlugin(), () -> { objective.unregister(); - //noinspection deprecation scoreboard.registerNewObjective("AAA", "BBB", "MissleWars"); objective.setDisplaySlot(DisplaySlot.SIDEBAR); diff --git a/src/de/steamwar/misslewars/MWTeam.java b/src/de/steamwar/misslewars/MWTeam.java index cd77b2f..4cfb1d3 100644 --- a/src/de/steamwar/misslewars/MWTeam.java +++ b/src/de/steamwar/misslewars/MWTeam.java @@ -6,6 +6,7 @@ import org.bukkit.Material; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.scoreboard.Team; import java.util.HashSet; @@ -16,7 +17,10 @@ public class MWTeam { private static final ItemStack bow = new ItemStack(Material.BOW); static { - Objects.requireNonNull(bow.getItemMeta()).addEnchant(Enchantment.ARROW_FIRE, 1, false); + ItemMeta bowMeta = Objects.requireNonNull(bow.getItemMeta()); + bowMeta.addEnchant(Enchantment.ARROW_FIRE, 1, false); + bowMeta.setUnbreakable(true); + bow.setItemMeta(bowMeta); } private final ChatColor color; @@ -31,7 +35,7 @@ public class MWTeam { return players; } - public MWTeam(ChatColor color, Location spawn, String teamName, int portalZ) { + MWTeam(ChatColor color, Location spawn, String teamName, int portalZ) { this.teamName = teamName; this.color = color; this.spawn = spawn; @@ -56,7 +60,7 @@ public class MWTeam { public void join (Player p) { players.add(p); p.teleport(spawn); - p.setItemOnCursor(bow); + p.getInventory().setItem(0, bow); sbteam.addPlayer(p); p.setDisplayName(color + teamName + " " + p.getName()); if (MissileWars.getFightState() == FightState.WAITING && !enemy().getPlayers().isEmpty()) @@ -69,11 +73,11 @@ public class MWTeam { players.remove(p); sbteam.removePlayer(p); - if (players.isEmpty()) + if (players.isEmpty() && MissileWars.getFightState() == FightState.FIGHTING) MissileWars.end(WinReasons.NO_ENEMY, enemy()); } - public MWTeam enemy() { + private MWTeam enemy() { if (this == MissileWars.getRedTeam()) return MissileWars.getBlueTeam(); diff --git a/src/de/steamwar/misslewars/MissileWars.java b/src/de/steamwar/misslewars/MissileWars.java index 73cb991..3b7e12f 100644 --- a/src/de/steamwar/misslewars/MissileWars.java +++ b/src/de/steamwar/misslewars/MissileWars.java @@ -1,16 +1,19 @@ package de.steamwar.misslewars; +import de.steamwar.misslewars.countdowns.EndCountdown; +import de.steamwar.misslewars.countdowns.ItemCountdown; +import de.steamwar.misslewars.countdowns.WaitingCountdown; +import de.steamwar.misslewars.items.Arrows; +import de.steamwar.misslewars.items.Fireball; +import de.steamwar.misslewars.items.Missile; +import de.steamwar.misslewars.items.Snowball; import de.steamwar.misslewars.listener.*; import org.bukkit.Bukkit; import org.bukkit.ChatColor; -import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; -import org.bukkit.scheduler.BukkitRunnable; public class MissileWars extends JavaPlugin { - private static final int END_PHASE_TIME = 600; //gameticks (30s) - private static MissileWars plugin; private static MWTeam redTeam; //red has South side -> spawns missles towards north private static MWTeam blueTeam; @@ -26,34 +29,44 @@ public class MissileWars extends JavaPlugin { fightState = FightState.WAITING; startTime = System.currentTimeMillis(); - //TODO: Config - redTeam = new MWTeam(ChatColor.RED, new Location(Bukkit.getWorlds().get(0), 0, 0, 0), "Rot", -63); - blueTeam = new MWTeam(ChatColor.BLUE, new Location(Bukkit.getWorlds().get(0), 0, 0, 0), "Blau", 63); - MissleSpawnSystem.load(); + redTeam = new MWTeam(ChatColor.RED, Config.RedSpawn, "Rot", Config.RedPortalZ); + blueTeam = new MWTeam(ChatColor.BLUE, Config.BlueSpawn, "Blau", Config.BluePortalZ); } @Override public void onEnable() { new DeathListener(); - new EggClickListener(); - new ArenaListener(arenaMinX, arenaMaxX, arenaMinZ, arenaMaxZ, arenaMinY); + new ItemListener(); + new ArenaListener(); new ConnectionListener(); new JoinListener(); new EndListener(); new PortalDestructListener(); + new WaitingListener(); + new FightListener(); - //TODO: Wait for players/Auto termination - BasicListener.setupListeners(fightState); + new WaitingCountdown(); + new ItemCountdown(); + new EndCountdown(); + + FightScoreboard.init(); + + Missile.init(); + new Arrows(); + new Fireball(); + new Snowball(); + + StateDependent.setupState(fightState); } /** * call to change fightstate from WAITING to INGAME */ - public static void startRound() { + static void startRound() { if (fightState != FightState.WAITING) // anti dual-call return; fightState = FightState.FIGHTING; - BasicListener.setupListeners(fightState); + StateDependent.setupState(fightState); startTime = System.currentTimeMillis(); } @@ -67,25 +80,19 @@ public class MissileWars extends JavaPlugin { if (fightState == FightState.END) //verhindern dass es mehrfach gecallt wird return; fightState = FightState.END; - BasicListener.setupListeners(fightState); + StateDependent.setupState(fightState); switch (reason) { + case PORTAL_DESTROYED: + Bukkit.getServer().broadcastMessage(winner.getColoredName() + ChatColor.RESET + " hat das gegnerische Portal zerstört."); + break; case NO_ENEMY: + default: Bukkit.getServer().broadcastMessage("Ohne Gegner kein Kampf - Team " + winner.getColoredName() + ChatColor.RESET + " hat gewonnen."); break; - case PORTAL_DESTROYED: - Bukkit.getServer().broadcastMessage(winner.getColoredName() + ChatColor.RESET + " hat das gegnerische Portal zerst�rt."); - break; } - new BukkitRunnable() { - public void run() { - Bukkit.getServer().shutdown(); - } - }.runTaskLater(plugin, END_PHASE_TIME); } - - public static MissileWars getPlugin() { return plugin; } @@ -103,9 +110,9 @@ public class MissileWars extends JavaPlugin { } public static MWTeam getTeam(Player p){ - if(blueTeam.getPlayers().contains(p)) + if(blueTeam.hasPlayer(p)) return blueTeam; - if(redTeam.getPlayers().contains(p)) + if(redTeam.hasPlayer(p)) return redTeam; return null; } diff --git a/src/de/steamwar/misslewars/MissleSpawnSystem.java b/src/de/steamwar/misslewars/MissleSpawnSystem.java deleted file mode 100644 index cc94fbe..0000000 --- a/src/de/steamwar/misslewars/MissleSpawnSystem.java +++ /dev/null @@ -1,143 +0,0 @@ -package de.steamwar.misslewars; - -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.block.data.type.Observer; -import org.bukkit.block.data.type.Piston; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; - -import java.io.File; -import java.util.ArrayList; - -public class MissleSpawnSystem { - - public static Missile[] missiles; - - /** - * load Config, ect - */ - @SuppressWarnings("unchecked") - public static void load() { - FileConfiguration c = YamlConfiguration.loadConfiguration(new File(MissileWars.getPlugin().getDataFolder(), "missles.yml")); - missiles = (c.getList("missles", new ArrayList())).toArray(); - } - - public static void paste(String missle, boolean red, Location l) { - for (Missile m : missiles) { - if (m.name == missle) - m.paste(l, red, red); - } - } - - /** - * Missle-Schematic - */ - @SuppressWarnings("unused") - private class Missile { - public String name; - private byte height; - private byte depth; - private byte width; - private MissleBlockTypes[] blocks; - - /** - * - * @param l Location of the spawning player - * @param redTeam for Block-color blue / red - * @param north facing north or south? - */ - public void paste(Location l, boolean redTeam, boolean north) { - byte a = 1; - if (!north) a = -1; - for (int x=0; x < width; x++) { - for (int y=height; y > 0; y--) { - for (int z=0; z < width; z++) { - int i = x+y*width+z*height*width; - if (i > blocks.length || i < 0) continue; - setBlock(blocks[i], Bukkit.getWorlds().get(0).getBlockAt(l.getBlockX() + x, l.getBlockY() + y, l.getBlockZ() + z * a), north, redTeam); - } - } - } - } - - //bewusst mit blockupdate, damit observer, ect beim pasten triggern - private void setBlock(MissleBlockTypes t, Block b, boolean n, boolean red) { - if (t == MissleBlockTypes.GLASS) { - if (red) - b.setType(Material.RED_STAINED_GLASS); - else - b.setType(Material.BLUE_STAINED_GLASS); - }else if (t == MissleBlockTypes.BLOCK) { - if (red) - b.setType(Material.RED_CONCRETE); - else - b.setType(Material.BLUE_CONCRETE); - }else if (t == MissleBlockTypes.HONEY_BLOCK) { - b.setType(Material.HONEY_BLOCK); - }else if (t == MissleBlockTypes.PANE) { - if (red) - b.setType(Material.RED_STAINED_GLASS_PANE); - else - b.setType(Material.BLUE_STAINED_GLASS_PANE); - }else if (t == MissleBlockTypes.TNT) { - b.setType(Material.TNT); - }else if (t == MissleBlockTypes.SLIME_BLOCK) { - b.setType(Material.SLIME_BLOCK); - }else if (t.toString().contains("STICKY_PISTON")) { - b.setType(Material.STICKY_PISTON); - ((Piston) b).setFacing(getFacing(t, n)); - }else if (t.toString().contains("PISTON")) { - b.setType(Material.PISTON); - ((Piston) b).setFacing(getFacing(t, n)); - }else if (t.toString().contains("OBSERVER")) { - b.setType(Material.OBSERVER); - ((Observer) b).setFacing(getFacing(t, n)); - } - } - } - - public BlockFace getFacing(MissleBlockTypes t, boolean north) { - String s = t.toString(); - if (s.contains("UP")) return BlockFace.UP; - if (s.contains("DOWN")) return BlockFace.DOWN; - if ((s.contains("NORTH") && north) || (s.contains("SOUTH") && !north)) return BlockFace.NORTH; - if ((s.contains("NORTH") && !north) || (s.contains("SOUTH") && north)) return BlockFace.SOUTH; - if ((s.contains("WEST") && north) || (s.contains("EAST") && !north)) return BlockFace.WEST; - return BlockFace.EAST; - } - - /** - * For Config & lowRAM save of missles - */ - private enum MissleBlockTypes { - PISTON_UP, - PISTON_DOWN, - PISTON_NORTH, - PISTON_SOUTH, - PISTON_EAST, - PISTON_WEST, - STICKY_PISTON_UP, - STICKY_PISTON_DOWN, - STICKY_PISTON_NORTH, - STICKY_PISTON_SOUTH, - STICKY_PISTON_WEST, - STICKY_PISTON_EAST, - GLASS, //teamcolored - BLOCK, //normal block, teamcolored - PANE, //teamcolored (glass-pane) - REDSTONE_BLOCK, - OBSERVER_UP, - OBSERVER_DOWN, - OBSERVER_NORTH, - OBSERVER_SOUTH, - OBSERVER_EAST, - OBSERVER_WEST, - SLIME_BLOCK, - HONEY_BLOCK, - TNT - } -} diff --git a/src/de/steamwar/misslewars/StateDependent.java b/src/de/steamwar/misslewars/StateDependent.java new file mode 100644 index 0000000..015fa2c --- /dev/null +++ b/src/de/steamwar/misslewars/StateDependent.java @@ -0,0 +1,32 @@ +package de.steamwar.misslewars; + +import java.util.HashSet; +import java.util.Set; + +public abstract class StateDependent { + private static Set listeners = new HashSet<>(); + + private final Set active; + private boolean running; + + public StateDependent(final Set active){ + this.active = active; + running = false; + listeners.add(this); + } + + public abstract void enable(); + public abstract void disable(); + + static void setupState(FightState state){ + for(StateDependent listener : listeners){ + if(listener.running && !listener.active.contains(state)){ + listener.enable(); + listener.running = false; + }else if(!listener.running && listener.active.contains(state)){ + listener.disable(); + listener.running = true; + } + } + } +} diff --git a/src/de/steamwar/misslewars/countdowns/EndCountdown.java b/src/de/steamwar/misslewars/countdowns/EndCountdown.java new file mode 100644 index 0000000..339e10f --- /dev/null +++ b/src/de/steamwar/misslewars/countdowns/EndCountdown.java @@ -0,0 +1,35 @@ +package de.steamwar.misslewars.countdowns; + +import de.steamwar.misslewars.Config; +import de.steamwar.misslewars.FightState; +import de.steamwar.misslewars.MissileWars; +import de.steamwar.misslewars.StateDependent; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitTask; + +import java.util.EnumSet; + +public class EndCountdown extends StateDependent { + + private BukkitTask task; + + public EndCountdown() { + super(EnumSet.of(FightState.END)); + } + + @Override + public void enable() { + task = Bukkit.getScheduler().runTaskLater(MissileWars.getPlugin(), () -> { + for(Player p : Bukkit.getOnlinePlayers()){ + p.kickPlayer(null); + } + }, Config.EndTime); + } + + @Override + public void disable() { + if(!task.isCancelled()) + task.cancel(); + } +} diff --git a/src/de/steamwar/misslewars/countdowns/ItemCountdown.java b/src/de/steamwar/misslewars/countdowns/ItemCountdown.java new file mode 100644 index 0000000..da39314 --- /dev/null +++ b/src/de/steamwar/misslewars/countdowns/ItemCountdown.java @@ -0,0 +1,66 @@ +package de.steamwar.misslewars.countdowns; + +import de.steamwar.misslewars.*; +import de.steamwar.misslewars.items.SpecialItem; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitTask; + +import java.util.EnumSet; + +public class ItemCountdown extends StateDependent { + + private BukkitTask task; + + public ItemCountdown() { + super(EnumSet.of(FightState.FIGHTING)); + } + + private void run(){ + ItemStack item = SpecialItem.getRandomItem(); + giveTeamItem(MissileWars.getBlueTeam(), item); + giveTeamItem(MissileWars.getRedTeam(), item); + } + + private void giveTeamItem(MWTeam team, ItemStack item){ + for(Player p : team.getPlayers()){ + givePlayerItem(p, item); + } + } + + private void givePlayerItem(Player p, ItemStack item){ + Inventory inventory = p.getInventory(); + for (int i = 0; i <= 35; i++) { //35 is the last normal inventory slot + ItemStack itemStack = inventory.getItem(i); + if (itemStack != null && itemStack.isSimilar(item) && itemStack.getAmount() != itemStack.getMaxStackSize()) { + itemStack.setAmount(itemStack.getAmount() + item.getAmount()); + inventory.setItem(i, itemStack); + p.updateInventory(); + return; + } + } + + for (int i = 0; i <= 35; i++) { //35 is the last normal inventory slot + ItemStack itemStack = inventory.getItem(i); + if (itemStack == null || itemStack.getType().equals(Material.AIR)) { + inventory.setItem(i, item); + p.updateInventory(); + return; + } + } + } + + @Override + public void enable() { + task = Bukkit.getScheduler().runTaskTimer(MissileWars.getPlugin(), this::run, Config.ItemTime, 0); + } + + @Override + public void disable() { + if(!task.isCancelled()) + task.cancel(); + } +} diff --git a/src/de/steamwar/misslewars/countdowns/WaitingCountdown.java b/src/de/steamwar/misslewars/countdowns/WaitingCountdown.java new file mode 100644 index 0000000..88ff1ce --- /dev/null +++ b/src/de/steamwar/misslewars/countdowns/WaitingCountdown.java @@ -0,0 +1,33 @@ +package de.steamwar.misslewars.countdowns; + +import de.steamwar.misslewars.Config; +import de.steamwar.misslewars.FightState; +import de.steamwar.misslewars.MissileWars; +import de.steamwar.misslewars.StateDependent; +import org.bukkit.Bukkit; +import org.bukkit.scheduler.BukkitTask; + +import java.util.EnumSet; + +public class WaitingCountdown extends StateDependent { + + private BukkitTask task; + + public WaitingCountdown() { + super(EnumSet.of(FightState.WAITING)); + } + + @Override + public void enable() { + task = Bukkit.getScheduler().runTaskLater(MissileWars.getPlugin(), () -> { + if(Bukkit.getOnlinePlayers().isEmpty()) + Bukkit.shutdown(); + }, Config.WaitingTime); + } + + @Override + public void disable() { + if(!task.isCancelled()) + task.cancel(); + } +} diff --git a/src/de/steamwar/misslewars/items/Arrows.java b/src/de/steamwar/misslewars/items/Arrows.java new file mode 100644 index 0000000..37c0bea --- /dev/null +++ b/src/de/steamwar/misslewars/items/Arrows.java @@ -0,0 +1,20 @@ +package de.steamwar.misslewars.items; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class Arrows extends SpecialItem { + + private final ItemStack item = new ItemStack(Material.ARROW, 3); + + @Override + public ItemStack getItem() { + return item; + } + + @Override + public boolean handleUse(Player p) { + return false; + } +} diff --git a/src/de/steamwar/misslewars/items/Fireball.java b/src/de/steamwar/misslewars/items/Fireball.java new file mode 100644 index 0000000..86b6d52 --- /dev/null +++ b/src/de/steamwar/misslewars/items/Fireball.java @@ -0,0 +1,22 @@ +package de.steamwar.misslewars.items; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class Fireball extends SpecialItem { + + private final ItemStack item = new ItemStack(Material.FIRE_CHARGE, 1); + + @Override + public ItemStack getItem() { + return item; + } + + @Override + public boolean handleUse(Player p) { + org.bukkit.entity.Fireball fb = p.launchProjectile(org.bukkit.entity.Fireball.class); + fb.setIsIncendiary(true); + return true; + } +} diff --git a/src/de/steamwar/misslewars/items/Missile.java b/src/de/steamwar/misslewars/items/Missile.java new file mode 100644 index 0000000..83bfa69 --- /dev/null +++ b/src/de/steamwar/misslewars/items/Missile.java @@ -0,0 +1,97 @@ +package de.steamwar.misslewars.items; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.bukkit.BukkitWorld; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat; +import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats; +import com.sk89q.worldedit.function.operation.Operations; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.math.transform.AffineTransform; +import com.sk89q.worldedit.session.ClipboardHolder; +import com.sk89q.worldedit.world.World; +import de.steamwar.misslewars.MissileWars; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Objects; + +public class Missile extends SpecialItem { + + private static final World world = new BukkitWorld(Bukkit.getWorlds().get(0)); + + private final Clipboard clipboard; + private final ItemStack item; + + private Missile(File missileFile){ + String name = missileFile.getName().split(".")[0]; + Material itemType = Material.valueOf(missileFile.getName().split(".")[1]); + + ClipboardFormat format = ClipboardFormats.findByFile(missileFile); + + try { + assert format != null; + clipboard = format.getReader(new FileInputStream(missileFile)).read(); + } catch (IOException e) { + throw new SecurityException("Corrupt missile"); + } + + item = new ItemStack(itemType, 1); + ItemMeta meta = item.getItemMeta(); + assert meta != null; + meta.setDisplayName(name); + item.setItemMeta(meta); + } + + @Override + public ItemStack getItem(){ + return item; + } + + @Override + public boolean handleUse(Player p){ + BlockVector3 dimensions = clipboard.getDimensions(); + Location location = p.getLocation(); + BlockVector3 v = BlockVector3.at(location.getBlockX(), location.getBlockY(), location.getBlockZ()); + BlockVector3 offset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin()); + AffineTransform aT = new AffineTransform(); + + double yaw = p.getLocation().getYaw(); + if(yaw > 45 && yaw <= 135) + aT = aT.rotateY(90); + else if(yaw > 135 && yaw <= 225) + aT = aT.rotateY(180); + else if(yaw > 225 && yaw <= 315) + aT = aT.rotateY(270); + + v = v.subtract(dimensions.getX()/2, dimensions.getY(), dimensions.getZ()/2 - dimensions.getZ()%2).subtract(offset); + + EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(world, -1); + ClipboardHolder ch = new ClipboardHolder(clipboard); + ch.setTransform(aT); + Operations.completeBlindly(ch.createPaste(e).to(v).build()); + e.flushSession(); + return true; + } + + public static void init(){ + File missileFolder = new File(MissileWars.getPlugin().getDataFolder(), "missiles"); + if(!missileFolder.exists() || !missileFolder.canRead() || !missileFolder.isDirectory()){ + throw new SecurityException("Missiles could not be loaded"); + } + for(File missileFile : Objects.requireNonNull(missileFolder.listFiles())){ + if(!missileFile.canRead() || !missileFile.isFile()) + continue; + + new Missile(missileFile); + } + } +} diff --git a/src/de/steamwar/misslewars/items/Snowball.java b/src/de/steamwar/misslewars/items/Snowball.java new file mode 100644 index 0000000..384b9fc --- /dev/null +++ b/src/de/steamwar/misslewars/items/Snowball.java @@ -0,0 +1,20 @@ +package de.steamwar.misslewars.items; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class Snowball extends SpecialItem { + + private final ItemStack item = new ItemStack(Material.SNOWBALL, 1); + + @Override + public ItemStack getItem() { + return item; + } + + @Override + public boolean handleUse(Player p) { + return false; + } +} diff --git a/src/de/steamwar/misslewars/items/SpecialItem.java b/src/de/steamwar/misslewars/items/SpecialItem.java new file mode 100644 index 0000000..bce73bf --- /dev/null +++ b/src/de/steamwar/misslewars/items/SpecialItem.java @@ -0,0 +1,33 @@ +package de.steamwar.misslewars.items; + +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import java.util.*; + +public abstract class SpecialItem { + + private static final Random random = new Random(); + + private static List items = new ArrayList<>(); + + SpecialItem(){ + items.add(this); + } + + public abstract ItemStack getItem(); + public abstract boolean handleUse(Player p); + + public static boolean handleUse(ItemStack item, Player player){ + for(SpecialItem specialItem : items){ + if(item.isSimilar(specialItem.getItem())){ + return specialItem.handleUse(player); + } + } + return false; + } + + public static ItemStack getRandomItem(){ + return items.get(random.nextInt(items.size())).getItem(); + } +} diff --git a/src/de/steamwar/misslewars/listener/ArenaListener.java b/src/de/steamwar/misslewars/listener/ArenaListener.java index 1af16d9..bf0b6de 100644 --- a/src/de/steamwar/misslewars/listener/ArenaListener.java +++ b/src/de/steamwar/misslewars/listener/ArenaListener.java @@ -1,5 +1,6 @@ package de.steamwar.misslewars.listener; +import de.steamwar.misslewars.Config; import de.steamwar.misslewars.FightState; import org.bukkit.GameMode; import org.bukkit.Location; @@ -11,19 +12,8 @@ import java.util.EnumSet; public class ArenaListener extends BasicListener { - private final int arenaMinX; - private final int arenaMaxX; - private final int arenaMinZ; - private final int arenaMaxZ; - private final int arenaMinY; - - public ArenaListener(int arenaMinX, int arenaMaxX, int arenaMinZ, int arenaMaxZ, int arenaMinY) { + public ArenaListener() { super(EnumSet.allOf(FightState.class)); - this.arenaMinX = arenaMinX; - this.arenaMaxX = arenaMaxX; - this.arenaMinZ = arenaMinZ; - this.arenaMaxZ = arenaMaxZ; - this.arenaMinY = arenaMinY; } @EventHandler @@ -32,16 +22,16 @@ public class ArenaListener extends BasicListener { Player p = e.getPlayer(); assert location != null; - if(location.getY() < arenaMinY){ + if(location.getY() < Config.ArenaMinY){ if(p.getGameMode() == GameMode.SPECTATOR) p.teleport(e.getFrom()); else p.damage(Double.MAX_VALUE); }else if( - location.getX() < arenaMinX || - location.getX() > arenaMaxX || - location.getZ() < arenaMinZ || - location.getZ() > arenaMaxZ){ + location.getX() < Config.ArenaMinX || + location.getX() > Config.ArenaMaxX || + location.getZ() < Config.ArenaMinZ || + location.getZ() > Config.ArenaMaxZ){ p.teleport(e.getFrom()); } } diff --git a/src/de/steamwar/misslewars/listener/BasicListener.java b/src/de/steamwar/misslewars/listener/BasicListener.java index 27daa5b..f0ee5ad 100644 --- a/src/de/steamwar/misslewars/listener/BasicListener.java +++ b/src/de/steamwar/misslewars/listener/BasicListener.java @@ -2,34 +2,27 @@ package de.steamwar.misslewars.listener; import de.steamwar.misslewars.FightState; import de.steamwar.misslewars.MissileWars; +import de.steamwar.misslewars.StateDependent; import org.bukkit.Bukkit; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; -import java.util.HashSet; import java.util.Set; -public abstract class BasicListener implements Listener { - private static Set listeners = new HashSet<>(); +public abstract class BasicListener extends StateDependent implements Listener { - private final Set active; - private boolean running; BasicListener(final Set active){ - this.active = active; - running = false; - listeners.add(this); + super(active); } - public static void setupListeners(FightState state){ - for(BasicListener listener : listeners){ - if(listener.running && !listener.active.contains(state)){ - HandlerList.unregisterAll(listener); - listener.running = false; - }else if(!listener.running && listener.active.contains(state)){ - Bukkit.getPluginManager().registerEvents(listener, MissileWars.getPlugin()); - listener.running = true; - } - } + @Override + public void enable(){ + Bukkit.getPluginManager().registerEvents(this, MissileWars.getPlugin()); + } + + @Override + public void disable(){ + HandlerList.unregisterAll(this); } } diff --git a/src/de/steamwar/misslewars/listener/EggClickListener.java b/src/de/steamwar/misslewars/listener/EggClickListener.java deleted file mode 100644 index e296e60..0000000 --- a/src/de/steamwar/misslewars/listener/EggClickListener.java +++ /dev/null @@ -1,24 +0,0 @@ -package de.steamwar.misslewars.listener; - -import de.steamwar.misslewars.FightState; -import de.steamwar.misslewars.MissileWars; -import de.steamwar.misslewars.MissleSpawnSystem; -import org.bukkit.event.EventHandler; -import org.bukkit.event.player.PlayerInteractEvent; - -import java.util.EnumSet; - -public class EggClickListener extends BasicListener { - public EggClickListener() { - super(EnumSet.of(FightState.FIGHTING)); - } - - @EventHandler - public void onItemClick(PlayerInteractEvent e) { - if (e.getItem() == null || !e.getItem().getType().toString().contains("SPAWN_EGG")) - return; - MissleSpawnSystem.paste(e.getItem().getItemMeta().getDisplayName() , MissileWars.getRedTeam().hasPlayer(e.getPlayer()), e.getPlayer().getLocation()); - e.getItem().setAmount(e.getItem().getAmount()-1); - e.setCancelled(true); - } -} diff --git a/src/de/steamwar/misslewars/listener/FightListener.java b/src/de/steamwar/misslewars/listener/FightListener.java new file mode 100644 index 0000000..a8e8c65 --- /dev/null +++ b/src/de/steamwar/misslewars/listener/FightListener.java @@ -0,0 +1,28 @@ +package de.steamwar.misslewars.listener; + +import de.steamwar.misslewars.FightState; +import de.steamwar.misslewars.MissileWars; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +import java.util.EnumSet; + +public class FightListener extends BasicListener { + + public FightListener() { + super(EnumSet.of(FightState.FIGHTING)); + } + + @EventHandler + public void onDamage(EntityDamageByEntityEvent e){ + if(!(e.getDamager() instanceof Player && e.getEntity() instanceof Player)) + return; + + Player damager = (Player)e.getDamager(); + Player reciever = (Player)e.getEntity(); + + if(MissileWars.getTeam(damager) == MissileWars.getTeam(reciever)) + e.setCancelled(true); + } +} diff --git a/src/de/steamwar/misslewars/listener/ItemListener.java b/src/de/steamwar/misslewars/listener/ItemListener.java new file mode 100644 index 0000000..30286c3 --- /dev/null +++ b/src/de/steamwar/misslewars/listener/ItemListener.java @@ -0,0 +1,77 @@ +package de.steamwar.misslewars.listener; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.bukkit.BukkitWorld; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats; +import com.sk89q.worldedit.function.operation.Operations; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.session.ClipboardHolder; +import com.sk89q.worldedit.world.World; +import de.steamwar.misslewars.Config; +import de.steamwar.misslewars.FightState; +import de.steamwar.misslewars.MissileWars; +import de.steamwar.misslewars.items.SpecialItem; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Snowball; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.ProjectileLaunchEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.EnumSet; +import java.util.Objects; + +public class ItemListener extends BasicListener { + + private static final File shield = new File(de.steamwar.misslewars.MissileWars.getPlugin().getDataFolder(), "shield.schematic"); + private static final World world = new BukkitWorld(Bukkit.getWorlds().get(0)); + private static final Clipboard clipboard; + private static final BlockVector3 offset; + + static { + try { + clipboard = Objects.requireNonNull(ClipboardFormats.findByFile(shield)).getReader(new FileInputStream(shield)).read(); + } catch (IOException e) { + throw new SecurityException("Could not load shield", e); + } + + offset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin()).add(clipboard.getDimensions().divide(2)); + } + + public ItemListener() { + super(EnumSet.of(FightState.FIGHTING)); + } + + @EventHandler + public void onItemClick(PlayerInteractEvent e) { + ItemStack item = e.getItem(); + if (item == null) + return; + + if(SpecialItem.handleUse(item, e.getPlayer())){ + item.setAmount(item.getAmount()-1); + e.getPlayer().updateInventory(); + e.setCancelled(true); + } + } + + @EventHandler + public void onThrow(ProjectileLaunchEvent e) { + if (e.getEntity() instanceof Snowball) { + Bukkit.getScheduler().runTaskLater(MissileWars.getPlugin(), () -> { + Location l = e.getEntity().getLocation(); + BlockVector3 paste = BlockVector3.at(l.getX(), l.getY(), l.getZ()).subtract(offset); + + EditSession editSession = WorldEdit.getInstance().getEditSessionFactory().getEditSession(world, -1); + Operations.completeBlindly(new ClipboardHolder(clipboard).createPaste(editSession).to(paste).build()); + editSession.flushSession(); + }, Config.ShieldFlyTime); + } + } +} diff --git a/src/de/steamwar/misslewars/listener/WaitingListener.java b/src/de/steamwar/misslewars/listener/WaitingListener.java new file mode 100644 index 0000000..a03aca9 --- /dev/null +++ b/src/de/steamwar/misslewars/listener/WaitingListener.java @@ -0,0 +1,26 @@ +package de.steamwar.misslewars.listener; + +import de.steamwar.misslewars.FightState; +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +import java.util.EnumSet; + +public class WaitingListener extends BasicListener { + public WaitingListener() { + super(EnumSet.of(FightState.WAITING)); + } + + @EventHandler + public void onDisconnect(PlayerQuitEvent e){ + if(Bukkit.getOnlinePlayers().isEmpty()) + Bukkit.shutdown(); + } + + @EventHandler + public void onDamage(EntityDamageEvent e){ + e.setCancelled(true); + } +}