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

Fixed double check

This commit is contained in:
XiaoMoMi
2024-09-07 17:14:47 +08:00
parent 31e7a26ab5
commit eb3cb7b0d6
6 changed files with 199 additions and 177 deletions

View File

@@ -51,6 +51,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
public class CropBlock extends AbstractCustomCropsBlock {
@@ -292,91 +293,103 @@ public class CropBlock extends AbstractCustomCropsBlock {
private void tickCrop(CustomCropsBlockState state, CustomCropsWorld<?> world, Pos3 location, boolean offline) {
CropConfig config = config(state);
BukkitCustomCropsPlugin plugin = BukkitCustomCropsPlugin.getInstance();
if (config == null) {
BukkitCustomCropsPlugin.getInstance().getPluginLogger().warn("Crop data is removed at location[" + world.worldName() + "," + location + "] because the crop config[" + id(state) + "] has been removed.");
plugin.getPluginLogger().warn("Crop data is removed at location[" + world.worldName() + "," + location + "] because the crop config[" + id(state) + "] has been removed.");
world.removeBlockState(location);
return;
}
int previousPoint = point(state);
World bukkitWorld = world.bukkitWorld();
if (ConfigManager.doubleCheck()) {
Map.Entry<Integer, CropStageConfig> nearest = config.getFloorStageEntry(previousPoint);
String blockID = BukkitCustomCropsPlugin.getInstance().getItemManager().id(location.toLocation(bukkitWorld), nearest.getValue().existenceForm());
if (!config.stageIDs().contains(blockID)) {
BukkitCustomCropsPlugin.getInstance().getPluginLogger().warn("Crop[" + config.id() + "] is removed at location[" + world.worldName() + "," + location + "] because the id of the block is [" + blockID + "]");
world.removeBlockState(location);
return;
}
}
Location bukkitLocation = location.toLocation(bukkitWorld);
Context<CustomCropsBlockState> context = Context.block(state, bukkitLocation).arg(ContextKeys.OFFLINE, offline);
for (DeathCondition deathCondition : config.deathConditions()) {
if (deathCondition.isMet(context)) {
BukkitCustomCropsPlugin.getInstance().getScheduler().sync().runLater(() -> {
FurnitureRotation rotation = BukkitCustomCropsPlugin.getInstance().getItemManager().remove(bukkitLocation, ExistenceForm.ANY);
CompletableFuture<Boolean> future = new CompletableFuture<>();
if (ConfigManager.doubleCheck()) {
plugin.getScheduler().sync().run(() -> {
CropStageConfig nearest = config.stageWithModelByPoint(previousPoint);
String blockID = plugin.getItemManager().id(location.toLocation(bukkitWorld), nearest.existenceForm());
if (!config.stageIDs().contains(blockID)) {
plugin.getPluginLogger().warn("Crop[" + config.id() + "] is removed at location[" + world.worldName() + "," + location + "] because the id of the block is [" + blockID + "]");
world.removeBlockState(location);
Optional.ofNullable(deathCondition.deathStage()).ifPresent(it -> {
BukkitCustomCropsPlugin.getInstance().getItemManager().place(bukkitLocation, deathCondition.existenceForm(), it, rotation);
});
ActionManager.trigger(context, config.deathActions());
}, deathCondition.deathDelay(), bukkitLocation);
return;
}
}
if (previousPoint >= config.maxPoints()) {
return;
}
int pointToAdd = 0;
GrowCondition[] growConditions = config.growConditions();
if (growConditions.length == 0) {
pointToAdd = 1;
future.complete(false);
return;
}
future.complete(true);
}, bukkitLocation);
} else {
for (GrowCondition growCondition : config.growConditions()) {
if (growCondition.isMet(context)) {
pointToAdd = growCondition.pointToAdd();
break;
future.complete(true);
}
future.thenAcceptAsync((run) -> {
if (!run) return;
Context<CustomCropsBlockState> context = Context.block(state, bukkitLocation).arg(ContextKeys.OFFLINE, offline);
for (DeathCondition deathCondition : config.deathConditions()) {
if (deathCondition.isMet(context)) {
plugin.getScheduler().sync().runLater(() -> {
FurnitureRotation rotation = plugin.getItemManager().remove(bukkitLocation, ExistenceForm.ANY);
world.removeBlockState(location);
Optional.ofNullable(deathCondition.deathStage()).ifPresent(it -> {
plugin.getItemManager().place(bukkitLocation, deathCondition.existenceForm(), it, rotation);
});
ActionManager.trigger(context, config.deathActions());
}, deathCondition.deathDelay(), bukkitLocation);
return;
}
}
}
if (pointToAdd == 0) return;
Optional<CustomCropsBlockState> optionalState = world.getBlockState(location.add(0,-1,0));
if (optionalState.isPresent()) {
CustomCropsBlockState belowState = optionalState.get();
if (belowState.type() instanceof PotBlock potBlock) {
for (Fertilizer fertilizer : potBlock.fertilizers(belowState)) {
FertilizerConfig fertilizerConfig = fertilizer.config();
if (fertilizerConfig != null) {
pointToAdd = fertilizerConfig.processGainPoints(pointToAdd);
if (previousPoint >= config.maxPoints()) {
return;
}
int pointToAdd = 0;
GrowCondition[] growConditions = config.growConditions();
if (growConditions.length == 0) {
pointToAdd = 1;
} else {
for (GrowCondition growCondition : config.growConditions()) {
if (growCondition.isMet(context)) {
pointToAdd = growCondition.pointToAdd();
break;
}
}
}
}
if (pointToAdd == 0) return;
int afterPoints = Math.min(previousPoint + pointToAdd, config.maxPoints());
point(state, afterPoints);
CropStageConfig currentStage = config.stageWithModelByPoint(previousPoint);
CropStageConfig nextStage = config.stageWithModelByPoint(afterPoints);
BukkitCustomCropsPlugin.getInstance().getScheduler().sync().run(() -> {
if (currentStage == nextStage) return;
FurnitureRotation rotation = BukkitCustomCropsPlugin.getInstance().getItemManager().remove(bukkitLocation, ExistenceForm.ANY);
if (rotation == FurnitureRotation.NONE && config.rotation()) {
rotation = FurnitureRotation.random();
}
BukkitCustomCropsPlugin.getInstance().getItemManager().place(bukkitLocation, nextStage.existenceForm(), Objects.requireNonNull(nextStage.stageID()), rotation);
for (int i = previousPoint + 1; i <= afterPoints; i++) {
CropStageConfig stage = config.stageByPoint(i);
if (stage != null) {
ActionManager.trigger(context, stage.growActions());
Optional<CustomCropsBlockState> optionalState = world.getBlockState(location.add(0,-1,0));
if (optionalState.isPresent()) {
CustomCropsBlockState belowState = optionalState.get();
if (belowState.type() instanceof PotBlock potBlock) {
for (Fertilizer fertilizer : potBlock.fertilizers(belowState)) {
FertilizerConfig fertilizerConfig = fertilizer.config();
if (fertilizerConfig != null) {
pointToAdd = fertilizerConfig.processGainPoints(pointToAdd);
}
}
}
}
}, bukkitLocation);
int afterPoints = Math.min(previousPoint + pointToAdd, config.maxPoints());
point(state, afterPoints);
CropStageConfig currentStage = config.stageWithModelByPoint(previousPoint);
CropStageConfig nextStage = config.stageWithModelByPoint(afterPoints);
plugin.getScheduler().sync().run(() -> {
if (currentStage == nextStage) return;
FurnitureRotation rotation = plugin.getItemManager().remove(bukkitLocation, ExistenceForm.ANY);
if (rotation == FurnitureRotation.NONE && config.rotation()) {
rotation = FurnitureRotation.random();
}
plugin.getItemManager().place(bukkitLocation, nextStage.existenceForm(), Objects.requireNonNull(nextStage.stageID()), rotation);
for (int i = previousPoint + 1; i <= afterPoints; i++) {
CropStageConfig stage = config.stageByPoint(i);
if (stage != null) {
ActionManager.trigger(context, stage.growActions());
}
}
}, bukkitLocation);
}, plugin.getScheduler().async());
}
public int point(CustomCropsBlockState state) {

View File

@@ -31,6 +31,7 @@ import net.momirealms.customcrops.api.event.GreenhouseGlassInteractEvent;
import net.momirealms.customcrops.api.event.GreenhouseGlassPlaceEvent;
import net.momirealms.customcrops.api.misc.NamedTextColor;
import net.momirealms.customcrops.api.util.EventUtils;
import org.bukkit.Location;
import java.util.Optional;
@@ -53,11 +54,14 @@ public class GreenhouseBlock extends AbstractCustomCropsBlock {
private void tickGreenhouse(CustomCropsWorld<?> world, Pos3 location) {
if (!ConfigManager.doubleCheck()) return;
String id = BukkitCustomCropsPlugin.getInstance().getItemManager().id(location.toLocation(world.bukkitWorld()), ConfigManager.greenhouseExistenceForm());
if (ConfigManager.greenhouse().contains(id)) return;
// remove outdated data
BukkitCustomCropsPlugin.getInstance().getPluginLogger().warn("Greenhouse is removed at location[" + world.worldName() + "," + location + "] because the id of the block/furniture is [" + id + "]");
world.removeBlockState(location);
Location bukkitLocation = location.toLocation(world.bukkitWorld());
BukkitCustomCropsPlugin.getInstance().getScheduler().sync().run(() -> {
String id = BukkitCustomCropsPlugin.getInstance().getItemManager().id(bukkitLocation, ConfigManager.greenhouseExistenceForm());
if (ConfigManager.greenhouse().contains(id)) return;
// remove outdated data
BukkitCustomCropsPlugin.getInstance().getPluginLogger().warn("Greenhouse is removed at location[" + world.worldName() + "," + location + "] because the id of the block/furniture is [" + id + "]");
world.removeBlockState(location);
}, bukkitLocation);
}
@Override

View File

@@ -60,6 +60,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
public class PotBlock extends AbstractCustomCropsBlock {
@@ -333,93 +334,96 @@ public class PotBlock extends AbstractCustomCropsBlock {
private void tickPot(CustomCropsBlockState state, CustomCropsWorld<?> world, Pos3 location, boolean offline) {
PotConfig config = config(state);
BukkitCustomCropsPlugin plugin = BukkitCustomCropsPlugin.getInstance();
if (config == null) {
BukkitCustomCropsPlugin.getInstance().getPluginLogger().warn("Pot data is removed at location[" + world.worldName() + "," + location + "] because the pot config[" + id(state) + "] has been removed.");
plugin.getPluginLogger().warn("Pot data is removed at location[" + world.worldName() + "," + location + "] because the pot config[" + id(state) + "] has been removed.");
world.removeBlockState(location);
return;
}
World bukkitWorld = world.bukkitWorld();
CompletableFuture<Boolean> future = new CompletableFuture<>();
if (ConfigManager.doubleCheck()) {
String blockID = BukkitCustomCropsPlugin.getInstance().getItemManager().blockID(location.toLocation(bukkitWorld));
String blockID = plugin.getItemManager().blockID(location.toLocation(bukkitWorld));
if (!config.blocks().contains(blockID)) {
BukkitCustomCropsPlugin.getInstance().getPluginLogger().warn("Pot[" + config.id() + "] is removed at location[" + world.worldName() + "," + location + "] because the id of the block is [" + blockID + "]");
plugin.getPluginLogger().warn("Pot[" + config.id() + "] is removed at location[" + world.worldName() + "," + location + "] because the id of the block is [" + blockID + "]");
world.removeBlockState(location);
future.complete(false);
return;
}
future.complete(true);
} else {
future.complete(true);
}
// work as vanilla farmland
if (config.vanillaFarmland()) return;
future.thenAcceptAsync((run) -> {
if (!run) return;
// work as vanilla farmland
if (config.vanillaFarmland()) return;
boolean hasNaturalWater = false;
boolean waterChanged = false;
boolean hasNaturalWater = false;
boolean waterChanged = false;
if (config.isRainDropAccepted()) {
if (bukkitWorld.hasStorm() || (!bukkitWorld.isClearWeather() && !bukkitWorld.isThundering())) {
double temperature = bukkitWorld.getTemperature(location.x(), location.y(), location.z());
if (temperature > 0.15 && temperature < 0.85) {
int y = bukkitWorld.getHighestBlockYAt(location.x(), location.z());
if (y == location.y()) {
if (addWater(state, 1)) {
waterChanged = true;
if (config.isRainDropAccepted()) {
if (bukkitWorld.hasStorm() || (!bukkitWorld.isClearWeather() && !bukkitWorld.isThundering())) {
double temperature = bukkitWorld.getTemperature(location.x(), location.y(), location.z());
if (temperature > 0.15 && temperature < 0.85) {
int y = bukkitWorld.getHighestBlockYAt(location.x(), location.z());
if (y == location.y()) {
if (addWater(state, 1)) {
waterChanged = true;
}
hasNaturalWater = true;
}
hasNaturalWater = true;
}
}
}
}
if (!hasNaturalWater && config.isNearbyWaterAccepted()) {
outer: {
for (int i = -4; i <= 4; i++) {
for (int j = -4; j <= 4; j++) {
for (int k : new int[]{0, 1}) {
BlockData block = bukkitWorld.getBlockData(location.x() + i, location.y() + j, location.z() + k);
if (block.getMaterial() == Material.WATER || (block instanceof Waterlogged waterlogged && waterlogged.isWaterlogged())) {
if (addWater(state, 1)) {
waterChanged = true;
if (!hasNaturalWater && config.isNearbyWaterAccepted()) {
outer: {
for (int i = -4; i <= 4; i++) {
for (int j = -4; j <= 4; j++) {
for (int k : new int[]{0, 1}) {
BlockData block = bukkitWorld.getBlockData(location.x() + i, location.y() + j, location.z() + k);
if (block.getMaterial() == Material.WATER || (block instanceof Waterlogged waterlogged && waterlogged.isWaterlogged())) {
if (addWater(state, 1)) {
waterChanged = true;
}
hasNaturalWater = true;
break outer;
}
hasNaturalWater = true;
break outer;
}
}
}
}
}
}
if (!hasNaturalWater) {
int waterToLose = 1;
Fertilizer[] fertilizers = fertilizers(state);
for (Fertilizer fertilizer : fertilizers) {
FertilizerConfig fertilizerConfig = fertilizer.config();
if (fertilizerConfig != null) {
waterToLose = fertilizerConfig.processWaterToLose(waterToLose);
if (!hasNaturalWater) {
int waterToLose = 1;
Fertilizer[] fertilizers = fertilizers(state);
for (Fertilizer fertilizer : fertilizers) {
FertilizerConfig fertilizerConfig = fertilizer.config();
if (fertilizerConfig != null) {
waterToLose = fertilizerConfig.processWaterToLose(waterToLose);
}
}
if (waterToLose > 0) {
if (addWater(state, -waterToLose)) {
waterChanged = true;
}
}
}
if (waterToLose > 0) {
if (addWater(state, -waterToLose)) {
waterChanged = true;
}
boolean fertilizerChanged = tickFertilizer(state);
Location bukkitLocation = location.toLocation(bukkitWorld);
if (fertilizerChanged || waterChanged) {
boolean finalHasNaturalWater = hasNaturalWater;
plugin.getScheduler().sync().run(() -> updateBlockAppearance(bukkitLocation, config, finalHasNaturalWater, fertilizers(state)), bukkitLocation);
}
}
boolean fertilizerChanged = tickFertilizer(state);
Location bukkitLocation = location.toLocation(bukkitWorld);
if (fertilizerChanged || waterChanged) {
boolean finalHasNaturalWater = hasNaturalWater;
BukkitCustomCropsPlugin.getInstance().getScheduler().sync().run(() -> {
updateBlockAppearance(bukkitLocation, config, finalHasNaturalWater, fertilizers(state));
}, bukkitLocation);
}
ActionManager.trigger(Context.block(state, bukkitLocation)
.arg(ContextKeys.OFFLINE, offline),
config.tickActions()
);
ActionManager.trigger(Context.block(state, bukkitLocation).arg(ContextKeys.OFFLINE, offline), config.tickActions());
}, plugin.getScheduler().async());
}
public int water(CustomCropsBlockState state) {

View File

@@ -31,6 +31,7 @@ import net.momirealms.customcrops.api.event.ScarecrowInteractEvent;
import net.momirealms.customcrops.api.event.ScarecrowPlaceEvent;
import net.momirealms.customcrops.api.misc.NamedTextColor;
import net.momirealms.customcrops.api.util.EventUtils;
import org.bukkit.Location;
import java.util.Optional;
@@ -53,11 +54,14 @@ public class ScarecrowBlock extends AbstractCustomCropsBlock {
private void tickScarecrow(CustomCropsWorld<?> world, Pos3 location) {
if (!ConfigManager.doubleCheck()) return;
String id = BukkitCustomCropsPlugin.getInstance().getItemManager().id(location.toLocation(world.bukkitWorld()), ConfigManager.scarecrowExistenceForm());
if (ConfigManager.scarecrow().contains(id)) return;
// remove outdated data
BukkitCustomCropsPlugin.getInstance().getPluginLogger().warn("Scarecrow is removed at location[" + world.worldName() + "," + location + "] because the id of the block/furniture is [" + id + "]");
world.removeBlockState(location);
Location bukkitLocation = location.toLocation(world.bukkitWorld());
BukkitCustomCropsPlugin.getInstance().getScheduler().sync().run(() -> {
String id = BukkitCustomCropsPlugin.getInstance().getItemManager().id(bukkitLocation, ConfigManager.scarecrowExistenceForm());
if (ConfigManager.scarecrow().contains(id)) return;
// remove outdated data
BukkitCustomCropsPlugin.getInstance().getPluginLogger().warn("Scarecrow is removed at location[" + world.worldName() + "," + location + "] because the id of the block/furniture is [" + id + "]");
world.removeBlockState(location);
}, bukkitLocation);
}
@Override

View File

@@ -263,8 +263,6 @@ public class SprinklerBlock extends AbstractCustomCropsBlock {
Location bukkitLocation = location.toLocation(bukkitWorld);
Context<CustomCropsBlockState> context = Context.block(state, bukkitLocation).arg(ContextKeys.OFFLINE, offline);
CompletableFuture<Boolean> syncCheck = new CompletableFuture<>();
// place/remove entities on main thread
BukkitCustomCropsPlugin.getInstance().getScheduler().sync().run(() -> {
@@ -273,7 +271,6 @@ public class SprinklerBlock extends AbstractCustomCropsBlock {
if (modelID == null || !config.modelIDs().contains(modelID)) {
world.removeBlockState(location);
BukkitCustomCropsPlugin.getInstance().getPluginLogger().warn("Sprinkler[" + config.id() + "] is removed at Location[" + world.worldName() + "," + location + "] because the id of the block/furniture is " + modelID);
syncCheck.complete(false);
return;
}
}
@@ -283,47 +280,41 @@ public class SprinklerBlock extends AbstractCustomCropsBlock {
updateBlockAppearance(bukkitLocation, config, false);
}
syncCheck.complete(true);
int[][] range = config.range();
Pos3[] pos3s = new Pos3[range.length * 2];
for (int i = 0; i < range.length; i++) {
int x = range[i][0];
int z = range[i][1];
pos3s[i] = location.add(x, 0, z);
pos3s[i] = location.add(x, -1, z);
}
for (Pos3 pos3 : pos3s) {
Optional<CustomCropsBlockState> optionalState = world.getBlockState(pos3);
if (optionalState.isPresent()) {
CustomCropsBlockState anotherState = optionalState.get();
if (anotherState.type() instanceof PotBlock potBlock) {
PotConfig potConfig = potBlock.config(anotherState);
if (!potConfig.vanillaFarmland()) {
if (config.potWhitelist().contains(potConfig.id())) {
if (potBlock.addWater(anotherState, potConfig, config.wateringAmount())) {
BukkitCustomCropsPlugin.getInstance().getScheduler().sync().run(
() -> potBlock.updateBlockAppearance(
pos3.toLocation(world.bukkitWorld()),
potConfig,
true,
potBlock.fertilizers(anotherState)
),
bukkitWorld,
pos3.chunkX(), pos3.chunkZ()
);
}
}
}
}
}
}
}, bukkitLocation);
syncCheck.thenAccept(result -> {
if (result) {
int[][] range = config.range();
Pos3[] pos3s = new Pos3[range.length * 2];
for (int i = 0; i < range.length; i++) {
int x = range[i][0];
int z = range[i][1];
pos3s[i] = location.add(x, 0, z);
pos3s[i] = location.add(x, -1, z);
}
for (Pos3 pos3 : pos3s) {
Optional<CustomCropsBlockState> optionalState = world.getBlockState(pos3);
if (optionalState.isPresent()) {
CustomCropsBlockState anotherState = optionalState.get();
if (anotherState.type() instanceof PotBlock potBlock) {
PotConfig potConfig = potBlock.config(anotherState);
if (!potConfig.vanillaFarmland()) {
if (config.potWhitelist().contains(potConfig.id())) {
if (potBlock.addWater(anotherState, potConfig, config.wateringAmount())) {
BukkitCustomCropsPlugin.getInstance().getScheduler().sync().run(
() -> potBlock.updateBlockAppearance(
pos3.toLocation(world.bukkitWorld()),
potConfig,
true,
potBlock.fertilizers(anotherState)
),
bukkitWorld,
pos3.chunkX(), pos3.chunkZ()
);
}
}
}
}
}
}
}
});
}
public boolean addWater(CustomCropsBlockState state, int water) {

View File

@@ -217,7 +217,7 @@ public class WateringCanItem extends AbstractCustomCropsItem {
int waterInCan = getCurrentWater(itemInHand);
SprinklerConfig sprinklerConfig = Registries.SPRINKLER.get(targetBlockID);
SprinklerConfig sprinklerConfig = Registries.ITEM_TO_SPRINKLER.get(targetBlockID);
if (sprinklerConfig != null) {
// ignore infinite sprinkler
if (sprinklerConfig.infinite()) {
@@ -237,7 +237,6 @@ public class WateringCanItem extends AbstractCustomCropsItem {
ActionManager.trigger(context, wateringCanConfig.wrongSprinklerActions());
return InteractionResult.COMPLETE;
}
SprinklerBlock sprinklerBlock = (SprinklerBlock) BuiltInBlockMechanics.SPRINKLER.mechanic();
CustomCropsBlockState sprinklerState = sprinklerBlock.fixOrGetState(world, Pos3.from(targetLocation), sprinklerConfig, targetBlockID);
@@ -266,6 +265,13 @@ public class WateringCanItem extends AbstractCustomCropsItem {
ActionManager.trigger(context, wateringCanConfig.consumeWaterActions());
setCurrentWater(itemInHand, wateringCanConfig, waterInCan - 1, context);
context.arg(ContextKeys.WATER_BAR, Optional.ofNullable(sprinklerConfig.waterBar()).map(bar -> bar.getWaterBar(sprinklerBlock.water(sprinklerState), sprinklerConfig.storage())).orElse(""));
context.arg(ContextKeys.STORAGE, sprinklerConfig.storage());
context.arg(ContextKeys.CURRENT_WATER, sprinklerBlock.water(sprinklerState));
ActionManager.trigger(context, sprinklerConfig.interactActions());
ActionManager.trigger(context, sprinklerConfig.addWaterActions());
return InteractionResult.COMPLETE;
}