소스 검색

Merge pull request #112 from RedstoneWorld/improvements/shield-schematics

Reworking schematic equipment mgnt. + Adding shield schematics
RedstoneFuture 1 년 전
부모
커밋
da2f80712e
28개의 변경된 파일455개의 추가작업 그리고 237개의 파일을 삭제
  1. 6 9
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/MissileWars.java
  2. 1 1
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/commands/MWCommandCompletions.java
  3. 5 5
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/commands/MWCommands.java
  4. 6 0
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/configuration/Config.java
  5. 4 3
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/configuration/arena/Arena.java
  6. 62 42
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/configuration/arena/MissileConfiguration.java
  7. 66 4
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/configuration/arena/ShieldConfiguration.java
  8. 34 8
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/Game.java
  9. 5 2
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/equipment/EquipmentManager.java
  10. 23 7
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/equipment/PlayerEquipmentRandomizer.java
  11. 22 14
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/equipment/SchematicGameEquipment.java
  12. 7 23
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/equipment/SpecialGameEquipment.java
  13. 1 1
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/misc/MissileWarsPlaceholder.java
  14. 23 0
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/schematics/SchematicConfiguration.java
  15. 11 10
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/schematics/SchematicFacing.java
  16. 31 42
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/schematics/objects/Missile.java
  17. 55 0
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/schematics/objects/SchematicObject.java
  18. 54 0
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/schematics/objects/Shield.java
  19. 1 1
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/schematics/paste/PasteProvider.java
  20. 5 4
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/schematics/paste/Paster.java
  21. 3 2
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/schematics/paste/R1_13FawePasteProvider.java
  22. 3 2
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/schematics/paste/R1_13WEPasteProvider.java
  23. 3 2
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/schematics/paste/R1_16FawePasteProvider.java
  24. 14 23
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/listener/ShieldListener.java
  25. 4 4
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/listener/game/GameListener.java
  26. 6 28
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/util/SetupUtil.java
  27. BIN
      missilewars-plugin/src/main/resources/shield.schematic
  28. BIN
      missilewars-plugin/src/main/resources/shields.zip

+ 6 - 9
missilewars-plugin/src/main/java/de/butzlabben/missilewars/MissileWars.java

@@ -19,11 +19,7 @@
 package de.butzlabben.missilewars;
 
 import co.aikar.commands.PaperCommandManager;
-import de.butzlabben.missilewars.commands.MWCommandCompletions;
-import de.butzlabben.missilewars.commands.MWCommands;
-import de.butzlabben.missilewars.commands.SetupCommands;
-import de.butzlabben.missilewars.commands.StatsCommands;
-import de.butzlabben.missilewars.commands.UserCommands;
+import de.butzlabben.missilewars.commands.*;
 import de.butzlabben.missilewars.configuration.Config;
 import de.butzlabben.missilewars.configuration.Messages;
 import de.butzlabben.missilewars.game.Arenas;
@@ -40,8 +36,6 @@ import de.butzlabben.missilewars.util.MoneyUtil;
 import de.butzlabben.missilewars.util.SetupUtil;
 import de.butzlabben.missilewars.util.stats.PreFetcher;
 import de.butzlabben.missilewars.util.version.VersionUtil;
-import java.io.File;
-import java.util.Date;
 import lombok.Getter;
 import org.apache.commons.io.FileUtils;
 import org.bstats.bukkit.Metrics;
@@ -50,6 +44,9 @@ import org.bukkit.configuration.serialization.ConfigurationSerialization;
 import org.bukkit.entity.Player;
 import org.bukkit.plugin.java.JavaPlugin;
 
