9
0
mirror of https://github.com/Xiao-MoMi/Custom-Crops.git synced 2025-12-27 02:49:11 +00:00
This commit is contained in:
XiaoMoMi
2023-07-26 21:03:13 +08:00
parent ca94e80feb
commit 8754add61a
7 changed files with 145 additions and 158 deletions

View File

@@ -19,7 +19,10 @@ package net.momirealms.customcrops.api.object;
import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.api.object.action.Action;
import net.momirealms.customcrops.api.object.requirement.CurrentState;
import net.momirealms.customcrops.api.object.requirement.Requirement;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
@@ -58,8 +61,14 @@ public class InteractCrop {
return actions;
}
@Nullable
public Requirement[] getRequirements() {
return requirements;
public boolean canInteract(Player player, Location location) {
if (requirements == null) return true;
CurrentState currentState = new CurrentState(location, player);
for (Requirement requirement : requirements) {
if (!requirement.isConditionMet(currentState)) {
return false;
}
}
return true;
}
}

View File

@@ -22,7 +22,10 @@ import net.momirealms.customcrops.api.object.ItemMode;
import net.momirealms.customcrops.api.object.action.Action;
import net.momirealms.customcrops.api.object.condition.Condition;
import net.momirealms.customcrops.api.object.condition.DeathCondition;
import net.momirealms.customcrops.api.object.requirement.CurrentState;
import net.momirealms.customcrops.api.object.requirement.Requirement;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -127,4 +130,26 @@ public class CropConfig {
public boolean isRotationEnabled() {
return rotation;
}
public boolean canPlant(Player player, Location location) {
if (plantRequirements == null) return true;
CurrentState currentState = new CurrentState(location, player);
for (Requirement requirement : plantRequirements) {
if (!requirement.isConditionMet(currentState)) {
return false;
}
}
return true;
}
public boolean canBreak(Player player, Location location) {
if (breakRequirements == null) return true;
CurrentState currentState = new CurrentState(location, player);
for (Requirement requirement : breakRequirements) {
if (!requirement.isConditionMet(currentState)) {
return false;
}
}
return true;
}
}

View File

