9
0
mirror of https://github.com/Xiao-MoMi/Custom-Crops.git synced 2025-12-27 19:09:09 +00:00

3.0.0-beta1

This commit is contained in:
Xiao-MoMi
2023-04-18 22:47:17 +08:00
parent 34f0e51908
commit 8eb277b8fc
58 changed files with 1921 additions and 651 deletions

View File

@@ -26,11 +26,11 @@ import net.momirealms.customcrops.api.customplugin.PlatformInterface;
import net.momirealms.customcrops.api.customplugin.PlatformManager;
import net.momirealms.customcrops.api.customplugin.itemsadder.ItemsAdderPluginImpl;
import net.momirealms.customcrops.api.customplugin.oraxen.OraxenPluginImpl;
import net.momirealms.customcrops.api.object.HologramManager;
import net.momirealms.customcrops.api.object.basic.ConfigManager;
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.hologram.HologramManager;
import net.momirealms.customcrops.api.object.pot.PotManager;
import net.momirealms.customcrops.api.object.scheduler.Scheduler;
import net.momirealms.customcrops.api.object.season.SeasonManager;
@@ -42,6 +42,7 @@ import net.momirealms.customcrops.command.CustomCropsCommand;
import net.momirealms.customcrops.helper.LibraryLoader;
import net.momirealms.customcrops.helper.VersionHelper;
import net.momirealms.customcrops.integration.IntegrationManager;
import net.momirealms.protectionlib.ProtectionLib;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
import org.bukkit.World;
@@ -78,11 +79,23 @@ public final class CustomCrops extends JavaPlugin {
public void onLoad(){
plugin = this;
this.loadLibs();
ProtectionLib.initialize(this);
}
@Override
public void onEnable() {
adventure = BukkitAudiences.create(this);
this.versionHelper = new VersionHelper(this);
if (versionHelper.isSpigot()) {
AdventureUtils.consoleMessage("<red>========================[CustomCrops]=========================");
AdventureUtils.consoleMessage("<red> Spigot is not officially supported by CustomCrops");
AdventureUtils.consoleMessage("<red> Please use Paper or its forks");
AdventureUtils.consoleMessage("<red> Paper download link: https://papermc.io/downloads");
AdventureUtils.consoleMessage("<red>==============================================================");
Bukkit.getPluginManager().disablePlugin(this);
return;
}
protocolManager = ProtocolLibrary.getProtocolManager();
AdventureUtils.consoleMessage("[CustomCrops] Running on <white>" + Bukkit.getVersion());
this.registerCommands();
@@ -91,7 +104,6 @@ public final class CustomCrops extends JavaPlugin {
this.scheduler = new Scheduler(this);
this.configManager = new ConfigManager(this);
this.messageManager = new MessageManager(this);
this.versionHelper = new VersionHelper(this);
this.cropManager = new CropManager(this);
this.integrationManager = new IntegrationManager(this);
this.seasonManager = new SeasonManager(this);

View File

@@ -18,19 +18,6 @@
package net.momirealms.customcrops.api;
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 {
@@ -45,77 +32,4 @@ public class CustomCropsAPI {
public static CustomCropsAPI getInstance() {
return instance;
}
public boolean isCrop(String stage_id) {
return plugin.getCropManager().getCropConfigByStage(stage_id) != null;
}
public CropConfig getCropConfig(String crop_config_id) {
return plugin.getCropManager().getCropConfigByID(crop_config_id);
}
public ItemStack buildItem(String id) {
return plugin.getIntegrationManager().build(id);
}
public boolean removeCustomItem(Location location, ItemMode itemMode) {
if (itemMode == ItemMode.TRIPWIRE || itemMode == ItemMode.CHORUS)
return plugin.getPlatformInterface().removeCustomBlock(location);
else if (itemMode == ItemMode.ITEM_FRAME)
return plugin.getPlatformInterface().removeItemFrame(location);
else if (itemMode == ItemMode.ITEM_DISPLAY)
return plugin.getPlatformInterface().removeItemDisplay(location);
return false;
}
public void placeCustomItem(Location location, String id, ItemMode itemMode) {
if (itemMode == ItemMode.TRIPWIRE)
plugin.getPlatformInterface().placeTripWire(location, id);
else if (itemMode == ItemMode.ITEM_FRAME)
plugin.getPlatformInterface().placeItemFrame(location, id);
else if (itemMode == ItemMode.ITEM_DISPLAY)
plugin.getPlatformInterface().placeItemDisplay(location, id);
else if (itemMode == ItemMode.CHORUS)
plugin.getPlatformInterface().placeChorus(location, id);
}
public void changePotModel(SimpleLocation simpleLocation, Pot pot) {
Location location = simpleLocation.getBukkitLocation();
if (location == null) return;
PlatformInterface platform = plugin.getPlatformInterface();
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);
}
}
public boolean isGreenhouse(SimpleLocation simpleLocation) {
return plugin.getWorldDataManager().isGreenhouse(simpleLocation);
}
public CCSeason getCurrentSeason(String world) {
return plugin.getIntegrationManager().getSeasonInterface().getSeason(world);
}
}

View File

@@ -24,7 +24,6 @@ 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;

View File

@@ -18,6 +18,7 @@
package net.momirealms.customcrops.api.customplugin;
import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.api.object.ItemMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
@@ -73,8 +74,6 @@ public interface PlatformInterface {
void placeChorus(Location location, String id);
Location getItemFrameLocation(Location location);
@NotNull
default String getAnyItemIDAt(Location location) {
String block = getBlockID(location.getBlock());
@@ -124,7 +123,7 @@ public interface PlatformInterface {
@Nullable
default ItemFrame getItemFrameAt(Location location) {
Collection<ItemFrame> itemFrames = getItemFrameLocation(location).getNearbyEntitiesByType(ItemFrame.class, 0.5, 0.5, 0.5);
Collection<ItemFrame> itemFrames = location.clone().add(0.5,0.5,0.5).getNearbyEntitiesByType(ItemFrame.class, 0.5, 0.5, 0.5);
int i = itemFrames.size();
int j = 1;
for (ItemFrame itemFrame : itemFrames) {
@@ -139,7 +138,7 @@ public interface PlatformInterface {
@Nullable
default ItemDisplay getItemDisplayAt(Location location) {
Collection<ItemDisplay> itemDisplays = getItemFrameLocation(location).getNearbyEntitiesByType(ItemDisplay.class, 0.5, 0.5, 0.5);
Collection<ItemDisplay> itemDisplays = location.clone().add(0.5,0.5,0.5).getNearbyEntitiesByType(ItemDisplay.class, 0.5, 0.5, 0.5);
int i = itemDisplays.size();
int j = 1;
for (ItemDisplay itemDisplay : itemDisplays) {
@@ -181,4 +180,25 @@ public interface PlatformInterface {
Collection<Entity> entities = location.clone().add(0.5,0.5,0.5).getNearbyEntitiesByType(ItemDisplay.class, 0.5, 0.5, 0.5);
return entities.size() != 0;
}
default boolean removeCustomItem(Location location, ItemMode itemMode) {
if (itemMode == ItemMode.TRIPWIRE || itemMode == ItemMode.CHORUS)
return removeCustomBlock(location);
else if (itemMode == ItemMode.ITEM_FRAME)
return removeItemFrame(location);
else if (itemMode == ItemMode.ITEM_DISPLAY)
return removeItemDisplay(location);
return false;
}
default void placeCustomItem(Location location, String id, ItemMode itemMode) {
if (itemMode == ItemMode.TRIPWIRE)
placeTripWire(location, id);
else if (itemMode == ItemMode.ITEM_FRAME)
placeItemFrame(location, id);
else if (itemMode == ItemMode.ITEM_DISPLAY)
placeItemDisplay(location, id);
else if (itemMode == ItemMode.CHORUS)
placeChorus(location, id);
}
}

View File

@@ -18,14 +18,12 @@
package net.momirealms.customcrops.api.customplugin;
import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.api.CustomCropsAPI;
import net.momirealms.customcrops.api.customplugin.itemsadder.ItemsAdderHandler;
import net.momirealms.customcrops.api.customplugin.oraxen.OraxenHandler;
import net.momirealms.customcrops.api.event.*;
import net.momirealms.customcrops.api.object.BoneMeal;
import net.momirealms.customcrops.api.object.Function;
import net.momirealms.customcrops.api.object.InteractWithItem;
import net.momirealms.customcrops.api.object.ItemType;
import net.momirealms.customcrops.api.object.action.Action;
import net.momirealms.customcrops.api.object.basic.ConfigManager;
import net.momirealms.customcrops.api.object.basic.MessageManager;
@@ -36,13 +34,14 @@ import net.momirealms.customcrops.api.object.fertilizer.Fertilizer;
import net.momirealms.customcrops.api.object.fertilizer.FertilizerConfig;
import net.momirealms.customcrops.api.object.fill.PassiveFillMethod;
import net.momirealms.customcrops.api.object.fill.PositiveFillMethod;
import net.momirealms.customcrops.api.object.hologram.FertilizerHologram;
import net.momirealms.customcrops.api.object.hologram.WaterAmountHologram;
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;
@@ -59,7 +58,6 @@ import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@@ -146,88 +144,78 @@ public class PlatformManager extends Function {
onInteractSomething(player, entity.getLocation().getBlock().getLocation(), id, event);
}
@NotNull
public ItemType onInteractAir(Player player) {
public void onInteractAir(Player player) {
ItemStack item_in_hand = player.getInventory().getItemInMainHand();
String id = plugin.getPlatformInterface().getItemStackID(item_in_hand);
if (onInteractWithWateringCan(player, id, item_in_hand)) {
return ItemType.WATERING_CAN;
if (onInteractWithWateringCan(player, id, item_in_hand, null, null)) {
return;
}
return ItemType.UNKNOWN;
}
@NotNull
public ItemType onBreakSomething(Player player, Location location, String id, Cancellable event) {
public void onBreakSomething(Player player, Location location, String id, Cancellable event) {
if (onBreakGlass(id, location)) {
return ItemType.GLASS;
return;
}
if (onBreakPot(player, id, location, event)) {
return ItemType.POT;
return;
}
if (onBreakCrop(player, id, location, event)) {
return ItemType.CROP;
return;
}
if (onBreakSprinkler(id, location)) {
return ItemType.SPRINKLER;
return;
}
if (onBreakScarecrow(id, location)) {
return ItemType.SCARECROW;
return;
}
return ItemType.UNKNOWN;
}
@NotNull
public ItemType onPlaceSomething(Location location, String id) {
public void onPlaceSomething(Location location, String id) {
if (onPlaceGlass(id, location)) {
return ItemType.GLASS;
return;
}
if (onPlacePot(id, location)) {
return ItemType.POT;
return;
}
if (onPlaceScarecrow(id, location)) {
return ItemType.SCARECROW;
return;
}
return ItemType.UNKNOWN;
}
@NotNull ItemType onInteractSomething(Player player, Location location, String id, Cancellable event) {
void onInteractSomething(Player player, Location location, String id, Cancellable event) {
ItemStack item_in_hand = player.getInventory().getItemInMainHand();
String item_in_hand_id = plugin.getPlatformInterface().getItemStackID(item_in_hand);
if (onInteractWithSprinkler(player, location, item_in_hand, item_in_hand_id)) {
return ItemType.SPRINKLER;
return;
}
if (onInteractSprinkler(player, id, location, item_in_hand, item_in_hand_id)) {
return ItemType.SPRINKLER;
if (onInteractSprinkler(player, id, location, item_in_hand, item_in_hand_id, event)) {
return;
}
if (onInteractPot(player, id, location, item_in_hand, item_in_hand_id, event)) {
return ItemType.POT;
return;
}
if (onInteractCrop(player, id, location, item_in_hand, item_in_hand_id, event)) {
return ItemType.CROP;
return;
}
if (onInteractWithWateringCan(player, item_in_hand_id, item_in_hand)) {
return ItemType.WATERING_CAN;
if (onInteractWithWateringCan(player, item_in_hand_id, item_in_hand, id, location)) {
return;
}
return ItemType.UNKNOWN;
}
public boolean onBreakGlass(String id, Location location) {
@@ -274,7 +262,7 @@ public class PlatformManager extends Function {
return true;
}
public boolean onInteractSprinkler(Player player, String id, Location location, ItemStack item_in_hand, String item_in_hand_id) {
public boolean onInteractSprinkler(Player player, String id, Location location, ItemStack item_in_hand, String item_in_hand_id, Cancellable event) {
SprinklerConfig sprinklerConfig = plugin.getSprinklerManager().getConfigByItemID(id);
if (sprinklerConfig == null) {
return false;
@@ -292,6 +280,7 @@ public class PlatformManager extends Function {
return true;
}
event.setCancelled(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;
@@ -338,12 +327,17 @@ public class PlatformManager extends Function {
}
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());
if (sprinkler != null) {
WaterAmountHologram waterAmountHologram = sprinklerConfig.getSprinklerHologram();
if (waterAmountHologram != null) {
String content = waterAmountHologram.getContent(sprinkler.getWater(), sprinklerConfig.getStorage());
plugin.getHologramManager().showHologram(player,
location.clone().add(0.5, waterAmountHologram.getOffset(),0.5),
AdventureUtils.getComponentFromMiniMessage(content),
waterAmountHologram.getDuration() * 1000,
waterAmountHologram.getMode(),
waterAmountHologram.getTextDisplayMeta()
);
}
}
return true;
@@ -381,7 +375,7 @@ public class PlatformManager extends Function {
}
if (player.getGameMode() != GameMode.CREATIVE) item_in_hand.setAmount(item_in_hand.getAmount() - 1);
CustomCropsAPI.getInstance().placeCustomItem(sprinkler_loc, sprinklerConfig.getThreeD(), sprinklerConfig.getItemMode());
CustomCrops.getInstance().getPlatformInterface().placeCustomItem(sprinkler_loc, sprinklerConfig.getThreeD(), sprinklerConfig.getItemMode());
if (sprinklerConfig.getSound() != null) {
AdventureUtils.playerSound(player, sprinklerConfig.getSound());
}
@@ -409,20 +403,21 @@ public class PlatformManager extends Function {
return true;
}
Pot potData = plugin.getWorldDataManager().getPotData(SimpleLocation.getByBukkitLocation(location).add(0,-1,0));
Location pot_loc = location.clone().subtract(0, 1, 0);
Pot potData = plugin.getWorldDataManager().getPotData(SimpleLocation.getByBukkitLocation(pot_loc));
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);
PotWaterEvent potWaterEvent = new PotWaterEvent(player, item_in_hand, passiveFillMethod.getAmount(), pot_loc);
Bukkit.getPluginManager().callEvent(potWaterEvent);
if (potWaterEvent.isCancelled()) {
return true;
}
event.setCancelled(true);
doPassiveFillAction(player, item_in_hand, passiveFillMethod, location);
doPassiveFillAction(player, item_in_hand, passiveFillMethod, pot_loc);
potData.addWater(potWaterEvent.getWater());
return true;
}
@@ -444,7 +439,6 @@ public class PlatformManager extends Function {
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()) {
@@ -571,7 +565,7 @@ public class PlatformManager extends Function {
if (player.getGameMode() != GameMode.CREATIVE) item_in_hand.setAmount(item_in_hand.getAmount() - 1);
player.swingMainHand();
CustomCropsAPI.getInstance().placeCustomItem(crop_loc, cropPlantEvent.getCropModel(), cropConfig.getCropMode());
CustomCrops.getInstance().getPlatformInterface().placeCustomItem(crop_loc, cropPlantEvent.getCropModel(), cropConfig.getCropMode());
plugin.getWorldDataManager().addCropData(SimpleLocation.getByBukkitLocation(crop_loc), new GrowingCrop(cropConfig.getKey(), cropPlantEvent.getPoint()));
return true;
}
@@ -658,13 +652,35 @@ public class PlatformManager extends Function {
PotInfoEvent potInfoEvent = new PotInfoEvent(player, location, item_in_hand, potConfig, potData == null ? null : potData.getFertilizer(), potData == null ? 0 : potData.getWater(), growingCrop);
Bukkit.getPluginManager().callEvent(potInfoEvent);
if (potConfig.isHologramEnabled() && potData != null) {
if (potConfig.getRequiredItem() != null && !item_in_hand_id.equals(potConfig.getRequiredItem())) {
return true;
}
WaterAmountHologram waterAmountHologram = potConfig.getWaterAmountHologram();
if (waterAmountHologram != null && potData != null) {
plugin.getHologramManager().showHologram(player,
location.clone().add(0.5,waterAmountHologram.getOffset(),0.5),
AdventureUtils.getComponentFromMiniMessage(waterAmountHologram.getContent(potData.getWater(), potConfig.getMaxStorage())),
waterAmountHologram.getDuration() * 1000,
waterAmountHologram.getMode(),
waterAmountHologram.getTextDisplayMeta()
);
}
FertilizerHologram fertilizerHologram = potConfig.getFertilizerHologram();
if (fertilizerHologram != null && potData != null && potData.getFertilizer() != null) {
double offset = 0;
StageConfig stageConfig = plugin.getCropManager().getStageConfig(plugin.getPlatformInterface().getAnyItemIDAt(location.clone().add(0,1,0)));
if (stageConfig != null) {
offset = stageConfig.getOffsetCorrection();
}
potConfig.getPotHologram().show(player, potData, location.clone().add(0.5,0,0.5), offset);
plugin.getHologramManager().showHologram(player,
location.clone().add(0.5,fertilizerHologram.getOffset() + offset,0.5),
AdventureUtils.getComponentFromMiniMessage(fertilizerHologram.getContent(potData.getFertilizer())),
fertilizerHologram.getDuration() * 1000,
fertilizerHologram.getMode(),
fertilizerHologram.getTextDisplayMeta()
);
}
return true;
}
@@ -701,7 +717,7 @@ public class PlatformManager extends Function {
}
private boolean onBreakSprinkler(String id, Location location) {
if (!plugin.getSprinklerManager().containsSprinkler(id)) {
if (plugin.getSprinklerManager().getConfigKeyByItemID(id) == null) {
return false;
}
@@ -804,7 +820,7 @@ public class PlatformManager extends Function {
}
}
public boolean onInteractWithWateringCan(Player player, String item_in_hand_id, ItemStack item_in_hand) {
public boolean onInteractWithWateringCan(Player player, String item_in_hand_id, ItemStack item_in_hand, @Nullable String id, @Nullable Location location) {
WateringCanConfig wateringCanConfig = plugin.getWateringCanManager().getConfigByItemID(item_in_hand_id);
if (wateringCanConfig == null) {
return false;
@@ -812,12 +828,27 @@ public class PlatformManager extends Function {
int current = plugin.getWateringCanManager().getCurrentWater(item_in_hand);
if (current >= wateringCanConfig.getStorage()) return true;
List<Block> lineOfSight = player.getLineOfSight(null, 5);
List<String> blockIds = lineOfSight.stream().map(block -> plugin.getPlatformInterface().getBlockID(block)).toList();
int add = 0;
for (PositiveFillMethod positiveFillMethod : wateringCanConfig.getPositiveFillMethods()) {
if (positiveFillMethod.getType() == PositiveFillMethod.InteractType.BLOCK) {
if (id != null && location != null) {
for (PositiveFillMethod positiveFillMethod : wateringCanConfig.getPositiveFillMethods()) {
if (positiveFillMethod.getId().equals(id)) {
add = positiveFillMethod.getAmount();
if (positiveFillMethod.getSound() != null) {
AdventureUtils.playerSound(player, positiveFillMethod.getSound());
}
if (positiveFillMethod.getParticle() != null) {
location.getWorld().spawnParticle(positiveFillMethod.getParticle(), location.clone().add(0.5,1.1, 0.5),5,0.1,0.1,0.1);
}
break;
}
}
} else {
List<Block> lineOfSight = player.getLineOfSight(null, 5);
List<String> blockIds = lineOfSight.stream().map(block -> plugin.getPlatformInterface().getBlockID(block)).toList();
for (PositiveFillMethod positiveFillMethod : wateringCanConfig.getPositiveFillMethods()) {
int index = 0;
for (String blockId : blockIds) {
if (positiveFillMethod.getId().equals(blockId)) {
@@ -827,7 +858,7 @@ public class PlatformManager extends Function {
}
if (positiveFillMethod.getParticle() != null) {
Block block = lineOfSight.get(index);
block.getWorld().spawnParticle(positiveFillMethod.getParticle(), block.getLocation().add(0.5,1, 0.5),5,0.1,0.1,0.1);
block.getWorld().spawnParticle(positiveFillMethod.getParticle(), block.getLocation().add(0.5,1.1, 0.5),5,0.1,0.1,0.1);
}
break;
}
@@ -844,5 +875,4 @@ public class PlatformManager extends Function {
}
return true;
}
}

View File

@@ -67,6 +67,7 @@ public class ItemsAdderPluginImpl implements PlatformInterface {
if (entity instanceof ItemFrame itemFrame)
return itemFrame;
else {
AdventureUtils.consoleMessage("<red>[CustomCrops] Item Frame not exists: " + id);
customFurniture.remove(false);
}
return null;
@@ -75,7 +76,18 @@ public class ItemsAdderPluginImpl implements PlatformInterface {
@Nullable
@Override
public ItemDisplay placeItemDisplay(Location location, String id) {
//TODO Not implemented
CustomFurniture customFurniture = CustomFurniture.spawn(id, location.getBlock());
if (customFurniture == null) {
AdventureUtils.consoleMessage("<red>[CustomCrops] Furniture not exists: " + id);
return null;
}
Entity entity = customFurniture.getArmorstand();
if (entity instanceof ItemDisplay itemDisplay)
return itemDisplay;
else {
AdventureUtils.consoleMessage("<red>[CustomCrops] Item Display not exists: " + id);
customFurniture.remove(false);
}
return null;
}
@@ -116,11 +128,6 @@ public class ItemsAdderPluginImpl implements PlatformInterface {
CustomBlock.place(id, location);
}
@Override
public Location getItemFrameLocation(Location location) {
return location.clone().add(0.5, 0.5, 0.5);
}
@NotNull
@Override
public String getItemStackID(@NotNull ItemStack itemStack) {
@@ -135,8 +142,9 @@ public class ItemsAdderPluginImpl implements PlatformInterface {
@Nullable
@Override
public String getItemDisplayID(ItemDisplay itemDisplay) {
//TODO Not implemented
return null;
CustomFurniture customFurniture = CustomFurniture.byAlreadySpawned(itemDisplay);
if (customFurniture == null) return null;
return customFurniture.getNamespacedID();
}
@Nullable

View File

@@ -71,7 +71,7 @@ public class OraxenPluginImpl implements PlatformInterface {
public ItemFrame placeItemFrame(Location location, String id) {
FurnitureMechanic mechanic = (FurnitureMechanic) FurnitureFactory.getInstance().getMechanic(id);
if (mechanic == null) {
AdventureUtils.consoleMessage("<red>[CustomCrops] Item Frame not exists: " + id);
AdventureUtils.consoleMessage("<red>[CustomCrops] Furniture not exists: " + id);
return null;
}
Entity entity = mechanic.place(location, 0, Rotation.NONE, BlockFace.UP);
@@ -89,7 +89,7 @@ public class OraxenPluginImpl implements PlatformInterface {
public ItemDisplay placeItemDisplay(Location location, String id) {
FurnitureMechanic mechanic = (FurnitureMechanic) FurnitureFactory.getInstance().getMechanic(id);
if (mechanic == null) {
AdventureUtils.consoleMessage("<red>[CustomCrops] Item Display not exists: " + id);
AdventureUtils.consoleMessage("<red>[CustomCrops] Furniture not exists: " + id);
return null;
}
Entity entity = mechanic.place(location);
@@ -135,15 +135,9 @@ public class OraxenPluginImpl implements PlatformInterface {
@Override
public void placeChorus(Location location, String id) {
//TODO Not implemented, so use tripwire instead
StringBlockMechanicFactory.setBlockModel(location.getBlock(), id);
}
@Override
public Location getItemFrameLocation(Location location) {
return location.clone().add(0.5,0.5,0.5);
}
@Nullable
@Override
public String getItemDisplayID(ItemDisplay itemDisplay) {

View File

@@ -0,0 +1,62 @@
package net.momirealms.customcrops.api.event;
import net.momirealms.customcrops.api.object.crop.CropConfig;
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.jetbrains.annotations.NotNull;
public class CropBreakEvent extends PlayerEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private boolean cancelled;
private final CropConfig cropConfig;
private final String crop_id;
private final Location location;
public CropBreakEvent(@NotNull Player who, CropConfig cropConfig, String crop_id, Location location) {
super(who);
this.cropConfig = cropConfig;
this.crop_id = crop_id;
this.location = location;
}
@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 CropConfig getCropConfig() {
return cropConfig;
}
/**
* Get the crop item id in IA/Oraxen
* @return item id
*/
public String getCropItemID() {
return crop_id;
}
public Location getLocation() {
return location;
}
}

View File

@@ -19,6 +19,10 @@ package net.momirealms.customcrops.api.object;
public class Function {
public void init() {
}
public void load() {
}

View File

@@ -18,7 +18,6 @@
package net.momirealms.customcrops.api.object.action;
import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.api.CustomCropsAPI;
import net.momirealms.customcrops.api.object.ItemMode;
import net.momirealms.customcrops.api.object.crop.StageConfig;
import net.momirealms.customcrops.api.object.world.SimpleLocation;
@@ -39,7 +38,7 @@ public class BreakImpl implements Action {
public void doOn(@Nullable Player player, @Nullable SimpleLocation crop_loc, ItemMode itemMode) {
if (crop_loc == null) return;
CustomCrops.getInstance().getScheduler().callSyncMethod(() -> {
CustomCropsAPI.getInstance().removeCustomItem(crop_loc.getBukkitLocation(), itemMode);
CustomCrops.getInstance().getPlatformInterface().removeCustomItem(crop_loc.getBukkitLocation(), itemMode);
CustomCrops.getInstance().getWorldDataManager().removeCropData(crop_loc);
return null;
});

View File

@@ -18,7 +18,6 @@
package net.momirealms.customcrops.api.object.action;
import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.api.CustomCropsAPI;
import net.momirealms.customcrops.api.object.ItemMode;
import net.momirealms.customcrops.api.object.basic.ConfigManager;
import net.momirealms.customcrops.api.object.basic.MessageManager;
@@ -55,7 +54,7 @@ public class ReplantImpl implements Action {
return null;
}
if (!CustomCrops.getInstance().getPlatformInterface().detectAnyThing(location)) {
CustomCropsAPI.getInstance().placeCustomItem(location, model, newCMode);
CustomCrops.getInstance().getPlatformInterface().placeCustomItem(location, model, newCMode);
CustomCrops.getInstance().getWorldDataManager().addCropData(crop_loc, new GrowingCrop(crop, point));
}
return null;

View File

@@ -18,7 +18,6 @@
package net.momirealms.customcrops.api.object.action;
import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.api.CustomCropsAPI;
import net.momirealms.customcrops.api.object.ItemMode;
import net.momirealms.customcrops.api.object.crop.VariationCrop;
import net.momirealms.customcrops.api.object.fertilizer.Variation;
@@ -66,8 +65,8 @@ public record VariationImpl(VariationCrop[] variationCrops) implements Action {
private void doVariation(@NotNull SimpleLocation crop_loc, ItemMode itemMode, VariationCrop variationCrop) {
CustomCrops.getInstance().getScheduler().callSyncMethod(() -> {
Location location = crop_loc.getBukkitLocation();
if (CustomCropsAPI.getInstance().removeCustomItem(location, itemMode)) {
CustomCropsAPI.getInstance().placeCustomItem(location, variationCrop.getId(), variationCrop.getCropMode());
if (CustomCrops.getInstance().getPlatformInterface().removeCustomItem(location, itemMode)) {
CustomCrops.getInstance().getPlatformInterface().placeCustomItem(location, variationCrop.getId(), variationCrop.getCropMode());
}
CustomCrops.getInstance().getWorldDataManager().removeCropData(crop_loc);
return null;

View File

@@ -76,11 +76,17 @@ public class ConfigManager extends Function {
debug = config.getBoolean("debug");
setUpMode = config.getBoolean("set-up-mode", true);
loadWorlds(Objects.requireNonNull(config.getConfigurationSection("worlds")));
loadOptimization(Objects.requireNonNull(config.getConfigurationSection("optimization")));
loadScheduleSystem(Objects.requireNonNull(config.getConfigurationSection("schedule-system")));
loadMechanic(Objects.requireNonNull(config.getConfigurationSection("mechanics")));
loadOtherSetting(Objects.requireNonNull(config.getConfigurationSection("other-settings")));
}
private void loadOptimization(ConfigurationSection section) {
enableLimitation = section.getBoolean("limitation.enable");
maxCropPerChunk = section.getInt("limitation.valid-crop-amount");
}
private void loadWorlds(ConfigurationSection section) {
worldFolderPath = section.getString("folder", "");
whiteListWorlds = section.getString("mode", "whitelist").equalsIgnoreCase("whitelist");
@@ -105,6 +111,7 @@ public class ConfigManager extends Function {
enableGreenhouse = section.getBoolean("season.greenhouse.enable", true);
greenhouseRange = section.getInt("season.greenhouse.range", 5);
greenhouseBlock = section.getString("season.greenhouse.block");
scarecrow = section.getString("scarecrow");
}
private void loadOtherSetting(ConfigurationSection section) {

View File

@@ -18,7 +18,6 @@
package net.momirealms.customcrops.api.object.condition;
import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.api.CustomCropsAPI;
import net.momirealms.customcrops.api.object.ItemMode;
import net.momirealms.customcrops.api.object.world.SimpleLocation;
import org.bukkit.Location;
@@ -48,9 +47,9 @@ public class DeathCondition {
Location location = simpleLocation.getBukkitLocation();
if (location == null) return;
CustomCrops.getInstance().getScheduler().callSyncMethod(() -> {
CustomCropsAPI.getInstance().removeCustomItem(location, itemMode);
CustomCrops.getInstance().getPlatformInterface().removeCustomItem(location, itemMode);
if (dead_model != null) {
CustomCropsAPI.getInstance().placeCustomItem(location, dead_model, itemMode);
CustomCrops.getInstance().getPlatformInterface().placeCustomItem(location, dead_model, itemMode);
}
return null;
});

View File

@@ -86,7 +86,7 @@ public class CropManager extends Function implements Listener {
for (String key : config.getKeys(false)) {
ConfigurationSection cropSec = config.getConfigurationSection(key);
if (cropSec == null) continue;
ItemMode itemMode = ItemMode.valueOf(cropSec.getString("crop-mode", "TripWire").toUpperCase());
ItemMode itemMode = ItemMode.valueOf(cropSec.getString("type", "TripWire").toUpperCase());
String[] bottomBlocks = cropSec.getStringList("pot-whitelist").toArray(new String[0]);
if (bottomBlocks.length == 0) {
AdventureUtils.consoleMessage("<red>[CustomCrops] pot-whitelist is not set for crop: " + key);

View File

@@ -55,4 +55,8 @@ public class Fertilizer implements Serializable {
public int getLeftTimes() {
return times;
}
public void setTimes(int times) {
this.times = times;
}
}

View File

@@ -22,26 +22,14 @@ import org.bukkit.Particle;
public class PositiveFillMethod extends AbstractFillMethod {
private final InteractType type;
private final String id;
public PositiveFillMethod(InteractType type, String id, int amount, Particle particle, Sound sound) {
public PositiveFillMethod(String id, int amount, Particle particle, Sound sound) {
super(amount, particle, sound);
this.type = type;
this.id = id;
}
public InteractType getType() {
return type;
}
public String getId() {
return id;
}
public enum InteractType {
BLOCK,
ENTITY,
MM
}
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customcrops.api.object.hologram;
public abstract class AbstractHologram {
protected final String content;
private final double offset;
private final HologramManager.Mode mode;
private final int duration;
private TextDisplayMeta textDisplayMeta;
public AbstractHologram(String content, double offset, HologramManager.Mode mode, int duration, TextDisplayMeta textDisplayMeta) {
this.content = content;
this.offset = offset;
this.mode = mode;
this.duration = duration;
this.textDisplayMeta = textDisplayMeta;
}
public String getContent() {
return content;
}
public double getOffset() {
return offset;
}
public HologramManager.Mode getMode() {
return mode;
}
public int getDuration() {
return duration;
}
public TextDisplayMeta getTextDisplayMeta() {
return textDisplayMeta;
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customcrops.api.object.hologram;
import net.momirealms.customcrops.api.object.fertilizer.Fertilizer;
import net.momirealms.customcrops.api.object.fertilizer.FertilizerConfig;
import org.jetbrains.annotations.NotNull;
public class FertilizerHologram extends AbstractHologram {
public FertilizerHologram(@NotNull String content, double offset, HologramManager.Mode mode, int duration, TextDisplayMeta textDisplayMeta) {
super(content, offset, mode, duration, textDisplayMeta);
}
public String getContent(Fertilizer fertilizer) {
FertilizerConfig fertilizerConfig = fertilizer.getConfig();
return content.replace("{icon}", String.valueOf(fertilizerConfig.getIcon()))
.replace("{left_times}", String.valueOf(fertilizer.getLeftTimes()))
.replace("{max_times}", String.valueOf(fertilizerConfig.getTimes()));
}
}

View File

@@ -15,10 +15,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customcrops.api.object;
package net.momirealms.customcrops.api.object.hologram;
import net.kyori.adventure.text.Component;
import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.api.object.Function;
import net.momirealms.customcrops.api.object.Tuple;
import net.momirealms.customcrops.api.util.FakeEntityUtils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@@ -86,13 +88,13 @@ public class HologramManager extends Function implements Listener {
this.hologramMap.remove(event.getPlayer().getUniqueId());
}
public void showHologram(Player player, Location location, Component component, int millis, Mode mode) {
public void showHologram(Player player, Location location, Component component, int millis, Mode mode, TextDisplayMeta textDisplayMeta) {
HologramCache hologramCache = hologramMap.get(player.getUniqueId());
if (hologramCache != null) {
hologramCache.showHologram(player, location, component, millis, mode);
hologramCache.showHologram(player, location, component, millis, mode, textDisplayMeta);
} else {
hologramCache = new HologramCache();
hologramCache.showHologram(player, location, component, millis, mode);
hologramCache.showHologram(player, location, component, millis, mode, textDisplayMeta);
hologramMap.put(player.getUniqueId(), hologramCache);
}
}
@@ -133,7 +135,7 @@ public class HologramManager extends Function implements Listener {
}
}
public void showHologram(Player player, Location location, Component component, int millis, Mode mode) {
public void showHologram(Player player, Location location, Component component, int millis, Mode mode, TextDisplayMeta textDisplayMeta) {
int entity_id = push(location, millis);
if (entity_id == 0) {
int random = ThreadLocalRandom.current().nextInt(Integer.MAX_VALUE);
@@ -143,14 +145,14 @@ public class HologramManager extends Function implements Listener {
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));
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getSpawnPacket(random, location.clone().add(0,1,0), EntityType.TEXT_DISPLAY));
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getTextDisplayMetaPacket(random, component, textDisplayMeta));
}
} else {
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));
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getTextDisplayMetaPacket(entity_id, component, textDisplayMeta));
}
}
}

View File

@@ -0,0 +1,38 @@
package net.momirealms.customcrops.api.object.hologram;
public class TextDisplayMeta {
private final boolean hasShadow;
private final boolean isSeeThrough;
private final boolean useDefaultBackground;
private final int backgroundColor;
private final byte opacity;
public TextDisplayMeta(boolean hasShadow, boolean isSeeThrough, boolean useDefaultBackground, int backgroundColor, byte opacity) {
this.hasShadow = hasShadow;
this.isSeeThrough = isSeeThrough;
this.useDefaultBackground = useDefaultBackground;
this.backgroundColor = backgroundColor;
this.opacity = opacity;
}
public boolean isHasShadow() {
return hasShadow;
}
public boolean isSeeThrough() {
return isSeeThrough;
}
public boolean isUseDefaultBackground() {
return useDefaultBackground;
}
public int getBackgroundColor() {
return backgroundColor;
}
public byte getOpacity() {
return opacity;
}
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customcrops.api.object.hologram;
import org.jetbrains.annotations.NotNull;
public class WaterAmountHologram extends AbstractHologram {
private final String bar_left;
private final String bar_full;
private final String bar_empty;
private final String bar_right;
public WaterAmountHologram(@NotNull String content, double offset, HologramManager.Mode mode, int duration,
String bar_left, String bar_full, String bar_empty, String bar_right, TextDisplayMeta textDisplayMeta) {
super(content, offset, mode, duration, textDisplayMeta);
this.bar_left = bar_left;
this.bar_full = bar_full;
this.bar_empty = bar_empty;
this.bar_right = bar_right;
}
public String getContent(int current, int storage) {
return super.content.replace("{current}", String.valueOf(current))
.replace("{storage}", String.valueOf(storage))
.replace("{water_bar}", getWaterBar(current, storage));
}
private 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;
}
}

View File

@@ -0,0 +1,239 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customcrops.api.object.migrate;
import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.api.object.Function;
import net.momirealms.customcrops.api.object.basic.ConfigManager;
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.world.CCChunk;
import net.momirealms.customcrops.api.object.world.ChunkCoordinate;
import net.momirealms.customcrops.api.object.world.SimpleLocation;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.*;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class MigrateWorld extends Function {
private final String worldName;
private final ConcurrentHashMap<ChunkCoordinate, CCChunk> chunkMap;
public MigrateWorld(String world) {
this.worldName = world;
this.chunkMap = new ConcurrentHashMap<>(64);
}
@Override
@SuppressWarnings("ResultOfMethodCallIgnored")
public void init() {
File chunks_folder = new File(CustomCrops.getInstance().getDataFolder().getParentFile().getParentFile(), ConfigManager.worldFolderPath + worldName + File.separator + "customcrops" + File.separator + "chunks");
if (!chunks_folder.exists()) chunks_folder.mkdirs();
File[] data_files = chunks_folder.listFiles();
if (data_files == null) return;
for (File file : data_files) {
ChunkCoordinate chunkCoordinate = ChunkCoordinate.getByString(file.getName().substring(0, file.getName().length() - 7));
try (FileInputStream fis = new FileInputStream(file); ObjectInputStream ois = new ObjectInputStream(fis)) {
CCChunk chunk = (CCChunk) ois.readObject();
if (chunk.isUseless()) {
file.delete();
continue;
}
if (chunkCoordinate != null) chunkMap.put(chunkCoordinate, chunk);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
@Override
@SuppressWarnings("ResultOfMethodCallIgnored")
public void disable() {
File chunks_folder = new File(CustomCrops.getInstance().getDataFolder().getParentFile().getParentFile(), ConfigManager.worldFolderPath + worldName + File.separator + "customcrops" + File.separator + "chunks");
if (!chunks_folder.exists()) chunks_folder.mkdirs();
for (Map.Entry<ChunkCoordinate, CCChunk> entry : chunkMap.entrySet()) {
ChunkCoordinate chunkCoordinate = entry.getKey();
CCChunk chunk = entry.getValue();
String fileName = chunkCoordinate.getFileName() + ".ccdata";
File file = new File(chunks_folder, fileName);
if (chunk.isUseless() && file.exists()) {
file.delete();
continue;
}
try (FileOutputStream fos = new FileOutputStream(file); ObjectOutputStream oos = new ObjectOutputStream(fos)) {
oos.writeObject(chunk);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public String getWorldName() {
return worldName;
}
public void removePotData(SimpleLocation simpleLocation) {
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
if (chunk == null) return;
chunk.removePotData(simpleLocation);
}
public void removeCropData(SimpleLocation simpleLocation) {
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
if (chunk == null) return;
chunk.removeCropData(simpleLocation);
}
public void addCropData(SimpleLocation simpleLocation, GrowingCrop growingCrop) {
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
if (chunk != null) {
chunk.addCropData(simpleLocation, growingCrop);
return;
}
chunk = createNewChunk(simpleLocation);
chunk.addCropData(simpleLocation, growingCrop);
}
public GrowingCrop getCropData(SimpleLocation simpleLocation) {
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
if (chunk != null) {
return chunk.getCropData(simpleLocation);
}
return null;
}
public int getChunkCropAmount(SimpleLocation simpleLocation) {
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
if (chunk == null) return 0;
return chunk.getCropAmount();
}
public void removeGreenhouse(SimpleLocation simpleLocation) {
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
if (chunk == null) return;
chunk.removeGreenhouse(simpleLocation);
}
public void addGreenhouse(SimpleLocation simpleLocation) {
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
if (chunk != null) {
chunk.addGreenhouse(simpleLocation);
return;
}
chunk = createNewChunk(simpleLocation);
chunk.addGreenhouse(simpleLocation);
}
public boolean isGreenhouse(SimpleLocation simpleLocation) {
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
if (chunk == null) return false;
return chunk.isGreenhouse(simpleLocation);
}
public void removeScarecrow(SimpleLocation simpleLocation) {
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
if (chunk == null) return;
chunk.removeScarecrow(simpleLocation);
}
public void addScarecrow(SimpleLocation simpleLocation) {
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
if (chunk != null) {
chunk.addScarecrow(simpleLocation);
return;
}
chunk = createNewChunk(simpleLocation);
chunk.addScarecrow(simpleLocation);
}
public boolean hasScarecrow(SimpleLocation simpleLocation) {
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
if (chunk == null) return false;
return chunk.hasScarecrow();
}
public void removeSprinklerData(SimpleLocation simpleLocation) {
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
if (chunk == null) return;
chunk.removeSprinklerData(simpleLocation);
}
public void addSprinklerData(SimpleLocation simpleLocation, Sprinkler sprinkler) {
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
if (chunk != null) {
chunk.addSprinklerData(simpleLocation, sprinkler);
return;
}
chunk = createNewChunk(simpleLocation);
chunk.addSprinklerData(simpleLocation, sprinkler);
}
@Nullable
public Sprinkler getSprinklerData(SimpleLocation simpleLocation) {
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
if (chunk == null) return null;
return chunk.getSprinklerData(simpleLocation);
}
public void addWaterToPot(SimpleLocation simpleLocation, int amount, @Nullable String pot_id) {
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
if (chunk != null) {
chunk.addWaterToPot(simpleLocation, amount, pot_id);
return;
}
chunk = createNewChunk(simpleLocation);
chunk.addWaterToPot(simpleLocation, amount, pot_id);
}
public void addFertilizerToPot(SimpleLocation simpleLocation, Fertilizer fertilizer, @NotNull String pot_id) {
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
if (chunk != null) {
chunk.addFertilizerToPot(simpleLocation, fertilizer, pot_id);
return;
}
chunk = createNewChunk(simpleLocation);
chunk.addFertilizerToPot(simpleLocation, fertilizer, pot_id);
}
public Pot getPotData(SimpleLocation simpleLocation) {
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
if (chunk == null) return null;
return chunk.getPotData(simpleLocation);
}
public void addPotData(SimpleLocation simpleLocation, Pot pot) {
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
if (chunk != null) {
chunk.addPotData(simpleLocation, pot);
return;
}
chunk = createNewChunk(simpleLocation);
chunk.addPotData(simpleLocation, pot);
}
public CCChunk createNewChunk(SimpleLocation simpleLocation) {
CCChunk newChunk = new CCChunk();
chunkMap.put(simpleLocation.getChunkCoordinate(), newChunk);
return newChunk;
}
}

View File

@@ -22,6 +22,8 @@ import net.momirealms.customcrops.api.object.fertilizer.Fertilizer;
import net.momirealms.customcrops.api.object.fertilizer.FertilizerConfig;
import net.momirealms.customcrops.api.object.fertilizer.FertilizerType;
import net.momirealms.customcrops.api.object.fill.PassiveFillMethod;
import net.momirealms.customcrops.api.object.hologram.FertilizerHologram;
import net.momirealms.customcrops.api.object.hologram.WaterAmountHologram;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -34,18 +36,23 @@ public class PotConfig {
private final Pair<String, String> pot;
private final boolean enableFertilized;
private final PassiveFillMethod[] passiveFillMethods;
private final boolean enableHologram;
private final PotHologram potHologram;
private final FertilizerHologram fertilizerHologram;
private final WaterAmountHologram waterAmountHologram;
private final String requiredItem;
public PotConfig(int max_storage, String dry_pot, String wet_pot, boolean enableFertilized,
@NotNull PassiveFillMethod[] passiveFillMethods, boolean enableHologram, @Nullable PotHologram potHologram) {
@NotNull PassiveFillMethod[] passiveFillMethods,
@Nullable FertilizerHologram fertilizerHologram,
@Nullable WaterAmountHologram waterAmountHologram,
String requiredItem) {
this.max_storage = max_storage;
this.pot = Pair.of(dry_pot, wet_pot);
this.enableFertilized = enableFertilized;
this.fertilizerConvertMap = new HashMap<>();
this.passiveFillMethods = passiveFillMethods;
this.enableHologram = enableHologram;
this.potHologram = potHologram;
this.fertilizerHologram = fertilizerHologram;
this.waterAmountHologram = waterAmountHologram;
this.requiredItem = requiredItem;
}
public void registerFertilizedPot(FertilizerType fertilizerType, String dry_pot, String wet_pot) {
@@ -81,11 +88,18 @@ public class PotConfig {
return passiveFillMethods;
}
public boolean isHologramEnabled() {
return enableHologram;
@Nullable
public FertilizerHologram getFertilizerHologram() {
return fertilizerHologram;
}
public PotHologram getPotHologram() {
return potHologram;
@Nullable
public WaterAmountHologram getWaterAmountHologram() {
return waterAmountHologram;
}
@Nullable
public String getRequiredItem() {
return requiredItem;
}
}

View File

@@ -1,122 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customcrops.api.object.pot;
import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.api.object.HologramManager;
import net.momirealms.customcrops.api.object.fertilizer.Fertilizer;
import net.momirealms.customcrops.api.util.AdventureUtils;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PotHologram {
private final String fertilizerText;
private final double fertilizerOffset;
private final String waterText;
private final double waterOffset;
private final HologramManager.Mode mode;
private final int duration;
private final String bar_left;
private final String bar_full;
private final String bar_empty;
private final String bar_right;
private final Pattern betterPattern = Pattern.compile("\\{(.+?)\\}");
public PotHologram(String fertilizerText, double fertilizerOffset, String waterText, double waterOffset, HologramManager.Mode mode, int duration,
String bar_left, String bar_full, String bar_empty, String bar_right) {
this.mode = mode;
this.duration = duration;
this.fertilizerText = fertilizerText;
this.waterText = waterText;
this.fertilizerOffset = fertilizerOffset;
this.waterOffset = waterOffset;
this.bar_left = bar_left;
this.bar_full = bar_full;
this.bar_empty = bar_empty;
this.bar_right = bar_right;
}
private List<String> detectBetterPlaceholders(String text) {
List<String> placeholders = new ArrayList<>();
Matcher matcher = betterPattern.matcher(text);
while (matcher.find()) placeholders.add(matcher.group());
return placeholders;
}
public void show(Player player, Pot pot, Location location, double offset) {
if (fertilizerText != null && pot.getFertilizer() != null) {
String parsed = CustomCrops.getInstance().getIntegrationManager().getPlaceholderManager().parse(player, fertilizerText);
parseAndSend(parsed, player, pot, location, offset + fertilizerOffset);
}
if (waterText != null) {
String parsed = CustomCrops.getInstance().getIntegrationManager().getPlaceholderManager().parse(player, waterText);
parseAndSend(parsed, player, pot, location, offset + waterOffset);
}
}
public void parseAndSend(String parsed, Player player, Pot pot, Location location, double offset) {
for (String detected : detectBetterPlaceholders(parsed)) {
String replacer = getReplacer(detected, pot);
parsed = parsed.replace(detected, replacer);
}
CustomCrops.getInstance().getHologramManager().showHologram(player, location.clone().add(0, offset, 0), AdventureUtils.getComponentFromMiniMessage(parsed), duration * 1000, mode);
}
public String getReplacer(String text, Pot pot) {
switch (text) {
case "{icon}" -> {
Fertilizer fertilizer = pot.getFertilizer();
if (fertilizer == null) return "";
return fertilizer.getConfig().getIcon();
}
case "{left_times}" -> {
Fertilizer fertilizer = pot.getFertilizer();
if (fertilizer == null) return "";
return String.valueOf(fertilizer.getLeftTimes());
}
case "{max_times}" -> {
Fertilizer fertilizer = pot.getFertilizer();
if (fertilizer == null) return "";
return String.valueOf(fertilizer.getConfig().getTimes());
}
case "{current}" -> {
return String.valueOf(pot.getWater());
}
case "{storage}" -> {
return String.valueOf(pot.getConfig().getMaxStorage());
}
case "{water_bar}" -> {
return getWaterBar(pot.getWater(), pot.getConfig().getMaxStorage());
}
}
return "";
}
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;
}
}

View File

@@ -19,9 +19,12 @@ package net.momirealms.customcrops.api.object.pot;
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.fertilizer.FertilizerType;
import net.momirealms.customcrops.api.object.fill.PassiveFillMethod;
import net.momirealms.customcrops.api.object.hologram.FertilizerHologram;
import net.momirealms.customcrops.api.object.hologram.HologramManager;
import net.momirealms.customcrops.api.object.hologram.TextDisplayMeta;
import net.momirealms.customcrops.api.object.hologram.WaterAmountHologram;
import net.momirealms.customcrops.api.util.AdventureUtils;
import net.momirealms.customcrops.api.util.ConfigUtils;
import org.bukkit.configuration.ConfigurationSection;
@@ -81,26 +84,43 @@ public class PotManager extends Function {
}
blockToPotKey.put(base_wet, key);
blockToPotKey.put(base_dry, key);
boolean enableHolo = section.getBoolean("hologram.enable", false);
PotConfig potConfig = new PotConfig(
section.getInt("max-water-storage"),
base_dry,
base_wet,
enableFertilized,
methods,
enableHolo,
enableHolo ? new PotHologram(
section.getString("hologram.fertilizer.text"),
section.getBoolean("hologram.fertilizer.enable", false) ? new FertilizerHologram(
section.getString("hologram.fertilizer.content", ""),
section.getDouble("hologram.fertilizer.vertical-offset"),
section.getString("hologram.water.text"),
HologramManager.Mode.valueOf(section.getString("hologram.type", "ARMOR_STAND").toUpperCase()),
section.getInt("hologram.duration"),
new TextDisplayMeta(
section.getBoolean("hologram.text-display-options.has-shadow", false),
section.getBoolean("hologram.text-display-options.is-see-through", false),
section.getBoolean("hologram.text-display-options.use-default-background-color", false),
ConfigUtils.rgbToDecimal(section.getString("hologram.text-display-options.background-color", "0,0,0,128")),
(byte) section.getInt("hologram.text-display-options.text-opacity")
)
) : null,
section.getBoolean("hologram.water.enable", false) ? new WaterAmountHologram(
section.getString("hologram.water.content", ""),
section.getDouble("hologram.water.vertical-offset"),
HologramManager.Mode.valueOf(section.getString("hologram.type", "ARMOR_STAND").toUpperCase()),
section.getInt("hologram.duration"),
section.getString("hologram.water.water-bar.left"),
section.getString("hologram.water.water-bar.full"),
section.getString("hologram.water.water-bar.empty"),
section.getString("hologram.water.water-bar.right")
) : null
section.getString("hologram.water.water-bar.right"),
new TextDisplayMeta(
section.getBoolean("hologram.text-display-options.has-shadow", false),
section.getBoolean("hologram.text-display-options.is-see-through", false),
section.getBoolean("hologram.text-display-options.use-default-background-color", false),
ConfigUtils.rgbToDecimal(section.getString("hologram.text-display-options.background-color", "0,0,0,128")),
(byte) section.getInt("hologram.text-display-options.text-opacity")
)
) : null,
section.getString("hologram.require-item")
);
if (enableFertilized) {
ConfigurationSection fertilizedSec = section.getConfigurationSection("fertilized-pots");

View File

@@ -20,6 +20,7 @@ package net.momirealms.customcrops.api.object.sprinkler;
import net.kyori.adventure.sound.Sound;
import net.momirealms.customcrops.api.object.ItemMode;
import net.momirealms.customcrops.api.object.fill.PassiveFillMethod;
import net.momirealms.customcrops.api.object.hologram.WaterAmountHologram;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -33,13 +34,11 @@ 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 WaterAmountHologram waterAmountHologram;
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, boolean hasHologram, boolean hasAnimation, @Nullable SprinklerHologram sprinklerHologram, SprinklerAnimation sprinklerAnimation) {
@NotNull PassiveFillMethod[] passiveFillMethods, @Nullable WaterAmountHologram waterAmountHologram, SprinklerAnimation sprinklerAnimation) {
this.key = key;
this.storage = storage;
this.range = range;
@@ -48,10 +47,8 @@ public class SprinklerConfig {
this.threeD = threeD;
this.twoD = twoD;
this.passiveFillMethods = passiveFillMethods;
this.hasAnimation = hasAnimation;
this.hasHologram = hasHologram;
this.sprinklerAnimation = sprinklerAnimation;
this.sprinklerHologram = sprinklerHologram;
this.waterAmountHologram = waterAmountHologram;
}
public String getKey() {
@@ -91,17 +88,9 @@ public class SprinklerConfig {
return passiveFillMethods;
}
public boolean hasAnimation() {
return hasAnimation;
}
public boolean hasHologram() {
return hasHologram;
}
@Nullable
public SprinklerHologram getSprinklerHologram() {
return sprinklerHologram;
public WaterAmountHologram getSprinklerHologram() {
return waterAmountHologram;
}
@Nullable

View File

@@ -1,53 +0,0 @@
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;
}
}

View File

@@ -21,9 +21,11 @@ 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.object.hologram.HologramManager;
import net.momirealms.customcrops.api.object.hologram.TextDisplayMeta;
import net.momirealms.customcrops.api.object.hologram.WaterAmountHologram;
import net.momirealms.customcrops.api.util.AdventureUtils;
import net.momirealms.customcrops.api.util.ConfigUtils;
import org.bukkit.Bukkit;
@@ -93,8 +95,6 @@ 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),
@@ -104,9 +104,7 @@ public class SprinklerManager extends Function implements Listener {
threeD,
twoD,
methods,
hasHologram,
hasAnimation,
hasHologram ? new SprinklerHologram(
sprinklerSec.getBoolean("hologram.enable") ? new WaterAmountHologram(
sprinklerSec.getString("hologram.content",""),
sprinklerSec.getDouble("hologram.vertical-offset"),
HologramManager.Mode.valueOf(sprinklerSec.getString("hologram.type", "ARMOR_STAND").toUpperCase()),
@@ -114,9 +112,16 @@ public class SprinklerManager extends Function implements Listener {
sprinklerSec.getString("hologram.water-bar.left"),
sprinklerSec.getString("hologram.water-bar.full"),
sprinklerSec.getString("hologram.water-bar.empty"),
sprinklerSec.getString("hologram.water-bar.right")
sprinklerSec.getString("hologram.water-bar.right"),
new TextDisplayMeta(
sprinklerSec.getBoolean("hologram.text-display-options.has-shadow", false),
sprinklerSec.getBoolean("hologram.text-display-options.is-see-through", false),
sprinklerSec.getBoolean("hologram.text-display-options.use-default-background-color", false),
ConfigUtils.rgbToDecimal(sprinklerSec.getString("hologram.text-display-options.background-color", "0,0,0,128")),
(byte) sprinklerSec.getInt("hologram.text-display-options.text-opacity")
)
) : null,
hasAnimation ? new SprinklerAnimation(
sprinklerSec.getBoolean("animation.enable") ? new SprinklerAnimation(
sprinklerSec.getInt("animation.duration"),
sprinklerSec.getString("animation.item"),
sprinklerSec.getDouble("animation.vertical-offset"),
@@ -148,10 +153,6 @@ public class SprinklerManager extends Function implements Listener {
return sprinklerConfigMap.get(key);
}
public boolean containsSprinkler(String key) {
return sprinklerConfigMap.containsKey(key);
}
@EventHandler
public void onItemSpawn(ItemSpawnEvent event) {
if (event.isCancelled()) return;

View File

@@ -18,12 +18,14 @@
package net.momirealms.customcrops.api.object.world;
import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.api.CustomCropsAPI;
import net.momirealms.customcrops.api.object.basic.ConfigManager;
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.util.ConfigUtils;
import org.bukkit.Location;
import org.bukkit.Material;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -127,7 +129,7 @@ public class CCChunk implements Serializable {
if (pot != null) {
if (pot.addWater(amount)) {
CustomCrops.getInstance().getScheduler().callSyncMethod(() -> {
CustomCropsAPI.getInstance().changePotModel(simpleLocation, pot);
changePotModel(simpleLocation, pot);
return null;
});
}
@@ -136,7 +138,7 @@ public class CCChunk implements Serializable {
Pot newPot = new Pot(pot_id, null, amount);
potMap.put(simpleLocation, newPot);
CustomCrops.getInstance().getScheduler().callSyncMethod(() -> {
CustomCropsAPI.getInstance().changePotModel(simpleLocation, newPot);
changePotModel(simpleLocation, newPot);
return null;
});
}
@@ -147,7 +149,7 @@ public class CCChunk implements Serializable {
if (pot != null) {
pot.setFertilizer(fertilizer);
CustomCrops.getInstance().getScheduler().callSyncMethod(() -> {
CustomCropsAPI.getInstance().changePotModel(simpleLocation, pot);
changePotModel(simpleLocation, pot);
return null;
});
}
@@ -155,7 +157,7 @@ public class CCChunk implements Serializable {
Pot newPot = new Pot(pot_id, fertilizer, 0);
potMap.put(simpleLocation, newPot);
CustomCrops.getInstance().getScheduler().callSyncMethod(() -> {
CustomCropsAPI.getInstance().changePotModel(simpleLocation, newPot);
changePotModel(simpleLocation, newPot);
return null;
});
}
@@ -181,4 +183,16 @@ public class CCChunk implements Serializable {
ccWorld.pushConsumeTask(simpleLocation, randomGenerator.nextInt(60));
}
}
public void changePotModel(SimpleLocation simpleLocation, Pot pot) {
Location location = simpleLocation.getBukkitLocation();
if (location == null) return;
if (CustomCrops.getInstance().getPlatformInterface().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 CustomCrops.getInstance().getPlatformInterface().placeNoteBlock(location, replacer);
} else {
CustomCrops.getInstance().getWorldDataManager().removePotData(simpleLocation);
}
}
}

View File

@@ -18,8 +18,6 @@
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;
@@ -50,10 +48,7 @@ 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.*;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
@@ -74,8 +69,9 @@ public class CCWorld extends Function {
private final GenericObjectPool<CropCheckTask> cropTaskPool;
private final GenericObjectPool<SprinklerCheckTask> sprinklerTaskPool;
private final GenericObjectPool<ConsumeCheckTask> consumeTaskPool;
private boolean hasWorkedToday;
private boolean hasConsumedToday;
private long lastWorkDay;
private long lastConsumeDay;
private ScheduledFuture<?> scheduledTimerTask;
public CCWorld(World world) {
this.world = new WeakReference<>(world);
@@ -94,12 +90,11 @@ public class CCWorld extends Function {
this.consumeTaskPool = new GenericObjectPool<>(new ConsumeTaskFactory(), new GenericObjectPoolConfig<>());
this.consumeTaskPool.setMaxTotal(10);
this.consumeTaskPool.setMinIdle(1);
this.hasConsumedToday = false;
this.hasWorkedToday = false;
}
@Override
@SuppressWarnings("ResultOfMethodCallIgnored")
public void load() {
public void init() {
File chunks_folder = new File(CustomCrops.getInstance().getDataFolder().getParentFile().getParentFile(), ConfigManager.worldFolderPath + worldName + File.separator + "customcrops" + File.separator + "chunks");
if (!chunks_folder.exists()) chunks_folder.mkdirs();
File[] data_files = chunks_folder.listFiles();
@@ -117,21 +112,24 @@ public class CCWorld extends Function {
e.printStackTrace();
}
}
YamlConfiguration dataFile = ConfigUtils.readData(new File(CustomCrops.getInstance().getDataFolder().getParentFile().getParentFile(), ConfigManager.worldFolderPath + worldName + File.separator + "customcrops" + File.separator + "data.yml"));
if (ConfigManager.enableSeason && !ConfigManager.rsHook) {
YamlConfiguration seasonDataFile = ConfigUtils.readData(new File(CustomCrops.getInstance().getDataFolder().getParentFile().getParentFile(), ConfigManager.worldFolderPath + worldName + File.separator + "customcrops" + File.separator + "data.yml"));
SeasonData seasonData;
if (seasonDataFile.contains("season") && seasonDataFile.contains("date")) {
seasonData = new SeasonData(worldName, CCSeason.valueOf(seasonDataFile.getString("season")), seasonDataFile.getInt("date"));
if (dataFile.contains("season") && dataFile.contains("date")) {
seasonData = new SeasonData(worldName, CCSeason.valueOf(dataFile.getString("season")), dataFile.getInt("date"));
} else {
seasonData = new SeasonData(worldName);
}
CustomCrops.getInstance().getSeasonManager().loadSeasonData(seasonData);
}
this.lastConsumeDay = dataFile.getLong("last-consume-day", 0);
this.lastWorkDay = dataFile.getLong("last-work-day", 0);
this.arrangeTask();
}
@Override
@SuppressWarnings("ResultOfMethodCallIgnored")
public void unload() {
public void disable() {
closePool();
File chunks_folder = new File(CustomCrops.getInstance().getDataFolder().getParentFile().getParentFile(), ConfigManager.worldFolderPath + worldName + File.separator + "customcrops" + File.separator + "chunks");
if (!chunks_folder.exists()) chunks_folder.mkdirs();
@@ -150,22 +148,41 @@ public class CCWorld extends Function {
e.printStackTrace();
}
}
YamlConfiguration dataFile = new YamlConfiguration();
if (ConfigManager.enableSeason && !ConfigManager.rsHook) {
YamlConfiguration seasonDataFile = new YamlConfiguration();
SeasonData seasonData = CustomCrops.getInstance().getSeasonManager().unloadSeasonData(worldName);
if (seasonData == null) {
seasonDataFile.set("season", "SPRING");
seasonDataFile.set("date", 1);
dataFile.set("season", "SPRING");
dataFile.set("date", 1);
} else {
seasonDataFile.set("season", seasonData.getSeason().name());
seasonDataFile.set("date", seasonData.getDate());
}
try {
seasonDataFile.save(new File(CustomCrops.getInstance().getDataFolder().getParentFile().getParentFile(), ConfigManager.worldFolderPath + worldName + File.separator + "customcrops" + File.separator + "data.yml"));
} catch (IOException e) {
AdventureUtils.consoleMessage("<red>[CustomCrops] Failed to save season data for world: " + worldName);
dataFile.set("season", seasonData.getSeason().name());
dataFile.set("date", seasonData.getDate());
}
}
dataFile.set("last-consume-day", lastConsumeDay);
dataFile.set("last-work-day", lastWorkDay);
try {
dataFile.save(new File(CustomCrops.getInstance().getDataFolder().getParentFile().getParentFile(), ConfigManager.worldFolderPath + worldName + File.separator + "customcrops" + File.separator + "data.yml"));
} catch (IOException e) {
AdventureUtils.consoleMessage("<red>[CustomCrops] Failed to save season data for world: " + worldName);
}
}
public void load() {
if (this.scheduledTimerTask == null) {
this.scheduledTimerTask = this.schedule.scheduleAtFixedRate(() -> {
for (CCChunk chunk : chunkMap.values()) {
chunk.scheduleGrowTask(this);
}
}, ThreadLocalRandom.current().nextInt(20), ConfigManager.pointGainInterval, TimeUnit.SECONDS);
}
}
public void unload() {
if (this.scheduledTimerTask != null) {
this.scheduledTimerTask.cancel(false);
this.scheduledTimerTask = null;
}
}
/**
@@ -176,45 +193,29 @@ public class CCWorld extends Function {
this.schedule.scheduleAtFixedRate(() -> {
World current = world.get();
if (current != null) {
long fullTime = current.getFullTime();
long day = fullTime / 24000;
long time = current.getTime();
if (time < 100 && !hasConsumedToday) {
hasConsumedToday = true;
if (time < 100 && day != lastConsumeDay) {
lastConsumeDay = day;
if (ConfigManager.enableSeason && !ConfigManager.rsHook && ConfigManager.autoSeasonChange) {
CustomCrops.getInstance().getSeasonManager().addDate(worldName);
}
if (ConfigManager.enableScheduleSystem) {
schedule.schedule(() -> {
for (CCChunk chunk : chunkMap.values()) {
chunk.scheduleConsumeTask(this);
}
}, 0, TimeUnit.SECONDS);
scheduleConsumeTask();
}
}
else if (time > 1950 && time < 2050 && !hasWorkedToday) {
hasWorkedToday = true;
else if (time > 1950 && time < 2050 && lastWorkDay != day) {
lastWorkDay = day;
if (ConfigManager.enableScheduleSystem) {
schedule.schedule(() -> {
for (CCChunk chunk : chunkMap.values()) {
chunk.scheduleSprinklerTask(this);
}
}, 0, TimeUnit.SECONDS);
scheduleSprinklerWork();
}
}
else if (time > 23900) {
hasConsumedToday = false;
hasWorkedToday = false;
}
}
else {
this.schedule.shutdown();
}
}, 2, 2, TimeUnit.SECONDS);
this.schedule.scheduleAtFixedRate(() -> {
for (CCChunk chunk : chunkMap.values()) {
chunk.scheduleGrowTask(this);
}
}, 1, ConfigManager.pointGainInterval, TimeUnit.SECONDS);
}
private void closePool() {
@@ -327,12 +328,19 @@ 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();
Location location = simpleLocation.getBukkitLocation();
if (location == null) return;
CustomCrops.getInstance().getScheduler().callSyncMethod(() -> {
CustomCropsAPI.getInstance().changePotModel(temp, potConfig, fertilizer, wet);
if (CustomCrops.getInstance().getPlatformInterface().removeAnyBlock(location)) {
String replacer = wet ? potConfig.getWetPot(fertilizer) : potConfig.getDryPot(fertilizer);
if (ConfigUtils.isVanillaItem(replacer)) location.getBlock().setType(Material.valueOf(replacer));
else CustomCrops.getInstance().getPlatformInterface().placeNoteBlock(location, replacer);
} else {
CustomCrops.getInstance().getWorldDataManager().removePotData(SimpleLocation.getByBukkitLocation(location));
}
return null;
});
}
@@ -366,18 +374,18 @@ public class CCWorld extends Function {
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());
}
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());
}
}
}
sprinkler.setWater(--water);
if (water == 0) {
removeSprinklerData(simpleLocation);
@@ -512,8 +520,8 @@ public class CCWorld extends Function {
});
loadEntities.whenComplete((result, throwable) ->
CustomCrops.getInstance().getScheduler().callSyncMethod(() -> {
if (CustomCropsAPI.getInstance().removeCustomItem(location, itemMode)) {
CustomCropsAPI.getInstance().placeCustomItem(location, finalNextModel, itemMode);
if (CustomCrops.getInstance().getPlatformInterface().removeCustomItem(location, itemMode)) {
CustomCrops.getInstance().getPlatformInterface().placeCustomItem(location, finalNextModel, itemMode);
} else {
removeCropData(simpleLocation);
}
@@ -523,8 +531,8 @@ public class CCWorld extends Function {
else {
asyncGetChunk.whenComplete((result, throwable) ->
CustomCrops.getInstance().getScheduler().callSyncMethod(() -> {
if (CustomCropsAPI.getInstance().removeCustomItem(location, itemMode)) {
CustomCropsAPI.getInstance().placeCustomItem(location, finalNextModel, itemMode);
if (CustomCrops.getInstance().getPlatformInterface().removeCustomItem(location, itemMode)) {
CustomCrops.getInstance().getPlatformInterface().placeCustomItem(location, finalNextModel, itemMode);
} else {
removeCropData(simpleLocation);
}
@@ -739,4 +747,20 @@ public class CCWorld extends Function {
chunkMap.put(simpleLocation.getChunkCoordinate(), newChunk);
return newChunk;
}
public void scheduleSprinklerWork() {
schedule.execute(() -> {
for (CCChunk chunk : chunkMap.values()) {
chunk.scheduleSprinklerTask(this);
}
});
}
public void scheduleConsumeTask() {
schedule.schedule(() -> {
for (CCChunk chunk : chunkMap.values()) {
chunk.scheduleConsumeTask(this);
}
}, 0, TimeUnit.SECONDS);
}
}

View File

@@ -47,18 +47,24 @@ public class WorldDataManager extends Function {
@Override
public void load() {
Bukkit.getPluginManager().registerEvents(worldListener, plugin);
for (CCWorld ccWorld : worldMap.values()) {
ccWorld.load();
}
}
@Override
public void unload() {
HandlerList.unregisterAll(worldListener);
for (CCWorld ccWorld : worldMap.values()) {
ccWorld.unload();
}
}
@Override
public void disable() {
this.unload();
for (CCWorld ccWorld : worldMap.values()) {
ccWorld.unload();
ccWorld.disable();
}
this.worldMap.clear();
}
@@ -66,6 +72,7 @@ public class WorldDataManager extends Function {
public void loadWorld(World world) {
if (!isWorldAllowed(world)) return;
CCWorld ccWorld = new CCWorld(world);
ccWorld.init();
ccWorld.load();
worldMap.put(world.getName(), ccWorld);
}
@@ -73,7 +80,7 @@ public class WorldDataManager extends Function {
public void unloadWorld(World world) {
CCWorld ccWorld = worldMap.remove(world.getName());
if (ccWorld != null) {
ccWorld.unload();
ccWorld.disable();
}
}
@@ -234,4 +241,9 @@ public class WorldDataManager extends Function {
}
return null;
}
@Nullable
public CCWorld getWorld(String world) {
return worldMap.get(world);
}
}

View File

@@ -389,11 +389,9 @@ public class ConfigUtils {
ConfigurationSection methodSec = section.getConfigurationSection(key);
if (methodSec == null) continue;
String id = methodSec.getString("target", "WATER");
PositiveFillMethod.InteractType type = PositiveFillMethod.InteractType.valueOf(methodSec.getString("type", "block").toUpperCase());
@Subst("namespace:key") String soundKey = methodSec.getString("sound", "minecraft:item.bucket.fill");
Sound sound = Sound.sound(Key.key(soundKey), Sound.Source.PLAYER, 1, 1);
PositiveFillMethod method = new PositiveFillMethod(
type,
id,
methodSec.getInt("amount"),
methodSec.contains("particle") ? Particle.valueOf(methodSec.getString("particle", "WATER_SPLASH").toUpperCase()) : null,
@@ -420,4 +418,13 @@ public class ConfigUtils {
}
return interactWithItems.toArray(new InteractWithItem[0]);
}
public static int rgbToDecimal(String rgba) {
String[] split = rgba.split(",");
int r = Integer.parseInt(split[0]);
int g = Integer.parseInt(split[1]);
int b = Integer.parseInt(split[2]);
int a = Integer.parseInt(split[3]);
return (a << 24) | (r << 16) | (g << 8) | b;
}
}

View File

@@ -25,6 +25,7 @@ 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 net.momirealms.customcrops.api.object.hologram.TextDisplayMeta;
import org.bukkit.Location;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
@@ -44,9 +45,7 @@ public class FakeEntityUtils {
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));
}, 1000L * duration);
CustomCrops.getInstance().getScheduler().runTaskAsyncLater(() -> CustomCrops.getProtocolManager().sendServerPacket(player, getDestroyPacket(id)), 1000L * duration);
}
public static WrappedDataWatcher createInvisibleDataWatcher() {
@@ -110,15 +109,13 @@ public class FakeEntityUtils {
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);
WrappedDataWatcher.Serializer serializer2 = WrappedDataWatcher.Registry.get(Byte.class);
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(2, WrappedDataWatcher.Registry.getChatComponentSerializer(true)), Optional.of(WrappedChatComponent.fromJson(GsonComponentSerializer.gson().serialize(component)).getHandle()));
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(3, serializer1), true);
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(5, serializer1), true);
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(3, WrappedDataWatcher.Registry.get(Boolean.class)), true);
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(5, WrappedDataWatcher.Registry.get(Boolean.class)), true);
byte mask1 = 0x20;
byte mask2 = 0x01;
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, serializer2), mask1);
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(15, serializer2), mask2);
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, WrappedDataWatcher.Registry.get(Byte.class)), mask1);
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(15, WrappedDataWatcher.Registry.get(Byte.class)), mask2);
metaPacket.getModifier().write(0, id);
if (CustomCrops.getInstance().getVersionHelper().isVersionNewerThan1_19_R2()) {
setWrappedDataValue(metaPacket, wrappedDataWatcher);
@@ -132,16 +129,24 @@ public class FakeEntityUtils {
PacketContainer metaPacket = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
metaPacket.getModifier().write(0, id);
WrappedDataWatcher wrappedDataWatcher = new WrappedDataWatcher();
wrappedDataWatcher.setObject(22, itemStack);
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(22, WrappedDataWatcher.Registry.getItemStackSerializer(false)), itemStack);
setWrappedDataValue(metaPacket, wrappedDataWatcher);
return metaPacket;
}
public static PacketContainer getTextDisplayMetaPacket(int id, Component component) {
public static PacketContainer getTextDisplayMetaPacket(int id, Component component, TextDisplayMeta textDisplayMeta) {
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()));
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(22, WrappedDataWatcher.Registry.getChatComponentSerializer(false)), WrappedChatComponent.fromJson(GsonComponentSerializer.gson().serialize(component)));
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(24, WrappedDataWatcher.Registry.get(Integer.class)), textDisplayMeta.getBackgroundColor());
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(14, WrappedDataWatcher.Registry.get(Byte.class)), (byte) 3);
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(25, WrappedDataWatcher.Registry.get(Byte.class)), textDisplayMeta.getOpacity());
int mask = 0;
if (textDisplayMeta.isHasShadow()) mask += 1;
if (textDisplayMeta.isSeeThrough()) mask += 2;
if (textDisplayMeta.isUseDefaultBackground()) mask += 4;
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(26, WrappedDataWatcher.Registry.get(Byte.class)), (byte) mask);
setWrappedDataValue(metaPacket, wrappedDataWatcher);
return metaPacket;
}

View File

@@ -27,5 +27,7 @@ public class CustomCropsCommand extends AbstractMainCommand {
regSubCommand(HelpCommand.INSTANCE);
regSubCommand(AboutCommand.INSTANCE);
regSubCommand(SetDateCommand.INSTANCE);
regSubCommand(ForceCommand.INSTANCE);
regSubCommand(MigrateCommand.INSTANCE);
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customcrops.command.subcmd;
import net.momirealms.customcrops.command.AbstractSubCommand;
import net.momirealms.customcrops.command.subcmd.force.ConsumeTaskCommand;
import net.momirealms.customcrops.command.subcmd.force.SprinklerWorkCommand;
public class ForceCommand extends AbstractSubCommand {
public static final ForceCommand INSTANCE = new ForceCommand();
public ForceCommand() {
super("force");
regSubCommand(SprinklerWorkCommand.INSTANCE);
regSubCommand(ConsumeTaskCommand.INSTANCE);
}
}

View File

@@ -0,0 +1,175 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customcrops.command.subcmd;
import com.google.gson.*;
import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.api.object.basic.ConfigManager;
import net.momirealms.customcrops.api.object.crop.GrowingCrop;
import net.momirealms.customcrops.api.object.fertilizer.Fertilizer;
import net.momirealms.customcrops.api.object.fertilizer.FertilizerConfig;
import net.momirealms.customcrops.api.object.migrate.MigrateWorld;
import net.momirealms.customcrops.api.object.season.CCSeason;
import net.momirealms.customcrops.api.object.season.SeasonData;
import net.momirealms.customcrops.api.object.world.SimpleLocation;
import net.momirealms.customcrops.api.util.AdventureUtils;
import net.momirealms.customcrops.command.AbstractSubCommand;
import org.apache.commons.lang3.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class MigrateCommand extends AbstractSubCommand {
public static final MigrateCommand INSTANCE = new MigrateCommand();
public MigrateCommand() {
super("migrate");
}
@Override
public boolean onCommand(CommandSender sender, List<String> args) {
if (sender instanceof Player player) {
AdventureUtils.playerMessage(player, "Migration started. See the console for more information.");
}
AdventureUtils.consoleMessage("[CustomCrops] Migration has started.");
Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.getInstance(), new MigrationTask());
return true;
}
public static class MigrationTask implements Runnable {
@Override
public void run() {
File outer_folder = new File(CustomCrops.getInstance().getDataFolder().getAbsoluteFile().getParentFile().getParentFile() + ConfigManager.worldFolderPath);
if (!outer_folder.isDirectory()) {
AdventureUtils.consoleMessage("<red>[CustomCrops] World folder is not detected");
return;
}
File[] files = outer_folder.listFiles();
if (files == null) return;
List<File> world_folders = Arrays.stream(files).filter(File::isDirectory).toList();
for (File world_folder : world_folders) {
File ccDataFolder = new File(world_folder, "customcrops_data");
if (!ccDataFolder.isDirectory()) continue;
String worldName = world_folder.getName();
AdventureUtils.consoleMessage("<green>[CustomCrops] Migrating world: " + worldName);
MigrateWorld migrateWorld = new MigrateWorld(worldName);
migrateWorld.init();
try {
JsonElement json = JsonParser.parseReader(new FileReader(new File(ccDataFolder, "season.json")));
if (json.isJsonObject()) {
JsonObject jsonObject = json.getAsJsonObject();
if (jsonObject.has("season")) {
JsonPrimitive jsonPrimitive = jsonObject.getAsJsonPrimitive("season");
String season = jsonPrimitive.getAsString();
CustomCrops.getInstance().getSeasonManager().loadSeasonData(new SeasonData(worldName, CCSeason.valueOf(season), 1));
}
}
} catch (FileNotFoundException ignored) {
}
AdventureUtils.consoleMessage("<white>[CustomCrops] Migrated " + worldName + "'s season");
try {
JsonElement json= JsonParser.parseReader(new FileReader(new File(ccDataFolder, "pot.json")));
if (json.isJsonObject()) {
JsonObject jsonObject = json.getAsJsonObject();
if (jsonObject.has("pot")) {
JsonArray jsonArray = jsonObject.getAsJsonArray("pot");
for (JsonElement jsonElement : jsonArray) {
String loc = jsonElement.getAsString();
String[] locs = StringUtils.split(loc, ",");
SimpleLocation simpleLocation = new SimpleLocation(worldName, Integer.parseInt(locs[0]), Integer.parseInt(locs[1]), Integer.parseInt(locs[2]));
migrateWorld.addWaterToPot(simpleLocation, 1, "default");
}
}
}
} catch (FileNotFoundException ignored) {
}
AdventureUtils.consoleMessage("<white>[CustomCrops] Migrated " + worldName + "'s pots");
YamlConfiguration data = YamlConfiguration.loadConfiguration(new File(ccDataFolder, "fertilizers.yml"));
for (String key : data.getKeys(false)) {
String[] loc = StringUtils.split(key, ",");
SimpleLocation location = new SimpleLocation(worldName, Integer.parseInt(loc[0]), Integer.parseInt(loc[1]), Integer.parseInt(loc[2]));
String fertilizer = data.getString(key + ".type");
int times = data.getInt(key + ".times");
FertilizerConfig fertilizerConfig = CustomCrops.getInstance().getFertilizerManager().getConfigByKey(fertilizer);
if (fertilizerConfig != null) {
Fertilizer fertilizer1 = new Fertilizer(fertilizerConfig);
fertilizer1.setTimes(times);
migrateWorld.addFertilizerToPot(location, fertilizer1, "default");
}
}
AdventureUtils.consoleMessage("<white>[CustomCrops] Migrated " + worldName + "'s fertilizers");
try {
JsonElement json= JsonParser.parseReader(new FileReader(new File(ccDataFolder, "scarecrow.json")));
if (json.isJsonObject()) {
JsonObject jsonObject = json.getAsJsonObject();
for (Map.Entry<String, JsonElement> en : jsonObject.entrySet()) {
JsonArray jsonArray = en.getValue().getAsJsonArray();
int size = jsonArray.size();
for (int i = 0; i < size; i++) {
String[] loc = StringUtils.split(jsonArray.get(i).getAsString(), ",");
migrateWorld.addScarecrow(new SimpleLocation(worldName, Integer.parseInt(loc[0]), Integer.parseInt(loc[1]), Integer.parseInt(loc[2])));
}
}
}
}
catch (FileNotFoundException ignore) {
}
AdventureUtils.consoleMessage("<white>[CustomCrops] Migrated " + worldName + "'s scarecrows");
YamlConfiguration cropData = YamlConfiguration.loadConfiguration(new File(ccDataFolder, "crops.yml"));
for (Map.Entry<String, Object> entry : cropData.getValues(false).entrySet()) {
String crop = (String) entry.getValue();
GrowingCrop growingCrop;
if (crop.contains("_")) {
String stageStr = crop.substring(crop.indexOf("_stage_") + 7);
int stage = Integer.parseInt(stageStr);
growingCrop = new GrowingCrop(crop.substring(0, crop.indexOf("_stage_")), stage);
String[] loc = StringUtils.split(entry.getKey(), ",");
SimpleLocation simpleLocation = new SimpleLocation(worldName, Integer.parseInt(loc[0]), Integer.parseInt(loc[1]), Integer.parseInt(loc[2]));
migrateWorld.addCropData(simpleLocation, growingCrop);
}
}
AdventureUtils.consoleMessage("<white>[CustomCrops] Migrated " + worldName + "'s crops");
migrateWorld.disable();
}
AdventureUtils.consoleMessage("<green>[CustomCrops] Migration finished!");
}
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customcrops.command.subcmd.force;
import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.api.object.basic.MessageManager;
import net.momirealms.customcrops.api.object.world.CCWorld;
import net.momirealms.customcrops.api.util.AdventureUtils;
import net.momirealms.customcrops.command.AbstractSubCommand;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.generator.WorldInfo;
import java.util.List;
import java.util.stream.Collectors;
public class ConsumeTaskCommand extends AbstractSubCommand {
public static final ConsumeTaskCommand INSTANCE = new ConsumeTaskCommand();
public ConsumeTaskCommand() {
super("consume");
}
@Override
public boolean onCommand(CommandSender sender, List<String> args) {
if (lackArgs(sender, 1, args.size())) return true;
World world = Bukkit.getWorld(args.get(0));
if (world == null) {
AdventureUtils.sendMessage(sender, MessageManager.prefix + MessageManager.worldNotExist.replace("{world}", args.get(0)));
return true;
}
CustomCrops.getInstance().getScheduler().runTaskAsync(() -> {
CCWorld ccworld = CustomCrops.getInstance().getWorldDataManager().getWorld(args.get(0));
if (ccworld != null) {
ccworld.scheduleConsumeTask();
}
});
return true;
}
@Override
public List<String> onTabComplete(CommandSender sender, List<String> args) {
if (args.size() == 1) {
return super.filterStartingWith(Bukkit.getWorlds().stream().filter(world -> CustomCrops.getInstance().getWorldDataManager().isWorldAllowed(world)).map(WorldInfo::getName).collect(Collectors.toList()), args.get(0));
}
return null;
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customcrops.command.subcmd.force;
import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.api.object.basic.MessageManager;
import net.momirealms.customcrops.api.object.world.CCWorld;
import net.momirealms.customcrops.api.util.AdventureUtils;
import net.momirealms.customcrops.command.AbstractSubCommand;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.generator.WorldInfo;
import java.util.List;
import java.util.stream.Collectors;
public class SprinklerWorkCommand extends AbstractSubCommand {
public static final SprinklerWorkCommand INSTANCE = new SprinklerWorkCommand();
public SprinklerWorkCommand() {
super("sprinklerwork");
}
@Override
public boolean onCommand(CommandSender sender, List<String> args) {
if (lackArgs(sender, 1, args.size())) return true;
World world = Bukkit.getWorld(args.get(0));
if (world == null) {
AdventureUtils.sendMessage(sender, MessageManager.prefix + MessageManager.worldNotExist.replace("{world}", args.get(0)));
return true;
}
CustomCrops.getInstance().getScheduler().runTaskAsync(() -> {
CCWorld ccworld = CustomCrops.getInstance().getWorldDataManager().getWorld(args.get(0));
if (ccworld != null) {
ccworld.scheduleSprinklerWork();
}
});
return true;
}
@Override
public List<String> onTabComplete(CommandSender sender, List<String> args) {
if (args.size() == 1) {
return super.filterStartingWith(Bukkit.getWorlds().stream().filter(world -> CustomCrops.getInstance().getWorldDataManager().isWorldAllowed(world)).map(WorldInfo::getName).collect(Collectors.toList()), args.get(0));
}
return null;
}
}

View File

@@ -27,6 +27,10 @@ import net.momirealms.customcrops.integration.item.MMOItemsItemImpl;
import net.momirealms.customcrops.integration.job.EcoJobsImpl;
import net.momirealms.customcrops.integration.job.JobsRebornImpl;
import net.momirealms.customcrops.integration.papi.PlaceholderManager;
import net.momirealms.customcrops.integration.quest.BattlePassCCQuest;
import net.momirealms.customcrops.integration.quest.BetonQuestCCQuest;
import net.momirealms.customcrops.integration.quest.ClueScrollCCQuest;
import net.momirealms.customcrops.integration.quest.LegacyBetonQuestCCQuest;
import net.momirealms.customcrops.integration.season.CustomCropsSeasonImpl;
import net.momirealms.customcrops.integration.season.RealisticSeasonsImpl;
import net.momirealms.customcrops.integration.skill.AureliumsImpl;
@@ -56,6 +60,7 @@ public class IntegrationManager extends Function {
this.plugin = plugin;
this.pluginManager = Bukkit.getPluginManager();
this.placeholderManager = new PlaceholderManager(plugin);
this.registerQuests();
}
@Override
@@ -141,6 +146,21 @@ public class IntegrationManager extends Function {
return new ItemStack(Material.AIR);
}
private void registerQuests() {
PluginManager pluginManager = Bukkit.getPluginManager();
if (pluginManager.isPluginEnabled("ClueScrolls")) {
ClueScrollCCQuest quest = new ClueScrollCCQuest(plugin);
Bukkit.getPluginManager().registerEvents(quest, plugin);
}
if (pluginManager.isPluginEnabled("BetonQuest")) {
if (Bukkit.getPluginManager().getPlugin("BetonQuest").getDescription().getVersion().startsWith("2")) BetonQuestCCQuest.register();
else LegacyBetonQuestCCQuest.register();
}
if (pluginManager.isPluginEnabled("BattlePass")) {
BattlePassCCQuest.register();
}
}
@Nullable
public SkillInterface getSkillInterface() {
return skillInterface;

View File

@@ -0,0 +1,45 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customcrops.integration.quest;
import io.github.battlepass.BattlePlugin;
import io.github.battlepass.quests.quests.external.executor.ExternalQuestExecutor;
import io.github.battlepass.registry.quest.QuestRegistry;
import net.momirealms.customcrops.api.event.CropBreakEvent;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
public class BattlePassCCQuest extends ExternalQuestExecutor implements Listener {
public static void register() {
QuestRegistry questRegistry = BattlePlugin.getApi().getQuestRegistry();
questRegistry.hook("customcrops", BattlePassCCQuest::new);
}
public BattlePassCCQuest(BattlePlugin battlePlugin) {
super(battlePlugin, "customcrops");
}
@EventHandler
public void onHarvest(CropBreakEvent event) {
if (event.isCancelled()) return;
Player player = event.getPlayer();
this.execute("harvest", player, (var1x) -> var1x.root(event.getCropItemID()));
}
}

View File

@@ -0,0 +1,113 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customcrops.integration.quest;
import net.momirealms.customcrops.api.event.CropBreakEvent;
import net.momirealms.customcrops.api.util.AdventureUtils;
import org.betonquest.betonquest.BetonQuest;
import org.betonquest.betonquest.Instruction;
import org.betonquest.betonquest.VariableNumber;
import org.betonquest.betonquest.api.CountingObjective;
import org.betonquest.betonquest.api.profiles.OnlineProfile;
import org.betonquest.betonquest.api.profiles.Profile;
import org.betonquest.betonquest.exceptions.InstructionParseException;
import org.betonquest.betonquest.utils.PlayerConverter;
import org.betonquest.betonquest.utils.location.CompoundLocation;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import java.util.Collections;
import java.util.HashSet;
public class BetonQuestCCQuest extends CountingObjective implements Listener {
private final CompoundLocation playerLocation;
private final VariableNumber rangeVar;
private final HashSet<String> crop_ids;
public BetonQuestCCQuest(Instruction instruction) throws InstructionParseException {
super(instruction, "crop_to_harvest");
crop_ids = new HashSet<>();
Collections.addAll(crop_ids, instruction.getArray());
targetAmount = instruction.getInt();
final String pack = instruction.getPackage().getQuestPath();
final String loc = instruction.getOptional("playerLocation");
final String range = instruction.getOptional("range");
if (loc != null && range != null) {
playerLocation = new CompoundLocation(pack, loc);
rangeVar = new VariableNumber(pack, range);
} else {
playerLocation = null;
rangeVar = null;
}
if (targetAmount <= 0) {
throw new InstructionParseException("Crop amount cannot be less than 0");
}
}
public static void register() {
BetonQuest.getInstance().registerObjectives("customcrops", BetonQuestCCQuest.class);
}
@EventHandler
public void onHarvest(CropBreakEvent event) {
OnlineProfile onlineProfile = PlayerConverter.getID(event.getPlayer());
if (!containsPlayer(onlineProfile)) {
return;
}
if (isInvalidLocation(event, onlineProfile)) {
return;
}
if (this.crop_ids.contains(event.getCropItemID()) && this.checkConditions(onlineProfile)) {
getCountingData(onlineProfile).progress(1);
completeIfDoneOrNotify(onlineProfile);
}
}
private boolean isInvalidLocation(CropBreakEvent event, final Profile profile) {
if (playerLocation == null || rangeVar == null) {
return false;
}
final Location targetLocation;
try {
targetLocation = playerLocation.getLocation(profile);
} catch (final org.betonquest.betonquest.exceptions.QuestRuntimeException e) {
AdventureUtils.consoleMessage(e.getMessage());
return true;
}
final int range = rangeVar.getInt(profile);
final Location playerLoc = event.getPlayer().getLocation();
return !playerLoc.getWorld().equals(targetLocation.getWorld()) || targetLocation.distanceSquared(playerLoc) > range * range;
}
@Override
public void start() {
Bukkit.getPluginManager().registerEvents(this, BetonQuest.getInstance());
}
@Override
public void stop() {
HandlerList.unregisterAll(this);
}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customcrops.integration.quest;
import com.electro2560.dev.cluescrolls.api.*;
import net.momirealms.customcrops.api.event.CropBreakEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin;
public class ClueScrollCCQuest implements Listener {
private final CustomClue commonClue;
public ClueScrollCCQuest(Plugin plugin) {
commonClue = ClueScrollsAPI.getInstance().registerCustomClue(plugin, "harvest", new ClueConfigData("crop_id", DataType.STRING));
}
@EventHandler
public void onHarvest(CropBreakEvent event) {
if (event.isCancelled()) return;
commonClue.handle(event.getPlayer(), 1, new ClueDataPair("crop_id", event.getCropItemID()));
}
}

View File

@@ -0,0 +1,156 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customcrops.integration.quest;
import net.momirealms.customcrops.api.event.CropBreakEvent;
import net.momirealms.customcrops.api.util.AdventureUtils;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import pl.betoncraft.betonquest.BetonQuest;
import pl.betoncraft.betonquest.Instruction;
import pl.betoncraft.betonquest.api.Objective;
import pl.betoncraft.betonquest.config.Config;
import pl.betoncraft.betonquest.exceptions.InstructionParseException;
import pl.betoncraft.betonquest.exceptions.QuestRuntimeException;
import pl.betoncraft.betonquest.utils.LogUtils;
import pl.betoncraft.betonquest.utils.PlayerConverter;
import java.util.Collections;
import java.util.HashSet;
import java.util.Locale;
import java.util.logging.Level;
public class LegacyBetonQuestCCQuest extends Objective implements Listener {
private final HashSet<String> crop_ids = new HashSet<>();
private final int amount;
private final boolean notify;
private final int notifyInterval;
public LegacyBetonQuestCCQuest(Instruction instruction) throws InstructionParseException {
super(instruction);
this.template = CropData.class;
this.notifyInterval = instruction.getInt(instruction.getOptional("notify"), 1);
this.notify = instruction.hasArgument("notify") || this.notifyInterval > 1;
this.amount = instruction.getInt(instruction.getOptional("amount"), 1);
Collections.addAll(this.crop_ids, instruction.getArray());
}
public static void register() {
BetonQuest.getInstance().registerObjectives("customfishing", LegacyBetonQuestCCQuest.class);
}
@Override
public void start() {
Bukkit.getPluginManager().registerEvents(this, BetonQuest.getInstance());
}
@Override
public void stop() {
HandlerList.unregisterAll(this);
}
@Override
public String getDefaultDataInstruction() {
return Integer.toString(this.amount);
}
@Override
public String getProperty(String name, String playerID) {
return switch (name.toLowerCase(Locale.ROOT)) {
case "amount" ->
Integer.toString(this.amount - ((LegacyBetonQuestCCQuest.CropData) this.dataMap.get(playerID)).getAmount());
case "left" -> Integer.toString(((LegacyBetonQuestCCQuest.CropData) this.dataMap.get(playerID)).getAmount());
case "total" -> Integer.toString(this.amount);
default -> "";
};
}
private boolean isValidPlayer(Player player) {
if (player == null) {
return false;
} else {
return player.isOnline() && player.isValid();
}
}
@EventHandler
public void onHarvest(CropBreakEvent event) {
String playerID = PlayerConverter.getID(event.getPlayer());
if (this.containsPlayer(playerID)) {
if (this.crop_ids.contains(event.getCropItemID())) {
if (this.checkConditions(playerID)) {
if (!isValidPlayer(event.getPlayer())) {
return;
}
CropData cropData = (CropData) this.dataMap.get(playerID);
cropData.harvest(1);
if (cropData.finished()) {
this.completeObjective(playerID);
}
else if (this.notify && cropData.getAmount() % this.notifyInterval == 0) {
try {
Config.sendNotify(this.instruction.getPackage().getName(), playerID, "crop_to_harvest", new String[]{String.valueOf(cropData.getAmount())}, "crop_to_harvest,info");
} catch (QuestRuntimeException e1) {
try {
LogUtils.getLogger().log(Level.WARNING, "The notify system was unable to play a sound for the 'crop_to_harvest' category in '" + this.instruction.getObjective().getFullID() + "'. Error was: '" + e1.getMessage() + "'");
} catch (InstructionParseException e2) {
LogUtils.logThrowableReport(e2);
}
}
}
}
}
}
}
public static class CropData extends Objective.ObjectiveData {
private int amount;
public CropData(String instruction, String playerID, String objID) {
super(instruction, playerID, objID);
try {
this.amount = Integer.parseInt(instruction);
}
catch (NumberFormatException e) {
AdventureUtils.consoleMessage("[CustomCrops] NumberFormatException");
this.amount = 1;
}
}
public void harvest(int caughtAmount) {
this.amount -= caughtAmount;
this.update();
}
public int getAmount() {
return this.amount;
}
public String toString() {
return String.valueOf(this.amount);
}
public boolean finished() {
return this.amount <= 0;
}
}
}