+import java.io.File;
+import java.util.Date;
+
 /**
  * @author Butzlabben
  * @since 01.01.2018
@@ -94,7 +91,8 @@ public class MissileWars extends JavaPlugin {
 
         Config.load();
         Messages.load();
-        SetupUtil.checkMissiles();
+        SetupUtil.saveDefaultSchematics(new File(Config.getMissilesFolder()), "missiles.zip");
+        SetupUtil.saveDefaultSchematics(new File(Config.getShieldsFolder()), "shields.zip");
 
         new File(Config.getLobbiesFolder()).mkdirs();
 
@@ -104,7 +102,6 @@ public class MissileWars extends JavaPlugin {
         registerCommands();
 
         Arenas.load();
-        SetupUtil.checkShields();
 
         GameManager.getInstance().loadGamesOnStartup();
 

+ 1 - 1
missilewars-plugin/src/main/java/de/butzlabben/missilewars/commands/MWCommandCompletions.java

@@ -52,7 +52,7 @@ public class MWCommandCompletions {
             Game game = GameManager.getInstance().getGame(player.getLocation());
             if (game == null) return null;
 
-            return game.getArena().getMissileConfiguration().getMissileNames();
+            return game.getArena().getMissileConfiguration().getSchematicNames();
         });
     }
 

+ 5 - 5
missilewars-plugin/src/main/java/de/butzlabben/missilewars/commands/MWCommands.java

@@ -30,8 +30,8 @@ import de.butzlabben.missilewars.game.GameManager;
 import de.butzlabben.missilewars.game.enums.GameResult;
 import de.butzlabben.missilewars.game.enums.GameState;
 import de.butzlabben.missilewars.game.enums.VoteState;
-import de.butzlabben.missilewars.game.missile.Missile;
-import de.butzlabben.missilewars.game.missile.MissileFacing;
+import de.butzlabben.missilewars.game.schematics.SchematicFacing;
+import de.butzlabben.missilewars.game.schematics.objects.Missile;
 import de.butzlabben.missilewars.game.timer.LobbyTimer;
 import org.bukkit.command.CommandSender;
 import org.bukkit.entity.Player;
@@ -110,14 +110,14 @@ public class MWCommands extends BaseCommand {
             return;
         }
 
-        Missile missile = game.getArena().getMissileConfiguration().getMissileFromName(args[0]);
+        Missile missile = (Missile) game.getArena().getMissileConfiguration().getSchematicFromName(args[0]);
         if (missile == null) {
             player.sendMessage(Messages.getMessage(true, Messages.MessageEnum.COMMAND_INVALID_MISSILE));
             return;
         }
 
-        MissileFacing missileFacing = MissileFacing.getFacingPlayer(player, game.getArena().getMissileConfiguration());
-        missile.paste(player, missileFacing, game);
+        SchematicFacing schematicFacing = SchematicFacing.getFacingPlayer(player, game.getArena().getMissileConfiguration());
+        missile.paste(game, player, schematicFacing);
     }
 
     @Subcommand("start")

+ 6 - 0
missilewars-plugin/src/main/java/de/butzlabben/missilewars/configuration/Config.java

@@ -64,6 +64,7 @@ public class Config {
         // re-save the config with only validated options
         SetupUtil.safeFile(FILE, cfg);
         cfg = SetupUtil.getLoadedConfig(FILE);
+
     }
 
     private static void addDefaults() {
@@ -86,6 +87,7 @@ public class Config {
         cfg.addDefault("lobbies.default_lobby", "lobby0.yml");
 
         cfg.addDefault("missiles.folder", "plugins/MissileWars/missiles");
+        cfg.addDefault("shields.folder", "plugins/MissileWars/shields");
 
         cfg.addDefault("replace.material", JUKEBOX.name());
         cfg.addDefault("replace.after_ticks", 2);
@@ -226,6 +228,10 @@ public class Config {
         return cfg.getString("missiles.folder");
     }
 
+    public static String getShieldsFolder() {
+        return cfg.getString("shields.folder");
+    }
+
     public static int getReplaceTicks() {
         return cfg.getInt("replace.after_ticks");
     }

+ 4 - 3
missilewars-plugin/src/main/java/de/butzlabben/missilewars/configuration/arena/Arena.java

@@ -21,13 +21,14 @@ package de.butzlabben.missilewars.configuration.arena;
 import com.google.gson.annotations.SerializedName;
 import de.butzlabben.missilewars.util.geometry.GameArea;
 import de.butzlabben.missilewars.util.serialization.Serializer;
-import java.io.File;
-import java.io.IOException;
 import lombok.Getter;
 import lombok.Setter;
 import lombok.ToString;
 import org.bukkit.Location;
 
+import java.io.File;
+import java.io.IOException;
+
 @Getter
 @ToString
 public class Arena implements Cloneable {
@@ -47,13 +48,13 @@ public class Arena implements Cloneable {
     @SerializedName("max_spectators") private int maxSpectators = -1;
     @SerializedName("game_duration") private int gameDuration = 30;
     @SerializedName("fireball") private FireballConfiguration fireballConfiguration = new FireballConfiguration();
-    @SerializedName("shield") private ShieldConfiguration shieldConfiguration = new ShieldConfiguration();
     @SerializedName("arrow") private ArrowConfiguration arrowConfiguration = new ArrowConfiguration();
     @SerializedName("save_statistics") private boolean saveStatistics = true;
     @SerializedName("fall_protection") private FallProtectionConfiguration fallProtection = new FallProtectionConfiguration();
     @SerializedName("money") private MoneyConfiguration money = new MoneyConfiguration();
     @SerializedName("equipment_interval") private EquipmentIntervalConfiguration interval = new EquipmentIntervalConfiguration();
     @SerializedName("missile") private MissileConfiguration missileConfiguration = new MissileConfiguration();
+    @SerializedName("shield") private ShieldConfiguration shieldConfiguration = new ShieldConfiguration();
     @Setter @SerializedName("area") private AreaConfiguration areaConfig = new AreaConfiguration(-30, 0, -72, 30, 256, 72);
 
     @SerializedName("spectator_spawn")

+ 62 - 42
missilewars-plugin/src/main/java/de/butzlabben/missilewars/configuration/arena/MissileConfiguration.java

@@ -19,27 +19,25 @@
 package de.butzlabben.missilewars.configuration.arena;
 
 import de.butzlabben.missilewars.Logger;
-import de.butzlabben.missilewars.game.missile.Missile;
-import de.butzlabben.missilewars.game.missile.MissileFacing;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import de.butzlabben.missilewars.game.schematics.SchematicConfiguration;
+import de.butzlabben.missilewars.game.schematics.SchematicFacing;
+import de.butzlabben.missilewars.game.schematics.objects.Missile;
+import de.butzlabben.missilewars.game.schematics.objects.SchematicObject;
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 import lombok.ToString;
 import org.bukkit.entity.EntityType;
 
+import java.io.File;
+import java.util.*;
+
 
 @Getter
 @ToString
 @RequiredArgsConstructor
-public class MissileConfiguration {
+public class MissileConfiguration extends SchematicConfiguration {
 
     // TODO pretty names
-
     private boolean onlyBlockPlaceable = false;
     private boolean onlyBetweenSpawnPlaceable = false;
     private boolean northFacing = true;
@@ -47,57 +45,79 @@ public class MissileConfiguration {
     private boolean southFacing = true;
     private boolean westFacing = true;
 
-    private List<Missile> missiles = new ArrayList<>() {{
-        add(new Missile("Tomahawk.schematic", "&aTomahawk", EntityType.CREEPER, 2, 2, 3));
-        add(new Missile("Cruiser.schematic", "&eCruiser", EntityType.BLAZE, 2, 2, 2));
-        add(new Missile("Sword.schematic", "&7Sword", EntityType.SKELETON, 2, 2, 2));
-        add(new Missile("Juggernaut.schematic", "&4Juggernaut", EntityType.MUSHROOM_COW, 2, 2, 1));
-        add(new Missile("Piranha.schematic", "&3Piranha", EntityType.HORSE, 2, 2, 3));
-        add(new Missile("Tunnelbore.schematic", "&0Tunnelbore", EntityType.ENDERMAN, 2, 2, 1));
+    private List<Missile> schematics = new ArrayList<>() {{
+        add(new Missile("Tomahawk.schematic", "&aTomahawk", 3, EntityType.CREEPER, 2, 2));
+        add(new Missile("Cruiser.schematic", "&eCruiser", 2, EntityType.BLAZE, 2, 2));
+        add(new Missile("Sword.schematic", "&7Sword", 2, EntityType.SKELETON, 2, 2));
+        add(new Missile("Juggernaut.schematic", "&4Juggernaut", 1, EntityType.MUSHROOM_COW, 2, 2));
+        add(new Missile("Piranha.schematic", "&3Piranha", 3, EntityType.HORSE, 2, 2));
+        add(new Missile("Tunnelbore.schematic", "&0Tunnelbore", 1, EntityType.ENDERMAN, 2, 2));
     }};
 
-    public List<MissileFacing> getEnabledFacings() {
-        List<MissileFacing> enabledDirections = new ArrayList<>();
 
-        if (northFacing) enabledDirections.add(MissileFacing.NORTH);
-        if (eastFacing) enabledDirections.add(MissileFacing.EAST);
-        if (southFacing) enabledDirections.add(MissileFacing.SOUTH);
-        if (westFacing) enabledDirections.add(MissileFacing.WEST);
+    @Override
+    public String getObjectNameSingular() {
+        return "Missile";
+    }
+
+    @Override
+    public String getObjectNamePlural() {
+        return "Missiles";
+    }
+    
+    @Override
+    public List<String> getSchematicNames() {
+        List<String> schematicNames = new ArrayList<>();
 
-        if (enabledDirections.isEmpty()) {
-            Logger.WARN.log("All facings were disabled for an arena. Please correct this issue");
-            enabledDirections.addAll(Arrays.asList(MissileFacing.values()));
+        for (Missile missile : getSchematics()) {
+            schematicNames.add(missile.getSchematicName(true));
         }
 
-        return enabledDirections;
+        return schematicNames;
     }
 
-    public Missile getMissileFromName(String name) {
+    @Override
+    public SchematicObject getSchematicFromName(String name) {
         String filteredName = name.replaceAll("§.", "");
-        for (Missile missile : missiles) {
+
+        for (Missile missile : getSchematics()) {
             if (missile.getSchematicName(true).equalsIgnoreCase(filteredName)) return missile;
         }
-        Logger.WARN.log("Missile not found: " + filteredName);
+        Logger.WARN.log("Schematic not found: " + filteredName);
         return null;
     }
 
+    @Override
     public void check() {
-        Set<Missile> toRemove = new HashSet<>();
-        for (Missile missile : missiles) {
+        if (getSchematics().isEmpty()) throw new IllegalStateException("The game cannot be started, when 0 " + getObjectNamePlural() + " are configured");
+
+        Set<SchematicObject> toRemove = new HashSet<>();
+        
+        for (Missile missile : getSchematics()) {
             File schematic = missile.getSchematic();
-            if (!schematic.exists()) {
-                Logger.WARN.log(missile.getDisplayName() + " §7has no schematic. Removing this missile");
-                toRemove.add(missile);
-            }
+
+            if (schematic.exists()) continue;
+
+            Logger.WARN.log(missile.getDisplayName() + " §7has no " + getObjectNameSingular() + ". Removing this schematic");
+            toRemove.add(missile);
         }
-        missiles.removeAll(toRemove);
+        getSchematics().removeAll(toRemove);
     }
+    
+    public List<SchematicFacing> getEnabledFacings() {
+        List<SchematicFacing> enabledDirections = new ArrayList<>();
+
+        if (northFacing) enabledDirections.add(SchematicFacing.NORTH);
+        if (eastFacing) enabledDirections.add(SchematicFacing.EAST);
+        if (southFacing) enabledDirections.add(SchematicFacing.SOUTH);
+        if (westFacing) enabledDirections.add(SchematicFacing.WEST);
 
-    public List<String> getMissileNames() {
-        List<String> missileNames = new ArrayList<>();
-        for (Missile missile : missiles) {
-            missileNames.add(missile.getSchematicName(true));
+        if (enabledDirections.isEmpty()) {
+            Logger.WARN.log("All facings were disabled for an arena. Please correct this issue");
+            enabledDirections.addAll(Arrays.asList(SchematicFacing.values()));
         }
-        return missileNames;
+
+        return enabledDirections;
     }
+    
 }

+ 66 - 4
missilewars-plugin/src/main/java/de/butzlabben/missilewars/configuration/arena/ShieldConfiguration.java

@@ -19,17 +19,79 @@
 package de.butzlabben.missilewars.configuration.arena;
 
 import com.google.gson.annotations.SerializedName;
+import de.butzlabben.missilewars.Logger;
+import de.butzlabben.missilewars.game.schematics.SchematicConfiguration;
+import de.butzlabben.missilewars.game.schematics.objects.SchematicObject;
+import de.butzlabben.missilewars.game.schematics.objects.Shield;
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 import lombok.ToString;
 
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
 @Getter
 @ToString
 @RequiredArgsConstructor
-public class ShieldConfiguration {
+public class ShieldConfiguration extends SchematicConfiguration {
 
-    private String name = "Shield";
-    private String schematic = "shield.schematic";
-    private int occurrence = 1;
     @SerializedName("fly_time") private int flyTime = 20;
+
+    private List<Shield> schematics = new ArrayList<>() {{
+        add(new Shield("shield.schematic", "&cShield", 1));
+    }};
+
+
+    @Override
+    public String getObjectNameSingular() {
+        return "Shield";
+    }
+
+    @Override
+    public String getObjectNamePlural() {
+        return "Shields";
+    }
+
+    @Override
+    public List<String> getSchematicNames() {
+        List<String> schematicNames = new ArrayList<>();
+
+        for (Shield shield : getSchematics()) {
+            schematicNames.add(shield.getSchematicName(true));
+        }
+
+        return schematicNames;
+    }
+
+    @Override
+    public SchematicObject getSchematicFromName(String name) {
+        String filteredName = name.replaceAll("§.", "");
+
+        for (Shield shield : getSchematics()) {
+            if (shield.getSchematicName(true).equalsIgnoreCase(filteredName)) return shield;
+        }
+        Logger.WARN.log("Schematic not found: " + filteredName);
+        return null;
+    }
+
+    @Override
+    public void check() {
+        if (getSchematics().isEmpty()) throw new IllegalStateException("The game cannot be started, when 0 " + getObjectNamePlural() + " are configured");
+
+        Set<SchematicObject> toRemove = new HashSet<>();
+
+        for (Shield shield : getSchematics()) {
+            File schematic = shield.getSchematic();
+
+            if (schematic.exists()) continue;
+
+            Logger.WARN.log(shield.getDisplayName() + " §7has no " + getObjectNameSingular() + ". Removing this schematic");
+            toRemove.add(shield);
+        }
+        getSchematics().removeAll(toRemove);
+    }
+    
 }

+ 34 - 8
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/Game.java

@@ -34,8 +34,9 @@ import de.butzlabben.missilewars.game.equipment.EquipmentManager;
 import de.butzlabben.missilewars.game.equipment.PlayerEquipmentRandomizer;
 import de.butzlabben.missilewars.game.misc.MotdManager;
 import de.butzlabben.missilewars.game.misc.ScoreboardManager;
-import de.butzlabben.missilewars.game.missile.Missile;
-import de.butzlabben.missilewars.game.missile.MissileFacing;
+import de.butzlabben.missilewars.game.schematics.SchematicFacing;
+import de.butzlabben.missilewars.game.schematics.objects.Missile;
+import de.butzlabben.missilewars.game.schematics.objects.Shield;
 import de.butzlabben.missilewars.game.signs.MWSign;
 import de.butzlabben.missilewars.game.stats.FightStats;
 import de.butzlabben.missilewars.game.timer.EndTimer;
@@ -57,9 +58,11 @@ import lombok.ToString;
 import org.bukkit.*;
 import org.bukkit.entity.Fireball;
 import org.bukkit.entity.Player;
+import org.bukkit.entity.Snowball;
 import org.bukkit.event.HandlerList;
 import org.bukkit.event.player.PlayerTeleportEvent;
 import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
 import org.bukkit.scheduler.BukkitTask;
 import org.bukkit.util.Vector;
 
@@ -617,6 +620,7 @@ public class Game {
      * This method spawns the missile for the player.
      *
      * @param player the executing player
+     * @param itemStack the spawn egg
      */
     public void spawnMissile(Player player, ItemStack itemStack) {
 
@@ -628,15 +632,39 @@ public class Game {
                 return;
             }
         }