@@ -18,8 +18,11 @@
package net.momirealms.customcrops.api.object.fertilizer;
import net.kyori.adventure.sound.Sound;
import net.momirealms.customcrops.api.object.requirement.CurrentState;
import net.momirealms.customcrops.api.object.requirement.Requirement;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
public abstract class FertilizerConfig {
@@ -105,4 +108,15 @@ public abstract class FertilizerConfig {
public Requirement[] getRequirements() {
return requirements;
}
public boolean canUse(Player player, Location location) {
if (requirements == null) return true;
CurrentState currentState = new CurrentState(location, player);
for (Requirement requirement : requirements) {
if (!requirement.isConditionMet(currentState)) {
return false;
}
}
return true;
}
}

View File

@@ -23,6 +23,7 @@ import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.momirealms.customcrops.api.object.fill.PositiveFillMethod;
import net.momirealms.customcrops.api.object.requirement.CurrentState;
import net.momirealms.customcrops.api.object.requirement.Requirement;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
@@ -165,7 +166,26 @@ public class WateringCanConfig {
return Optional.ofNullable(appearanceMap.get(water)).orElse(0);
}
public Requirement[] getRequirements() {
return requirements;
public boolean canUse(Player player, Location location) {
if (requirements == null) return true;
CurrentState currentState = new CurrentState(location, player);
for (Requirement requirement : requirements) {
if (!requirement.isConditionMet(currentState)) {
return false;
}
}
return true;
}
public boolean isWhiteListedPot(String potID) {
if (potWhitelist != null) {
inner: {
for (String pot : potWhitelist)
if (pot.equals(potID))
break inner;
return false;
}
}
return true;
}
}

View File

@@ -57,13 +57,15 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.*;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.*;
import java.util.concurrent.*;
public class CCWorld extends Function {
private final String worldName;
private final World world;
private final Reference<World> world;
private final ConcurrentHashMap<ChunkCoordinate, CCChunk> chunkMap;
private final ScheduledThreadPoolExecutor schedule;
private long currentDay;
@@ -86,7 +88,7 @@ public class CCWorld extends Function {
this.chunksFolder = ConfigUtils.getFile(world, "chunks");
this.dateFile = ConfigUtils.getFile(world, "data.yml");
this.corruptedFile = ConfigUtils.getFile(world, "corrupted.yml");
this.world = world;
this.world = new WeakReference<>(world);
this.chunkMap = new ConcurrentHashMap<>(64);
this.schedule = new ScheduledThreadPoolExecutor(ConfigManager.corePoolSize);
this.schedule.setMaximumPoolSize(ConfigManager.maxPoolSize);
@@ -127,7 +129,7 @@ public class CCWorld extends Function {
}
public void unload() {
if (this.timerTask != null) {
if (this.timerTask != null && !this.timerTask.isCancelled()) {
this.timerTask.cancel(false);
this.timerTask = null;
}
@@ -235,17 +237,18 @@ public class CCWorld extends Function {
private void scheduleTask() {
if (this.timerTask == null) {
this.timerTask = plugin.getScheduler().runTaskTimerAsync(() -> {
if (world != null) {
World worldInstance = world.get();
if (worldInstance != null) {
if (ConfigManager.debugScheduler) {
Log.info("Queue size: " + schedule.getQueue().size() + " Completed: " + schedule.getCompletedTaskCount());
}
long day = world.getFullTime() / 24000;
long time = world.getTime();
long day = worldInstance.getFullTime() / 24000;
long time = worldInstance.getTime();
this.tryDayCycleTask(time, day);
this.timerTask();
} else {
AdventureUtils.consoleMessage("<red>[CustomCrops] World: " + worldName + " unloaded unexpectedly. Shutdown the schedule.");
this.schedule.shutdown();
this.disable();
}
}, 1000, 1000L);
}
@@ -311,6 +314,9 @@ public class CCWorld extends Function {
private void closePool() {
this.schedule.shutdown();
if (this.timerTask != null && !this.timerTask.isCancelled()) {
this.timerTask.cancel(false);
}
}
@SuppressWarnings("ResultOfMethodCallIgnored")
@@ -448,7 +454,7 @@ public class CCWorld extends Function {
return;
}
if (world.isChunkLoaded(simpleLocation.getX() >> 4, simpleLocation.getZ() >> 4)) {
if (world.get().isChunkLoaded(simpleLocation.getX() >> 4, simpleLocation.getZ() >> 4)) {
replacePot(simpleLocation, pot, potConfig);
return;
}
@@ -533,7 +539,7 @@ public class CCWorld extends Function {
SprinklerAnimation sprinklerAnimation = sprinklerConfig.getSprinklerAnimation();
if (world.isChunkLoaded(simpleLocation.getX() >> 4, simpleLocation.getZ() >> 4) && sprinklerAnimation != null) {
if (world.get().isChunkLoaded(simpleLocation.getX() >> 4, simpleLocation.getZ() >> 4) && sprinklerAnimation != null) {
for (Player player : Bukkit.getOnlinePlayers()) {
SimpleLocation playerLoc = SimpleLocation.getByBukkitLocation(player.getLocation());
if (playerLoc.isNear(simpleLocation, 48)) {
@@ -572,7 +578,7 @@ public class CCWorld extends Function {
@Override
public void run() {
if (world.isChunkLoaded(simpleLocation.getX() >> 4, simpleLocation.getZ() >> 4)) {
if (world.get().isChunkLoaded(simpleLocation.getX() >> 4, simpleLocation.getZ() >> 4)) {
replacePot(simpleLocation, amount, whitelist);
return;
}
@@ -584,7 +590,7 @@ public class CCWorld extends Function {
return;
}
CompletableFuture<Chunk> asyncGetChunk = world.getChunkAtAsync(simpleLocation.getX() >> 4, simpleLocation.getZ() >> 4);
CompletableFuture<Chunk> asyncGetChunk = world.get().getChunkAtAsync(simpleLocation.getX() >> 4, simpleLocation.getZ() >> 4);
asyncGetChunk.whenComplete((result, throwable) -> replacePot(simpleLocation, amount, whitelist));
}
}
@@ -721,7 +727,7 @@ public class CCWorld extends Function {
String finalNextModel = nextModel;
if (finalNextModel == null || location == null) return;
if (world.isChunkLoaded(location.getBlockX() >> 4, location.getBlockZ() >> 4)) {
if (world.get().isChunkLoaded(location.getBlockX() >> 4, location.getBlockZ() >> 4)) {
switch (itemMode) {
case ITEM_FRAME -> replaceItemFrameCrop(location, finalNextModel, cropConfig.isRotationEnabled());
case ITEM_DISPLAY -> replaceItemDisplayCrop(location, finalNextModel, cropConfig.isRotationEnabled());

View File

@@ -432,13 +432,8 @@ public class PlatformManager extends Function {
WateringCanConfig wateringCanConfig = plugin.getWateringCanManager().getConfigByItemID(item_in_hand_id);
if (wateringCanConfig != null) {
if (wateringCanConfig.getRequirements() != null) {
CurrentState currentState = new CurrentState(location, player);
for (Requirement requirement : wateringCanConfig.getRequirements()) {
if (!requirement.isConditionMet(currentState)) {
return true;
}
}
if (!wateringCanConfig.canUse(player, location)) {
return true;
}
String[] sprinkler_whitelist = wateringCanConfig.getSprinklerWhitelist();
@@ -579,18 +574,10 @@ public class PlatformManager extends Function {
if (item_in_hand_id.equals("AIR")) {
InteractCrop interactCrop = stageConfig.getInteractByHand();
if (interactCrop != null) {
Requirement[] requirements = interactCrop.getRequirements();
if (requirements != null) {
CurrentState currentState = new CurrentState(location, player);
for (Requirement requirement : requirements) {
if (!requirement.isConditionMet(currentState)) {
return true;
}
}
}
for (Action action : interactCrop.getActions()) {
if (interactCrop.canInteract(player, location))
return true;
for (Action action : interactCrop.getActions())
action.doOn(player, SimpleLocation.getByBukkitLocation(location), cropConfig.getCropMode());
}
}
return true;
}
@@ -623,35 +610,19 @@ public class PlatformManager extends Function {
WateringCanConfig wateringCanConfig = plugin.getWateringCanManager().getConfigByItemID(item_in_hand_id);
if (wateringCanConfig != null) {
if (wateringCanConfig.getRequirements() != null) {
CurrentState currentState = new CurrentState(location, player);
for (Requirement requirement : wateringCanConfig.getRequirements()) {
if (!requirement.isConditionMet(currentState)) {
return true;
}
}
}
if (!wateringCanConfig.canUse(player, location))
return true;
String[] pot_whitelist = wateringCanConfig.getPotWhitelist();
if (pot_whitelist != null) {
inner: {
for (String pot : pot_whitelist) {
if (pot.equals(pot_id)) {
break inner;
}
}
return true;
}
}
if (!wateringCanConfig.isWhiteListedPot(pot_id))
return true;
int current_water = plugin.getWateringCanManager().getCurrentWater(item_in_hand);
if (current_water <= 0) return true;
PotWaterEvent potWaterEvent = new PotWaterEvent(player, item_in_hand, 1, bottomLoc);
Bukkit.getPluginManager().callEvent(potWaterEvent);
if (potWaterEvent.isCancelled()) {
if (potWaterEvent.isCancelled())
return true;
}
current_water--;
this.waterPot(wateringCanConfig.getWidth(), wateringCanConfig.getLength(), bottomLoc, player.getLocation().getYaw(), pot_id, wateringCanConfig.getParticle(), potWaterEvent.getWater());
@@ -686,30 +657,24 @@ public class PlatformManager extends Function {
InteractCrop[] interactActions = stageConfig.getInteractCropWithItem();
if (interactActions != null) {
outer:
for (InteractCrop interactCrop : interactActions) {
if (interactCrop.isRightItem(item_in_hand_id)) {
Requirement[] requirements = interactCrop.getRequirements();
if (requirements != null) {
CurrentState currentState = new CurrentState(location, player);
for (Requirement requirement : requirements) {
if (!requirement.isConditionMet(currentState)) {
continue outer;
}
}
}
if (interactCrop.canInteract(player, location))
continue;
if (player.getGameMode() != GameMode.CREATIVE) {
if (interactCrop.isConsumed()) {
if (interactCrop.isConsumed())
item_in_hand.setAmount(item_in_hand.getAmount() - 1);
}
if (interactCrop.getReturned() != null) {
if (interactCrop.getReturned() != null)
player.getInventory().addItem(interactCrop.getReturned());
}
}
Action[] inAc = interactCrop.getActions();
if (inAc != null) {
for (Action action : inAc) {
action.doOn(player, SimpleLocation.getByBukkitLocation(location), cropConfig.getCropMode());
action.doOn(
player,
SimpleLocation.getByBukkitLocation(location),
cropConfig.getCropMode()
);
}
}
return true;
@@ -721,24 +686,20 @@ public class PlatformManager extends Function {
public boolean onInteractPot(Player player, String id, Location location, ItemStack item_in_hand, String item_in_hand_id, Cancellable event) {
String pot_id = plugin.getPotManager().getPotKeyByBlockID(id);
if (pot_id == null) {
if (pot_id == null)
return false;
}
PotConfig potConfig = plugin.getPotManager().getPotConfig(pot_id);
if (potConfig == null) {
if (potConfig == null)
return false;
}
if (!ProtectionLib.canPlace(player, location)) {
if (!ProtectionLib.canPlace(player, location))
return true;
}
PotInteractEvent potInteractEvent = new PotInteractEvent(player, item_in_hand, location, pot_id);
Bukkit.getPluginManager().callEvent(potInteractEvent);
if (potInteractEvent.isCancelled()) {
if (potInteractEvent.isCancelled())
return true;
}
outer: {
// plant
@@ -756,17 +717,12 @@ public class PlatformManager extends Function {
}
Location crop_loc = location.clone().add(0,1,0);
Requirement[] requirements = cropConfig.getPlantRequirements();
if (requirements != null) {
CurrentState currentState = new CurrentState(crop_loc, player);
for (Requirement requirement : requirements) {
if (!requirement.isConditionMet(currentState)) {
return true;
}
}
}
if (!cropConfig.canPlant(player, crop_loc))
return true;
if (plugin.getPlatformInterface().detectAnyThing(crop_loc))
return true;
if (plugin.getPlatformInterface().detectAnyThing(crop_loc)) return true;
if (ConfigManager.enableLimitation && plugin.getWorldDataManager().getChunkCropAmount(SimpleLocation.getByBukkitLocation(crop_loc)) >= plugin.getConfigManager().getCropLimit(location.getWorld().getName())) {
AdventureUtils.playerMessage(player, MessageManager.prefix + MessageManager.reachChunkLimit);
return true;
@@ -775,9 +731,8 @@ public class PlatformManager extends Function {
String crop_model = Objects.requireNonNull(cropConfig.getStageConfig(0)).getModel();
CropPlantEvent cropPlantEvent = new CropPlantEvent(player, item_in_hand, location, cropConfig.getKey(), 0, crop_model);
Bukkit.getPluginManager().callEvent(cropPlantEvent);
if (cropPlantEvent.isCancelled()) {
if (cropPlantEvent.isCancelled())
return true;
}
Action[] plantActions = cropConfig.getPlantActions();
if (plantActions != null) {
@@ -812,9 +767,8 @@ public class PlatformManager extends Function {
PotWaterEvent potWaterEvent = new PotWaterEvent(player, item_in_hand, passiveFillMethod.getAmount(), location);
Bukkit.getPluginManager().callEvent(potWaterEvent);
if (potWaterEvent.isCancelled()) {
if (potWaterEvent.isCancelled())
return true;
}
event.setCancelled(true);
doPassiveFillAction(player, item_in_hand, passiveFillMethod, location.clone().add(0,1,0));
@@ -827,26 +781,20 @@ public class PlatformManager extends Function {
// use watering can
WateringCanConfig wateringCanConfig = plugin.getWateringCanManager().getConfigByItemID(item_in_hand_id);
if (wateringCanConfig != null) {
String[] pot_whitelist = wateringCanConfig.getPotWhitelist();
if (pot_whitelist != null) {
inner: {
for (String pot : pot_whitelist) {
if (pot.equals(pot_id)) {
break inner;
}
}
return true;
}
}
if (!wateringCanConfig.canUse(player, location))
return true;
if (!wateringCanConfig.isWhiteListedPot(pot_id))
return true;
int current_water = plugin.getWateringCanManager().getCurrentWater(item_in_hand);
if (current_water <= 0) return true;
PotWaterEvent potWaterEvent = new PotWaterEvent(player, item_in_hand, 1, location);
Bukkit.getPluginManager().callEvent(potWaterEvent);
if (potWaterEvent.isCancelled()) {
if (potWaterEvent.isCancelled())
return true;
}
current_water--;
this.waterPot(wateringCanConfig.getWidth(), wateringCanConfig.getLength(), location, player.getLocation().getYaw(), pot_id, wateringCanConfig.getParticle(), potWaterEvent.getWater());
@@ -858,20 +806,13 @@ public class PlatformManager extends Function {
FertilizerConfig fertilizerConfig = plugin.getFertilizerManager().getConfigByItemID(item_in_hand_id);
if (fertilizerConfig != null) {
if (fertilizerConfig.getRequirements() != null) {
CurrentState currentState = new CurrentState(location, player);
for (Requirement requirement : fertilizerConfig.getRequirements()) {
if (!requirement.isConditionMet(currentState)) {
return true;
}
}
}
if (!fertilizerConfig.canUse(player, location))
return true;
FertilizerUseEvent fertilizerUseEvent = new FertilizerUseEvent(player, item_in_hand, fertilizerConfig.getKey(), location);
Bukkit.getPluginManager().callEvent(fertilizerUseEvent);
if (fertilizerUseEvent.isCancelled()) {
if (fertilizerUseEvent.isCancelled())
return true;
}
if (fertilizerConfig.isBeforePlant() && plugin.getCropManager().containsStage(plugin.getPlatformInterface().getAnyItemIDAt(location.clone().add(0,1,0)))) {
AdventureUtils.playerMessage(player, MessageManager.prefix + MessageManager.beforePlant);
@@ -1002,15 +943,17 @@ public class PlatformManager extends Function {
// The entity might be other creatures when the pot is FARMLAND
// because of vanilla farmland mechanics
if (entity instanceof Player player) {
if (!canBreak(player, cropConfig, location)) {
if (!cropConfig.canBreak(player, location)) {
event.setCancelled(true);
return true;
}
CropBreakEvent cropBreakEvent = new CropBreakEvent(entity, cropConfig.getKey(), id, location);
Bukkit.getPluginManager().callEvent(cropBreakEvent);
if (cropBreakEvent.isCancelled()) {
if (cropBreakEvent.isCancelled())
return true;
}
if (player.getGameMode() != GameMode.CREATIVE) {
StageConfig stageConfig = plugin.getCropManager().getStageConfig(id);
if (stageConfig != null) {
@@ -1025,9 +968,9 @@ public class PlatformManager extends Function {
} else {
CropBreakEvent cropBreakEvent = new CropBreakEvent(entity, cropConfig.getKey(), id, location);
Bukkit.getPluginManager().callEvent(cropBreakEvent);
if (cropBreakEvent.isCancelled()) {
if (cropBreakEvent.isCancelled())
return true;
}
StageConfig stageConfig = plugin.getCropManager().getStageConfig(id);
if (stageConfig != null) {
Action[] breakActions = stageConfig.getBreakActions();
@@ -1042,18 +985,6 @@ public class PlatformManager extends Function {
return true;
}
public boolean canBreak(Player player, CropConfig cropConfig, Location crop_loc) {
Requirement[] requirements = cropConfig.getBreakRequirements();
if (requirements == null) return true;
CurrentState currentState = new CurrentState(crop_loc, player);
for (Requirement requirement : requirements) {
if (!requirement.isConditionMet(currentState)) {
return false;
}
}
return true;
}
private void waterPot(int width, int length, Location location, float yaw, String id, @Nullable Particle particle, int water){
int extend = width / 2;
if (yaw < 45 && yaw > -135) {
@@ -1111,7 +1042,6 @@ public class PlatformManager extends Function {
return false;
}
int current = plugin.getWateringCanManager().getCurrentWater(item_in_hand);
if (current >= wateringCanConfig.getStorage()) return true;
@@ -1119,18 +1049,11 @@ public class PlatformManager extends Function {
outer: {
if (id != null && location != null) {
if (!ProtectionLib.canPlace(player, location)) {
return true;
}
if (wateringCanConfig.getRequirements() != null) {
CurrentState currentState = new CurrentState(location, player);
for (Requirement requirement : wateringCanConfig.getRequirements()) {
if (!requirement.isConditionMet(currentState)) {
return true;
}
}
}
if (!ProtectionLib.canPlace(player, location))
return true;
if (!wateringCanConfig.canUse(player, location))
return true;
for (PositiveFillMethod positiveFillMethod : wateringCanConfig.getPositiveFillMethods()) {
if (positiveFillMethod.getId().equals(id)) {
@@ -1153,26 +1076,16 @@ public class PlatformManager extends Function {
int index = 0;
for (String blockId : blockIds) {
if (positiveFillMethod.getId().equals(blockId)) {
Block block = lineOfSight.get(index);
if (!ProtectionLib.canPlace(player, block.getLocation()))
return true;
if (wateringCanConfig.getRequirements() != null) {
CurrentState currentState = new CurrentState(block.getLocation(), player);
for (Requirement requirement : wateringCanConfig.getRequirements()) {
if (!requirement.isConditionMet(currentState)) {
return true;
}
}
}
if (!wateringCanConfig.canUse(player, location))
return true;
add = positiveFillMethod.getAmount();
if (positiveFillMethod.getSound() != null)
AdventureUtils.playerSound(player, positiveFillMethod.getSound());
if (positiveFillMethod.getParticle() != null)
block.getWorld().spawnParticle(positiveFillMethod.getParticle(), block.getLocation().add(0.5,1.1, 0.5),5,0.1,0.1,0.1);
break;
}
index++;