mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2024-12-22 00:58:04 +01:00
Added GeoLimit for mobs - world setting.
Adds a world menu for preventing mobs from exiting an island. Defaults are for flying mobs. Adds an event that is called when the plugin loads. Test classes are still to be developed.
This commit is contained in:
parent
944ab36488
commit
b40023bcf9
19
config.yml
19
config.yml
@ -294,12 +294,12 @@ island:
|
|||||||
team-join-reset: true
|
team-join-reset: true
|
||||||
customranks: {}
|
customranks: {}
|
||||||
protection:
|
protection:
|
||||||
# Allow pistons to push outside of the protected area (maybe to make bridges)
|
# Geo restrict mobs.
|
||||||
allow-piston-push: true
|
# Mobs that exit the island space where they were spawned will be removed.
|
||||||
# Restrict Wither and other flying mobs.
|
geo-limit-settings:
|
||||||
# Any flying mobs that exit the island space where they were spawned will be removed.
|
- GHAST
|
||||||
# Includes blaze and ghast.
|
- BAT
|
||||||
restrict-flying-mobs: true
|
- BLAZE
|
||||||
# Invincible visitors. List of damages that will not affect visitors.
|
# Invincible visitors. List of damages that will not affect visitors.
|
||||||
# Make list blank if visitors should receive all damages
|
# Make list blank if visitors should receive all damages
|
||||||
invincible-visitors:
|
invincible-visitors:
|
||||||
@ -328,13 +328,6 @@ protection:
|
|||||||
- CRAMMING
|
- CRAMMING
|
||||||
- VOID
|
- VOID
|
||||||
togglePvPCooldown: 0
|
togglePvPCooldown: 0
|
||||||
allowEndermanGriefing: false
|
|
||||||
endermanDeathDrop: false
|
|
||||||
allowTNTDamage: false
|
|
||||||
allowChestDamage: false
|
|
||||||
allowCreeperDamage: false
|
|
||||||
allowCreeperGriefing: false
|
|
||||||
allowMobDamageToItemFrames: false
|
|
||||||
panel:
|
panel:
|
||||||
close-on-click-outside: true
|
close-on-click-outside: true
|
||||||
uniqueId: config
|
uniqueId: config
|
||||||
|
@ -442,6 +442,12 @@ protection:
|
|||||||
description: "Toggle use"
|
description: "Toggle use"
|
||||||
name: "Gates"
|
name: "Gates"
|
||||||
hint: "No gate use"
|
hint: "No gate use"
|
||||||
|
GEO_LIMIT_MOBS:
|
||||||
|
description: |
|
||||||
|
&eRemove mobs that go
|
||||||
|
&eoutside protected
|
||||||
|
&eisland space
|
||||||
|
name: "Limit mobs to island"
|
||||||
HURT_ANIMALS:
|
HURT_ANIMALS:
|
||||||
description: "Toggle hurting"
|
description: "Toggle hurting"
|
||||||
name: "Hurt animals"
|
name: "Hurt animals"
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
package us.tastybento.bskyblock;
|
package us.tastybento.bskyblock;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.plugin.PluginManager;
|
import org.bukkit.plugin.PluginManager;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
import us.tastybento.bskyblock.api.configuration.BSBConfig;
|
import us.tastybento.bskyblock.api.configuration.BSBConfig;
|
||||||
import us.tastybento.bskyblock.api.configuration.WorldSettings;
|
import us.tastybento.bskyblock.api.configuration.WorldSettings;
|
||||||
|
import us.tastybento.bskyblock.api.events.BSBReadyEvent;
|
||||||
import us.tastybento.bskyblock.api.placeholders.PlaceholderHandler;
|
import us.tastybento.bskyblock.api.placeholders.PlaceholderHandler;
|
||||||
import us.tastybento.bskyblock.api.user.Notifier;
|
import us.tastybento.bskyblock.api.user.Notifier;
|
||||||
import us.tastybento.bskyblock.commands.AdminCommand;
|
import us.tastybento.bskyblock.commands.AdminCommand;
|
||||||
@ -148,6 +150,8 @@ public class BSkyBlock extends JavaPlugin {
|
|||||||
instance.log("- Tastybento and Poslovitch, 2017-2018");
|
instance.log("- Tastybento and Poslovitch, 2017-2018");
|
||||||
instance.log("#############################################");
|
instance.log("#############################################");
|
||||||
|
|
||||||
|
// Fire plugin ready event
|
||||||
|
Bukkit.getServer().getPluginManager().callEvent(new BSBReadyEvent());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -404,26 +404,12 @@ public class Settings implements DataObject, WorldSettings {
|
|||||||
// ---------------------------------------------
|
// ---------------------------------------------
|
||||||
|
|
||||||
/* PROTECTION */
|
/* PROTECTION */
|
||||||
@ConfigComment("Allow pistons to push outside of the protected area (maybe to make bridges)")
|
|
||||||
@ConfigEntry(path = "protection.allow-piston-push")
|
|
||||||
private boolean allowPistonPush = false;
|
|
||||||
|
|
||||||
@ConfigComment("Restrict Wither and other flying mobs.")
|
|
||||||
@ConfigComment("Any flying mobs that exit the island space where they were spawned will be removed.")
|
|
||||||
@ConfigComment("Includes blaze and ghast. ")
|
|
||||||
@ConfigEntry(path = "protection.restrict-flying-mobs")
|
|
||||||
private boolean restrictFlyingMobs = true;
|
|
||||||
|
|
||||||
private int togglePvPCooldown;
|
private int togglePvPCooldown;
|
||||||
|
|
||||||
//TODO transform these options below into flags
|
@ConfigComment("Geo restrict mobs.")
|
||||||
private boolean allowEndermanGriefing;
|
@ConfigComment("Mobs that exit the island space where they were spawned will be removed.")
|
||||||
private boolean endermanDeathDrop;
|
@ConfigEntry(path = "protection.geo-limit-settings")
|
||||||
private boolean allowTNTDamage;
|
private List<String> geoLimitSettings = new ArrayList<>();
|
||||||
private boolean allowChestDamage;
|
|
||||||
private boolean allowCreeperDamage;
|
|
||||||
private boolean allowCreeperGriefing;
|
|
||||||
private boolean allowMobDamageToItemFrames;
|
|
||||||
|
|
||||||
// Invincible visitor settings
|
// Invincible visitor settings
|
||||||
@ConfigComment("Invincible visitors. List of damages that will not affect visitors.")
|
@ConfigComment("Invincible visitors. List of damages that will not affect visitors.")
|
||||||
@ -737,54 +723,12 @@ public class Settings implements DataObject, WorldSettings {
|
|||||||
public String getWorldName() {
|
public String getWorldName() {
|
||||||
return worldName;
|
return worldName;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* @return the allowChestDamage
|
|
||||||
*/
|
|
||||||
public boolean isAllowChestDamage() {
|
|
||||||
return allowChestDamage;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @return the allowCreeperDamage
|
|
||||||
*/
|
|
||||||
public boolean isAllowCreeperDamage() {
|
|
||||||
return allowCreeperDamage;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @return the allowCreeperGriefing
|
|
||||||
*/
|
|
||||||
public boolean isAllowCreeperGriefing() {
|
|
||||||
return allowCreeperGriefing;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @return the allowEndermanGriefing
|
|
||||||
*/
|
|
||||||
public boolean isAllowEndermanGriefing() {
|
|
||||||
return allowEndermanGriefing;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @return the allowMobDamageToItemFrames
|
|
||||||
*/
|
|
||||||
public boolean isAllowMobDamageToItemFrames() {
|
|
||||||
return allowMobDamageToItemFrames;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* @return the allowObsidianScooping
|
* @return the allowObsidianScooping
|
||||||
*/
|
*/
|
||||||
public boolean isAllowObsidianScooping() {
|
public boolean isAllowObsidianScooping() {
|
||||||
return allowObsidianScooping;
|
return allowObsidianScooping;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* @return the allowPistonPush
|
|
||||||
*/
|
|
||||||
public boolean isAllowPistonPush() {
|
|
||||||
return allowPistonPush;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @return the allowTNTDamage
|
|
||||||
*/
|
|
||||||
public boolean isAllowTNTDamage() {
|
|
||||||
return allowTNTDamage;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* @return the checkUpdates
|
* @return the checkUpdates
|
||||||
*/
|
*/
|
||||||
@ -797,12 +741,6 @@ public class Settings implements DataObject, WorldSettings {
|
|||||||
public boolean isDeathsSumTeam() {
|
public boolean isDeathsSumTeam() {
|
||||||
return deathsSumTeam;
|
return deathsSumTeam;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* @return the endermanDeathDrop
|
|
||||||
*/
|
|
||||||
public boolean isEndermanDeathDrop() {
|
|
||||||
return endermanDeathDrop;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* @return the endGenerate
|
* @return the endGenerate
|
||||||
*/
|
*/
|
||||||
@ -898,12 +836,6 @@ public class Settings implements DataObject, WorldSettings {
|
|||||||
public boolean isRespawnOnIsland() {
|
public boolean isRespawnOnIsland() {
|
||||||
return respawnOnIsland;
|
return respawnOnIsland;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* @return the restrictFlyingMobs
|
|
||||||
*/
|
|
||||||
public boolean isRestrictFlyingMobs() {
|
|
||||||
return restrictFlyingMobs;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* @return the useEconomy
|
* @return the useEconomy
|
||||||
*/
|
*/
|
||||||
@ -917,54 +849,12 @@ public class Settings implements DataObject, WorldSettings {
|
|||||||
public boolean isUseOwnGenerator() {
|
public boolean isUseOwnGenerator() {
|
||||||
return useOwnGenerator;
|
return useOwnGenerator;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* @param allowChestDamage the allowChestDamage to set
|
|
||||||
*/
|
|
||||||
public void setAllowChestDamage(boolean allowChestDamage) {
|
|
||||||
this.allowChestDamage = allowChestDamage;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @param allowCreeperDamage the allowCreeperDamage to set
|
|
||||||
*/
|
|
||||||
public void setAllowCreeperDamage(boolean allowCreeperDamage) {
|
|
||||||
this.allowCreeperDamage = allowCreeperDamage;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @param allowCreeperGriefing the allowCreeperGriefing to set
|
|
||||||
*/
|
|
||||||
public void setAllowCreeperGriefing(boolean allowCreeperGriefing) {
|
|
||||||
this.allowCreeperGriefing = allowCreeperGriefing;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @param allowEndermanGriefing the allowEndermanGriefing to set
|
|
||||||
*/
|
|
||||||
public void setAllowEndermanGriefing(boolean allowEndermanGriefing) {
|
|
||||||
this.allowEndermanGriefing = allowEndermanGriefing;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @param allowMobDamageToItemFrames the allowMobDamageToItemFrames to set
|
|
||||||
*/
|
|
||||||
public void setAllowMobDamageToItemFrames(boolean allowMobDamageToItemFrames) {
|
|
||||||
this.allowMobDamageToItemFrames = allowMobDamageToItemFrames;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* @param allowObsidianScooping the allowObsidianScooping to set
|
* @param allowObsidianScooping the allowObsidianScooping to set
|
||||||
*/
|
*/
|
||||||
public void setAllowObsidianScooping(boolean allowObsidianScooping) {
|
public void setAllowObsidianScooping(boolean allowObsidianScooping) {
|
||||||
this.allowObsidianScooping = allowObsidianScooping;
|
this.allowObsidianScooping = allowObsidianScooping;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* @param allowPistonPush the allowPistonPush to set
|
|
||||||
*/
|
|
||||||
public void setAllowPistonPush(boolean allowPistonPush) {
|
|
||||||
this.allowPistonPush = allowPistonPush;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @param allowTNTDamage the allowTNTDamage to set
|
|
||||||
*/
|
|
||||||
public void setAllowTNTDamage(boolean allowTNTDamage) {
|
|
||||||
this.allowTNTDamage = allowTNTDamage;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* @param checkUpdates the checkUpdates to set
|
* @param checkUpdates the checkUpdates to set
|
||||||
*/
|
*/
|
||||||
@ -1037,12 +927,6 @@ public class Settings implements DataObject, WorldSettings {
|
|||||||
public void setDefaultLanguage(String defaultLanguage) {
|
public void setDefaultLanguage(String defaultLanguage) {
|
||||||
this.defaultLanguage = defaultLanguage;
|
this.defaultLanguage = defaultLanguage;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* @param endermanDeathDrop the endermanDeathDrop to set
|
|
||||||
*/
|
|
||||||
public void setEndermanDeathDrop(boolean endermanDeathDrop) {
|
|
||||||
this.endermanDeathDrop = endermanDeathDrop;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* @param endGenerate the endGenerate to set
|
* @param endGenerate the endGenerate to set
|
||||||
*/
|
*/
|
||||||
@ -1253,12 +1137,6 @@ public class Settings implements DataObject, WorldSettings {
|
|||||||
public void setRespawnOnIsland(boolean respawnOnIsland) {
|
public void setRespawnOnIsland(boolean respawnOnIsland) {
|
||||||
this.respawnOnIsland = respawnOnIsland;
|
this.respawnOnIsland = respawnOnIsland;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* @param restrictFlyingMobs the restrictFlyingMobs to set
|
|
||||||
*/
|
|
||||||
public void setRestrictFlyingMobs(boolean restrictFlyingMobs) {
|
|
||||||
this.restrictFlyingMobs = restrictFlyingMobs;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* @param seaHeight the seaHeight to set
|
* @param seaHeight the seaHeight to set
|
||||||
*/
|
*/
|
||||||
@ -1588,6 +1466,19 @@ public class Settings implements DataObject, WorldSettings {
|
|||||||
public boolean isWaterUnsafe() {
|
public boolean isWaterUnsafe() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @return the geoLimitSettings
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<String> getGeoLimitSettings() {
|
||||||
|
return geoLimitSettings;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param geoLimitSettings the geoLimitSettings to set
|
||||||
|
*/
|
||||||
|
public void setGeoLimitSettings(List<String> geoLimitSettings) {
|
||||||
|
this.geoLimitSettings = geoLimitSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -230,4 +230,9 @@ public interface WorldSettings {
|
|||||||
* @return true if water is not safe in this world, e.g, should not be a home location
|
* @return true if water is not safe in this world, e.g, should not be a home location
|
||||||
*/
|
*/
|
||||||
boolean isWaterUnsafe();
|
boolean isWaterUnsafe();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return list of entity types that should not exit the island limits
|
||||||
|
*/
|
||||||
|
List<String> getGeoLimitSettings();
|
||||||
}
|
}
|
||||||
|
@ -327,6 +327,11 @@ public class Island implements DataObject {
|
|||||||
return x >= getMinX() && x < getMinX() + range*2 && z >= getMinZ() && z < getMinZ() + range*2;
|
return x >= getMinX() && x < getMinX() + range*2 && z >= getMinZ() && z < getMinZ() + range*2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if location is in full island space, not just protected space
|
||||||
|
* @param location - location
|
||||||
|
* @return true if in island space
|
||||||
|
*/
|
||||||
public boolean inIslandSpace(Location location) {
|
public boolean inIslandSpace(Location location) {
|
||||||
return Util.sameWorld(world, location.getWorld()) && inIslandSpace(location.getBlockX(), location.getBlockZ());
|
return Util.sameWorld(world, location.getWorld()) && inIslandSpace(location.getBlockX(), location.getBlockZ());
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,103 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package us.tastybento.bskyblock.listeners.flags;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.event.inventory.ClickType;
|
||||||
|
|
||||||
|
import us.tastybento.bskyblock.BSkyBlock;
|
||||||
|
import us.tastybento.bskyblock.api.panels.Panel;
|
||||||
|
import us.tastybento.bskyblock.api.panels.PanelItem;
|
||||||
|
import us.tastybento.bskyblock.api.panels.PanelItem.ClickHandler;
|
||||||
|
import us.tastybento.bskyblock.api.panels.builders.PanelBuilder;
|
||||||
|
import us.tastybento.bskyblock.api.panels.builders.PanelItemBuilder;
|
||||||
|
import us.tastybento.bskyblock.api.user.User;
|
||||||
|
import us.tastybento.bskyblock.managers.IslandWorldManager;
|
||||||
|
import us.tastybento.bskyblock.util.Util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide geo limiting to mobs - removed them if they go outside island bounds
|
||||||
|
* @author tastybento
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class GeoLimitClickListener implements ClickHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of all living entity types, minus some
|
||||||
|
*/
|
||||||
|
private final List<EntityType> livingEntityTypes = Arrays.stream(EntityType.values())
|
||||||
|
.filter(EntityType::isAlive)
|
||||||
|
.filter(t -> !(t.equals(EntityType.PLAYER) || t.equals(EntityType.GIANT) || t.equals(EntityType.ARMOR_STAND)))
|
||||||
|
.sorted(Comparator.comparing(EntityType::name))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onClick(Panel panel, User user, ClickType clickType, int slot) {
|
||||||
|
// Get the world
|
||||||
|
if (!user.inWorld()) {
|
||||||
|
user.sendMessage("general.errors.wrong-world");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
IslandWorldManager iwm = BSkyBlock.getInstance().getIWM();
|
||||||
|
String reqPerm = iwm.getPermissionPrefix(Util.getWorld(user.getWorld())) + ".admin.settings.GEO_LIMIT_MOBS";
|
||||||
|
if (!user.hasPermission(reqPerm)) {
|
||||||
|
user.sendMessage("general.errors.no-permission");
|
||||||
|
user.sendMessage("general.errors.you-need", "[permission]", reqPerm);
|
||||||
|
user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_METAL_HIT, 1F, 1F);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String panelName = user.getTranslation("protection.flags.GEO_LIMIT_MOBS.name");
|
||||||
|
if (panel.getName().equals(panelName)) {
|
||||||
|
// This is a click on the geo limit panel
|
||||||
|
// Slot relates to the enum
|
||||||
|
EntityType c = livingEntityTypes.get(slot);
|
||||||
|
if (iwm.getGeoLimitSettings(user.getWorld()).contains(c.name())) {
|
||||||
|
iwm.getGeoLimitSettings(user.getWorld()).remove(c.name());
|
||||||
|
} else {
|
||||||
|
iwm.getGeoLimitSettings(user.getWorld()).add(c.name());
|
||||||
|
}
|
||||||
|
// Apply change to panel
|
||||||
|
panel.getInventory().setItem(slot, getPanelItem(c, user).getItem());
|
||||||
|
} else {
|
||||||
|
// Open the Sub Settings panel
|
||||||
|
openPanel(user, panelName);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openPanel(User user, String panelName) {
|
||||||
|
// Close the current panel
|
||||||
|
user.closeInventory();
|
||||||
|
// Open a new panel
|
||||||
|
PanelBuilder pb = new PanelBuilder();
|
||||||
|
pb.user(user).name(panelName);
|
||||||
|
// Make panel items
|
||||||
|
livingEntityTypes.forEach(c -> pb.item(getPanelItem(c, user)));
|
||||||
|
pb.build();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private PanelItem getPanelItem(EntityType c, User user) {
|
||||||
|
PanelItemBuilder pib = new PanelItemBuilder();
|
||||||
|
pib.name(Util.prettifyText(c.toString()));
|
||||||
|
pib.clickHandler(this);
|
||||||
|
if (BSkyBlock.getInstance().getIWM().getGeoLimitSettings(user.getWorld()).contains(c.name())) {
|
||||||
|
pib.icon(Material.GREEN_SHULKER_BOX);
|
||||||
|
pib.description(user.getTranslation("protection.panel.flag-item.setting-active"));
|
||||||
|
} else {
|
||||||
|
pib.icon(Material.RED_SHULKER_BOX);
|
||||||
|
pib.description(user.getTranslation("protection.panel.flag-item.setting-disabled"));
|
||||||
|
}
|
||||||
|
return pib.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,85 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package us.tastybento.bskyblock.listeners.flags;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.Projectile;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
|
import org.bukkit.event.entity.EntityDeathEvent;
|
||||||
|
import org.bukkit.event.entity.ExplosionPrimeEvent;
|
||||||
|
import org.bukkit.projectiles.ProjectileSource;
|
||||||
|
|
||||||
|
import us.tastybento.bskyblock.api.events.BSBReadyEvent;
|
||||||
|
import us.tastybento.bskyblock.api.flags.AbstractFlagListener;
|
||||||
|
import us.tastybento.bskyblock.database.objects.Island;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide geo limiting to mobs - removed them if they go outside island bounds
|
||||||
|
* @author tastybento
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class GeoLimitMobsListener extends AbstractFlagListener {
|
||||||
|
|
||||||
|
private Map<Entity, Island> mobSpawnTracker = new WeakHashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the tracker when the plugin is loaded
|
||||||
|
*/
|
||||||
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||||
|
public void pluginReady(BSBReadyEvent event) {
|
||||||
|
// Kick off the task to remove entities that go outside island boundaries
|
||||||
|
Bukkit.getScheduler().runTaskTimer(getPlugin(), () -> {
|
||||||
|
mobSpawnTracker.entrySet().stream()
|
||||||
|
.filter(e -> !e.getValue().onIsland(e.getKey().getLocation()))
|
||||||
|
.map(Map.Entry::getKey)
|
||||||
|
.forEach(Entity::remove);
|
||||||
|
mobSpawnTracker.keySet().removeIf(e -> e == null || e.isDead());
|
||||||
|
}, 20L, 20L);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Track where the mob was created. This will determine its allowable movement zone.
|
||||||
|
* @param e - event
|
||||||
|
*/
|
||||||
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||||
|
public void mobSpawn(CreatureSpawnEvent e) {
|
||||||
|
if (getIWM().inWorld(e.getLocation())
|
||||||
|
&& getIWM().getGeoLimitSettings(e.getLocation().getWorld()).contains(e.getEntityType().name())) {
|
||||||
|
getIslands().getIslandAt(e.getLocation()).ifPresent(i -> mobSpawnTracker.put(e.getEntity(), i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean up the map when entity dies (does not handle entity removal)
|
||||||
|
*/
|
||||||
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||||
|
public void MobDeath(final EntityDeathEvent e) {
|
||||||
|
mobSpawnTracker.remove(e.getEntity());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deal with projectiles fired by entities
|
||||||
|
* @param e
|
||||||
|
*/
|
||||||
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||||
|
public void ProjectileExplode(final ExplosionPrimeEvent e) {
|
||||||
|
if (e.getEntity() instanceof Projectile && getIWM().inWorld(e.getEntity().getLocation())) {
|
||||||
|
ProjectileSource source = ((Projectile)e.getEntity()).getShooter();
|
||||||
|
if (source instanceof Entity) {
|
||||||
|
Entity shooter = (Entity)source;
|
||||||
|
if (mobSpawnTracker.containsKey(shooter)
|
||||||
|
&& !mobSpawnTracker.get(shooter).onIsland(e.getEntity().getLocation())) {
|
||||||
|
e.getEntity().remove();
|
||||||
|
e.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -23,6 +23,7 @@ import us.tastybento.bskyblock.listeners.flags.EndermanListener;
|
|||||||
import us.tastybento.bskyblock.listeners.flags.EnterExitListener;
|
import us.tastybento.bskyblock.listeners.flags.EnterExitListener;
|
||||||
import us.tastybento.bskyblock.listeners.flags.EntityInteractListener;
|
import us.tastybento.bskyblock.listeners.flags.EntityInteractListener;
|
||||||
import us.tastybento.bskyblock.listeners.flags.FireListener;
|
import us.tastybento.bskyblock.listeners.flags.FireListener;
|
||||||
|
import us.tastybento.bskyblock.listeners.flags.GeoLimitClickListener;
|
||||||
import us.tastybento.bskyblock.listeners.flags.GeoLimitMobsListener;
|
import us.tastybento.bskyblock.listeners.flags.GeoLimitMobsListener;
|
||||||
import us.tastybento.bskyblock.listeners.flags.HurtingListener;
|
import us.tastybento.bskyblock.listeners.flags.HurtingListener;
|
||||||
import us.tastybento.bskyblock.listeners.flags.InventoryListener;
|
import us.tastybento.bskyblock.listeners.flags.InventoryListener;
|
||||||
@ -191,9 +192,8 @@ public class Flags {
|
|||||||
public static final Flag INVINCIBLE_VISITORS = new FlagBuilder().id("INVINCIBLE_VISITORS").icon(Material.DIAMOND_CHESTPLATE).type(Type.WORLD_SETTING)
|
public static final Flag INVINCIBLE_VISITORS = new FlagBuilder().id("INVINCIBLE_VISITORS").icon(Material.DIAMOND_CHESTPLATE).type(Type.WORLD_SETTING)
|
||||||
.listener(ilv).onClick(ilv).subPanel(true).build();
|
.listener(ilv).onClick(ilv).subPanel(true).build();
|
||||||
|
|
||||||
private static GeoLimitMobsListener glm = new GeoLimitMobsListener();
|
public static final Flag GEO_LIMIT_MOBS = new FlagBuilder().id("GEO_LIMIT_MOBS").icon(Material.CHAINMAIL_CHESTPLATE).type(Type.WORLD_SETTING)
|
||||||
static final Flag GEO_LIMIT_MOBS = new FlagBuilder().id("GEO_LIMIT_MOBS").icon(Material.CHAINMAIL_CHESTPLATE).type(Type.WORLD_SETTING)
|
.listener(new GeoLimitMobsListener()).onClick(new GeoLimitClickListener()).subPanel(true).build();
|
||||||
.listener(glm).onClick(glm).subPanel(true).build();
|
|
||||||
|
|
||||||
public static final Flag REMOVE_MOBS = new FlagBuilder().id("REMOVE_MOBS").icon(Material.GLOWSTONE_DUST).type(Type.WORLD_SETTING)
|
public static final Flag REMOVE_MOBS = new FlagBuilder().id("REMOVE_MOBS").icon(Material.GLOWSTONE_DUST).type(Type.WORLD_SETTING)
|
||||||
.listener(new RemoveMobsListener()).allowedByDefault(true).build();
|
.listener(new RemoveMobsListener()).allowedByDefault(true).build();
|
||||||
|
@ -573,7 +573,7 @@ public class IslandWorldManager {
|
|||||||
*
|
*
|
||||||
* @param world
|
* @param world
|
||||||
* - world
|
* - world
|
||||||
* @return invisible visitor settings
|
* @return invincible visitor settings
|
||||||
*/
|
*/
|
||||||
public List<String> getIvSettings(World world) {
|
public List<String> getIvSettings(World world) {
|
||||||
return worldSettings.get(Util.getWorld(world)).getIvSettings();
|
return worldSettings.get(Util.getWorld(world)).getIvSettings();
|
||||||
@ -725,4 +725,13 @@ public class IslandWorldManager {
|
|||||||
public boolean isWaterNotSafe(World world) {
|
public boolean isWaterNotSafe(World world) {
|
||||||
return worldSettings.get(Util.getWorld(world)).isWaterUnsafe();
|
return worldSettings.get(Util.getWorld(world)).isWaterUnsafe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of entity types that should not exit the island limits
|
||||||
|
* @param world - world
|
||||||
|
* @return list
|
||||||
|
*/
|
||||||
|
public List<String> getGeoLimitSettings(World world) {
|
||||||
|
return worldSettings.get(Util.getWorld(world)).getGeoLimitSettings();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user