-
-        Missile missile = this.arena.getMissileConfiguration().getMissileFromName(itemStack.getItemMeta().getDisplayName());
+        
+        ItemMeta itemMeta = itemStack.getItemMeta();
+        if (itemMeta == null) return;
+        
+        Missile missile = (Missile) this.arena.getMissileConfiguration().getSchematicFromName(itemMeta.getDisplayName());
         if (missile == null) {
             player.sendMessage(Messages.getMessage(true, Messages.MessageEnum.COMMAND_INVALID_MISSILE));
             return;
         }
+        
         itemStack.setAmount(itemStack.getAmount() - 1);
         player.setItemInHand(itemStack);
-        missile.paste(player, MissileFacing.getFacingPlayer(player, this.arena.getMissileConfiguration()), this);
+        missile.paste(this, player, SchematicFacing.getFacingPlayer(player, this.arena.getMissileConfiguration()));
+    }
+
+    /**
+     * This method spawns the shield after his flight route.
+     *
+     * @param player the executing player
+     * @param ball the snowball
+     */
+    public void spawnShield(Player player, Snowball ball) {
+        
+        ItemMeta itemMeta = ball.getItem().getItemMeta();
+        if (itemMeta == null) return;
+
+        Shield shield = (Shield) this.arena.getShieldConfiguration().getSchematicFromName(itemMeta.getDisplayName());
+        if (shield == null) {
+            player.sendMessage(Messages.getMessage(true, Messages.MessageEnum.COMMAND_INVALID_MISSILE));
+            return;
+        }
+        
+        shield.paste(ball);
     }
 
     /**
@@ -663,9 +691,7 @@ public class Game {
         }
 
         arena.getMissileConfiguration().check();
-        if (arena.getMissileConfiguration().getMissiles().size() == 0) {
-            throw new IllegalStateException("The game cannot be started, when 0 missiles are configured");
-        }
+        arena.getShieldConfiguration().check();
 
         this.arena = arena.clone();
         gameWorld = new GameWorld(this, arena.getTemplateWorld());

+ 5 - 2
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/equipment/EquipmentManager.java

@@ -19,6 +19,7 @@
 package de.butzlabben.missilewars.game.equipment;
 
 import de.butzlabben.missilewars.game.Game;
+import de.butzlabben.missilewars.game.schematics.objects.SchematicObject;
 import lombok.Getter;
 import org.bukkit.Material;
 import org.bukkit.enchantments.Enchantment;
@@ -36,7 +37,8 @@ public class EquipmentManager {
 
     private final Game game;
 
-    private final MissileGameEquipment missileEquipment;
+    private final SchematicGameEquipment missileEquipment;
+    private final SchematicGameEquipment shieldEquipment;
     private final SpecialGameEquipment specialEquipment;
     private ItemStack customBow;
     private ItemStack customPickaxe;
@@ -45,7 +47,8 @@ public class EquipmentManager {
     public EquipmentManager(Game game) {
         this.game = game;
 
-        missileEquipment = new MissileGameEquipment(game);
+        missileEquipment = new SchematicGameEquipment(game, SchematicObject.schematicType.MISSILE);
+        shieldEquipment = new SchematicGameEquipment(game, SchematicObject.schematicType.SHIELD);
         specialEquipment = new SpecialGameEquipment(game);
     }
 

+ 23 - 7
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/equipment/PlayerEquipmentRandomizer.java

@@ -21,11 +21,13 @@ package de.butzlabben.missilewars.game.equipment;
 import de.butzlabben.missilewars.Logger;
 import de.butzlabben.missilewars.configuration.arena.Arena;
 import de.butzlabben.missilewars.game.Game;
-import de.butzlabben.missilewars.game.missile.Missile;
+import de.butzlabben.missilewars.game.schematics.objects.Missile;
+import de.butzlabben.missilewars.game.schematics.objects.Shield;
 import de.butzlabben.missilewars.player.MWPlayer;
-import java.util.Random;
 import org.bukkit.inventory.ItemStack;
 
+import java.util.Random;
+
 /**
  * @author Butzlabben
  * @since 19.01.2018
@@ -110,18 +112,32 @@ public class PlayerEquipmentRandomizer {
         int randomID;
 
         // switch between type of "items":
-        // after 2 missile items, you get one special item
+        // after 2 missile items, you get one special item or a shield
         if (sendEquipmentCounter >= 2) {
 
-            randomID = randomizer.nextInt(equipmentManager.getSpecialEquipment().getSpecialEquipmentList().size());
-            item = equipmentManager.getSpecialEquipment().getSpecialEquipmentList().get(randomID);
+            // Special Equipment or Schematic Game-Equipment of the type "Shield":
+            
+            int specialEquipment = equipmentManager.getSpecialEquipment().getSpecialEquipmentList().size();
+            int shieldsEquipment = equipmentManager.getShieldEquipment().getSchematicEquipmentList().size();
+            
+            randomID = randomizer.nextInt(1, specialEquipment + shieldsEquipment + 1);
+            if (randomID <= specialEquipment) {
+                item = equipmentManager.getSpecialEquipment().getSpecialEquipmentList().get(randomID - 1);
+            } else {
+                Shield shield = (Shield) equipmentManager.getShieldEquipment().getSchematicEquipmentList().get(randomID - specialEquipment - 1);
+                item = shield.getItem();
+            }
 
             sendEquipmentCounter = 0;
 
         } else {
 
-            randomID = randomizer.nextInt(equipmentManager.getMissileEquipment().getMissileEquipmentList().size());
-            Missile missile = equipmentManager.getMissileEquipment().getMissileEquipmentList().get(randomID);
+            // Schematic Game-Equipment of the type "Missile":
+            
+            int missilesEquipment = equipmentManager.getMissileEquipment().getSchematicEquipmentList().size();
+            
+            randomID = randomizer.nextInt(1, missilesEquipment + 1);
+            Missile missile = (Missile) equipmentManager.getMissileEquipment().getSchematicEquipmentList().get(randomID - 1);
             item = missile.getItem();
 
         }

+ 22 - 14
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/equipment/MissileGameEquipment.java → missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/equipment/SchematicGameEquipment.java

@@ -19,10 +19,11 @@
 package de.butzlabben.missilewars.game.equipment;
 
 import de.butzlabben.missilewars.game.Game;
-import de.butzlabben.missilewars.game.missile.Missile;
+import de.butzlabben.missilewars.game.schematics.objects.SchematicObject;
+import lombok.Getter;
+
 import java.util.ArrayList;
 import java.util.List;
-import lombok.Getter;
 
 /**
  * @author Butzlabben
@@ -30,33 +31,40 @@ import lombok.Getter;
  */
 
 @Getter
