From bd93918d9bdb97f62cd2c1245d6784ef86240936 Mon Sep 17 00:00:00 2001 From: CocoTheOwner Date: Fri, 6 Aug 2021 11:00:09 +0200 Subject: [PATCH] Better --- src/main/java/com/volmit/iris/Iris.java | 13 +-- .../volmit/iris/core/InteractionManager.java | 64 +++++++++++++++ .../object/dimensional/IrisDimension.java | 4 + .../entity/IrisEntityVillagerOverride.java | 42 ++++++++++ .../IrisEntityVillagerOverrideItems.java | 81 +++++++++++++++++++ 5 files changed, 192 insertions(+), 12 deletions(-) create mode 100644 src/main/java/com/volmit/iris/core/InteractionManager.java create mode 100644 src/main/java/com/volmit/iris/engine/object/entity/IrisEntityVillagerOverride.java create mode 100644 src/main/java/com/volmit/iris/engine/object/entity/IrisEntityVillagerOverrideItems.java diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index 83dbb91d1..054751536 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -104,17 +104,6 @@ public class Iris extends VolmitPlugin implements Listener { public static IrisCompat compat; public static FileWatcher configWatcher; - // TODO: Fix maps' behaviour so it doesn't crash Iris worlds - static class NoDolphin implements Listener { - @EventHandler - public void on(EntitySpawnEvent event) { - if (event.getEntityType().equals(EntityType.DOLPHIN)) { - Iris.debug("Cancelled Dolphin because of the map glitch (https://github.com/VolmitSoftware/Iris/issues/499) @ " + event.getLocation().getBlockX() + "/" + event.getLocation().getBlockY() + "/" + event.getLocation().getBlockZ()); - event.setCancelled(true); - } - } - } - @Permission public static PermissionIris perm; @@ -167,7 +156,7 @@ public class Iris extends VolmitPlugin implements Listener { configWatcher = new FileWatcher(getDataFile("settings.json")); getServer().getPluginManager().registerEvents(new CommandLocate(), this); getServer().getPluginManager().registerEvents(new WandManager(), this); - getServer().getPluginManager().registerEvents(new NoDolphin(), this); + getServer().getPluginManager().registerEvents(new InteractionManager(), this); super.onEnable(); Bukkit.getPluginManager().registerEvents(this, this); J.s(this::lateBind); diff --git a/src/main/java/com/volmit/iris/core/InteractionManager.java b/src/main/java/com/volmit/iris/core/InteractionManager.java new file mode 100644 index 000000000..1de34dd61 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/InteractionManager.java @@ -0,0 +1,64 @@ +package com.volmit.iris.core; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.tools.IrisToolbelt; +import com.volmit.iris.engine.object.entity.IrisEntityVillagerOverride; +import com.volmit.iris.util.math.RNG; +import org.bukkit.Material; +import org.bukkit.entity.EntityType; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityInteractEvent; +import org.bukkit.event.entity.EntityPickupItemEvent; +import org.bukkit.event.entity.VillagerAcquireTradeEvent; +import org.bukkit.inventory.MerchantRecipe; + +public class InteractionManager implements Listener { + + /** + * Prevents dolphins from trying to locate a treasure map. + * Note: This results in odd dolphin behaviour, but it's the best we can do. + */ + @EventHandler + public void on(EntityPickupItemEvent event){ + if (!IrisToolbelt.isIrisWorld(event.getEntity().getWorld())){ + return; + } + + if (event.getEntityType().equals(EntityType.DOLPHIN)){ + event.setCancelled(true); + } + } + + /** + * Replace or disable villager trade add event to prevent explorer map + */ + @EventHandler + public void on(VillagerAcquireTradeEvent event){ + if (!IrisToolbelt.isIrisWorld((event.getEntity().getWorld()))){ + return; + } + + // Iris.info("Trade event: type " + event.getRecipe().getResult().getType() + " / meta " + event.getRecipe().getResult().getItemMeta() + " / data " + event.getRecipe().getResult().getData()); + if (event.getRecipe().getResult().getType().equals(Material.FILLED_MAP)){ + IrisEntityVillagerOverride override = IrisToolbelt.access(event.getEntity().getWorld()).getCompound().getRootDimension().getVillagerTrade(); + + if (override.isDisableTrade()){ + event.setCancelled(true); + Iris.debug("Cancelled cartographer trade @ " + event.getEntity().getLocation()); + return; + } + + if (!override.getItems().isValidItems()){ + event.setCancelled(true); + Iris.debug("Cancelled cartographer trade because override items not valid @ " + event.getEntity().getLocation()); + return; + } + + MerchantRecipe recipe = new MerchantRecipe(override.getItems().getResult(), override.getItems().getAmount()); + recipe.setIngredients(override.getItems().getIngredients()); + event.setRecipe(recipe); + Iris.debug("Overrode cartographer trade with: " + recipe + " to prevent allowing cartography map trades"); + } + } +} diff --git a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java b/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java index c78be70e0..c9eedcc6e 100644 --- a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java +++ b/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java @@ -34,6 +34,7 @@ import com.volmit.iris.engine.object.carve.IrisCaveFluid; import com.volmit.iris.engine.object.carve.IrisCaveLayer; import com.volmit.iris.engine.object.carve.IrisCaverns; import com.volmit.iris.engine.object.deposits.IrisDepositGenerator; +import com.volmit.iris.engine.object.entity.IrisEntityVillagerOverride; import com.volmit.iris.engine.object.feature.IrisFeaturePositional; import com.volmit.iris.engine.object.feature.IrisFeaturePotential; import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructure; @@ -330,6 +331,9 @@ public class IrisDimension extends IrisRegistrant { @Desc("Define biome mutations for this dimension") private KList mutations = new KList<>(); + @Desc("Cartographer map trade overrides") + private IrisEntityVillagerOverride villagerTrade = new IrisEntityVillagerOverride().setDisableTrade(false); + private final transient AtomicCache parallaxSize = new AtomicCache<>(); private final transient AtomicCache rockLayerGenerator = new AtomicCache<>(); private final transient AtomicCache fluidLayerGenerator = new AtomicCache<>(); diff --git a/src/main/java/com/volmit/iris/engine/object/entity/IrisEntityVillagerOverride.java b/src/main/java/com/volmit/iris/engine/object/entity/IrisEntityVillagerOverride.java new file mode 100644 index 000000000..90ed5e23a --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/entity/IrisEntityVillagerOverride.java @@ -0,0 +1,42 @@ +package com.volmit.iris.engine.object.entity; + +import com.volmit.iris.engine.object.annotations.DependsOn; +import com.volmit.iris.engine.object.annotations.Desc; +import com.volmit.iris.engine.object.annotations.Required; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +@Accessors(chain = true) +@NoArgsConstructor +@AllArgsConstructor + +@Desc("Override cartographer map trades with others or disable the trade altogether") +@Data +@EqualsAndHashCode(callSuper = false) +public class IrisEntityVillagerOverride { + @Desc(""" + Disable the trade altogether. + If a cartographer villager gets a new explorer map trade: + If this is enabled -> the trade is removed + If this is disabled -> the trade is replaced with the "override" setting below + Default is true, so if you omit this, trades will be removed.""") + private boolean disableTrade = true; + + @DependsOn("disableTrade") + @Required + @Desc(""" + The items to override the cartographer trade with. + By default, this is 3 emeralds + 3 glass blocks -> 1 spyglass. + Can trade 3 to 5 times""") + private IrisEntityVillagerOverrideItems items = new IrisEntityVillagerOverrideItems() + .setIngredient1(new ItemStack(Material.EMERALD, 3)) + .setIngredient2(new ItemStack(Material.GLASS, 3)) + .setResult(new ItemStack(Material.SPYGLASS)) + .setMinTrades(3) + .setMaxTrades(5); +} diff --git a/src/main/java/com/volmit/iris/engine/object/entity/IrisEntityVillagerOverrideItems.java b/src/main/java/com/volmit/iris/engine/object/entity/IrisEntityVillagerOverrideItems.java new file mode 100644 index 000000000..4f065144e --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/entity/IrisEntityVillagerOverrideItems.java @@ -0,0 +1,81 @@ +package com.volmit.iris.engine.object.entity; + + +import com.volmit.iris.engine.object.annotations.*; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.math.RNG; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import org.bukkit.inventory.ItemStack; + +import java.util.List; + + +@Accessors(chain = true) +@NoArgsConstructor +@AllArgsConstructor + +@SuppressWarnings("BooleanMethodIsAlwaysInverted") +@Desc("Override cartographer map trades with these items. ") +@Data +@EqualsAndHashCode(callSuper = false) +public class IrisEntityVillagerOverrideItems { + + @Required + @RegistryListItemType + @Desc("The first, required, ingredient for the trade.\nNote: this MUST be an item, and may not be a non-obtainable block!") + private ItemStack ingredient1; + + @RegistryListItemType + @Desc("The second, optional, ingredient for the trade.\nNote: this MUST be an item, and may not be a non-obtainable block!") + private ItemStack ingredient2 = null; + + @Required + @RegistryListItemType + @Desc("The result of the trade.\nNote: this MUST be an item, and may not be a non-obtainable block!") + private ItemStack result; + + @Desc("The min amount of times this trade can be done. Default 3") + @MinNumber(1) + @MaxNumber(64) + private int minTrades = 3; + + @Desc("The max amount of times this trade can be done. Default 5") + @MinNumber(1) + @MaxNumber(64) + private int maxTrades = 5; + + /** + * @return true if:
+ * ingredient 1 & result are non-null,
+ * mintrades > 0, maxtrades > 0, maxtrades > mintrades, and
+ * ingredient 1, (if defined ingredient 2) and the result are valid items + */ + public boolean isValidItems(){ + if (ingredient1 == null || result == null || minTrades <= 0 || maxTrades <= 0 || maxTrades < minTrades){ + return false; + } + return ingredient1.getType().isItem() && (ingredient2 == null || ingredient2.getType().isItem()) && result.getType().isItem(); + } + + /** + * Get the ingredients + * @return The list of 1 or 2 ingredients (depending on if ing2 is null) + */ + public List getIngredients() { + if (!isValidItems()){ + return null; + } + return ingredient2 == null ? new KList<>(ingredient1) : new KList<>(ingredient1, ingredient2); + } + + /** + * @return the amount of trades (RNG.r.i(min, max)) + */ + public int getAmount() { + return RNG.r.i(minTrades, maxTrades); + } +}