diff --git a/core/src/main/java/io/github/dre2n/dungeonsxl/config/DMessages.java b/core/src/main/java/io/github/dre2n/dungeonsxl/config/DMessages.java index 47f3445c..da5c433e 100644 --- a/core/src/main/java/io/github/dre2n/dungeonsxl/config/DMessages.java +++ b/core/src/main/java/io/github/dre2n/dungeonsxl/config/DMessages.java @@ -134,6 +134,7 @@ public enum DMessages implements Messages { GROUP_KICKED_PLAYER("Group_KickedPlayer", "&4&v1&6 kicked the player &4&v2&6 from the group &4&v3&6."), GROUP_PLAYER_JOINED("Group_PlayerJoined", "&6Player &4&v1&6 has joined the group!"), GROUP_WAVE_FINISHED("Group_WaveFinished", "&6Your group finished wave no. &4&v1&6. The next one is going to start in &4&v2&6 seconds."), + LOG_DISABLED_TWEAKS("Log_DisabledTweaks", "&4Disabled performance tweaks because there is no support for this server software."), LOG_ERROR_MOB_ENCHANTMENT("Log_Error_MobEnchantment", "&4Error at loading mob.yml: Enchantment &6&v1&4 doesn't exist!"), LOG_ERROR_MOBTYPE("Log_Error_MobType", "&4Error at loading mob.yml: Mob &6&v1&4 doesn't exist!"), LOG_ERROR_NO_CONSOLE_COMMAND("Log_Error_NoConsoleCommand", "&6/dxl &v1&4 can not be executed as console!"), diff --git a/core/src/main/java/io/github/dre2n/dungeonsxl/config/MainConfig.java b/core/src/main/java/io/github/dre2n/dungeonsxl/config/MainConfig.java index a16ba0f1..320d4f3f 100644 --- a/core/src/main/java/io/github/dre2n/dungeonsxl/config/MainConfig.java +++ b/core/src/main/java/io/github/dre2n/dungeonsxl/config/MainConfig.java @@ -16,8 +16,11 @@ */ package io.github.dre2n.dungeonsxl.config; +import io.github.dre2n.commons.compatibility.CompatibilityHandler; +import io.github.dre2n.commons.compatibility.Internals; import io.github.dre2n.commons.config.BRConfig; import io.github.dre2n.commons.util.EnumUtil; +import io.github.dre2n.commons.util.messageutil.MessageUtil; import java.io.File; import java.util.ArrayList; import java.util.Arrays; @@ -496,7 +499,12 @@ public void load() { } if (config.contains("tweaksEnabled")) { - tweaksEnabled = config.getBoolean("tweaksEnabled"); + if (Internals.andHigher(Internals.v1_9_R1).contains(CompatibilityHandler.getInstance().getInternals())) { + tweaksEnabled = config.getBoolean("tweaksEnabled"); + } else { + tweaksEnabled = false; + MessageUtil.log(DMessages.LOG_DISABLED_TWEAKS.getMessage()); + } } if (config.contains("secureMode.enabled")) { diff --git a/core/src/main/java/io/github/dre2n/dungeonsxl/config/WorldConfig.java b/core/src/main/java/io/github/dre2n/dungeonsxl/config/WorldConfig.java index d9e8888b..d1f7b65c 100644 --- a/core/src/main/java/io/github/dre2n/dungeonsxl/config/WorldConfig.java +++ b/core/src/main/java/io/github/dre2n/dungeonsxl/config/WorldConfig.java @@ -30,10 +30,14 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import org.bukkit.GameMode; +import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; @@ -121,12 +125,7 @@ public void load(ConfigurationSection configFile) { keepInventoryOnDeath = configFile.getBoolean("keepInventoryOnDeath"); } - /* Build */ - if (configFile.contains("build")) { - build = configFile.getBoolean("build"); - } - - /* GameMode */ + /* World interaction */ if (configFile.contains("gameMode")) { if (EnumUtil.isValidEnum(GameMode.class, configFile.getString("gameMode").toUpperCase())) { gameMode = GameMode.valueOf(configFile.getString("gameMode")); @@ -135,6 +134,47 @@ public void load(ConfigurationSection configFile) { } } + if (configFile.contains("breakBlocks")) { + breakBlocks = configFile.getBoolean("breakBlocks"); + } + + if (configFile.contains("breakPlacedBlocks")) { + breakPlacedBlocks = configFile.getBoolean("breakPlacedBlocks"); + } + + if (configFile.contains("breakWhitelist")) { + breakWhitelist = new HashMap<>(); + for (Entry entry : configFile.getConfigurationSection("breakWhitelist").getValues(true).entrySet()) { + Material breakable = Material.matchMaterial(entry.getKey()); + + HashSet tools = new HashSet<>(); + if (entry.getValue() instanceof List) { + for (String materialString : (List) entry.getValue()) { + Material tool = Material.matchMaterial(materialString); + if (tool != null) { + tools.add(tool); + } + } + } + + breakWhitelist.put(breakable, tools); + } + } + + if (configFile.contains("placeBlocks")) { + placeBlocks = configFile.getBoolean("placeBlocks"); + } + + if (configFile.contains("placeWhitelist")) { + placeWhitelist = new HashSet<>(); + for (String materialString : configFile.getStringList("placeWhitelist")) { + Material material = Material.matchMaterial(materialString); + if (material != null) { + placeWhitelist.add(material); + } + } + } + /* PvP */ if (configFile.contains("playerVersusPlayer")) { playerVersusPlayer = configFile.getBoolean("playerVersusPlayer"); diff --git a/core/src/main/java/io/github/dre2n/dungeonsxl/game/GameRules.java b/core/src/main/java/io/github/dre2n/dungeonsxl/game/GameRules.java index 98dc7654..a211ad58 100644 --- a/core/src/main/java/io/github/dre2n/dungeonsxl/game/GameRules.java +++ b/core/src/main/java/io/github/dre2n/dungeonsxl/game/GameRules.java @@ -20,9 +20,12 @@ import io.github.dre2n.dungeonsxl.reward.Reward; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import org.bukkit.GameMode; +import org.bukkit.Material; import org.bukkit.inventory.ItemStack; /** @@ -42,7 +45,11 @@ public class GameRules { /* World interaction */ DEFAULT_VALUES.gameMode = GameMode.SURVIVAL; - DEFAULT_VALUES.build = false; + DEFAULT_VALUES.breakBlocks = false; + DEFAULT_VALUES.breakPlacedBlocks = false; + DEFAULT_VALUES.breakWhitelist = null; + DEFAULT_VALUES.placeBlocks = false; + DEFAULT_VALUES.placeWhitelist = null; /* Fighting */ DEFAULT_VALUES.playerVersusPlayer = false; @@ -81,7 +88,11 @@ public class GameRules { /* World interaction */ protected GameMode gameMode; - protected Boolean build; + protected Boolean breakBlocks; + protected Boolean breakPlacedBlocks; + protected Map> breakWhitelist; + protected Boolean placeBlocks; + protected Set placeWhitelist; /* Fighting */ protected Boolean playerVersusPlayer; @@ -156,10 +167,38 @@ public GameMode getGameMode() { } /** - * @return if players may build + * @return if all blocks may be destroyed */ - public boolean canBuild() { - return build; + public boolean canBreakBlocks() { + return breakBlocks; + } + + /** + * @return if blocks placed in game may be destroyed + */ + public boolean canBreakPlacedBlocks() { + return breakPlacedBlocks; + } + + /** + * @return the destroyable materials and the materials that may be used to break them or null if any + */ + public Map> getBreakWhitelist() { + return breakWhitelist; + } + + /** + * @return if blocks may be placed + */ + public boolean canPlaceBlocks() { + return placeBlocks; + } + + /** + * @return the placeable materials + */ + public Set getPlaceWhitelist() { + return placeWhitelist; } // Fight @@ -353,12 +392,20 @@ public void apply(GameType defaultValues) { friendlyFire = defaultValues.isFriendlyFire(); } - if (timeToFinish == null) { + if (timeToFinish == null && defaultValues.getShowTime() != null) { timeToFinish = defaultValues.getShowTime() ? null : -1; } - if (build == null) { - build = defaultValues.canBuild(); + if (breakBlocks == null) { + breakBlocks = defaultValues.canBreakBlocks(); + } + + if (breakPlacedBlocks == null) { + breakPlacedBlocks = defaultValues.canBreakPlacedBlocks(); + } + + if (placeBlocks == null) { + placeBlocks = defaultValues.canPlaceBlocks(); } if (gameMode == null) { @@ -397,8 +444,24 @@ public void apply(GameRules defaultValues) { gameMode = defaultValues.gameMode; } - if (build == null) { - build = defaultValues.build; + if (breakBlocks == null) { + breakBlocks = defaultValues.breakBlocks; + } + + if (breakPlacedBlocks == null) { + breakPlacedBlocks = defaultValues.breakPlacedBlocks; + } + + if (breakWhitelist == null) { + breakWhitelist = defaultValues.breakWhitelist; + } + + if (placeBlocks == null) { + placeBlocks = defaultValues.placeBlocks; + } + + if (placeWhitelist == null) { + placeWhitelist = defaultValues.placeWhitelist; } /* Fighting */ diff --git a/core/src/main/java/io/github/dre2n/dungeonsxl/game/GameType.java b/core/src/main/java/io/github/dre2n/dungeonsxl/game/GameType.java index f5f84333..cef39160 100644 --- a/core/src/main/java/io/github/dre2n/dungeonsxl/game/GameType.java +++ b/core/src/main/java/io/github/dre2n/dungeonsxl/game/GameType.java @@ -48,68 +48,90 @@ public interface GameType { /** * @return the playerVersusPlayer */ - public boolean isPlayerVersusPlayer(); + public Boolean isPlayerVersusPlayer(); /** * @param playerVersusPlayer * the playerVersusPlayer to set */ - public void setPlayerVersusPlayer(boolean playerVersusPlayer); + public void setPlayerVersusPlayer(Boolean playerVersusPlayer); /** * @return the friendlyFire */ - public boolean isFriendlyFire(); + public Boolean isFriendlyFire(); /** * @param friendlyFire * the friendlyFire to set */ - public void setFriendlyFire(boolean friendlyFire); + public void setFriendlyFire(Boolean friendlyFire); /** * @return the mobWaves */ - public boolean hasMobWaves(); + public Boolean hasMobWaves(); /** * @param mobWaves * enable / disable mob waves */ - public void setMobWaves(boolean mobWaves); + public void setMobWaves(Boolean mobWaves); /** * @return if players get rewards after the dungeon */ - public boolean hasRewards(); + public Boolean hasRewards(); /** * @param rewards * enable / disable rewards */ - public void setRewards(boolean rewards); + public void setRewards(Boolean rewards); /** * @return if players shall see how long they play */ - public boolean getShowTime(); + public Boolean getShowTime(); /** * @param showTime * set if players shall see how long they play */ - public void setShowTime(boolean showTime); + public void setShowTime(Boolean showTime); /** - * @return if players can build + * @return if all blocks may be destroyed */ - public boolean canBuild(); + public Boolean canBreakBlocks(); /** - * @param build - * enable / disable building + * @param breakBlocks + * if blocks may be destroyed */ - public void setBuild(boolean build); + public void setBreakBlocks(Boolean breakBlocks); + + /** + * @return if blocks placed in game may be destroyed + */ + public Boolean canBreakPlacedBlocks(); + + /** + * @param breakPlacedBlocks + * if placed blocks may be destroyed + */ + public void setBreakPlacedBlocks(Boolean breakPlacedBlocks); + + /** + * @return if blocks may be placed + */ + public Boolean canPlaceBlocks(); + + /** + * @param placeBlocks + * if blocks may be placed + */ + public void setPlaceBlocks(Boolean placeBlocks); /** * @return the gameMode @@ -125,12 +147,12 @@ public interface GameType { /** * @return if players lose lives */ - public boolean hasLives(); + public Boolean hasLives(); /** * @param lives * set if the gametype uses player lives */ - public void setLives(boolean lives); + public void setLives(Boolean lives); } diff --git a/core/src/main/java/io/github/dre2n/dungeonsxl/game/GameTypeDefault.java b/core/src/main/java/io/github/dre2n/dungeonsxl/game/GameTypeDefault.java index ab131494..2777cddb 100644 --- a/core/src/main/java/io/github/dre2n/dungeonsxl/game/GameTypeDefault.java +++ b/core/src/main/java/io/github/dre2n/dungeonsxl/game/GameTypeDefault.java @@ -23,34 +23,39 @@ */ public enum GameTypeDefault implements GameType { - ADVENTURE("Adventure", "Adventure", false, false, false, true, false, true, GameMode.ADVENTURE, true), - ADVENTURE_TIME_IS_RUNNING("Adventure - Time is Running", "Adventure TiR", false, false, false, true, true, true, GameMode.ADVENTURE, true), - APOCALYPSE_LAST_MAN_STANDING("Apocalypse", "Apocalypse LMS", true, true, true, true, false, false, GameMode.SURVIVAL, true), - APOCALYPSE_LIMITED_MOBS("Apocalypse - Limited Mobs", "Apc Limited", true, true, true, true, false, false, GameMode.SURVIVAL, true), - APOCALYPSE_TIME_IS_RUNNING("Apocalypse - Time is Running", "Apocalypse TiR", true, true, true, true, true, false, GameMode.SURVIVAL, true), - PVE_LAST_MAN_STANDING("Player versus Environment - Last Man Standing", "PvE LMS", false, false, true, true, false, false, GameMode.SURVIVAL, true), - PVE_LIMITED_MOBS("Player versus Environment - Limited Mobs", "PvE Limited", false, false, true, true, false, false, GameMode.SURVIVAL, true), - PVE_TIME_IS_RUNNING("Player versus Environment - Time is Running", "PvE TiR", false, false, true, true, true, false, GameMode.SURVIVAL, true), - PVP_FACTIONS_BATTLEFIELD("Player versus Player - Factions Battlefield", "FactionsPvP", true, false, false, false, false, false, GameMode.SURVIVAL, true), - PVP_LAST_MAN_STANDING("Player versus Player - Last Man Standing", "PvP LMS", true, false, false, false, false, false, GameMode.SURVIVAL, true), - QUEST("Quest", "Quest", false, false, false, true, false, false, GameMode.SURVIVAL, true), - QUEST_TIME_IS_RUNNING("Quest - Time is Running", "Quest TiR", false, false, false, true, true, false, GameMode.SURVIVAL, true), - TEST("Test", "Test", false, false, false, false, true, true, GameMode.SURVIVAL, false), - TUTORIAL("Tutorial", "Tutorial", false, false, false, true, false, false, GameMode.SURVIVAL, false), - DEFAULT("Default", "Default", false, false, false, true, false, false, GameMode.SURVIVAL, true); + ADVENTURE("Adventure", "Adventure", false, false, false, true, false, true, true, true, GameMode.ADVENTURE, true), + ADVENTURE_TIME_IS_RUNNING("Adventure - Time is Running", "Adventure TiR", false, false, false, true, true, true, true, true, GameMode.ADVENTURE, true), + APOCALYPSE_LAST_MAN_STANDING("Apocalypse", "Apocalypse LMS", true, true, true, true, false, false, false, false, GameMode.SURVIVAL, true), + APOCALYPSE_LIMITED_MOBS("Apocalypse - Limited Mobs", "Apc Limited", true, true, true, true, false, false, false, false, GameMode.SURVIVAL, true), + APOCALYPSE_TIME_IS_RUNNING("Apocalypse - Time is Running", "Apocalypse TiR", true, true, true, true, true, false, false, false, GameMode.SURVIVAL, true), + BEDWARS("Bedwars", "Bedwars", true, false, false, false, false, false, true, true, GameMode.SURVIVAL, true), + PVE_LAST_MAN_STANDING("Player versus Environment - Last Man Standing", "PvE LMS", false, false, true, true, false, false, false, false, GameMode.SURVIVAL, true), + PVE_LIMITED_MOBS("Player versus Environment - Limited Mobs", "PvE Limited", false, false, true, true, false, false, false, false, GameMode.SURVIVAL, true), + PVE_TIME_IS_RUNNING("Player versus Environment - Time is Running", "PvE TiR", false, false, true, true, true, false, false, false, GameMode.SURVIVAL, true), + PVP_FACTIONS_BATTLEFIELD("Player versus Player - Factions Battlefield", "FactionsPvP", true, false, false, false, false, false, false, false, GameMode.SURVIVAL, true), + PVP_LAST_MAN_STANDING("Player versus Player - Last Man Standing", "PvP LMS", true, false, false, false, false, false, false, false, GameMode.SURVIVAL, true), + QUEST("Quest", "Quest", false, false, false, true, false, false, false, false, GameMode.SURVIVAL, true), + QUEST_TIME_IS_RUNNING("Quest - Time is Running", "Quest TiR", false, false, false, true, true, false, false, false, GameMode.SURVIVAL, true), + TEST("Test", "Test", false, false, false, false, true, true, true, true, GameMode.SURVIVAL, false), + TUTORIAL("Tutorial", "Tutorial", false, false, false, true, false, false, false, false, GameMode.SURVIVAL, false), + DEFAULT("Default", "Default", false, false, false, true, false, false, false, false, GameMode.SURVIVAL, true), + CUSTOM("Custom", "Custom"); private String displayName; private String signName; - private boolean playerVersusPlayer; - private boolean friendlyFire; - private boolean mobWaves; - private boolean rewards; - private boolean showTime; - private boolean build; + private Boolean playerVersusPlayer; + private Boolean friendlyFire; + private Boolean mobWaves; + private Boolean rewards; + private Boolean showTime; + private Boolean breakBlocks; + private Boolean breakPlacedBlocks; + private Boolean placeBlocks; private GameMode gameMode; - private boolean lives; + private Boolean lives; - GameTypeDefault(String displayName, String signName, boolean playerVersusPlayer, boolean friendlyFire, boolean mobWaves, boolean rewards, boolean showTime, boolean build, GameMode gameMode, boolean lives) { + GameTypeDefault(String displayName, String signName, Boolean playerVersusPlayer, Boolean friendlyFire, Boolean mobWaves, Boolean rewards, + Boolean showTime, Boolean breakBlocks, Boolean breakPlacedBlocks, Boolean placeBlocks, GameMode gameMode, Boolean lives) { this.displayName = displayName; this.signName = signName; this.playerVersusPlayer = playerVersusPlayer; @@ -58,11 +63,18 @@ public enum GameTypeDefault implements GameType { this.mobWaves = mobWaves; this.rewards = rewards; this.showTime = showTime; - this.build = build; + this.breakBlocks = breakBlocks; + this.breakPlacedBlocks = breakPlacedBlocks; + this.placeBlocks = placeBlocks; this.gameMode = gameMode; this.lives = lives; } + GameTypeDefault(String displayName, String signName) { + this.displayName = displayName; + this.signName = signName; + } + @Override public String getDisplayName() { return displayName; @@ -84,63 +96,83 @@ public void setSignName(String signName) { } @Override - public boolean isPlayerVersusPlayer() { + public Boolean isPlayerVersusPlayer() { return playerVersusPlayer; } @Override - public void setPlayerVersusPlayer(boolean playerVersusPlayer) { + public void setPlayerVersusPlayer(Boolean playerVersusPlayer) { this.playerVersusPlayer = playerVersusPlayer; } @Override - public boolean isFriendlyFire() { + public Boolean isFriendlyFire() { return friendlyFire; } @Override - public void setFriendlyFire(boolean friendlyFire) { + public void setFriendlyFire(Boolean friendlyFire) { this.friendlyFire = friendlyFire; } @Override - public boolean hasMobWaves() { + public Boolean hasMobWaves() { return mobWaves; } @Override - public void setMobWaves(boolean mobWaves) { + public void setMobWaves(Boolean mobWaves) { this.mobWaves = mobWaves; } @Override - public boolean hasRewards() { + public Boolean hasRewards() { return rewards; } @Override - public void setRewards(boolean rewards) { + public void setRewards(Boolean rewards) { this.rewards = rewards; } @Override - public boolean getShowTime() { + public Boolean getShowTime() { return showTime; } @Override - public void setShowTime(boolean showTime) { + public void setShowTime(Boolean showTime) { this.showTime = showTime; } @Override - public boolean canBuild() { - return build; + public Boolean canBreakBlocks() { + return breakBlocks; + } + + @Override + public void setBreakBlocks(Boolean breakBlocks) { + this.breakBlocks = breakBlocks; + } + + @Override + public Boolean canBreakPlacedBlocks() { + return breakPlacedBlocks; + } + + @Override + public void setBreakPlacedBlocks(Boolean breakPlacedBlocks) { + this.breakPlacedBlocks = breakPlacedBlocks; + } + + @Override + public Boolean canPlaceBlocks() { + return placeBlocks; } @Override - public void setBuild(boolean build) { - this.build = build; + public void setPlaceBlocks(Boolean placeBlocks) { + this.placeBlocks = placeBlocks; } @Override @@ -154,12 +186,12 @@ public void setGameMode(GameMode gameMode) { } @Override - public boolean hasLives() { + public Boolean hasLives() { return lives; } @Override - public void setLives(boolean lives) { + public void setLives(Boolean lives) { this.lives = lives; } diff --git a/core/src/main/java/io/github/dre2n/dungeonsxl/global/GlobalProtection.java b/core/src/main/java/io/github/dre2n/dungeonsxl/global/GlobalProtection.java index 42e30ba5..e081bcbd 100644 --- a/core/src/main/java/io/github/dre2n/dungeonsxl/global/GlobalProtection.java +++ b/core/src/main/java/io/github/dre2n/dungeonsxl/global/GlobalProtection.java @@ -5,7 +5,10 @@ */ package io.github.dre2n.dungeonsxl.global; +import io.github.dre2n.commons.util.messageutil.MessageUtil; import io.github.dre2n.dungeonsxl.DungeonsXL; +import io.github.dre2n.dungeonsxl.config.DMessages; +import io.github.dre2n.dungeonsxl.player.DGlobalPlayer; import java.io.File; import java.util.Collection; import org.bukkit.World; @@ -54,6 +57,7 @@ public int getId() { return id; } + /* Actions */ /** * Delete this protection. */ @@ -61,7 +65,6 @@ public void delete() { protections.removeProtection(this); } - /* Abstracts */ /** * Save the data to the default file */ @@ -77,6 +80,20 @@ public void save(File file) { save(YamlConfiguration.loadConfiguration(file)); } + public boolean onBreak(DGlobalPlayer dPlayer) { + if (dPlayer.isInBreakMode()) { + delete(); + MessageUtil.sendMessage(dPlayer.getPlayer(), plugin.getMessageConfig().getMessage(DMessages.PLAYER_PROTECTED_BLOCK_DELETED)); + MessageUtil.sendMessage(dPlayer.getPlayer(), plugin.getMessageConfig().getMessage(DMessages.CMD_BREAK_PROTECTED_MODE)); + dPlayer.setInBreakMode(false); + return false; + + } else { + return true; + } + } + + /* Abstracts */ /** * @param config * the config to save the protection to diff --git a/core/src/main/java/io/github/dre2n/dungeonsxl/listener/BlockListener.java b/core/src/main/java/io/github/dre2n/dungeonsxl/listener/BlockListener.java index cdc945fb..b55c7fca 100644 --- a/core/src/main/java/io/github/dre2n/dungeonsxl/listener/BlockListener.java +++ b/core/src/main/java/io/github/dre2n/dungeonsxl/listener/BlockListener.java @@ -20,10 +20,6 @@ import io.github.dre2n.commons.util.messageutil.MessageUtil; import io.github.dre2n.dungeonsxl.DungeonsXL; import io.github.dre2n.dungeonsxl.config.DMessages; -import io.github.dre2n.dungeonsxl.game.Game; -import io.github.dre2n.dungeonsxl.game.GamePlaceableBlock; -import io.github.dre2n.dungeonsxl.game.GameType; -import io.github.dre2n.dungeonsxl.game.GameTypeDefault; import io.github.dre2n.dungeonsxl.global.DPortal; import io.github.dre2n.dungeonsxl.global.GameSign; import io.github.dre2n.dungeonsxl.global.GlobalProtection; @@ -36,7 +32,6 @@ import io.github.dre2n.dungeonsxl.task.RedstoneEventTask; import io.github.dre2n.dungeonsxl.world.DEditWorld; import io.github.dre2n.dungeonsxl.world.DGameWorld; -import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.Sign; @@ -80,16 +75,9 @@ public void onBreak(BlockBreakEvent event) { GlobalProtection protection = plugin.getGlobalProtections().getByBlock(event.getBlock()); if (protection != null) { - if (dGlobalPlayer.isInBreakMode()) { - protection.delete(); - MessageUtil.sendMessage(player, plugin.getMessageConfig().getMessage(DMessages.PLAYER_PROTECTED_BLOCK_DELETED)); - MessageUtil.sendMessage(player, plugin.getMessageConfig().getMessage(DMessages.CMD_BREAK_PROTECTED_MODE)); - dGlobalPlayer.setInBreakMode(false); - - } else { + if (protection.onBreak(dGlobalPlayer)) { event.setCancelled(true); } - return; } @@ -103,24 +91,7 @@ public void onBreak(BlockBreakEvent event) { // Deny DGameWorld block breaking DGameWorld gameWorld = DGameWorld.getByWorld(block.getWorld()); if (gameWorld != null) { - for (DSign dSign : gameWorld.getDSigns()) { - if (dSign.getSign().equals(block)) { - event.setCancelled(true); - return; - } - } - - Game game = gameWorld.getGame(); - if (game != null) { - GameType gameType = game.getType(); - if (gameType == GameTypeDefault.DEFAULT) { - event.setCancelled(!game.getRules().canBuild()); - - } else if (!gameType.canBuild()) { - event.setCancelled(true); - } - - } else { + if (gameWorld.onBreak(player, block)) { event.setCancelled(true); } } @@ -136,27 +107,9 @@ public void onPlace(BlockPlaceEvent event) { return; } - Game game = gameWorld.getGame(); - if (game != null) { - if (game.getRules().canBuild() || GamePlaceableBlock.canBuildHere(block, block.getFace(event.getBlockAgainst()), event.getItemInHand().getType(), gameWorld)) { - return; - } - } - - // Workaround for a bug that would allow 3-Block-high jumping - Location loc = event.getPlayer().getLocation(); - if (loc.getY() > block.getY() + 1.0 && loc.getY() <= block.getY() + 1.5) { - if (loc.getX() >= block.getX() - 0.3 && loc.getX() <= block.getX() + 1.3) { - if (loc.getZ() >= block.getZ() - 0.3 && loc.getZ() <= block.getZ() + 1.3) { - loc.setX(block.getX() + 0.5); - loc.setY(block.getY()); - loc.setZ(block.getZ() + 0.5); - event.getPlayer().teleport(loc); - } - } + if (gameWorld.onPlace(event.getPlayer(), block, event.getBlockAgainst(), event.getItemInHand())) { + event.setCancelled(true); } - - event.setCancelled(true); } @EventHandler(priority = EventPriority.NORMAL) diff --git a/core/src/main/java/io/github/dre2n/dungeonsxl/player/DGroup.java b/core/src/main/java/io/github/dre2n/dungeonsxl/player/DGroup.java index 1b9c8c29..c707d6b0 100644 --- a/core/src/main/java/io/github/dre2n/dungeonsxl/player/DGroup.java +++ b/core/src/main/java/io/github/dre2n/dungeonsxl/player/DGroup.java @@ -658,18 +658,9 @@ public void startGame(Game game) { requirement.demand(player); } - GameType gameType = game.getType(); - if (gameType == GameTypeDefault.DEFAULT) { - player.setGameMode(rules.getGameMode()); - if (rules.isTimeIsRunning()) { - timeIsRunningTask = new TimeIsRunningTask(this, rules.getTimeToFinish()).runTaskTimer(plugin, 20, 20); - } - - } else { - player.setGameMode(gameType.getGameMode()); - if (gameType.getShowTime()) { - timeIsRunningTask = new TimeIsRunningTask(this, rules.getTimeToFinish()).runTaskTimer(plugin, 20, 20); - } + player.setGameMode(rules.getGameMode()); + if (rules.isTimeIsRunning()) { + timeIsRunningTask = new TimeIsRunningTask(this, rules.getTimeToFinish()).runTaskTimer(plugin, 20, 20); } // Permission bridge diff --git a/core/src/main/java/io/github/dre2n/dungeonsxl/sign/ClassesSign.java b/core/src/main/java/io/github/dre2n/dungeonsxl/sign/ClassesSign.java index 13eba0ff..63b8831b 100644 --- a/core/src/main/java/io/github/dre2n/dungeonsxl/sign/ClassesSign.java +++ b/core/src/main/java/io/github/dre2n/dungeonsxl/sign/ClassesSign.java @@ -59,13 +59,17 @@ public boolean check() { @Override public void onInit() { - getSign().setLine(0, ChatColor.DARK_BLUE + "############"); - getSign().setLine(1, ChatColor.DARK_GREEN + dClass.getName()); - getSign().setLine(2, ""); - getSign().setLine(3, ChatColor.DARK_BLUE + "############"); - getSign().update(); + if (dClass != null) { + getSign().setLine(0, ChatColor.DARK_BLUE + "############"); + getSign().setLine(1, ChatColor.DARK_GREEN + dClass.getName()); + getSign().setLine(2, ""); + getSign().setLine(3, ChatColor.DARK_BLUE + "############"); + getSign().update(); + getGameWorld().getClassesSigns().add(getSign()); - getGameWorld().getClassesSigns().add(getSign()); + } else { + markAsErroneous(); + } } @Override diff --git a/core/src/main/java/io/github/dre2n/dungeonsxl/sign/PlaceSign.java b/core/src/main/java/io/github/dre2n/dungeonsxl/sign/PlaceSign.java index a79527d6..e7a13ae0 100644 --- a/core/src/main/java/io/github/dre2n/dungeonsxl/sign/PlaceSign.java +++ b/core/src/main/java/io/github/dre2n/dungeonsxl/sign/PlaceSign.java @@ -16,8 +16,8 @@ */ package io.github.dre2n.dungeonsxl.sign; -import io.github.dre2n.dungeonsxl.game.GamePlaceableBlock; import io.github.dre2n.dungeonsxl.world.DGameWorld; +import io.github.dre2n.dungeonsxl.world.GamePlaceableBlock; import org.bukkit.Material; import org.bukkit.block.Sign; diff --git a/core/src/main/java/io/github/dre2n/dungeonsxl/sign/ReadySign.java b/core/src/main/java/io/github/dre2n/dungeonsxl/sign/ReadySign.java index d3719748..65de59da 100644 --- a/core/src/main/java/io/github/dre2n/dungeonsxl/sign/ReadySign.java +++ b/core/src/main/java/io/github/dre2n/dungeonsxl/sign/ReadySign.java @@ -88,7 +88,7 @@ public void onInit() { gameType = plugin.getGameTypes().getBySign(this); } else { - gameType = GameTypeDefault.DEFAULT; + gameType = GameTypeDefault.CUSTOM; } if (!lines[2].isEmpty()) { diff --git a/core/src/main/java/io/github/dre2n/dungeonsxl/world/DGameWorld.java b/core/src/main/java/io/github/dre2n/dungeonsxl/world/DGameWorld.java index c0cadd6a..cc441f7b 100644 --- a/core/src/main/java/io/github/dre2n/dungeonsxl/world/DGameWorld.java +++ b/core/src/main/java/io/github/dre2n/dungeonsxl/world/DGameWorld.java @@ -21,7 +21,7 @@ import io.github.dre2n.dungeonsxl.event.gameworld.GameWorldStartGameEvent; import io.github.dre2n.dungeonsxl.event.gameworld.GameWorldUnloadEvent; import io.github.dre2n.dungeonsxl.game.Game; -import io.github.dre2n.dungeonsxl.game.GamePlaceableBlock; +import io.github.dre2n.dungeonsxl.game.GameRules; import io.github.dre2n.dungeonsxl.mob.DMob; import io.github.dre2n.dungeonsxl.player.DGroup; import io.github.dre2n.dungeonsxl.reward.RewardChest; @@ -38,15 +38,22 @@ import io.github.dre2n.dungeonsxl.trigger.TriggerTypeDefault; import java.io.File; import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedList; import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import org.bukkit.Chunk; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.World; +import org.bukkit.block.Block; import org.bukkit.block.Sign; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; import org.bukkit.entity.Spider; import org.bukkit.inventory.ItemStack; import org.bukkit.scheduler.BukkitRunnable; @@ -61,6 +68,7 @@ public class DGameWorld extends DInstanceWorld { private boolean isPlaying = false; // TO DO: Which lists actually need to be CopyOnWriteArrayLists? + private List placedBlocks = new LinkedList<>(); private CopyOnWriteArrayList placeableBlocks = new CopyOnWriteArrayList<>(); private List secureObjects = new CopyOnWriteArrayList<>(); private CopyOnWriteArrayList loadedChunks = new CopyOnWriteArrayList<>(); @@ -452,6 +460,84 @@ public void update() { } } + public boolean onBreak(Player player, Block block) { + for (DSign dSign : dSigns) { + if (dSign.getSign().getBlock().equals(block)) { + return true; + } + } + + for (RewardChest rChest : rewardChests) { + if (rChest.getChest().getBlock().equals(block)) { + return true; + } + } + + Game game = getGame(); + if (game == null) { + return true; + } + + GameRules rules = game.getRules(); + if (!rules.canBreakBlocks() && !rules.canBreakPlacedBlocks()) { + return true; + } + + Map> whitelist = rules.getBreakWhitelist(); + Material material = block.getType(); + Material breakTool = player.getItemInHand().getType(); + + if (whitelist == null) { + if (rules.canBreakPlacedBlocks()) { + return (!placedBlocks.contains(block)); + } else if (rules.canBreakBlocks()) { + return false; + } + + } else if (whitelist.containsKey(material) && whitelist.get(material) == null | whitelist.get(material).isEmpty() | whitelist.get(material).contains(breakTool)) { + if (rules.canBreakPlacedBlocks()) { + return (!placedBlocks.contains(block)); + } else if (rules.canBreakBlocks()) { + return false; + } + } + + return true; + } + + public boolean onPlace(Player player, Block block, Block against, ItemStack hand) { + // Workaround for a bug that would allow 3-Block-high jumping + Location loc = player.getLocation(); + if (loc.getY() > block.getY() + 1.0 && loc.getY() <= block.getY() + 1.5) { + if (loc.getX() >= block.getX() - 0.3 && loc.getX() <= block.getX() + 1.3) { + if (loc.getZ() >= block.getZ() - 0.3 && loc.getZ() <= block.getZ() + 1.3) { + loc.setX(block.getX() + 0.5); + loc.setY(block.getY()); + loc.setZ(block.getZ() + 0.5); + player.teleport(loc); + } + } + } + + Game game = getGame(); + if (game == null) { + return true; + } + + GameRules rules = game.getRules(); + if (!rules.canPlaceBlocks() && !GamePlaceableBlock.canBuildHere(block, block.getFace(against), hand.getType(), this)) { + return true; + } + + Set whitelist = rules.getPlaceWhitelist(); + if (whitelist == null || whitelist.contains(block.getType())) { + placedBlocks.add(block); + return false; + } + + return true; + } + /* Statics */ /** * @param world diff --git a/core/src/main/java/io/github/dre2n/dungeonsxl/game/GamePlaceableBlock.java b/core/src/main/java/io/github/dre2n/dungeonsxl/world/GamePlaceableBlock.java similarity index 98% rename from core/src/main/java/io/github/dre2n/dungeonsxl/game/GamePlaceableBlock.java rename to core/src/main/java/io/github/dre2n/dungeonsxl/world/GamePlaceableBlock.java index f2fa393b..5f1f324d 100644 --- a/core/src/main/java/io/github/dre2n/dungeonsxl/game/GamePlaceableBlock.java +++ b/core/src/main/java/io/github/dre2n/dungeonsxl/world/GamePlaceableBlock.java @@ -14,10 +14,9 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package io.github.dre2n.dungeonsxl.game; +package io.github.dre2n.dungeonsxl.world; import io.github.dre2n.commons.util.NumberUtil; -import io.github.dre2n.dungeonsxl.world.DGameWorld; import java.util.HashSet; import java.util.Set; import org.bukkit.Material; diff --git a/core/src/test/java/io/github/dre2n/dungeonsxl/game/CustomGameType.java b/core/src/test/java/io/github/dre2n/dungeonsxl/game/CustomGameType.java index da570b5a..16a14714 100644 --- a/core/src/test/java/io/github/dre2n/dungeonsxl/game/CustomGameType.java +++ b/core/src/test/java/io/github/dre2n/dungeonsxl/game/CustomGameType.java @@ -23,20 +23,23 @@ */ public enum CustomGameType implements GameType { - GHOST("My awesome game type", "Identifier", false, false, false, false, false, false, GameMode.SPECTATOR, false); + GHOST("My awesome game type", "Identifier", false, false, false, false, false, false, false, false, GameMode.SPECTATOR, false); private String displayName; private String signName; - private boolean playerVersusPlayer; - private boolean friendlyFire; - private boolean mobWaves; - private boolean rewards; - private boolean showTime; - private boolean build; + private Boolean playerVersusPlayer; + private Boolean friendlyFire; + private Boolean mobWaves; + private Boolean rewards; + private Boolean showTime; + private Boolean breakBlocks; + private Boolean breakPlacedBlocks; + private Boolean placeBlocks; private GameMode gameMode; - private boolean lives; + private Boolean lives; - CustomGameType(String displayName, String signName, boolean playerVersusPlayer, boolean friendlyFire, boolean mobWaves, boolean rewards, boolean showTime, boolean build, GameMode gameMode, boolean lives) { + CustomGameType(String displayName, String signName, Boolean playerVersusPlayer, Boolean friendlyFire, Boolean mobWaves, Boolean rewards, + Boolean showTime, Boolean breakBlocks, Boolean breakPlacedBlocks, Boolean placeBlocks, GameMode gameMode, Boolean lives) { this.displayName = displayName; this.signName = signName; this.playerVersusPlayer = playerVersusPlayer; @@ -44,7 +47,9 @@ public enum CustomGameType implements GameType { this.mobWaves = mobWaves; this.rewards = rewards; this.showTime = showTime; - this.build = build; + this.breakBlocks = breakBlocks; + this.breakPlacedBlocks = breakPlacedBlocks; + this.placeBlocks = placeBlocks; this.gameMode = gameMode; this.lives = lives; } @@ -70,63 +75,83 @@ public void setSignName(String signName) { } @Override - public boolean isPlayerVersusPlayer() { + public Boolean isPlayerVersusPlayer() { return playerVersusPlayer; } @Override - public void setPlayerVersusPlayer(boolean playerVersusPlayer) { + public void setPlayerVersusPlayer(Boolean playerVersusPlayer) { this.playerVersusPlayer = playerVersusPlayer; } @Override - public boolean isFriendlyFire() { + public Boolean isFriendlyFire() { return friendlyFire; } @Override - public void setFriendlyFire(boolean friendlyFire) { + public void setFriendlyFire(Boolean friendlyFire) { this.friendlyFire = friendlyFire; } @Override - public boolean hasMobWaves() { + public Boolean hasMobWaves() { return mobWaves; } @Override - public void setMobWaves(boolean mobWaves) { + public void setMobWaves(Boolean mobWaves) { this.mobWaves = mobWaves; } @Override - public boolean hasRewards() { + public Boolean hasRewards() { return rewards; } @Override - public void setRewards(boolean rewards) { + public void setRewards(Boolean rewards) { this.rewards = rewards; } @Override - public boolean getShowTime() { + public Boolean getShowTime() { return showTime; } @Override - public void setShowTime(boolean showTime) { + public void setShowTime(Boolean showTime) { this.showTime = showTime; } @Override - public boolean canBuild() { - return build; + public Boolean canBreakBlocks() { + return breakBlocks; } @Override - public void setBuild(boolean build) { - this.build = build; + public void setBreakBlocks(Boolean breakBlocks) { + this.breakBlocks = breakBlocks; + } + + @Override + public Boolean canBreakPlacedBlocks() { + return breakPlacedBlocks; + } + + @Override + public void setBreakPlacedBlocks(Boolean breakPlacedBlocks) { + this.breakPlacedBlocks = breakPlacedBlocks; + } + + @Override + public Boolean canPlaceBlocks() { + return placeBlocks; + } + + @Override + public void setPlaceBlocks(Boolean placeBlocks) { + this.placeBlocks = placeBlocks; } @Override @@ -140,12 +165,12 @@ public void setGameMode(GameMode gameMode) { } @Override - public boolean hasLives() { + public Boolean hasLives() { return lives; } @Override - public void setLives(boolean lives) { + public void setLives(Boolean lives) { this.lives = lives; }