diff --git a/core/src/main/java/tc/oc/pgm/api/map/GameRule.java b/core/src/main/java/tc/oc/pgm/api/map/GameRule.java new file mode 100644 index 0000000000..8457ae2f2d --- /dev/null +++ b/core/src/main/java/tc/oc/pgm/api/map/GameRule.java @@ -0,0 +1,40 @@ +package tc.oc.pgm.api.map; + +public enum GameRule { + DO_DAYLIGHT_CYCLE("doDaylightCycle"), + DO_FIRE_TICK("doFireTick"), + DO_MOB_LOOT("doMobLoot"), + DO_TILE_DROPS("doTileDrops"), + MOB_GRIEFING("mobGriefing"), + NATURAL_REGENERATION("naturalRegeneration"); + + /* Unsupported Gamerules: + doMobSpawning + keepInventory + commandBlockOutput + logAdminCommands + randomTickSpeed + reducedDebugInfo + sendCommandFeedback + showDeathMessages + */ + + private final String id; + + GameRule(String id) { + this.id = id; + } + + public static GameRule byId(String gameRuleId) { + for (GameRule gameRule : GameRule.values()) { + if (gameRule.getId().equals(gameRuleId)) { + return gameRule; + } + } + return null; + } + + public String getId() { + return id; + } +} diff --git a/core/src/main/java/tc/oc/pgm/gamerules/GameRulesMatchModule.java b/core/src/main/java/tc/oc/pgm/gamerules/GameRulesMatchModule.java index 5d5a538a3b..dc20a82111 100644 --- a/core/src/main/java/tc/oc/pgm/gamerules/GameRulesMatchModule.java +++ b/core/src/main/java/tc/oc/pgm/gamerules/GameRulesMatchModule.java @@ -1,10 +1,11 @@ package tc.oc.pgm.gamerules; import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableMap; import java.util.Map; +import tc.oc.pgm.api.map.GameRule; import tc.oc.pgm.api.match.Match; import tc.oc.pgm.api.match.MatchModule; +import tc.oc.pgm.modules.WorldTimeModule; public class GameRulesMatchModule implements MatchModule { @@ -18,12 +19,25 @@ public GameRulesMatchModule(Match match, Map gameRules) { @Override public void load() { + // saves and sets gamerules from XML for (Map.Entry gameRule : this.gameRules.entrySet()) { + gameRules.put(gameRule.getKey(), gameRule.getValue()); this.match.getWorld().setGameRuleValue(gameRule.getKey(), gameRule.getValue()); } + + // saves gamerules from world (level.dat) as fallback + for (String gameRule : this.match.getWorld().getGameRules()) { + gameRules.putIfAbsent(gameRule, this.match.getWorld().getGameRuleValue(gameRule)); + } + + // if timelock is off, save doDayLightCycle as true + WorldTimeModule wtm = this.match.getModule(WorldTimeModule.class); + if (wtm != null && !wtm.isTimeLocked()) { + gameRules.put(GameRule.DO_DAYLIGHT_CYCLE.getId(), Boolean.toString(true)); + } } - public ImmutableMap getGameRules() { - return ImmutableMap.copyOf(gameRules); + public String getGameRule(String gameRule) { + return gameRules.get(gameRule); } } diff --git a/core/src/main/java/tc/oc/pgm/listeners/PGMListener.java b/core/src/main/java/tc/oc/pgm/listeners/PGMListener.java index 8304063591..641b062e6c 100644 --- a/core/src/main/java/tc/oc/pgm/listeners/PGMListener.java +++ b/core/src/main/java/tc/oc/pgm/listeners/PGMListener.java @@ -39,6 +39,7 @@ import tc.oc.pgm.api.PGM; import tc.oc.pgm.api.Permissions; import tc.oc.pgm.api.event.BlockTransformEvent; +import tc.oc.pgm.api.map.GameRule; import tc.oc.pgm.api.match.Match; import tc.oc.pgm.api.match.MatchManager; import tc.oc.pgm.api.match.event.MatchFinishEvent; @@ -60,7 +61,6 @@ import tc.oc.pgm.util.text.TextTranslations; public class PGMListener implements Listener { - private static final String DO_DAYLIGHT_CYCLE = "doDaylightCycle"; /* 1000 /time set day 6000 noon, sun is at its peak @@ -258,13 +258,36 @@ public void handleItemPickup(final PlayerPickupItemEvent event) { if (nearestPlayer != event.getPlayer()) event.setCancelled(true); } + @EventHandler + public void lockFireTick(final MatchLoadEvent event) { + setGameRule(event, GameRule.DO_FIRE_TICK.getId(), false); + } + + @EventHandler + public void unlockFireTick(final MatchStartEvent event) { + event + .getMatch() + .getWorld() + .setGameRuleValue( + GameRule.DO_FIRE_TICK.getId(), + event + .getMatch() + .needModule(GameRulesMatchModule.class) + .getGameRule(GameRule.DO_FIRE_TICK.getId())); + } + + @EventHandler + public void lockFireTick(final MatchFinishEvent event) { + setGameRule(event, GameRule.DO_DAYLIGHT_CYCLE.getId(), false); + } + // // Time Lock // lock time before, during (if time lock enabled), and after the match // @EventHandler public void lockTime(final MatchLoadEvent event) { - event.getMatch().getWorld().setGameRuleValue(DO_DAYLIGHT_CYCLE, Boolean.toString(false)); + setGameRule(event, GameRule.DO_DAYLIGHT_CYCLE.getId(), false); } @EventHandler @@ -272,17 +295,22 @@ public void unlockTime(final MatchStartEvent event) { // if there is a timelock module and it is off, unlock time boolean unlockTime = !event.getMatch().getModule(WorldTimeModule.class).isTimeLocked(); - GameRulesMatchModule gameRulesModule = event.getMatch().getModule(GameRulesMatchModule.class); - if (gameRulesModule != null && gameRulesModule.getGameRules().containsKey(DO_DAYLIGHT_CYCLE)) { - unlockTime = Boolean.parseBoolean(gameRulesModule.getGameRules().get(DO_DAYLIGHT_CYCLE)); + GameRulesMatchModule gameRulesMatchModule = + event.getMatch().getModule(GameRulesMatchModule.class); + if (gameRulesMatchModule != null + && Boolean.parseBoolean( + gameRulesMatchModule.getGameRule(GameRule.DO_DAYLIGHT_CYCLE.getId()))) { + unlockTime = true; } - - event.getMatch().getWorld().setGameRuleValue(DO_DAYLIGHT_CYCLE, Boolean.toString(unlockTime)); + event + .getMatch() + .getWorld() + .setGameRuleValue(GameRule.DO_DAYLIGHT_CYCLE.getId(), Boolean.toString(unlockTime)); } @EventHandler public void lockTime(final MatchFinishEvent event) { - event.getMatch().getWorld().setGameRuleValue(DO_DAYLIGHT_CYCLE, Boolean.toString(false)); + setGameRule(event, GameRule.DO_DAYLIGHT_CYCLE.getId(), false); } @EventHandler @@ -405,4 +433,12 @@ public void storeSkinOnMatchJoin(PlayerJoinMatchEvent event) { final MatchPlayer player = event.getPlayer(); PGM.get().getDatastore().setSkin(player.getId(), NMSHacks.getPlayerSkin(player.getBukkit())); } + + public void setGameRule(MatchLoadEvent event, String gameRule, boolean gameRuleValue) { + event.getMatch().getWorld().setGameRuleValue(gameRule, Boolean.toString(gameRuleValue)); + } + + public void setGameRule(MatchFinishEvent event, String gameRule, boolean gameRuleValue) { + event.getMatch().getWorld().setGameRuleValue(gameRule, Boolean.toString(gameRuleValue)); + } }