From 360ba0b2dedb4ba39c1d5375f97a61202f2b1217 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 2 Jan 2022 16:31:02 -0800 Subject: [PATCH] Rework how offsets are used. https://github.com/BentoBoxWorld/Upgrades/issues/40 https://github.com/BentoBoxWorld/Limits/issues/117 --- .../limits/listeners/BlockLimitsListener.java | 19 ++++++--- .../limits/listeners/EntityLimitListener.java | 38 ++++++++++++------ .../limits/objects/IslandBlockCount.java | 39 ++++++++++++++++--- 3 files changed, 72 insertions(+), 24 deletions(-) diff --git a/src/main/java/world/bentobox/limits/listeners/BlockLimitsListener.java b/src/main/java/world/bentobox/limits/listeners/BlockLimitsListener.java index 1cb80b7..0fa02b9 100644 --- a/src/main/java/world/bentobox/limits/listeners/BlockLimitsListener.java +++ b/src/main/java/world/bentobox/limits/listeners/BlockLimitsListener.java @@ -209,6 +209,13 @@ public class BlockLimitsListener implements Listener { notify(e, User.getInstance(e.getPlayer()), process(e.getBlock(), true), e.getBlock().getType()); } + /** + * Cancel the event and notify the user of failure + * @param e event + * @param user user + * @param limit maximum limit allowed + * @param m material + */ private void notify(Cancellable e, User user, int limit, Material m) { if (limit > -1) { user.notify("block-limits.hit-limit", @@ -389,18 +396,18 @@ public class BlockLimitsListener implements Listener { */ private int checkLimit(World w, Material m, String id) { // Check island limits - IslandBlockCount island = islandCountMap.get(id); - if (island.isBlockLimited(m)) { - return island.isAtLimit(m) ? island.getBlockLimit(m) : -1; + IslandBlockCount ibc = islandCountMap.get(id); + if (ibc.isBlockLimited(m)) { + return ibc.isAtLimit(m) ? ibc.getBlockLimit(m) + ibc.getBlockLimitOffset(m) : -1; } // Check specific world limits if (worldLimitMap.containsKey(w) && worldLimitMap.get(w).containsKey(m)) { // Material is overridden in world - return island.isAtLimit(m, worldLimitMap.get(w).get(m)) ? worldLimitMap.get(w).get(m) : -1; + return ibc.isAtLimit(m, worldLimitMap.get(w).get(m)) ? worldLimitMap.get(w).get(m) + ibc.getBlockLimitOffset(m) : -1; } // Check default limit map - if (defaultLimitMap.containsKey(m) && island.isAtLimit(m, defaultLimitMap.get(m))) { - return defaultLimitMap.get(m); + if (defaultLimitMap.containsKey(m) && ibc.isAtLimit(m, defaultLimitMap.get(m))) { + return defaultLimitMap.get(m) + ibc.getBlockLimitOffset(m); } // No limit return -1; diff --git a/src/main/java/world/bentobox/limits/listeners/EntityLimitListener.java b/src/main/java/world/bentobox/limits/listeners/EntityLimitListener.java index 32bacac..cf5a4f1 100644 --- a/src/main/java/world/bentobox/limits/listeners/EntityLimitListener.java +++ b/src/main/java/world/bentobox/limits/listeners/EntityLimitListener.java @@ -30,6 +30,7 @@ import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; import org.bukkit.event.entity.EntityBreedEvent; import org.bukkit.event.hanging.HangingPlaceEvent; import org.bukkit.event.vehicle.VehicleCreateEvent; +import org.eclipse.jdt.annotation.Nullable; import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.localization.TextVariables; @@ -39,6 +40,7 @@ import world.bentobox.bentobox.util.Util; import world.bentobox.limits.Limits; import world.bentobox.limits.Settings; import world.bentobox.limits.Settings.EntityGroup; +import world.bentobox.limits.objects.IslandBlockCount; public class EntityLimitListener implements Listener { private static final String MOD_BYPASS = "mod.bypass"; @@ -369,11 +371,16 @@ public class EntityLimitListener implements Listener { // Check island settings first int limitAmount = -1; Map groupsLimits = new HashMap<>(); - if (addon.getBlockLimitListener().getIsland(island.getUniqueId()) != null) { - limitAmount = addon.getBlockLimitListener().getIsland(island.getUniqueId()).getEntityLimit(ent.getType()); + + @Nullable + IslandBlockCount ibc = addon.getBlockLimitListener().getIsland(island.getUniqueId()); + if (ibc != null) { + // Get the limit amount for this type + limitAmount = ibc.getEntityLimit(ent.getType()); + // Handle entity groups List groupdefs = addon.getSettings().getGroupLimits().getOrDefault(ent.getType(), new ArrayList<>()); groupdefs.forEach(def -> { - int limit = addon.getBlockLimitListener().getIsland(island.getUniqueId()).getEntityGroupLimit(def.getName()); + int limit = ibc.getEntityGroupLimit(def.getName()); if (limit >= 0) groupsLimits.put(def, limit); }); @@ -382,12 +389,15 @@ public class EntityLimitListener implements Listener { if (limitAmount < 0 && addon.getSettings().getLimits().containsKey(ent.getType())) { limitAmount = addon.getSettings().getLimits().get(ent.getType()); } + // Group limits if (addon.getSettings().getGroupLimits().containsKey(ent.getType())) { addon.getSettings().getGroupLimits().getOrDefault(ent.getType(), new ArrayList<>()).stream() .filter(group -> !groupsLimits.containsKey(group) || groupsLimits.get(group) > group.getLimit()) .forEach(group -> groupsLimits.put(group, group.getLimit())); } - if (limitAmount < 0 && groupsLimits.isEmpty()) return new AtLimitResult(); + if (limitAmount < 0 && groupsLimits.isEmpty()) { + return new AtLimitResult(); + } // We have to count the entities if (limitAmount >= 0) @@ -396,14 +406,16 @@ public class EntityLimitListener implements Listener { .filter(e -> e.getType().equals(ent.getType())) .filter(e -> island.inIslandSpace(e.getLocation())) .count(); - if (count >= limitAmount) { - return new AtLimitResult(ent.getType(), limitAmount); + int max = limitAmount + ibc.getEntityLimitOffset(ent.getType()); + if (count >= max) { + return new AtLimitResult(ent.getType(), max); } } - // Merge in any permission-based limits - if (addon.getBlockLimitListener().getIsland(island.getUniqueId()) != null) { - Map groupbyname = groupsLimits.keySet().stream().collect(Collectors.toMap(EntityGroup::getName, e -> e)); - addon.getBlockLimitListener().getIsland(island.getUniqueId()).getEntityGroupLimits().entrySet().stream() + // Group limits + if (ibc != null) { + Map groupbyname = groupsLimits.keySet().stream() + .collect(Collectors.toMap(EntityGroup::getName, e -> e)); + ibc.getEntityGroupLimits().entrySet().stream() .filter(e -> groupbyname.containsKey(e.getKey())) .forEach(e -> groupsLimits.put(groupbyname.get(e.getKey()), e.getValue())); } @@ -414,8 +426,10 @@ public class EntityLimitListener implements Listener { int count = (int) ent.getWorld().getEntities().stream() .filter(e -> group.getKey().contains(e.getType())) .filter(e -> island.inIslandSpace(e.getLocation())).count(); - if (count >= group.getValue()) - return new AtLimitResult(group.getKey(), group.getValue()); + int max = group.getValue() + ibc.getEntityGroupLimitOffset(group.getKey().getName()); + if (count >= max) { + return new AtLimitResult(group.getKey(), max); + } } return new AtLimitResult(); } diff --git a/src/main/java/world/bentobox/limits/objects/IslandBlockCount.java b/src/main/java/world/bentobox/limits/objects/IslandBlockCount.java index 69088cb..8cc137e 100644 --- a/src/main/java/world/bentobox/limits/objects/IslandBlockCount.java +++ b/src/main/java/world/bentobox/limits/objects/IslandBlockCount.java @@ -127,7 +127,7 @@ public class IslandBlockCount implements DataObject { * @return true if count is >= limit */ public boolean isAtLimit(Material material, int limit) { - return blockCounts.getOrDefault(material, 0) >= limit; + return blockCounts.getOrDefault(material, 0) >= limit + this.getBlockLimitOffset(material); } /** @@ -137,7 +137,7 @@ public class IslandBlockCount implements DataObject { */ public boolean isAtLimit(Material m) { // Check island limits first - return blockLimits.containsKey(m) && blockCounts.getOrDefault(m, 0) >= getBlockLimit(m); + return blockLimits.containsKey(m) && blockCounts.getOrDefault(m, 0) >= getBlockLimit(m) + this.getBlockLimitOffset(m); } public boolean isBlockLimited(Material m) { @@ -164,8 +164,17 @@ public class IslandBlockCount implements DataObject { * @param m - material * @return limit or -1 for unlimited */ - public Integer getBlockLimit(Material m) { - return blockLimits.getOrDefault(m, -1) + getBlockLimitsOffset().getOrDefault(m, 0); + public int getBlockLimit(Material m) { + return blockLimits.getOrDefault(m, -1); + } + + /** + * Get the block offset for this material for this island + * @param m - material + * @return offset + */ + public int getBlockLimitOffset(Material m) { + return getBlockLimitsOffset().getOrDefault(m, 0); } /** @@ -228,7 +237,16 @@ public class IslandBlockCount implements DataObject { * @return limit or -1 for unlimited */ public int getEntityLimit(EntityType t) { - return entityLimits.getOrDefault(t, -1) + getEntityLimitsOffset().getOrDefault(t, 0); + return entityLimits.getOrDefault(t, -1); + } + + /** + * Get the limit offset for an entity type + * @param t - entity type + * @return offset + */ + public int getEntityLimitOffset(EntityType t) { + return getEntityLimitsOffset().getOrDefault(t, 0); } /** @@ -270,7 +288,16 @@ public class IslandBlockCount implements DataObject { * @return limit or -1 for unlimited */ public int getEntityGroupLimit(String name) { - return entityGroupLimits.getOrDefault(name, -1) + getEntityGroupLimitsOffset().getOrDefault(name, 0); + return entityGroupLimits.getOrDefault(name, -1); + } + + /** + * Get the offset for an entity group + * @param name - entity group + * @return offset + */ + public int getEntityGroupLimitOffset(String name) { + return getEntityGroupLimitsOffset().getOrDefault(name, 0); } /**