diff --git a/src/main/java/net/momirealms/customcrops/CustomCrops.java b/src/main/java/net/momirealms/customcrops/CustomCrops.java index 07935b9..cd6ee07 100644 --- a/src/main/java/net/momirealms/customcrops/CustomCrops.java +++ b/src/main/java/net/momirealms/customcrops/CustomCrops.java @@ -32,7 +32,7 @@ import net.momirealms.customcrops.api.object.basic.MessageManager; import net.momirealms.customcrops.api.object.crop.CropManager; import net.momirealms.customcrops.api.object.fertilizer.FertilizerManager; import net.momirealms.customcrops.api.object.pot.PotManager; -import net.momirealms.customcrops.api.object.schedule.Scheduler; +import net.momirealms.customcrops.api.object.scheduler.Scheduler; import net.momirealms.customcrops.api.object.season.SeasonManager; import net.momirealms.customcrops.api.object.sprinkler.SprinklerManager; import net.momirealms.customcrops.api.object.wateringcan.WateringCanManager; diff --git a/src/main/java/net/momirealms/customcrops/api/CustomCropsAPI.java b/src/main/java/net/momirealms/customcrops/api/CustomCropsAPI.java index a767156..3fee499 100644 --- a/src/main/java/net/momirealms/customcrops/api/CustomCropsAPI.java +++ b/src/main/java/net/momirealms/customcrops/api/CustomCropsAPI.java @@ -21,10 +21,15 @@ import net.momirealms.customcrops.CustomCrops; import net.momirealms.customcrops.api.customplugin.PlatformInterface; import net.momirealms.customcrops.api.object.ItemMode; import net.momirealms.customcrops.api.object.crop.CropConfig; +import net.momirealms.customcrops.api.object.fertilizer.Fertilizer; import net.momirealms.customcrops.api.object.pot.Pot; +import net.momirealms.customcrops.api.object.pot.PotConfig; import net.momirealms.customcrops.api.object.season.CCSeason; import net.momirealms.customcrops.api.object.world.SimpleLocation; +import net.momirealms.customcrops.api.util.ConfigUtils; import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; import org.bukkit.inventory.ItemStack; public class CustomCropsAPI { @@ -78,8 +83,29 @@ public class CustomCropsAPI { Location location = simpleLocation.getBukkitLocation(); if (location == null) return; PlatformInterface platform = plugin.getPlatformInterface(); - if (platform.removeCustomBlock(location)) { - platform.placeNoteBlock(location, pot.isWet() ? pot.getConfig().getWetPot(pot.getFertilizer()) : pot.getConfig().getDryPot(pot.getFertilizer())); + if (platform.removeAnyBlock(location)) { + String replacer = pot.isWet() ? pot.getConfig().getWetPot(pot.getFertilizer()) : pot.getConfig().getDryPot(pot.getFertilizer()); + if (ConfigUtils.isVanillaItem(replacer)) { + location.getBlock().setType(Material.valueOf(replacer)); + } else { + platform.placeNoteBlock(location, replacer); + } + } else { + CustomCrops.getInstance().getWorldDataManager().removePotData(simpleLocation); + } + } + + public void changePotModel(SimpleLocation simpleLocation, PotConfig potConfig, Fertilizer fertilizer, boolean wet) { + Location location = simpleLocation.getBukkitLocation(); + if (location == null) return; + PlatformInterface platform = plugin.getPlatformInterface(); + if (platform.removeAnyBlock(location)) { + String replacer = wet ? potConfig.getWetPot(fertilizer) : potConfig.getDryPot(fertilizer); + if (ConfigUtils.isVanillaItem(replacer)) { + location.getBlock().setType(Material.valueOf(replacer)); + } else { + platform.placeNoteBlock(location, replacer); + } } else { CustomCrops.getInstance().getWorldDataManager().removePotData(simpleLocation); } diff --git a/src/main/java/net/momirealms/customcrops/api/customplugin/Handler.java b/src/main/java/net/momirealms/customcrops/api/customplugin/Handler.java index 05740bb..c222881 100644 --- a/src/main/java/net/momirealms/customcrops/api/customplugin/Handler.java +++ b/src/main/java/net/momirealms/customcrops/api/customplugin/Handler.java @@ -23,6 +23,9 @@ import org.bukkit.Bukkit; import org.bukkit.event.EventHandler; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockFromToEvent; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.player.PlayerInteractEvent; public abstract class Handler extends Function implements Listener { @@ -47,4 +50,14 @@ public abstract class Handler extends Function implements Listener { public void onInteract(PlayerInteractEvent event) { platformManager.onInteractBlock(event); } + + @EventHandler + public void onBreak(BlockBreakEvent event) { + platformManager.onBreakVanilla(event); + } + + @EventHandler + public void onPlace(BlockPlaceEvent event) { + platformManager.onPlaceVanilla(event); + } } \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/api/customplugin/PlatformInterface.java b/src/main/java/net/momirealms/customcrops/api/customplugin/PlatformInterface.java index 200bffe..e2aa2fd 100644 --- a/src/main/java/net/momirealms/customcrops/api/customplugin/PlatformInterface.java +++ b/src/main/java/net/momirealms/customcrops/api/customplugin/PlatformInterface.java @@ -34,6 +34,20 @@ public interface PlatformInterface { boolean removeCustomBlock(Location location); + default boolean removeAnyBlock(Location location) { + String id = getCustomBlockID(location); + if (id != null) { + return removeCustomBlock(location); + } + Block block = location.getBlock(); + if (block.getType() == Material.AIR) { + return false; + } else { + block.setType(Material.AIR); + return true; + } + } + @Nullable String getCustomBlockID(Location location); diff --git a/src/main/java/net/momirealms/customcrops/api/customplugin/PlatformManager.java b/src/main/java/net/momirealms/customcrops/api/customplugin/PlatformManager.java index 54b53ec..90c8e85 100644 --- a/src/main/java/net/momirealms/customcrops/api/customplugin/PlatformManager.java +++ b/src/main/java/net/momirealms/customcrops/api/customplugin/PlatformManager.java @@ -40,7 +40,9 @@ import net.momirealms.customcrops.api.object.pot.Pot; import net.momirealms.customcrops.api.object.pot.PotConfig; import net.momirealms.customcrops.api.object.requirement.CurrentState; import net.momirealms.customcrops.api.object.requirement.Requirement; +import net.momirealms.customcrops.api.object.sprinkler.Sprinkler; import net.momirealms.customcrops.api.object.sprinkler.SprinklerConfig; +import net.momirealms.customcrops.api.object.sprinkler.SprinklerHologram; import net.momirealms.customcrops.api.object.wateringcan.WateringCanConfig; import net.momirealms.customcrops.api.object.world.SimpleLocation; import net.momirealms.customcrops.api.util.AdventureUtils; @@ -52,6 +54,8 @@ import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; @@ -84,6 +88,18 @@ public class PlatformManager extends Function { this.handler.unload(); } + public void onBreakVanilla(BlockBreakEvent event) { + if (event.isCancelled()) return; + Block block = event.getBlock(); + onBreakSomething(event.getPlayer(), block.getLocation(), block.getType().name(), event); + } + + public void onPlaceVanilla(BlockPlaceEvent event) { + if (event.isCancelled()) return; + Block block = event.getBlock(); + onPlaceSomething(block.getLocation(), block.getType().name()); + } + public void onBreakTripWire(Player player, Block block, String id, Cancellable event) { if (event.isCancelled()) return; onBreakSomething(player, block.getLocation(), id, event); @@ -199,11 +215,11 @@ public class PlatformManager extends Function { return ItemType.SPRINKLER; } - if (onInteractPot(player, id, location, item_in_hand, item_in_hand_id)) { + if (onInteractPot(player, id, location, item_in_hand, item_in_hand_id, event)) { return ItemType.POT; } - if (onInteractCrop(player, id, location, item_in_hand, item_in_hand_id)) { + if (onInteractCrop(player, id, location, item_in_hand, item_in_hand_id, event)) { return ItemType.CROP; } @@ -264,61 +280,72 @@ public class PlatformManager extends Function { return false; } - // water - PassiveFillMethod[] passiveFillMethods = sprinklerConfig.getPassiveFillMethods(); - for (PassiveFillMethod passiveFillMethod : passiveFillMethods) { - if (passiveFillMethod.isRightItem(item_in_hand_id)) { + outer: { + // water + PassiveFillMethod[] passiveFillMethods = sprinklerConfig.getPassiveFillMethods(); + for (PassiveFillMethod passiveFillMethod : passiveFillMethods) { + if (passiveFillMethod.isRightItem(item_in_hand_id)) { - SprinklerFillEvent sprinklerFillEvent = new SprinklerFillEvent(player, item_in_hand, passiveFillMethod.getAmount(), location); + SprinklerFillEvent sprinklerFillEvent = new SprinklerFillEvent(player, item_in_hand, passiveFillMethod.getAmount(), location); + Bukkit.getPluginManager().callEvent(sprinklerFillEvent); + if (sprinklerFillEvent.isCancelled()) { + return true; + } + + doPassiveFillAction(player, item_in_hand, passiveFillMethod, location.clone().add(0,0.2,0)); + plugin.getWorldDataManager().addWaterToSprinkler(SimpleLocation.getByBukkitLocation(location), sprinklerFillEvent.getWater(), sprinklerConfig); + break outer; + } + } + + WateringCanConfig wateringCanConfig = plugin.getWateringCanManager().getConfigByItemID(item_in_hand_id); + if (wateringCanConfig != null) { + String[] sprinkler_whitelist = wateringCanConfig.getSprinklerWhitelist(); + if (sprinkler_whitelist != null) { + inner: { + for (String sprinkler_allowed : sprinkler_whitelist) { + if (sprinkler_allowed.equals(plugin.getSprinklerManager().getConfigKeyByItemID(id))) { + break inner; + } + } + return true; + } + } + int current_water = plugin.getWateringCanManager().getCurrentWater(item_in_hand); + if (current_water <= 0) return true; + + SprinklerFillEvent sprinklerFillEvent = new SprinklerFillEvent(player, item_in_hand, 1, location); Bukkit.getPluginManager().callEvent(sprinklerFillEvent); if (sprinklerFillEvent.isCancelled()) { return true; } - doPassiveFillAction(player, item_in_hand, passiveFillMethod, location.clone().add(0,0.2,0)); - plugin.getWorldDataManager().addWaterToSprinkler(SimpleLocation.getByBukkitLocation(location), sprinklerFillEvent.getWater(), sprinklerConfig.getRange(), sprinklerConfig.getStorage()); - return true; - } - } - - WateringCanConfig wateringCanConfig = plugin.getWateringCanManager().getConfigByItemID(item_in_hand_id); - if (wateringCanConfig != null) { - String[] sprinkler_whitelist = wateringCanConfig.getSprinklerWhitelist(); - if (sprinkler_whitelist != null) { - outer: { - for (String sprinkler_allowed : sprinkler_whitelist) { - if (sprinkler_allowed.equals(plugin.getSprinklerManager().getConfigKeyByItemID(id))) { - break outer; - } - } - return true; + current_water--; + if (wateringCanConfig.hasActionBar()) { + AdventureUtils.playerActionbar(player, wateringCanConfig.getActionBarMsg(current_water)); + } + if (wateringCanConfig.getSound() != null) { + AdventureUtils.playerSound(player, wateringCanConfig.getSound()); + } + if (wateringCanConfig.getParticle() != null) { + location.getWorld().spawnParticle(wateringCanConfig.getParticle(), location.clone().add(0.5,0.4, 0.5),5,0.3,0.1,0.3); } - } - int current_water = plugin.getWateringCanManager().getCurrentWater(item_in_hand); - if (current_water <= 0) return true; - SprinklerFillEvent sprinklerFillEvent = new SprinklerFillEvent(player, item_in_hand, 1, location); - Bukkit.getPluginManager().callEvent(sprinklerFillEvent); - if (sprinklerFillEvent.isCancelled()) { - return true; + plugin.getWateringCanManager().setWater(item_in_hand, current_water, wateringCanConfig); + plugin.getWorldDataManager().addWaterToSprinkler(SimpleLocation.getByBukkitLocation(location), 1, sprinklerConfig); + break outer; } - - current_water--; - if (wateringCanConfig.hasActionBar()) { - AdventureUtils.playerActionbar(player, wateringCanConfig.getActionBarMsg(current_water)); - } - if (wateringCanConfig.getSound() != null) { - AdventureUtils.playerSound(player, wateringCanConfig.getSound()); - } - if (wateringCanConfig.getParticle() != null) { - location.getWorld().spawnParticle(wateringCanConfig.getParticle(), location.clone().add(0.5,0.4, 0.5),5,0.3,0.1,0.3); - } - - plugin.getWateringCanManager().setWater(item_in_hand, current_water, wateringCanConfig); - plugin.getWorldDataManager().addWaterToSprinkler(SimpleLocation.getByBukkitLocation(location), 1, sprinklerConfig.getRange(), sprinklerConfig.getStorage()); - return true; } + Sprinkler sprinkler = plugin.getWorldDataManager().getSprinklerData(SimpleLocation.getByBukkitLocation(location)); + if (sprinkler != null && sprinklerConfig.hasHologram()) { + SprinklerHologram sprinklerHologram = sprinklerConfig.getSprinklerHologram(); + if (sprinklerHologram != null) { + String content = sprinklerHologram.getContent(sprinkler.getWater(), sprinklerConfig.getStorage()); + plugin.getHologramManager().showHologram(player, location.clone().add(0.5,sprinklerHologram.getOffset(),0.5), AdventureUtils.getComponentFromMiniMessage(content), + sprinklerHologram.getDuration() * 1000, sprinklerHologram.getMode()); + } + } return true; } @@ -347,6 +374,12 @@ public class PlatformManager extends Function { Location sprinkler_loc = location.clone().add(0,1,0); if (plugin.getPlatformInterface().detectAnyThing(sprinkler_loc)) return true; + SprinklerPlaceEvent sprinklerPlaceEvent = new SprinklerPlaceEvent(player, item_in_hand, sprinkler_loc, sprinklerConfig); + Bukkit.getPluginManager().callEvent(sprinklerPlaceEvent); + if (sprinklerPlaceEvent.isCancelled()) { + return true; + } + if (player.getGameMode() != GameMode.CREATIVE) item_in_hand.setAmount(item_in_hand.getAmount() - 1); CustomCropsAPI.getInstance().placeCustomItem(sprinkler_loc, sprinklerConfig.getThreeD(), sprinklerConfig.getItemMode()); if (sprinklerConfig.getSound() != null) { @@ -355,7 +388,7 @@ public class PlatformManager extends Function { return true; } - public boolean onInteractCrop(Player player, String id, Location location, ItemStack item_in_hand, String item_in_hand_id) { + public boolean onInteractCrop(Player player, String id, Location location, ItemStack item_in_hand, String item_in_hand_id, Cancellable event) { CropConfig cropConfig = plugin.getCropManager().getCropConfigByStage(id); if (cropConfig == null) { return false; @@ -376,34 +409,53 @@ public class PlatformManager extends Function { return true; } - WateringCanConfig wateringCanConfig = plugin.getWateringCanManager().getConfigByItemID(item_in_hand_id); Pot potData = plugin.getWorldDataManager().getPotData(SimpleLocation.getByBukkitLocation(location).add(0,-1,0)); - if (wateringCanConfig != null && potData != null) { - String[] pot_whitelist = wateringCanConfig.getPotWhitelist(); - if (pot_whitelist != null) { - outer: { - for (String pot : pot_whitelist) { - if (pot.equals(potData.getPotKey())) { - break outer; - } + if (potData != null) { + PassiveFillMethod[] passiveFillMethods = potData.getConfig().getPassiveFillMethods(); + for (PassiveFillMethod passiveFillMethod : passiveFillMethods) { + if (passiveFillMethod.isRightItem(item_in_hand_id)) { + + PotWaterEvent potWaterEvent = new PotWaterEvent(player, item_in_hand, passiveFillMethod.getAmount(), location); + Bukkit.getPluginManager().callEvent(potWaterEvent); + if (potWaterEvent.isCancelled()) { + return true; } + + event.setCancelled(true); + doPassiveFillAction(player, item_in_hand, passiveFillMethod, location); + potData.addWater(potWaterEvent.getWater()); return true; } } - int current_water = plugin.getWateringCanManager().getCurrentWater(item_in_hand); - if (current_water <= 0) return true; - Location pot_loc = location.clone().subtract(0,1,0); - PotWaterEvent potWaterEvent = new PotWaterEvent(player, item_in_hand, 1, pot_loc); - Bukkit.getPluginManager().callEvent(potWaterEvent); - if (potWaterEvent.isCancelled()) { + WateringCanConfig wateringCanConfig = plugin.getWateringCanManager().getConfigByItemID(item_in_hand_id); + if (wateringCanConfig != null) { + String[] pot_whitelist = wateringCanConfig.getPotWhitelist(); + if (pot_whitelist != null) { + outer: { + for (String pot : pot_whitelist) { + if (pot.equals(potData.getPotKey())) { + break outer; + } + } + return true; + } + } + int current_water = plugin.getWateringCanManager().getCurrentWater(item_in_hand); + if (current_water <= 0) return true; + + Location pot_loc = location.clone().subtract(0,1,0); + PotWaterEvent potWaterEvent = new PotWaterEvent(player, item_in_hand, 1, pot_loc); + Bukkit.getPluginManager().callEvent(potWaterEvent); + if (potWaterEvent.isCancelled()) { + return true; + } + + current_water--; + this.waterPot(wateringCanConfig.getWidth(), wateringCanConfig.getLength(), pot_loc, player.getLocation().getYaw(), potData.getPotKey(), wateringCanConfig.getParticle(), potWaterEvent.getWater()); + this.doWateringCanActions(player, item_in_hand, wateringCanConfig, current_water); return true; } - - current_water--; - this.waterPot(wateringCanConfig.getWidth(), wateringCanConfig.getLength(), pot_loc, player.getLocation().getYaw(), potData.getPotKey(), wateringCanConfig.getParticle(), potWaterEvent.getWater()); - this.doWateringCanActions(player, item_in_hand, wateringCanConfig, current_water); - return true; } BoneMeal[] boneMeals = cropConfig.getBoneMeals(); @@ -454,7 +506,7 @@ public class PlatformManager extends Function { return true; } - public boolean onInteractPot(Player player, String id, Location location, ItemStack item_in_hand, String item_in_hand_id) { + public boolean onInteractPot(Player player, String id, Location location, ItemStack item_in_hand, String item_in_hand_id, Cancellable event) { String pot_id = plugin.getPotManager().getPotKeyByBlockID(id); if (pot_id == null) { return false; @@ -535,6 +587,7 @@ public class PlatformManager extends Function { return true; } + event.setCancelled(true); doPassiveFillAction(player, item_in_hand, passiveFillMethod, location); plugin.getWorldDataManager().addWaterToPot(SimpleLocation.getByBukkitLocation(location), potWaterEvent.getWater(), pot_id); break outer; @@ -791,4 +844,5 @@ public class PlatformManager extends Function { } return true; } + } diff --git a/src/main/java/net/momirealms/customcrops/api/customplugin/itemsadder/ItemsAdderPluginImpl.java b/src/main/java/net/momirealms/customcrops/api/customplugin/itemsadder/ItemsAdderPluginImpl.java index 460bdce..6566fe3 100644 --- a/src/main/java/net/momirealms/customcrops/api/customplugin/itemsadder/ItemsAdderPluginImpl.java +++ b/src/main/java/net/momirealms/customcrops/api/customplugin/itemsadder/ItemsAdderPluginImpl.java @@ -23,6 +23,7 @@ import dev.lone.itemsadder.api.CustomBlock; import dev.lone.itemsadder.api.CustomFurniture; import dev.lone.itemsadder.api.CustomStack; import net.momirealms.customcrops.api.customplugin.PlatformInterface; +import net.momirealms.customcrops.api.util.AdventureUtils; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; @@ -58,6 +59,10 @@ public class ItemsAdderPluginImpl implements PlatformInterface { @Override public ItemFrame placeItemFrame(Location location, String id) { CustomFurniture customFurniture = CustomFurniture.spawn(id, location.getBlock()); + if (customFurniture == null) { + AdventureUtils.consoleMessage("[CustomCrops] Furniture not exists: " + id); + return null; + } Entity entity = customFurniture.getArmorstand(); if (entity instanceof ItemFrame itemFrame) return itemFrame; diff --git a/src/main/java/net/momirealms/customcrops/api/event/SprinklerPlaceEvent.java b/src/main/java/net/momirealms/customcrops/api/event/SprinklerPlaceEvent.java new file mode 100644 index 0000000..13627e4 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/api/event/SprinklerPlaceEvent.java @@ -0,0 +1,59 @@ +package net.momirealms.customcrops.api.event; + +import net.momirealms.customcrops.api.object.sprinkler.SprinklerConfig; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + +public class SprinklerPlaceEvent extends PlayerEvent implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private final ItemStack hand; + private final Location location; + private final SprinklerConfig sprinklerConfig; + + public SprinklerPlaceEvent(@NotNull Player who, ItemStack hand, Location location, SprinklerConfig sprinklerConfig) { + super(who); + this.hand = hand; + this.location = location; + this.sprinklerConfig = sprinklerConfig; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @NotNull + public static HandlerList getHandlerList() { + return handlers; + } + + @NotNull + @Override + public HandlerList getHandlers() { + return getHandlerList(); + } + + public ItemStack getHand() { + return hand; + } + + public Location getLocation() { + return location; + } + + public SprinklerConfig getSprinklerConfig() { + return sprinklerConfig; + } +} diff --git a/src/main/java/net/momirealms/customcrops/api/object/CrowTask.java b/src/main/java/net/momirealms/customcrops/api/object/CrowTask.java index bc99018..09f96f0 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/CrowTask.java +++ b/src/main/java/net/momirealms/customcrops/api/object/CrowTask.java @@ -53,7 +53,7 @@ public class CrowTask implements Runnable { this.vectorDown = new Vector(relative.getX() / 100, -0.1, relative.getZ() / 100); this.vectorUp = new Vector(relative.getX() / 100, 0.1, relative.getZ() / 100); CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getSpawnPacket(entityID, from, EntityType.ARMOR_STAND)); - CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getMetaPacket(entityID)); + CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getVanishArmorStandMetaPacket(entityID)); CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getEquipPacket(entityID, fly)); } diff --git a/src/main/java/net/momirealms/customcrops/api/object/HologramManager.java b/src/main/java/net/momirealms/customcrops/api/object/HologramManager.java index 18eddf6..9f6ed3c 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/HologramManager.java +++ b/src/main/java/net/momirealms/customcrops/api/object/HologramManager.java @@ -139,10 +139,19 @@ public class HologramManager extends Function implements Listener { int random = ThreadLocalRandom.current().nextInt(Integer.MAX_VALUE); tupleList.add(Tuple.of(location, random, System.currentTimeMillis() + millis)); this.tuples = tupleList.toArray(new Tuple[0]); - CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getSpawnPacket(random, location, EntityType.ARMOR_STAND)); - CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getMetaPacket(random, component)); + if (mode == Mode.ARMOR_STAND) { + CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getSpawnPacket(random, location, EntityType.ARMOR_STAND)); + CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getVanishArmorStandMetaPacket(random, component)); + } else if (mode == Mode.TEXT_DISPLAY) { + CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getSpawnPacket(random, location, EntityType.TEXT_DISPLAY)); + CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getTextDisplayMetaPacket(random, component)); + } } else { - CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getMetaPacket(entity_id, component)); + if (mode == Mode.ARMOR_STAND) { + CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getVanishArmorStandMetaPacket(entity_id, component)); + } else if (mode == Mode.TEXT_DISPLAY) { + CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getTextDisplayMetaPacket(entity_id, component)); + } } } diff --git a/src/main/java/net/momirealms/customcrops/api/object/ItemMode.java b/src/main/java/net/momirealms/customcrops/api/object/ItemMode.java index b8d9b1c..ca9e242 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/ItemMode.java +++ b/src/main/java/net/momirealms/customcrops/api/object/ItemMode.java @@ -19,6 +19,7 @@ package net.momirealms.customcrops.api.object; public enum ItemMode { + ARMOR_STAND, TRIPWIRE, ITEM_FRAME, ITEM_DISPLAY, diff --git a/src/main/java/net/momirealms/customcrops/api/object/basic/MessageManager.java b/src/main/java/net/momirealms/customcrops/api/object/basic/MessageManager.java index df570e1..9d93eb7 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/basic/MessageManager.java +++ b/src/main/java/net/momirealms/customcrops/api/object/basic/MessageManager.java @@ -61,25 +61,25 @@ public class MessageManager extends Function { private void loadMessage() { YamlConfiguration config = ConfigUtils.getConfig("messages" + File.separator + "messages_" + ConfigManager.lang + ".yml"); - prefix = config.getString("prefix","[CustomCrops] "); - reload = config.getString("reload", "Reloaded! Took {time}ms."); - unavailableArgs = config.getString("invalid-args", "Invalid arguments."); - noConsole = config.getString("no-console", "This command can only be executed by a player."); - notOnline = config.getString("not-online", "Player {player} is not online."); - lackArgs = config.getString("lack-args", "Arguments are insufficient."); - nonArgs = config.getString("not-none-args", "Not a none argument command."); - beforePlant = config.getString("before-plant", "This fertilizer can only be used before planting."); - unsuitablePot = config.getString("unsuitable-pot", "You can't plant the seed in this pot."); - reachChunkLimit = config.getString("reach-crop-limit", "The number of crops has reached the limitation."); - noPerm = config.getString("no-perm", "You don't have permission to do that."); - spring = config.getString("spring", "Spring"); - summer = config.getString("summer", "Summer"); - autumn = config.getString("autumn", "Autumn"); - winter = config.getString("winter", "Winter"); - noSeason = config.getString("no-season", "SEASON DISABLED IN THIS WORLD"); - setSeason = config.getString("set-season", "Successfully set {world}'s season to {season}."); - setDate = config.getString("set-date", "Successfully set {world}'s date to {date}."); - worldNotExist = config.getString("world-not-exist", "World {world} does not exist."); - seasonNotExist = config.getString("season-not-exist", "Season {season} does not exist."); + prefix = config.getString("messages.prefix","[CustomCrops] "); + reload = config.getString("messages.reload", "Reloaded! Took {time}ms."); + unavailableArgs = config.getString("messages.invalid-args", "Invalid arguments."); + noConsole = config.getString("messages.no-console", "This command can only be executed by a player."); + notOnline = config.getString("messages.not-online", "Player {player} is not online."); + lackArgs = config.getString("messages.lack-args", "Arguments are insufficient."); + nonArgs = config.getString("messages.not-none-args", "Not a none argument command."); + beforePlant = config.getString("messages.before-plant", "This fertilizer can only be used before planting."); + unsuitablePot = config.getString("messages.unsuitable-pot", "You can't plant the seed in this pot."); + reachChunkLimit = config.getString("messages.reach-crop-limit", "The number of crops has reached the limitation."); + noPerm = config.getString("messages.no-perm", "You don't have permission to do that."); + spring = config.getString("messages.spring", "Spring"); + summer = config.getString("messages.summer", "Summer"); + autumn = config.getString("messages.autumn", "Autumn"); + winter = config.getString("messages.winter", "Winter"); + noSeason = config.getString("messages.no-season", "SEASON DISABLED IN THIS WORLD"); + setSeason = config.getString("messages.set-season", "Successfully set {world}'s season to {season}."); + setDate = config.getString("messages.set-date", "Successfully set {world}'s date to {date}."); + worldNotExist = config.getString("messages.world-not-exist", "World {world} does not exist."); + seasonNotExist = config.getString("messages.season-not-exist", "Season {season} does not exist."); } } diff --git a/src/main/java/net/momirealms/customcrops/api/object/pot/Pot.java b/src/main/java/net/momirealms/customcrops/api/object/pot/Pot.java index 5dda063..6667f50 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/pot/Pot.java +++ b/src/main/java/net/momirealms/customcrops/api/object/pot/Pot.java @@ -70,7 +70,8 @@ public class Pot implements Serializable { */ public boolean reduceWater() { water--; - return water <= 0; + water = Math.max(0, water); + return water == 0; } /* diff --git a/src/main/java/net/momirealms/customcrops/api/object/pot/PotHologram.java b/src/main/java/net/momirealms/customcrops/api/object/pot/PotHologram.java index 50dfb4c..3bb8b38 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/pot/PotHologram.java +++ b/src/main/java/net/momirealms/customcrops/api/object/pot/PotHologram.java @@ -116,7 +116,7 @@ public class PotHologram { public String getWaterBar(int current, int storage) { return bar_left + String.valueOf(bar_full).repeat(current) + - String.valueOf(bar_empty).repeat(storage - current) + + String.valueOf(bar_empty).repeat(Math.max(storage - current, 0)) + bar_right; } } diff --git a/src/main/java/net/momirealms/customcrops/api/object/schedule/BukkitSchedulerImpl.java b/src/main/java/net/momirealms/customcrops/api/object/scheduler/BukkitSchedulerImpl.java similarity index 95% rename from src/main/java/net/momirealms/customcrops/api/object/schedule/BukkitSchedulerImpl.java rename to src/main/java/net/momirealms/customcrops/api/object/scheduler/BukkitSchedulerImpl.java index 5b16a74..8c3a2b9 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/schedule/BukkitSchedulerImpl.java +++ b/src/main/java/net/momirealms/customcrops/api/object/scheduler/BukkitSchedulerImpl.java @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package net.momirealms.customcrops.api.object.schedule; +package net.momirealms.customcrops.api.object.scheduler; import net.momirealms.customcrops.CustomCrops; import org.bukkit.Bukkit; diff --git a/src/main/java/net/momirealms/customcrops/api/object/schedule/Scheduler.java b/src/main/java/net/momirealms/customcrops/api/object/scheduler/Scheduler.java similarity index 97% rename from src/main/java/net/momirealms/customcrops/api/object/schedule/Scheduler.java rename to src/main/java/net/momirealms/customcrops/api/object/scheduler/Scheduler.java index e329c70..4d5ab4e 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/schedule/Scheduler.java +++ b/src/main/java/net/momirealms/customcrops/api/object/scheduler/Scheduler.java @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package net.momirealms.customcrops.api.object.schedule; +package net.momirealms.customcrops.api.object.scheduler; import net.momirealms.customcrops.CustomCrops; import net.momirealms.customcrops.api.object.Function; diff --git a/src/main/java/net/momirealms/customcrops/api/object/schedule/SchedulerPlatform.java b/src/main/java/net/momirealms/customcrops/api/object/scheduler/SchedulerPlatform.java similarity index 94% rename from src/main/java/net/momirealms/customcrops/api/object/schedule/SchedulerPlatform.java rename to src/main/java/net/momirealms/customcrops/api/object/scheduler/SchedulerPlatform.java index dd936b4..85c95cb 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/schedule/SchedulerPlatform.java +++ b/src/main/java/net/momirealms/customcrops/api/object/scheduler/SchedulerPlatform.java @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package net.momirealms.customcrops.api.object.schedule; +package net.momirealms.customcrops.api.object.scheduler; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/net/momirealms/customcrops/api/object/sprinkler/Sprinkler.java b/src/main/java/net/momirealms/customcrops/api/object/sprinkler/Sprinkler.java index 416e823..79e87a1 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/sprinkler/Sprinkler.java +++ b/src/main/java/net/momirealms/customcrops/api/object/sprinkler/Sprinkler.java @@ -17,16 +17,19 @@ package net.momirealms.customcrops.api.object.sprinkler; +import net.momirealms.customcrops.CustomCrops; +import org.jetbrains.annotations.Nullable; + import java.io.Serializable; public class Sprinkler implements Serializable { private int water; - private int range; + private final String key; - public Sprinkler(int water, int range) { + public Sprinkler(String key, int water) { this.water = water; - this.range = range; + this.key = key; } public int getWater() { @@ -37,11 +40,12 @@ public class Sprinkler implements Serializable { this.water = water; } - public void setRange(int range) { - this.range = range; + public String getKey() { + return key; } - public int getRange() { - return range; + @Nullable + public SprinklerConfig getConfig() { + return CustomCrops.getInstance().getSprinklerManager().getConfigByKey(key); } } diff --git a/src/main/java/net/momirealms/customcrops/api/object/sprinkler/SprinklerAnimation.java b/src/main/java/net/momirealms/customcrops/api/object/sprinkler/SprinklerAnimation.java new file mode 100644 index 0000000..7c1ce4b --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/api/object/sprinkler/SprinklerAnimation.java @@ -0,0 +1,7 @@ +package net.momirealms.customcrops.api.object.sprinkler; + +import net.momirealms.customcrops.api.object.ItemMode; + +public record SprinklerAnimation(int duration, String id, double offset, ItemMode itemMode) { + +} diff --git a/src/main/java/net/momirealms/customcrops/api/object/sprinkler/SprinklerConfig.java b/src/main/java/net/momirealms/customcrops/api/object/sprinkler/SprinklerConfig.java index 60a1247..0e17fa2 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/sprinkler/SprinklerConfig.java +++ b/src/main/java/net/momirealms/customcrops/api/object/sprinkler/SprinklerConfig.java @@ -33,8 +33,13 @@ public class SprinklerConfig { private final String threeD; private final String twoD; private final PassiveFillMethod[] passiveFillMethods; + private final boolean hasAnimation; + private final boolean hasHologram; + private final SprinklerHologram sprinklerHologram; + private final SprinklerAnimation sprinklerAnimation; - public SprinklerConfig(String key, int storage, int range, @Nullable Sound sound, @NotNull ItemMode itemMode, @NotNull String threeD, @NotNull String twoD, @NotNull PassiveFillMethod[] passiveFillMethods) { + public SprinklerConfig(String key, int storage, int range, @Nullable Sound sound, @NotNull ItemMode itemMode, @NotNull String threeD, @NotNull String twoD, + @NotNull PassiveFillMethod[] passiveFillMethods, boolean hasHologram, boolean hasAnimation, @Nullable SprinklerHologram sprinklerHologram, SprinklerAnimation sprinklerAnimation) { this.key = key; this.storage = storage; this.range = range; @@ -43,6 +48,10 @@ public class SprinklerConfig { this.threeD = threeD; this.twoD = twoD; this.passiveFillMethods = passiveFillMethods; + this.hasAnimation = hasAnimation; + this.hasHologram = hasHologram; + this.sprinklerAnimation = sprinklerAnimation; + this.sprinklerHologram = sprinklerHologram; } public String getKey() { @@ -81,4 +90,22 @@ public class SprinklerConfig { public PassiveFillMethod[] getPassiveFillMethods() { return passiveFillMethods; } + + public boolean hasAnimation() { + return hasAnimation; + } + + public boolean hasHologram() { + return hasHologram; + } + + @Nullable + public SprinklerHologram getSprinklerHologram() { + return sprinklerHologram; + } + + @Nullable + public SprinklerAnimation getSprinklerAnimation() { + return sprinklerAnimation; + } } diff --git a/src/main/java/net/momirealms/customcrops/api/object/sprinkler/SprinklerHologram.java b/src/main/java/net/momirealms/customcrops/api/object/sprinkler/SprinklerHologram.java new file mode 100644 index 0000000..1270d45 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/api/object/sprinkler/SprinklerHologram.java @@ -0,0 +1,53 @@ +package net.momirealms.customcrops.api.object.sprinkler; + +import net.momirealms.customcrops.api.object.HologramManager; +import org.jetbrains.annotations.NotNull; + +public class SprinklerHologram { + + private final double offset; + private final HologramManager.Mode mode; + private final String content; + private final int duration; + private final String bar_left; + private final String bar_full; + private final String bar_empty; + private final String bar_right; + + public SprinklerHologram(@NotNull String content, double offset, HologramManager.Mode mode, int duration, String bar_left, String bar_full, String bar_empty, String bar_right) { + this.offset = offset; + this.content = content; + this.mode = mode; + this.duration = duration; + this.bar_left = bar_left; + this.bar_full = bar_full; + this.bar_empty = bar_empty; + this.bar_right = bar_right; + } + + public double getOffset() { + return offset; + } + + public HologramManager.Mode getMode() { + return mode; + } + + public int getDuration() { + return duration; + } + + public String getContent(int current, int storage) { + return content.replace("{current}", String.valueOf(current)) + .replace("{storage}", String.valueOf(storage)) + .replace("{water_bar}", getWaterBar(current, storage)); + } + + public String getWaterBar(int current, int storage) { + return bar_left + + String.valueOf(bar_full).repeat(current) + + String.valueOf(bar_empty).repeat(Math.max(storage - current, 0)) + + bar_right; + } + +} diff --git a/src/main/java/net/momirealms/customcrops/api/object/sprinkler/SprinklerManager.java b/src/main/java/net/momirealms/customcrops/api/object/sprinkler/SprinklerManager.java index 6659833..62b608d 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/sprinkler/SprinklerManager.java +++ b/src/main/java/net/momirealms/customcrops/api/object/sprinkler/SprinklerManager.java @@ -21,6 +21,7 @@ import net.kyori.adventure.key.Key; import net.kyori.adventure.sound.Sound; import net.momirealms.customcrops.CustomCrops; import net.momirealms.customcrops.api.object.Function; +import net.momirealms.customcrops.api.object.HologramManager; import net.momirealms.customcrops.api.object.ItemMode; import net.momirealms.customcrops.api.object.fill.PassiveFillMethod; import net.momirealms.customcrops.api.util.AdventureUtils; @@ -92,6 +93,8 @@ public class SprinklerManager extends Function implements Listener { @Subst("namespace:key") String soundKey = sprinklerSec.getString("place-sound", "minecraft:block.bone_block.place"); Sound sound = sprinklerSec.contains("place-sound") ? Sound.sound(Key.key(soundKey), Sound.Source.PLAYER, 1, 1) : null; ItemMode itemMode = ItemMode.valueOf(sprinklerSec.getString("type","ITEM_FRAME").toUpperCase()); + boolean hasAnimation = sprinklerSec.getBoolean("animation.enable"); + boolean hasHologram = sprinklerSec.getBoolean("hologram.enable"); SprinklerConfig sprinklerConfig = new SprinklerConfig( key, sprinklerSec.getInt("storage", 3), @@ -100,7 +103,25 @@ public class SprinklerManager extends Function implements Listener { itemMode, threeD, twoD, - methods + methods, + hasHologram, + hasAnimation, + hasHologram ? new SprinklerHologram( + sprinklerSec.getString("hologram.content",""), + sprinklerSec.getDouble("hologram.vertical-offset"), + HologramManager.Mode.valueOf(sprinklerSec.getString("hologram.type", "ARMOR_STAND").toUpperCase()), + sprinklerSec.getInt("hologram.duration"), + sprinklerSec.getString("hologram.water-bar.left"), + sprinklerSec.getString("hologram.water-bar.full"), + sprinklerSec.getString("hologram.water-bar.empty"), + sprinklerSec.getString("hologram.water-bar.right") + ) : null, + hasAnimation ? new SprinklerAnimation( + sprinklerSec.getInt("animation.duration"), + sprinklerSec.getString("animation.item"), + sprinklerSec.getDouble("animation.vertical-offset"), + ItemMode.valueOf(sprinklerSec.getString("animation.type", "ARMOR_STAND").toUpperCase()) + ) : null ); this.itemToKey.put(threeD, key); this.itemToKey.put(twoD, key); @@ -122,6 +143,11 @@ public class SprinklerManager extends Function implements Listener { return itemToKey.get(id); } + @Nullable + public SprinklerConfig getConfigByKey(String key) { + return sprinklerConfigMap.get(key); + } + public boolean containsSprinkler(String key) { return sprinklerConfigMap.containsKey(key); } diff --git a/src/main/java/net/momirealms/customcrops/api/object/wateringcan/WateringCanConfig.java b/src/main/java/net/momirealms/customcrops/api/object/wateringcan/WateringCanConfig.java index eaa00a1..9feb4c6 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/wateringcan/WateringCanConfig.java +++ b/src/main/java/net/momirealms/customcrops/api/object/wateringcan/WateringCanConfig.java @@ -83,7 +83,7 @@ public class WateringCanConfig { public String getWaterBar(int current) { return bar_left + String.valueOf(bar_full).repeat(current) + - String.valueOf(bar_empty).repeat(storage - current) + + String.valueOf(bar_empty).repeat(Math.max(storage - current, 0)) + bar_right; } diff --git a/src/main/java/net/momirealms/customcrops/api/object/world/CCWorld.java b/src/main/java/net/momirealms/customcrops/api/object/world/CCWorld.java index 6853917..f117f5d 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/world/CCWorld.java +++ b/src/main/java/net/momirealms/customcrops/api/object/world/CCWorld.java @@ -19,6 +19,7 @@ package net.momirealms.customcrops.api.object.world; import net.momirealms.customcrops.CustomCrops; import net.momirealms.customcrops.api.CustomCropsAPI; +import net.momirealms.customcrops.api.object.CrowTask; import net.momirealms.customcrops.api.object.Function; import net.momirealms.customcrops.api.object.ItemMode; import net.momirealms.customcrops.api.object.action.Action; @@ -34,21 +35,27 @@ import net.momirealms.customcrops.api.object.fertilizer.FertilizerConfig; import net.momirealms.customcrops.api.object.fertilizer.SoilRetain; import net.momirealms.customcrops.api.object.fertilizer.SpeedGrow; import net.momirealms.customcrops.api.object.pot.Pot; +import net.momirealms.customcrops.api.object.pot.PotConfig; import net.momirealms.customcrops.api.object.season.CCSeason; import net.momirealms.customcrops.api.object.season.SeasonData; import net.momirealms.customcrops.api.object.sprinkler.Sprinkler; +import net.momirealms.customcrops.api.object.sprinkler.SprinklerAnimation; +import net.momirealms.customcrops.api.object.sprinkler.SprinklerConfig; import net.momirealms.customcrops.api.util.AdventureUtils; import net.momirealms.customcrops.api.util.ConfigUtils; +import net.momirealms.customcrops.api.util.FakeEntityUtils; import net.momirealms.customcrops.helper.Log; import org.apache.commons.pool2.BasePooledObjectFactory; import org.apache.commons.pool2.PooledObject; import org.apache.commons.pool2.impl.DefaultPooledObject; import org.apache.commons.pool2.impl.GenericObjectPool; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; +import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -320,8 +327,12 @@ public class CCWorld extends Function { pot.setWater(pot.getWater() + 1); } if (pot.reduceWater() | pot.reduceFertilizer()) { + SimpleLocation temp = simpleLocation.copy(); + PotConfig potConfig = pot.getConfig(); + Fertilizer fertilizer = pot.getFertilizer(); + boolean wet = pot.isWet(); CustomCrops.getInstance().getScheduler().callSyncMethod(() -> { - CustomCropsAPI.getInstance().changePotModel(simpleLocation, pot); + CustomCropsAPI.getInstance().changePotModel(temp, potConfig, fertilizer, wet); return null; }); } @@ -345,22 +356,38 @@ public class CCWorld extends Function { } public void execute() { + SprinklerConfig sprinklerConfig = sprinkler.getConfig(); + if (sprinklerConfig == null) { + removeSprinklerData(simpleLocation); + return; + } int water = sprinkler.getWater(); - if (water > 0) { - sprinkler.setWater(--water); - if (water == 0) { - removeSprinklerData(simpleLocation); - } - int range = sprinkler.getRange(); - for (int i = -range; i <= range; i++) { - for (int j = -range; j <= range; j++) { - addWaterToPot(simpleLocation.add(i, -1, j), 1, null); + if (water < 1) { + removeSprinklerData(simpleLocation); + return; + } + if (sprinklerConfig.hasAnimation()) { + SprinklerAnimation sprinklerAnimation = sprinklerConfig.getSprinklerAnimation(); + Location location = simpleLocation.getBukkitLocation(); + if (location != null && sprinklerAnimation != null) { + for (Player player : Bukkit.getOnlinePlayers()) { + SimpleLocation playerLoc = SimpleLocation.getByBukkitLocation(player.getLocation()); + if (playerLoc.isNear(simpleLocation, 48)) { + FakeEntityUtils.playWaterAnimation(player, location.clone().add(0.5, sprinklerAnimation.offset(), 0.5), sprinklerAnimation.id(), sprinklerAnimation.duration(), sprinklerAnimation.itemMode()); + } } } } - else { + sprinkler.setWater(--water); + if (water == 0) { removeSprinklerData(simpleLocation); } + int range = sprinklerConfig.getRange(); + for (int i = -range; i <= range; i++) { + for (int j = -range; j <= range; j++) { + addWaterToPot(simpleLocation.add(i, -1, j), 1, null); + } + } } public void clear() { diff --git a/src/main/java/net/momirealms/customcrops/api/object/world/WorldDataManager.java b/src/main/java/net/momirealms/customcrops/api/object/world/WorldDataManager.java index f9b5886..cf048a1 100644 --- a/src/main/java/net/momirealms/customcrops/api/object/world/WorldDataManager.java +++ b/src/main/java/net/momirealms/customcrops/api/object/world/WorldDataManager.java @@ -24,6 +24,7 @@ import net.momirealms.customcrops.api.object.crop.GrowingCrop; import net.momirealms.customcrops.api.object.fertilizer.Fertilizer; import net.momirealms.customcrops.api.object.pot.Pot; import net.momirealms.customcrops.api.object.sprinkler.Sprinkler; +import net.momirealms.customcrops.api.object.sprinkler.SprinklerConfig; import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.event.HandlerList; @@ -206,14 +207,13 @@ public class WorldDataManager extends Function { } } - public void addWaterToSprinkler(SimpleLocation simpleLocation, int add, int range, int max) { + public void addWaterToSprinkler(SimpleLocation simpleLocation, int add, SprinklerConfig sprinklerConfig) { Sprinkler sprinkler = getSprinklerData(simpleLocation); if (sprinkler != null) { - sprinkler.setWater(Math.min(add + sprinkler.getWater(), max)); - sprinkler.setRange(range); + sprinkler.setWater(Math.min(add + sprinkler.getWater(), sprinklerConfig.getStorage())); } else { - Sprinkler newSprinkler = new Sprinkler(Math.min(add, max), range); + Sprinkler newSprinkler = new Sprinkler(sprinklerConfig.getKey(), Math.min(add, sprinklerConfig.getStorage())); addSprinklerData(simpleLocation, newSprinkler); } } diff --git a/src/main/java/net/momirealms/customcrops/api/util/FakeEntityUtils.java b/src/main/java/net/momirealms/customcrops/api/util/FakeEntityUtils.java index b9e2862..b260c79 100644 --- a/src/main/java/net/momirealms/customcrops/api/util/FakeEntityUtils.java +++ b/src/main/java/net/momirealms/customcrops/api/util/FakeEntityUtils.java @@ -24,6 +24,7 @@ import com.google.common.collect.Lists; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.momirealms.customcrops.CustomCrops; +import net.momirealms.customcrops.api.object.ItemMode; import org.bukkit.Location; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; @@ -33,14 +34,19 @@ import java.util.*; public class FakeEntityUtils { - public static void playWaterAnimation(Player player, Location location, String animation_id) { + public static void playWaterAnimation(Player player, Location location, String animation_id, int duration, ItemMode itemMode) { int id = new Random().nextInt(Integer.MAX_VALUE); - CustomCrops.getProtocolManager().sendServerPacket(player, getSpawnPacket(id, location, EntityType.ARMOR_STAND)); - CustomCrops.getProtocolManager().sendServerPacket(player, getMetaPacket(id)); - CustomCrops.getProtocolManager().sendServerPacket(player, getEquipPacket(id, CustomCrops.getInstance().getIntegrationManager().build(animation_id))); + if (itemMode == ItemMode.ARMOR_STAND) { + CustomCrops.getProtocolManager().sendServerPacket(player, getSpawnPacket(id, location, EntityType.ARMOR_STAND)); + CustomCrops.getProtocolManager().sendServerPacket(player, getVanishArmorStandMetaPacket(id)); + CustomCrops.getProtocolManager().sendServerPacket(player, getEquipPacket(id, CustomCrops.getInstance().getIntegrationManager().build(animation_id))); + } else if (itemMode == ItemMode.ITEM_DISPLAY) { + CustomCrops.getProtocolManager().sendServerPacket(player, getSpawnPacket(id, location, EntityType.ITEM_DISPLAY)); + CustomCrops.getProtocolManager().sendServerPacket(player, getItemDisplayMetaPacket(id, CustomCrops.getInstance().getIntegrationManager().build(animation_id))); + } CustomCrops.getInstance().getScheduler().runTaskAsyncLater(() -> { CustomCrops.getProtocolManager().sendServerPacket(player, getDestroyPacket(id)); - }, 10000); + }, 1000L * duration); } public static WrappedDataWatcher createInvisibleDataWatcher() { @@ -70,7 +76,7 @@ public class FakeEntityUtils { return entityPacket; } - public static PacketContainer getMetaPacket(int id) { + public static PacketContainer getVanishArmorStandMetaPacket(int id) { PacketContainer metaPacket = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA); metaPacket.getIntegers().write(0, id); if (CustomCrops.getInstance().getVersionHelper().isVersionNewerThan1_19_R2()) { @@ -101,7 +107,7 @@ public class FakeEntityUtils { return packet; } - public static PacketContainer getMetaPacket(int id, Component component) { + public static PacketContainer getVanishArmorStandMetaPacket(int id, Component component) { PacketContainer metaPacket = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA); WrappedDataWatcher wrappedDataWatcher = new WrappedDataWatcher(); WrappedDataWatcher.Serializer serializer1 = WrappedDataWatcher.Registry.get(Boolean.class); @@ -122,6 +128,24 @@ public class FakeEntityUtils { return metaPacket; } + public static PacketContainer getItemDisplayMetaPacket(int id, ItemStack itemStack) { + PacketContainer metaPacket = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA); + metaPacket.getModifier().write(0, id); + WrappedDataWatcher wrappedDataWatcher = new WrappedDataWatcher(); + wrappedDataWatcher.setObject(22, itemStack); + setWrappedDataValue(metaPacket, wrappedDataWatcher); + return metaPacket; + } + + public static PacketContainer getTextDisplayMetaPacket(int id, Component component) { + PacketContainer metaPacket = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA); + metaPacket.getModifier().write(0, id); + WrappedDataWatcher wrappedDataWatcher = new WrappedDataWatcher(); + wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(22, WrappedDataWatcher.Registry.getChatComponentSerializer(true)), Optional.of(WrappedChatComponent.fromJson(GsonComponentSerializer.gson().serialize(component)).getHandle())); + setWrappedDataValue(metaPacket, wrappedDataWatcher); + return metaPacket; + } + private static void setWrappedDataValue(PacketContainer metaPacket, WrappedDataWatcher wrappedDataWatcher) { List wrappedDataValueList = Lists.newArrayList(); wrappedDataWatcher.getWatchableObjects().stream().filter(Objects::nonNull).forEach(entry -> { diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 0c637d5..245a530 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -4,8 +4,6 @@ config-version: '25' metrics: true # Language: english / spanish / chinese / turkish lang: english -# Set up mode -set-up-mode: true # AntiGrief integrations: Residence: false @@ -38,7 +36,7 @@ schedule-system: enable: true # The average interval for a crop to gain one point (measured in seconds) # 平均每个农作物获得一生长点的时间间隔(秒) - point-gain-interval: 10 + point-gain-interval: 1200 # Thread pool settings # 线程池设置 thread-pool-settings: diff --git a/src/main/resources/contents/crops/tomato.yml b/src/main/resources/contents/crops/tomato.yml index 2487c96..4a25724 100644 --- a/src/main/resources/contents/crops/tomato.yml +++ b/src/main/resources/contents/crops/tomato.yml @@ -145,7 +145,7 @@ tomato: type: variation value: golden: - model: tomato_stage_golden + item: customcrops:tomato_stage_golden type: TripWire chance: 0.01 interact-by-hand: diff --git a/src/main/resources/contents/sprinklers/default.yml b/src/main/resources/contents/sprinklers/default.yml index 044759e..eafcd12 100644 --- a/src/main/resources/contents/sprinklers/default.yml +++ b/src/main/resources/contents/sprinklers/default.yml @@ -12,7 +12,7 @@ sprinkler_1: enable: true # ARMOR_STAND / TEXT_DISPLAY (1.19.4+) type: ARMOR_STAND - y-offset: 0.8 + vertical-offset: -0.3 duration: 1 # Available variables: # {water_bar} water bar image @@ -25,10 +25,11 @@ sprinkler_1: empty: '뀁뀄' right: '뀁뀅' # Water splash animation when sprinkler works - sprinkler-animation: + animation: enable: true - y-offset: 0.4 - item: customcrops:water_animation + duration: 10 + vertical-offset: 0.4 + item: customcrops:water_effect # ARMOR_STAND / ITEM_DISPLAY (1.19.4+) type: ARMOR_STAND pot-whitelist: @@ -58,7 +59,7 @@ sprinkler_2: hologram: enable: true type: ARMOR_STAND - y-offset: 0.8 + vertical-offset: -0.3 duration: 1 content: '{water_bar}' water-bar: @@ -66,10 +67,10 @@ sprinkler_2: full: '뀁뀃' empty: '뀁뀄' right: '뀁뀅' - sprinkler-animation: + animation: enable: true - y-offset: 0.4 - item: customcrops:water_animation + vertical-offset: 0.4 + item: customcrops:water_effect type: ARMOR_STAND pot-whitelist: - default @@ -97,7 +98,7 @@ sprinkler_3: hologram: enable: true type: ARMOR_STAND - y-offset: 0.8 + vertical-offset: -0.3 duration: 1 content: '{water_bar}' water-bar: @@ -105,10 +106,10 @@ sprinkler_3: full: '뀁뀃' empty: '뀁뀄' right: '뀁뀅' - sprinkler-animation: + animation: enable: true - y-offset: 0.4 - item: customcrops:water_animation + vertical-offset: 0.4 + item: customcrops:water_effect type: ARMOR_STAND pot-whitelist: - default diff --git a/src/main/resources/messages/messages_chinese.yml b/src/main/resources/messages/messages_chinese.yml index e69de29..709af4e 100644 --- a/src/main/resources/messages/messages_chinese.yml +++ b/src/main/resources/messages/messages_chinese.yml @@ -0,0 +1,22 @@ +# https://docs.advntr.dev/minimessage/format.html +messages: + prefix: '[CustomCrops] ' + reload: '已重载! 用时 {time}ms.' + invalid-args: '无效参数.' + no-console: '这个命令只能由玩家使用.' + not-online: '玩家 {player} 当前不在线.' + lack-args: '缺少参数.' + not-none-args: '你需要输入一个参数.' + before-plant: '这种肥料必须在种植之前使用.' + unsuitable-pot: "你不能在这里面种植它." + reach-crop-limit: '农作物数量已达上限.' + no-perm: "你没有权限这样做." + spring: '春季' + summer: '夏季' + autumn: '秋季' + winter: '冬季' + no-season: '这个世界禁用了季节' + set-season: "成功将 {world} 世界的季节设置为 {season}." + set-date: "成功将 {world} 世界的日期设置为 {date}." + world-not-exist: '世界 {world} 不存在.' + season-not-exist: '{season} 不是一个有效的季节.' \ No newline at end of file diff --git a/src/main/resources/messages/messages_english.yml b/src/main/resources/messages/messages_english.yml index 8751de7..f718ebe 100644 --- a/src/main/resources/messages/messages_english.yml +++ b/src/main/resources/messages/messages_english.yml @@ -1,3 +1,4 @@ +# https://docs.advntr.dev/minimessage/format.html messages: prefix: '[CustomCrops] ' reload: 'Reloaded! Took {time}ms.' @@ -6,7 +7,7 @@ messages: not-online: 'Player {player} is not online.' lack-args: 'Arguments are insufficient.' not-none-args: 'Not a none argument command.' - before-plant: 'This fertilizer must be used before planting!' + before-plant: 'This fertilizer should be used before planting.' unsuitable-pot: "You can't plant the seed in this pot." reach-crop-limit: 'The number of crops has reached the limitation.' no-perm: "You don't have permission to do that." diff --git a/src/main/resources/messages/messages_turkish.yml b/src/main/resources/messages/messages_turkish.yml index e69de29..6127ba2 100644 --- a/src/main/resources/messages/messages_turkish.yml +++ b/src/main/resources/messages/messages_turkish.yml @@ -0,0 +1,22 @@ +# https://docs.advntr.dev/minimessage/format.html +messages: + prefix: '[CustomCrops] ' + reload: 'Yenilendi {time}ms sürdü.' + invalid-args: 'Geçersiz argümanlar. (argüman örneği: /customcrops )' + no-console: 'Bu komut sadece bir oyuncu tarafından kullanılabilir.' + not-online: '{player} adındaki oyuncu aktif değil.' + lack-args: 'Yetersiz argümanlar. Geçersiz argümanlar. (argüman örneği: /customcrops )' + not-none-args: 'Bu komut için bir argüman belirtmelisin. (argüman örneği: /customcrops )' + before-plant: 'Bu gübre, ekimden önce kullanılmalıdır!' + unsuitable-pot: "Tohumu bu saksıya ekemezsin." + reach-crop-limit: 'Ekinlerin sayısı sınıra ulaştı.' + no-perm: "Bunu yapmak için yetkin yok." + spring: 'Bahar' + summer: 'Yaz' + autumn: 'Sonbahar' + winter: 'Kış' + no-season: 'MEVSİMLER BU DÜNYADA DEVRE DIŞI BIRAKILDI' + set-season: "{world} adlı dünyanın mevsimi başarıyla {season} ile değiştirildi." + set-date: "{world} adlı dünyanın tarihi başarıyla {date} ile değiştirildi." + world-not-exist: '{world} adında bir dünya bulunamadı.' + season-not-exist: '{season} adında bir mevsim bulunamadı.' \ No newline at end of file