diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/settings/MobSpawnListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/settings/MobSpawnListener.java index d30cab11e..892f60459 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/settings/MobSpawnListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/settings/MobSpawnListener.java @@ -3,11 +3,13 @@ package world.bentobox.bentobox.listeners.flags.settings; import java.util.Optional; import org.bukkit.Location; -import org.bukkit.entity.Entity; -import org.bukkit.entity.PufferFish; +import org.bukkit.entity.*; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.raid.RaidFinishEvent; +import org.bukkit.event.raid.RaidTriggerEvent; +import org.bukkit.potion.PotionEffectType; import world.bentobox.bentobox.api.flags.Flag; import world.bentobox.bentobox.api.flags.FlagListener; @@ -33,6 +35,60 @@ public class MobSpawnListener extends FlagListener } + /** + * This prevents to start a raid if mob spawning rules prevents it. + * @param event RaidTriggerEvent + */ + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onRaidStartEvent(RaidTriggerEvent event) + { + // If not in the right world exit immediately. + if (!this.getIWM().inWorld(event.getWorld())) + { + return; + } + + Optional island = getIslands().getIslandAt(event.getPlayer().getLocation()); + + if (island.map(i -> !i.isAllowed(Flags.MONSTER_NATURAL_SPAWN)).orElseGet( + () -> !Flags.MONSTER_NATURAL_SPAWN.isSetForWorld(event.getWorld()))) + { + // Monster spawning is disabled on island or world. Cancel the raid. + event.setCancelled(true); + } + } + + + /** + * This removes HERO_OF_THE_VILLAGE from players that cheated victory. + * @param event RaidFinishEvent + */ + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onRaidFinishEvent(RaidFinishEvent event) + { + // If not in the right world exit immediately. + if (!this.getIWM().inWorld(event.getWorld())) + { + return; + } + + Optional island = getIslands().getIslandAt(event.getRaid().getLocation()); + + if (island.map(i -> !i.isAllowed(Flags.MONSTER_NATURAL_SPAWN)).orElseGet( + () -> !Flags.MONSTER_NATURAL_SPAWN.isSetForWorld(event.getWorld()))) + { + // CHEATERS. PUNISH THEM. + event.getWinners().forEach(player -> + { + if (player.isOnline()) + { + player.removePotionEffect(PotionEffectType.HERO_OF_THE_VILLAGE); + } + }); + } + } + + /** * Prevents mobs spawning naturally * @param e - event diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/VisitorsStartingRaidListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/VisitorsStartingRaidListener.java new file mode 100644 index 000000000..8d01f8917 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/VisitorsStartingRaidListener.java @@ -0,0 +1,61 @@ +// +// Created by BONNe +// Copyright - 2022 +// + + +package world.bentobox.bentobox.listeners.flags.worldsettings; + + +import org.bukkit.World; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.raid.RaidTriggerEvent; +import java.util.Optional; + +import world.bentobox.bentobox.api.flags.FlagListener; +import world.bentobox.bentobox.api.user.User; +import world.bentobox.bentobox.database.objects.Island; +import world.bentobox.bentobox.lists.Flags; +import world.bentobox.bentobox.util.Util; + + +/** + * This listener checks for island visitors that want to start a new raid. + */ +public class VisitorsStartingRaidListener extends FlagListener +{ + /** + * This method process raid allowance from visitors. + * @param event RaidTriggerEvent + */ + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onRaidTrigger(RaidTriggerEvent event) + { + World world = Util.getWorld(event.getWorld()); + + if (!this.getIWM().inWorld(world) || Flags.VISITOR_TRIGGER_RAID.isSetForWorld(world)) + { + // If the player triggers raid non-protected world or VISITOR_TRIGGER_RAID is disabled then do nothing. + this.report(User.getInstance(event.getPlayer()), + event, + event.getPlayer().getLocation(), + Flags.VISITOR_TRIGGER_RAID, + Why.SETTING_ALLOWED_IN_WORLD); + + return; + } + + Optional island = this.getIslands().getProtectedIslandAt(event.getPlayer().getLocation()); + + if (island.isPresent() && !island.get().getMemberSet().contains(event.getPlayer().getUniqueId())) + { + event.setCancelled(true); + this.report(User.getInstance(event.getPlayer()), + event, + event.getPlayer().getLocation(), + Flags.VISITOR_TRIGGER_RAID, + Why.SETTING_NOT_ALLOWED_IN_WORLD); + } + } +} diff --git a/src/main/java/world/bentobox/bentobox/lists/Flags.java b/src/main/java/world/bentobox/bentobox/lists/Flags.java index 53d631335..ac5ce1a6a 100644 --- a/src/main/java/world/bentobox/bentobox/lists/Flags.java +++ b/src/main/java/world/bentobox/bentobox/lists/Flags.java @@ -18,30 +18,7 @@ import world.bentobox.bentobox.listeners.flags.protection.*; import world.bentobox.bentobox.listeners.flags.settings.DecayListener; import world.bentobox.bentobox.listeners.flags.settings.MobSpawnListener; import world.bentobox.bentobox.listeners.flags.settings.PVPListener; -import world.bentobox.bentobox.listeners.flags.worldsettings.ChestDamageListener; -import world.bentobox.bentobox.listeners.flags.worldsettings.CleanSuperFlatListener; -import world.bentobox.bentobox.listeners.flags.worldsettings.CoarseDirtTillingListener; -import world.bentobox.bentobox.listeners.flags.worldsettings.CreeperListener; -import world.bentobox.bentobox.listeners.flags.worldsettings.EnderChestListener; -import world.bentobox.bentobox.listeners.flags.worldsettings.EndermanListener; -import world.bentobox.bentobox.listeners.flags.worldsettings.EnterExitListener; -import world.bentobox.bentobox.listeners.flags.worldsettings.GeoLimitMobsListener; -import world.bentobox.bentobox.listeners.flags.worldsettings.InvincibleVisitorsListener; -import world.bentobox.bentobox.listeners.flags.worldsettings.IslandRespawnListener; -import world.bentobox.bentobox.listeners.flags.worldsettings.ItemFrameListener; -import world.bentobox.bentobox.listeners.flags.worldsettings.LimitMobsListener; -import world.bentobox.bentobox.listeners.flags.worldsettings.LiquidsFlowingOutListener; -import world.bentobox.bentobox.listeners.flags.worldsettings.NaturalSpawningOutsideRangeListener; -import world.bentobox.bentobox.listeners.flags.worldsettings.ObsidianScoopingListener; -import world.bentobox.bentobox.listeners.flags.worldsettings.OfflineGrowthListener; -import world.bentobox.bentobox.listeners.flags.worldsettings.OfflineRedstoneListener; -import world.bentobox.bentobox.listeners.flags.worldsettings.PetTeleportListener; -import world.bentobox.bentobox.listeners.flags.worldsettings.PistonPushListener; -import world.bentobox.bentobox.listeners.flags.worldsettings.RemoveMobsListener; -import world.bentobox.bentobox.listeners.flags.worldsettings.SpawnerSpawnEggsListener; -import world.bentobox.bentobox.listeners.flags.worldsettings.TreesGrowingOutsideRangeListener; -import world.bentobox.bentobox.listeners.flags.worldsettings.VisitorKeepInventoryListener; -import world.bentobox.bentobox.listeners.flags.worldsettings.WitherListener; +import world.bentobox.bentobox.listeners.flags.worldsettings.*; import world.bentobox.bentobox.managers.RanksManager; import world.bentobox.bentobox.util.Util; @@ -585,7 +562,14 @@ public final class Flags { * @see VisitorKeepInventoryListener */ public static final Flag VISITOR_KEEP_INVENTORY = new Flag.Builder("VISITOR_KEEP_INVENTORY", Material.TOTEM_OF_UNDYING).listener(new VisitorKeepInventoryListener()).type(Type.WORLD_SETTING).defaultSetting(false).build(); - + + /** + * Toggles whether island visitors can trigger to start a raid on another player's island. + * @since 1.21.0 + * @see VisitorsStartingRaidListener + */ + public static final Flag VISITOR_TRIGGER_RAID = new Flag.Builder("VISITOR_TRIGGER_RAID", Material.RAVAGER_SPAWN_EGG).listener(new VisitorsStartingRaidListener()).type(Type.WORLD_SETTING).defaultSetting(true).build(); + /** * Provides a list of all the Flag instances contained in this class using reflection. * Deprecated Flags are ignored. diff --git a/src/main/resources/locales/en-US.yml b/src/main/resources/locales/en-US.yml index 977b89850..d97361f42 100644 --- a/src/main/resources/locales/en-US.yml +++ b/src/main/resources/locales/en-US.yml @@ -1356,6 +1356,14 @@ protection: &a &a Island members still lose their items &a if they die on their own island! + VISITOR_TRIGGER_RAID: + name: "Visitors triggers raids" + description: |- + &a Toggles if visitors can start + &a a raid on an island which they are + &a visiting. + &a + &a Bad Omen effect will be removed! WITHER_DAMAGE: name: "Toggle wither damage" description: |-