-public class MissileGameEquipment {
+public class SchematicGameEquipment {
 
     private final Game game;
 
-    private List<Missile> missileEquipmentList = new ArrayList<>();
+    private List<SchematicObject> schematicEquipmentList = new ArrayList<>();
 
 
-    public MissileGameEquipment(Game game) {
+    public SchematicGameEquipment(Game game, SchematicObject.schematicType schematicType) {
         this.game = game;
 
-        createMissileEquipmentList();
+        createSchematicEquipmentList(schematicType);
     }
 
     /**
-     * This method goes through all configured missiles and adds them
-     * to the list. The higher the defined spawn-occurrence of a missile
+     * This method goes through all configured schematic and adds them
+     * to the list. The higher the defined spawn-occurrence of a schematic
      * being set, the more often it will be added to the list.
      */
-    private void createMissileEquipmentList() {
+    private void createSchematicEquipmentList(SchematicObject.schematicType schematicType) {
 
-        for (Missile missile : game.getArena().getMissileConfiguration().getMissiles()) {
-            for (int i = missile.getOccurrence(); i > 0; i--) {
-                missileEquipmentList.add(missile);
+        if (schematicType == SchematicObject.schematicType.MISSILE) {
+            for (SchematicObject object : game.getArena().getMissileConfiguration().getSchematics()) {
+                for (int i = object.getOccurrence(); i > 0; i--) {
+                    schematicEquipmentList.add(object);
+                }
+            }
+        } else if (schematicType == SchematicObject.schematicType.SHIELD) {
+            for (SchematicObject object : game.getArena().getShieldConfiguration().getSchematics()) {
+                for (int i = object.getOccurrence(); i > 0; i--) {
+                    schematicEquipmentList.add(object);
+                }
             }
         }
-
-
+        
     }
 
 }

+ 7 - 23
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/equipment/SpecialGameEquipment.java

@@ -19,13 +19,14 @@
 package de.butzlabben.missilewars.game.equipment;
 
 import de.butzlabben.missilewars.game.Game;
-import java.util.ArrayList;
-import java.util.List;
 import lombok.Getter;
 import org.bukkit.Material;
 import org.bukkit.inventory.ItemStack;
 import org.bukkit.inventory.meta.ItemMeta;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * @author Butzlabben
  * @since 19.01.2018
@@ -35,8 +36,7 @@ import org.bukkit.inventory.meta.ItemMeta;
 public class SpecialGameEquipment {
 
     private final Game game;
-
-    private ItemStack shield;
+    
     private ItemStack arrow;
     private ItemStack fireball;
 
@@ -45,8 +45,7 @@ public class SpecialGameEquipment {
 
     public SpecialGameEquipment(Game game) {
         this.game = game;
-
-        createShield();
+        
         createArrow();
         createFireball();
 
@@ -60,15 +59,10 @@ public class SpecialGameEquipment {
      * If the spawn-occurrence is 0, the equipment is skipped.
      */
     private void createSpecialEquipmentList() {
-
-        int shieldOccurrence = game.getArena().getShieldConfiguration().getOccurrence();
+        
         int arrowOccurrence = game.getArena().getArrowConfiguration().getOccurrence();
         int fireballOccurrence = game.getArena().getFireballConfiguration().getOccurrence();
 
-        for (int i = shieldOccurrence; i > 0; i--) {
-            specialEquipmentList.add(shield);
-        }
-
         for (int i = arrowOccurrence; i > 0; i--) {
             specialEquipmentList.add(arrow);
         }
@@ -78,17 +72,7 @@ public class SpecialGameEquipment {
         }
 
     }
-
-    /**
-     * This method creates the shield item stack.
-     */
-    private void createShield() {
-        shield = new ItemStack(Material.SNOWBALL);
-        ItemMeta shieldMeta = shield.getItemMeta();
-        shieldMeta.setDisplayName(game.getArena().getShieldConfiguration().getName());
-        shield.setItemMeta(shieldMeta);
-    }
-
+    
     /**
      * This method creates the arrow item stack.
      */

+ 1 - 1
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/misc/MissileWarsPlaceholder.java

@@ -96,7 +96,7 @@ public class MissileWarsPlaceholder extends PlaceholderExpansion {
 
                 // %missilewars_arena_missileamount_<arena name or 'this'>%
                 if (params.equalsIgnoreCase("arena_missileamount_" + arena.getName())) {
-                    return Integer.toString(arena.getMissileConfiguration().getMissiles().size());
+                    return Integer.toString(arena.getMissileConfiguration().getSchematics().size());
                 }
 
             }

+ 23 - 0
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/schematics/SchematicConfiguration.java

@@ -0,0 +1,23 @@
+package de.butzlabben.missilewars.game.schematics;
+
+import de.butzlabben.missilewars.game.schematics.objects.SchematicObject;
+
+import java.util.List;
+
+public abstract class SchematicConfiguration {
+
+    public String getObjectNameSingular() {
+        return "Schematic";
+    }
+
+    public String getObjectNamePlural() {
+        return "Schematics";
+    }
+
+    public abstract List<String> getSchematicNames();
+
+    public abstract SchematicObject getSchematicFromName(String name);
+
+    public abstract void check();
+    
+}

+ 11 - 10
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/missile/MissileFacing.java → missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/schematics/SchematicFacing.java

@@ -16,21 +16,22 @@
  * along with MissileWars.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package de.butzlabben.missilewars.game.missile;
+package de.butzlabben.missilewars.game.schematics;
 
 import de.butzlabben.missilewars.Logger;
 import de.butzlabben.missilewars.configuration.arena.MissileConfiguration;
 import de.butzlabben.missilewars.util.missile.Interval;
+import org.bukkit.entity.Player;
+
 import java.util.Arrays;
 import java.util.List;
 import java.util.stream.Collectors;
-import org.bukkit.entity.Player;
 
 /**
  * @author Butzlabben
  * @since 06.01.2018
  */
-public enum MissileFacing {
+public enum SchematicFacing {
 
     NORTH(new Interval(180, 270), new Interval(135, 315)),
     EAST(new Interval(270, 360), new Interval(225, 360), new Interval(0, 45)),
@@ -40,22 +41,22 @@ public enum MissileFacing {
     public final Interval primary;
     public final Interval[] secondary;
 
-    MissileFacing(Interval primary, Interval... secondary) {
+    SchematicFacing(Interval primary, Interval... secondary) {
         this.primary = primary;
         this.secondary = secondary;
     }
 
-    public static MissileFacing getFacing(double degree, MissileConfiguration configuration) {
-        List<MissileFacing> values = Arrays.stream(MissileFacing.values()).filter(f -> configuration.getEnabledFacings().contains(f)).collect(Collectors.toList());
-        MissileFacing facing = null;
-        for (MissileFacing fac : values) {
+    public static SchematicFacing getFacing(double degree, MissileConfiguration configuration) {
+        List<SchematicFacing> values = Arrays.stream(SchematicFacing.values()).filter(f -> configuration.getEnabledFacings().contains(f)).collect(Collectors.toList());
+        SchematicFacing facing = null;
+        for (SchematicFacing fac : values) {
             if (fac.primary.isIn(degree)) {
                 facing = fac;
                 break;
             }
         }
         if (facing == null) {
-            for (MissileFacing fac : values) {
+            for (SchematicFacing fac : values) {
                 for (int i = 0; i < fac.secondary.length; i++) {
                     if (fac.secondary[i].isIn(degree)) {
                         facing = fac;
@@ -71,7 +72,7 @@ public enum MissileFacing {
         return facing;
     }
 
-    public static MissileFacing getFacingPlayer(Player playerSelf, MissileConfiguration configuration) {
+    public static SchematicFacing getFacingPlayer(Player playerSelf, MissileConfiguration configuration) {
         float y = playerSelf.getLocation().getYaw();
         if (y < 0) {
             y += 360;

+ 31 - 42
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/missile/Missile.java → missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/schematics/objects/Missile.java

@@ -16,16 +16,13 @@
  * along with MissileWars.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package de.butzlabben.missilewars.game.missile;
+package de.butzlabben.missilewars.game.schematics.objects;
 
-import com.google.gson.annotations.SerializedName;
 import de.butzlabben.missilewars.Logger;
 import de.butzlabben.missilewars.configuration.Config;
 import de.butzlabben.missilewars.game.Game;
-import de.butzlabben.missilewars.game.missile.paste.PasteProvider;
-import java.io.File;
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
+import de.butzlabben.missilewars.game.schematics.SchematicFacing;
+import de.butzlabben.missilewars.game.schematics.paste.PasteProvider;
 import org.bukkit.Location;
 import org.bukkit.Material;
 import org.bukkit.entity.EntityType;
@@ -34,78 +31,69 @@ import org.bukkit.inventory.ItemStack;
 import org.bukkit.inventory.meta.ItemMeta;
 import org.bukkit.util.Vector;
 
+import java.io.File;
+
 /**
  * @author Butzlabben
  * @since 06.01.2018
  */
-@SuppressWarnings("deprecation")
-@RequiredArgsConstructor
-public class Missile {
-
-    private final String schematic;
-    @SerializedName("name") private final String displayName;
+public class Missile extends SchematicObject {
+    
     private final EntityType egg;
     private final int down;
     private final int dist;
-    @Getter private final int occurrence;
-
-    public void paste(Player p, MissileFacing mf, Game game) {
+    
+    
+    public Missile(String schematic, String displayName, int occurrence, EntityType egg, int down, int dist) {
+        super(schematic, displayName, occurrence);
+        this.egg = egg;
+        this.down = down;
+        this.dist = dist;
+    }
+    
+    @Override
+    public File getSchematicFolder() {
+        return new File(Config.getMissilesFolder());
+    }
+    
+    public void paste(Game game, Player p, SchematicFacing mf) {
         if (mf == null)
             return;
         try {
             Location loc = p.getLocation();
             Vector pastePos = new Vector(loc.getX(), loc.getY(), loc.getZ());
+            
             pastePos = pastePos.add(new Vector(0, -down, 0));
 
             int rotation = 0;
-            if (mf == MissileFacing.NORTH) {
+            if (mf == SchematicFacing.NORTH) {
                 pastePos = pastePos.add(new Vector(0, 0, -dist));
-            } else if (mf == MissileFacing.SOUTH) {
+            } else if (mf == SchematicFacing.SOUTH) {
                 pastePos = pastePos.add(new Vector(0, 0, dist));
                 rotation = 180;
-            } else if (mf == MissileFacing.EAST) {
+            } else if (mf == SchematicFacing.EAST) {
                 pastePos = pastePos.add(new Vector(dist, 0, 0));
                 rotation = 270;
-            } else if (mf == MissileFacing.WEST) {
+            } else if (mf == SchematicFacing.WEST) {
                 pastePos = pastePos.add(new Vector(-dist, 0, 0));
                 rotation = 90;
             }
 
-
             PasteProvider.getPaster().pasteMissile(getSchematic(), pastePos, rotation, loc.getWorld(),
                     game.getPlayer(p).getTeam());
         } catch (Exception e) {
-            Logger.ERROR.log("Could not load " + displayName);
+            Logger.ERROR.log("Could not load " + getDisplayName());
             e.printStackTrace();
         }
     }
-
-    public File getSchematic() {
-        File missilesFolder = new File(Config.getMissilesFolder());
-        return new File(missilesFolder, getSchematicName(false));
-    }
-
-    public String getSchematicName(boolean withoutExtension) {
-        if (withoutExtension) {
-            return schematic.replace(".schematic", "")
-                    .replace(".schem", "");
-        }
-        return schematic;
-    }
-
-    public String getDisplayName() {
-        String name = displayName;
-        name = name.replace("%schematic_name%", getSchematicName(false))
-                .replace("%schematic_name_compact%", getSchematicName(true));
-        return name;
-    }
-
+    
     /**
      * This method provides the missile spawn item based on the
      * mob spawn item specification in the arena configuration.
      *
      * @return ItemStack = the spawn egg with the missile name
      */
+    @Override
     public ItemStack getItem() {
         ItemStack spawnEgg = new ItemStack(getSpawnEgg(egg));
         ItemMeta spawnEggMeta = spawnEgg.getItemMeta();
@@ -129,4 +117,5 @@ public class Missile {
         String name = material.name();
         return name.contains("SPAWN_EGG") || name.equals("MONSTER_EGG");
     }
+    
 }

+ 55 - 0
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/schematics/objects/SchematicObject.java

@@ -0,0 +1,55 @@
+package de.butzlabben.missilewars.game.schematics.objects;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.bukkit.inventory.ItemStack;
+
+import java.io.File;
+
+@RequiredArgsConstructor
+public class SchematicObject {
+    
+    // Class is not abstract because of Serializer:
+    // "com.google.gson.JsonIOException: Abstract classes can't be instantiated! 
+    // Register an InstanceCreator or a TypeAdapter for this type."
+
+    @SerializedName("schematic") private final String schematicName;
+    @SerializedName("name") private final String displayName;
+    @Getter private final int occurrence;
+    
+    
+    public File getSchematicFolder() {
+        return null;
+    }
+    
+    public File getSchematic() {
+        File file = new File(getSchematicFolder(), getSchematicName(false));
+        return file;
+    }
+    
+    public String getSchematicName(boolean withoutExtension) {
+        if (withoutExtension) {
+            return schematicName.replace(".schematic", "")
+                    .replace(".schem", "");
+        }
+        return schematicName;
+    }
+    
+    public String getDisplayName() {
+        String name = displayName;
+        name = name.replace("%schematic_name%", getSchematicName(false))
+                .replace("%schematic_name_compact%", getSchematicName(true));
+        return name;
+    }
+
+    public ItemStack getItem() {
+        return null;
+    }
+    
+    public enum schematicType {
+        MISSILE,
+        SHIELD
+    }
+
+}

+ 54 - 0
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/schematics/objects/Shield.java

@@ -0,0 +1,54 @@
+package de.butzlabben.missilewars.game.schematics.objects;
+
+import de.butzlabben.missilewars.Logger;
+import de.butzlabben.missilewars.configuration.Config;
+import de.butzlabben.missilewars.game.schematics.paste.PasteProvider;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.entity.Snowball;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.bukkit.util.Vector;
+
+import java.io.File;
+
+public class Shield extends SchematicObject {
+
+
+    public Shield(String schematic, String displayName, int occurrence) {
+        super(schematic, displayName, occurrence);
+    }
+
+    @Override
+    public File getSchematicFolder() {
+        return new File(Config.getShieldsFolder());
+    }
+
+    public void paste(Snowball ball) {
+        try {
+            Location loc = ball.getLocation();
+            Vector pastePos = new Vector(loc.getX(), loc.getY(), loc.getZ());
+            
+            PasteProvider.getPaster().pasteSchematic(getSchematic(), pastePos, loc.getWorld());
+        } catch (Exception e) {
+            Logger.ERROR.log("Could not load " + getDisplayName());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * This method provides the shield spawn item based on the
+     * snowball item specification in the arena configuration.
+     *
+     * @return ItemStack = the snowball with the shield name
+     */
+    @Override
+    public ItemStack getItem() {
+        ItemStack snowball = new ItemStack(Material.SNOWBALL);
+        ItemMeta snowballMeta = snowball.getItemMeta();
+        snowballMeta.setDisplayName(getDisplayName());
+        snowball.setItemMeta(snowballMeta);
+        return snowball;
+    }
+    
+}

+ 1 - 1
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/missile/paste/PasteProvider.java → missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/schematics/paste/PasteProvider.java

@@ -16,7 +16,7 @@
  * along with MissileWars.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package de.butzlabben.missilewars.game.missile.paste;
+package de.butzlabben.missilewars.game.schematics.paste;
 
 
 import de.butzlabben.missilewars.Logger;

+ 5 - 4
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/missile/paste/Paster.java → missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/schematics/paste/Paster.java

@@ -16,19 +16,20 @@
  * along with MissileWars.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package de.butzlabben.missilewars.game.missile.paste;
+package de.butzlabben.missilewars.game.schematics.paste;
 
 import de.butzlabben.missilewars.game.Team;
-import java.io.File;
 import org.bukkit.util.Vector;
 
+import java.io.File;
+
 /**
  * @author Butzlabben
  * @since 23.09.2018
  */
 public interface Paster {
 
-    void pasteMissile(File schematic, Vector position, int rotation, org.bukkit.World world, Team team);
-
     void pasteSchematic(File schematic, Vector position, org.bukkit.World world);
+
+    void pasteMissile(File schematic, Vector position, int rotation, org.bukkit.World world, Team team);
 }

+ 3 - 2
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/missile/paste/R1_13FawePasteProvider.java → missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/schematics/paste/R1_13FawePasteProvider.java

@@ -16,17 +16,18 @@
  * along with MissileWars.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package de.butzlabben.missilewars.game.missile.paste;
+package de.butzlabben.missilewars.game.schematics.paste;
 
 import de.butzlabben.missilewars.MissileWars;
 import de.butzlabben.missilewars.configuration.Config;
 import de.butzlabben.missilewars.game.Team;
 import de.butzlabben.missilewars.missile.paste.r1_13.fawe.R1_13Paster;
 import de.butzlabben.missilewars.util.version.ColorConverter;
-import java.io.File;
 import org.bukkit.World;
 import org.bukkit.util.Vector;
 
+import java.io.File;
+
 /**
  * @author Butzlabben
  * @since 23.09.2018

+ 3 - 2
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/missile/paste/R1_13WEPasteProvider.java → missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/schematics/paste/R1_13WEPasteProvider.java

@@ -16,17 +16,18 @@
  * along with MissileWars.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package de.butzlabben.missilewars.game.missile.paste;
+package de.butzlabben.missilewars.game.schematics.paste;
 
 import de.butzlabben.missilewars.MissileWars;
 import de.butzlabben.missilewars.configuration.Config;
 import de.butzlabben.missilewars.game.Team;
 import de.butzlabben.missilewars.missile.paste.r1_13.we.R1_13Paster;
 import de.butzlabben.missilewars.util.version.ColorConverter;
-import java.io.File;
 import org.bukkit.World;
 import org.bukkit.util.Vector;
 
+import java.io.File;
+
 /**
  * @author Butzlabben
  * @since 23.09.2018

+ 3 - 2
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/missile/paste/R1_16FawePasteProvider.java → missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/schematics/paste/R1_16FawePasteProvider.java

@@ -16,17 +16,18 @@
  * along with MissileWars.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package de.butzlabben.missilewars.game.missile.paste;
+package de.butzlabben.missilewars.game.schematics.paste;
 
 import de.butzlabben.missilewars.MissileWars;
 import de.butzlabben.missilewars.configuration.Config;
 import de.butzlabben.missilewars.game.Team;
 import de.butzlabben.missilewars.missile.paste.r1_16.fawe.R1_16Paster;
 import de.butzlabben.missilewars.util.version.ColorConverter;
-import java.io.File;
 import org.bukkit.World;
 import org.bukkit.util.Vector;
 
+import java.io.File;
+
 /**
  * @author Butzlabben
  * @since 23.09.2018

+ 14 - 23
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/misc/Shield.java → missilewars-plugin/src/main/java/de/butzlabben/missilewars/listener/ShieldListener.java

@@ -16,43 +16,43 @@
  * along with MissileWars.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-package de.butzlabben.missilewars.game.misc;
+package de.butzlabben.missilewars.listener;
 
 import de.butzlabben.missilewars.MissileWars;
-import de.butzlabben.missilewars.configuration.arena.ShieldConfiguration;
-import de.butzlabben.missilewars.game.missile.paste.PasteProvider;
-import java.io.File;
+import de.butzlabben.missilewars.game.Game;
 import lombok.RequiredArgsConstructor;
 import org.bukkit.Bukkit;
-import org.bukkit.Location;
 import org.bukkit.Sound;
 import org.bukkit.entity.Player;
+import org.bukkit.entity.Snowball;
 import org.bukkit.event.EventHandler;
 import org.bukkit.event.HandlerList;
 import org.bukkit.event.Listener;
 import org.bukkit.event.entity.ProjectileHitEvent;
 import org.bukkit.event.entity.ProjectileLaunchEvent;
-import org.bukkit.util.Vector;
 
 /**
  * @author Butzlabben
  * @since 11.09.2018
  */
 @RequiredArgsConstructor
-public class Shield implements Listener {
+public class ShieldListener implements Listener {
 
     private final Player player;
-    private final ShieldConfiguration shieldConfiguration;
-    private org.bukkit.entity.Snowball ball;
+    private final Game game;
+    private Snowball ball;
 
     public void onThrow(ProjectileLaunchEvent event) {
-        ball = (org.bukkit.entity.Snowball) event.getEntity();
+        ball = (Snowball) event.getEntity();
         Bukkit.getPluginManager().registerEvents(this, MissileWars.getInstance());
 
         Bukkit.getScheduler().runTaskLater(MissileWars.getInstance(), () -> {
-            if (!ball.isDead()) pasteShield();
+            if (!ball.isDead()) {
+                game.spawnShield(player, ball);
+                player.playSound(player.getLocation(), Sound.ENTITY_ENDER_DRAGON_FLAP, 1, 1);
+            }
             HandlerList.unregisterAll(this);
-        }, shieldConfiguration.getFlyTime());
+        }, game.getArena().getShieldConfiguration().getFlyTime());
     }
 
     @EventHandler
@@ -60,16 +60,7 @@ public class Shield implements Listener {
         if (!event.getEntity().equals(ball)) return;
 
         HandlerList.unregisterAll(this);
-        pasteShield();
-    }
-
-    public void pasteShield() {
-        Location loc = ball.getLocation();
-        Vector pastePos = new Vector(loc.getX(), loc.getY(), loc.getZ());
-        File pluginDir = MissileWars.getInstance().getDataFolder();
-        File schem = new File(pluginDir, "shields/" + shieldConfiguration.getSchematic());
-
-        PasteProvider.getPaster().pasteSchematic(schem, pastePos, loc.getWorld());
-        player.playSound(player.getLocation(), Sound.ENTITY_ENDER_DRAGON_FLAP, 1, 1);
+        game.spawnShield(player, ball);
     }
+    
 }

+ 4 - 4
missilewars-plugin/src/main/java/de/butzlabben/missilewars/listener/game/GameListener.java

@@ -26,8 +26,8 @@ import de.butzlabben.missilewars.game.Game;
 import de.butzlabben.missilewars.game.Team;
 import de.butzlabben.missilewars.game.enums.GameResult;
 import de.butzlabben.missilewars.game.misc.RespawnGoldBlock;
-import de.butzlabben.missilewars.game.misc.Shield;
-import de.butzlabben.missilewars.game.missile.Missile;
+import de.butzlabben.missilewars.game.schematics.objects.Missile;
+import de.butzlabben.missilewars.listener.ShieldListener;
 import de.butzlabben.missilewars.player.MWPlayer;
 import de.butzlabben.missilewars.util.geometry.Geometry;
 import org.bukkit.GameMode;
@@ -135,8 +135,8 @@ public class GameListener extends GameBoundListener {
         if (!(snowball.getShooter() instanceof Player)) return;
 
         Player shooter = (Player) snowball.getShooter();
-        Shield shield = new Shield(shooter, getGame().getArena().getShieldConfiguration());
-        shield.onThrow(event);
+        ShieldListener shieldListener = new ShieldListener(shooter, getGame());
+        shieldListener.onThrow(event);
     }
 
     @EventHandler

+ 6 - 28
missilewars-plugin/src/main/java/de/butzlabben/missilewars/util/SetupUtil.java

@@ -21,8 +21,6 @@ package de.butzlabben.missilewars.util;
 import de.butzlabben.missilewars.Logger;
 import de.butzlabben.missilewars.MissileWars;
 import de.butzlabben.missilewars.configuration.Config;
-import de.butzlabben.missilewars.configuration.arena.Arena;
-import de.butzlabben.missilewars.game.Arenas;
 import org.bukkit.configuration.file.YamlConfiguration;
 import org.bukkit.plugin.java.JavaPlugin;
 
@@ -93,25 +91,7 @@ public class SetupUtil {
             e.printStackTrace();
         }
     }
-
-    public static void checkShields() {
-        File shieldFolder = new File(MissileWars.getInstance().getDataFolder(), "shields");
-        if (!shieldFolder.exists()) {
-            shieldFolder.mkdir();
-        }
-
-        for (Arena arena : Arenas.getARENAS().values()) {
-            File shield = new File(shieldFolder, arena.getShieldConfiguration().getSchematic());
-            if (!shield.isFile()) {
-                String resource = "shield.schematic";
-
-                Logger.BOOT.log("Copying default shield schematic (" + resource + ")");
-                copyFile(resource, shield.getPath());
-
-            }
-        }
-    }
-
+    
     public static void checkMap(String worldName) {
         File arenasFolder = new File(Config.getArenasFolder());
         File file = new File(arenasFolder, worldName);
@@ -130,17 +110,15 @@ public class SetupUtil {
         }
     }
 
-    public static void checkMissiles() {
-        File file = new File(Config.getMissilesFolder());
-        if (!file.isDirectory()) {
-            String resource = "missiles.zip";
+    public static void saveDefaultSchematics(File schematicFile, String defaultFile) {
+        if (!schematicFile.isDirectory()) {
 
-            Logger.BOOT.log("Copying default missiles folder (" + resource + ")");
+            Logger.BOOT.log("Copying default schematic ressource folder (" + defaultFile + ")");
 
             try {
-                copyZip(resource, file.getPath());
+                copyZip(defaultFile, schematicFile.getPath());
             } catch (IOException e) {
-                Logger.ERROR.log("Unable to copy missiles!");
+                Logger.ERROR.log("Unable to copy schematic ressource folder '" + defaultFile + "'!");
                 e.printStackTrace();
             }
         }

BIN
missilewars-plugin/src/main/resources/shield.schematic


BIN
missilewars-plugin/src/main/resources/shields.zip