diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/FeatureSwitchGameMode.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/FeatureSwitchGameMode.java index 5db9dce..4e0b2ce 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/FeatureSwitchGameMode.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/FeatureSwitchGameMode.java @@ -5,6 +5,7 @@ import java.util.List; import org.bukkit.Bukkit; import org.bukkit.GameMode; +import org.bukkit.World; import org.bukkit.entity.Player; import de.jaschastarke.IHasName; @@ -24,6 +25,8 @@ import de.jaschastarke.bukkit.lib.commands.annotations.NeedsPermission; import de.jaschastarke.bukkit.lib.commands.annotations.Usages; import de.jaschastarke.minecraft.lib.permissions.IAbstractPermission; import de.jaschastarke.minecraft.lib.permissions.IPermission; +import de.jaschastarke.minecraft.limitedcreative.regions.Flags; +import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.ApplicableRegions; public class FeatureSwitchGameMode extends CoreModule { public FeatureSwitchGameMode(LimitedCreative plugin) { @@ -82,10 +85,12 @@ public class FeatureSwitchGameMode extends CoreModule { if (!target.equals(context.getSender()) && !context.checkPermission(SwitchGameModePermissions.OTHER)) throw new MissingPermissionCommandException(SwitchGameModePermissions.OTHER); - GameMode wgm = Hooks.DefaultWorldGameMode.get(target.getWorld()); + GameMode wgm = this.getDefaultGameMode(target.getWorld()); - if (!context.checkPermission(permission) && (wgm != tgm || !context.checkPermission(SwitchGameModePermissions.BACKONLY))) - throw new MissingPermissionCommandException(permission); + if (!this.regionOptional(target, tgm)) { + if (!context.checkPermission(permission) && (wgm != tgm || !context.checkPermission(SwitchGameModePermissions.BACKONLY))) + throw new MissingPermissionCommandException(permission); + } if (target.getGameMode() != tgm) { target.setGameMode(tgm); @@ -97,6 +102,22 @@ public class FeatureSwitchGameMode extends CoreModule { } return true; } + + protected GameMode getDefaultGameMode(World world) { + return Hooks.DefaultWorldGameMode.get(world); + } + + private boolean regionOptional(Player player, GameMode tgm) { + ModRegions mod = plugin.getModule(ModRegions.class); + if (mod != null) { + ApplicableRegions rs = mod.getRegionManager().getRegionSet(player.getLocation()); + if (rs.allows(Flags.GAMEMODE_OPTIONAL)) { + if ((tgm == rs.getFlag(Flags.GAMEMODE, player)) || (tgm == this.getDefaultGameMode(player.getWorld()))) + return true; + } + } + return false; + } @IsCommand("survival") @Alias("s") diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModCreativeLimits.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModCreativeLimits.java index d744f25..31c52af 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModCreativeLimits.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModCreativeLimits.java @@ -1,5 +1,9 @@ package de.jaschastarke.minecraft.limitedcreative; +import java.util.WeakHashMap; + +import org.bukkit.entity.Entity; + import de.jaschastarke.bukkit.lib.CoreModule; import de.jaschastarke.minecraft.limitedcreative.limits.BlockListener; import de.jaschastarke.minecraft.limitedcreative.limits.EntityListener; @@ -11,6 +15,7 @@ import de.jaschastarke.modularize.ModuleEntry.ModuleState; public class ModCreativeLimits extends CoreModule { protected LimitConfig config; + private WeakHashMap no_xp_mobs = new WeakHashMap(); public ModCreativeLimits(LimitedCreative plugin) { super(plugin); @@ -51,5 +56,9 @@ public class ModCreativeLimits extends CoreModule { public LimitConfig getConfig() { return config; } + + public WeakHashMap getNoXPMobs() { + return no_xp_mobs; + } } diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/limits/EntityListener.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/limits/EntityListener.java index 37c7e40..a4fe370 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/limits/EntityListener.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/limits/EntityListener.java @@ -19,9 +19,11 @@ package de.jaschastarke.minecraft.limitedcreative.limits; import org.bukkit.GameMode; import org.bukkit.entity.Creature; +import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.entity.EntityTargetEvent; import de.jaschastarke.minecraft.lib.permissions.IAbstractPermission; @@ -49,6 +51,16 @@ public class EntityListener implements Listener { } } + @EventHandler + public void onEntityDeath(EntityDeathEvent event) { + if (event.getEntity() instanceof LivingEntity && event.getDroppedExp() > 0) { + if (mod.getNoXPMobs().containsKey(event.getEntity())) { + event.setDroppedExp(0); + mod.getNoXPMobs().remove(event.getEntity()); + } + } + } + private boolean checkPermission(Player player, IAbstractPermission perm) { return mod.getPlugin().getPermManager().hasPermission(player, perm); } diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/limits/NoLimitPermissions.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/limits/NoLimitPermissions.java index 8f74839..60e4d74 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/limits/NoLimitPermissions.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/limits/NoLimitPermissions.java @@ -90,6 +90,24 @@ public class NoLimitPermissions extends SimplePermissionContainerNode { @IsChildPermission public static final IPermission BASE_BREAK = new BasicPermission(PARENT, "break", PermissionDefault.FALSE); + /** + * Allows bypassing the "don't change heal/food-state"-limitation + */ + @IsChildPermission + public static final IPermission STATS_HEALTH = new BasicPermission(PARENT, "health", PermissionDefault.FALSE); + + /** + * Allows bypassing the "don't get xp/level"-limitation + */ + @IsChildPermission + public static final IPermission STATS_XP = new BasicPermission(PARENT, "xp", PermissionDefault.FALSE); + + /** + * Allows bypassing the "remove all effects on leaving creative"-limitation + */ + @IsChildPermission + public static final IPermission STATS_POTION = new BasicPermission(PARENT, "potion", PermissionDefault.FALSE); + public static IDynamicPermission INTERACT(Block block) { return new MaterialPermission(BASE_INTERACT, new MaterialData(block.getType(), block.getData())); } diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/limits/PlayerListener.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/limits/PlayerListener.java index e160c40..45ae779 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/limits/PlayerListener.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/limits/PlayerListener.java @@ -26,18 +26,24 @@ import org.bukkit.entity.Player; import org.bukkit.entity.Projectile; import org.bukkit.event.Event; import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.entity.EntityRegainHealthEvent; +import org.bukkit.event.entity.FoodLevelChangeEvent; import org.bukkit.event.player.PlayerDropItemEvent; import org.bukkit.event.player.PlayerEvent; +import org.bukkit.event.player.PlayerExpChangeEvent; +import org.bukkit.event.player.PlayerGameModeChangeEvent; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerPickupItemEvent; import org.bukkit.inventory.InventoryHolder; import org.bukkit.material.DirectionalContainer; +import org.bukkit.potion.PotionEffect; import de.jaschastarke.minecraft.lib.permissions.IAbstractPermission; import de.jaschastarke.minecraft.lib.permissions.IDynamicPermission; @@ -99,6 +105,48 @@ public class PlayerListener implements Listener { } } + @EventHandler + public void onPlayerChangeExp(PlayerExpChangeEvent event) { + if (event.getAmount() > 0 && event.getPlayer().getGameMode() == GameMode.CREATIVE) { + if (checkPermission(event, NoLimitPermissions.STATS_XP)) + return; + event.setAmount(0); + } + } + @EventHandler + public void onEntityFoodLevelChange(FoodLevelChangeEvent event) { + if (event.getEntity() instanceof Player) { + if (!event.isCancelled() && ((Player) event.getEntity()).getGameMode() == GameMode.CREATIVE) { + if (checkPermission((Player) event.getEntity(), NoLimitPermissions.STATS_HEALTH)) + return; + event.setCancelled(true); + } + } + } + @EventHandler + public void onEntityRegainHealth(EntityRegainHealthEvent event) { + if (event.getEntity() instanceof Player) { + if (!event.isCancelled() && ((Player) event.getEntity()).getGameMode() == GameMode.CREATIVE) { + if (checkPermission((Player) event.getEntity(), NoLimitPermissions.STATS_HEALTH)) + return; + event.setCancelled(true); + } + } + } + + @EventHandler(priority=EventPriority.LOW) + public void onGameMode(PlayerGameModeChangeEvent event) { + if (!event.isCancelled()) { + if ((event.getPlayer().getGameMode() == GameMode.CREATIVE) && (event.getNewGameMode() != GameMode.CREATIVE)) { + if (checkPermission(event, NoLimitPermissions.STATS_POTION)) + return; + for (PotionEffect effect : event.getPlayer().getActivePotionEffects()) { + event.getPlayer().removePotionEffect(effect.getType()); + } + } + } + } + @EventHandler public void onPlayerInteract(PlayerInteractEvent event) { if (!isCancelled(event) && event.getPlayer().getGameMode() == GameMode.CREATIVE) { @@ -175,6 +223,10 @@ public class PlayerListener implements Listener { if (!checkPermission(player, NoLimitPermissions.MOB_DAMAGE)) { event.setCancelled(true); } + } else if (event.getEntity() instanceof LivingEntity) { + if (!checkPermission(player, NoLimitPermissions.STATS_XP)) { + mod.getNoXPMobs().put(event.getEntity(), null); + } } } } diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/PlayerListener.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/PlayerListener.java index c494944..34e3b93 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/PlayerListener.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/PlayerListener.java @@ -58,7 +58,7 @@ public class PlayerListener extends Listener { } private boolean isRegionOptional(Player player) { - return mod.getRegionManager().getRegionSet(player.getLocation()).allows(Flags.GAMEMODE_OPTIONAL, player); + return mod.getRegionManager().getRegionSet(player.getLocation()).allows(Flags.GAMEMODE_OPTIONAL); } @EventHandler(priority = EventPriority.LOW)