mirror of
https://github.com/Xiao-MoMi/Custom-Crops.git
synced 2025-12-28 19:39:20 +00:00
Implement logic for dead crops
This commit is contained in:
@@ -758,17 +758,8 @@ public abstract class AbstractActionManager<T> implements ActionManager<T> {
|
||||
return;
|
||||
}
|
||||
if (applyCorrection) {
|
||||
Optional<CustomCropsBlockState> optionalState = optionalWorld.get().getBlockState(pos3);
|
||||
if (optionalState.isPresent()) {
|
||||
if (optionalState.get().type() instanceof CropBlock cropBlock) {
|
||||
CropConfig config = cropBlock.config(optionalState.get());
|
||||
int point = cropBlock.point(optionalState.get());
|
||||
if (config != null) {
|
||||
CropStageConfig stageConfig = config.stageWithModelByPoint(point);
|
||||
location.add(0,stageConfig.displayInfoOffset(),0);
|
||||
}
|
||||
}
|
||||
}
|
||||
String itemID = plugin.getItemManager().anyID(location.clone().add(0,1,0));
|
||||
location.add(0,ConfigManager.getOffset(itemID),0);
|
||||
}
|
||||
ArrayList<Player> viewers = new ArrayList<>();
|
||||
if (onlyShowToOne) {
|
||||
|
||||
@@ -42,6 +42,9 @@ public class ContextKeys<T> {
|
||||
public static final ContextKeys<EquipmentSlot> SLOT = of("slot", EquipmentSlot.class);
|
||||
public static final ContextKeys<String> TEMP_NEAR_PLAYER = of("near", String.class);
|
||||
public static final ContextKeys<Boolean> OFFLINE = of("offline", Boolean.class);
|
||||
public static final ContextKeys<String> ICON = of("icon", String.class);
|
||||
public static final ContextKeys<Integer> MAX_TIMES = of("max_times", Integer.class);
|
||||
public static final ContextKeys<Integer> LEFT_TIMES = of("left_times", Integer.class);
|
||||
public static final ContextKeys<Player> PLAYER_INSTANCE = of("player_instance", Player.class);
|
||||
|
||||
private final String key;
|
||||
|
||||
@@ -50,7 +50,10 @@ import org.bukkit.event.player.PlayerItemDamageEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
public abstract class AbstractCustomEventListener implements Listener {
|
||||
|
||||
@@ -324,27 +327,8 @@ public abstract class AbstractCustomEventListener implements Listener {
|
||||
Context<Player> context = Context.player(null);
|
||||
context.arg(ContextKeys.LOCATION, location);
|
||||
boneMeal.triggerActions(context);
|
||||
|
||||
int afterPoints = Math.min(point + boneMeal.rollPoint(), cropConfig.maxPoints());
|
||||
cropBlock.point(state, afterPoints);
|
||||
|
||||
String afterStage = null;
|
||||
ExistenceForm afterForm = null;
|
||||
int tempPoints = afterPoints;
|
||||
while (tempPoints >= 0) {
|
||||
Map.Entry<Integer, CropStageConfig> afterEntry = cropConfig.getFloorStageEntry(tempPoints);
|
||||
CropStageConfig after = afterEntry.getValue();
|
||||
if (after.stageID() != null) {
|
||||
afterStage = after.stageID();
|
||||
afterForm = after.existenceForm();
|
||||
break;
|
||||
}
|
||||
tempPoints = after.point() - 1;
|
||||
}
|
||||
|
||||
Objects.requireNonNull(afterForm);
|
||||
Objects.requireNonNull(afterStage);
|
||||
|
||||
Context<CustomCropsBlockState> blockContext = Context.block(state);
|
||||
blockContext.arg(ContextKeys.LOCATION, LocationUtils.toBlockLocation(location));
|
||||
for (int i = point + 1; i <= afterPoints; i++) {
|
||||
@@ -353,14 +337,15 @@ public abstract class AbstractCustomEventListener implements Listener {
|
||||
ActionManager.trigger(blockContext, stage.growActions());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO if the block model chanegs
|
||||
CropStageConfig currentStage = cropConfig.stageWithModelByPoint(point);
|
||||
CropStageConfig afterStage = cropConfig.stageWithModelByPoint(afterPoints);
|
||||
if (currentStage == afterStage) return;
|
||||
Location bukkitLocation = location.toLocation(world.bukkitWorld());
|
||||
FurnitureRotation rotation = BukkitCustomCropsPlugin.getInstance().getItemManager().remove(bukkitLocation, ExistenceForm.ANY);
|
||||
if (rotation == FurnitureRotation.NONE && cropConfig.rotation()) {
|
||||
rotation = FurnitureRotation.random();
|
||||
}
|
||||
BukkitCustomCropsPlugin.getInstance().getItemManager().place(bukkitLocation, afterForm, afterStage, rotation);
|
||||
BukkitCustomCropsPlugin.getInstance().getItemManager().place(bukkitLocation, afterStage.existenceForm(), Objects.requireNonNull(afterStage.stageID()), rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.util.Objects;
|
||||
public class BuiltInBlockMechanics {
|
||||
|
||||
public static final BuiltInBlockMechanics CROP = create("crop");
|
||||
public static final BuiltInBlockMechanics DEAD_CROP = create("dead_crop");
|
||||
public static final BuiltInBlockMechanics SPRINKLER = create("sprinkler");
|
||||
public static final BuiltInBlockMechanics GREENHOUSE = create("greenhouse");
|
||||
public static final BuiltInBlockMechanics POT = create("pot");
|
||||
|
||||
@@ -63,12 +63,17 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
|
||||
|
||||
protected boolean preventTrampling;
|
||||
protected boolean disableMoistureMechanic;
|
||||
protected HashMap<String, Double> offsets = new HashMap<>();
|
||||
|
||||
public ConfigManager(BukkitCustomCropsPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
instance = this;
|
||||
}
|
||||
|
||||
public static double getOffset(String id) {
|
||||
return instance.offsets.getOrDefault(id, 0d);
|
||||
}
|
||||
|
||||
public static boolean syncSeasons() {
|
||||
return instance.syncSeasons;
|
||||
}
|
||||
|
||||
@@ -57,4 +57,5 @@ public class Registries {
|
||||
public static final ClearableRegistry<String, PotConfig> ITEM_TO_POT = new ClearableMappedRegistry<>(Key.key("fast_lookup", "item_to_pot"));
|
||||
public static final ClearableRegistry<String, SprinklerConfig> ITEM_TO_SPRINKLER = new ClearableMappedRegistry<>(Key.key("fast_lookup", "item_to_sprinkler"));
|
||||
public static final ClearableRegistry<String, WateringCanConfig> ITEM_TO_WATERING_CAN = new ClearableMappedRegistry<>(Key.key("fast_lookup", "item_to_wateringcan"));
|
||||
public static final ClearableRegistry<String, Integer> ITEM_TO_DEAD_CROP = new ClearableMappedRegistry<>(Key.key("fast_lookup", "item_to_dead_crop"));
|
||||
}
|
||||
|
||||
@@ -225,22 +225,7 @@ public class CropBlock extends AbstractCustomCropsBlock {
|
||||
int afterPoints = Math.min(point + boneMeal.rollPoint(), cropConfig.maxPoints());
|
||||
point(state, afterPoints);
|
||||
|
||||
String afterStage = null;
|
||||
ExistenceForm afterForm = null;
|
||||
int tempPoints = afterPoints;
|
||||
while (tempPoints >= 0) {
|
||||
Map.Entry<Integer, CropStageConfig> afterEntry = cropConfig.getFloorStageEntry(tempPoints);
|
||||
CropStageConfig after = afterEntry.getValue();
|
||||
if (after.stageID() != null) {
|
||||
afterStage = after.stageID();
|
||||
afterForm = after.existenceForm();
|
||||
break;
|
||||
}
|
||||
tempPoints = after.point() - 1;
|
||||
}
|
||||
|
||||
Objects.requireNonNull(afterForm);
|
||||
Objects.requireNonNull(afterStage);
|
||||
CropStageConfig nextStage = cropConfig.stageWithModelByPoint(afterPoints);
|
||||
|
||||
Context<CustomCropsBlockState> blockContext = Context.block(state);
|
||||
blockContext.arg(ContextKeys.LOCATION, LocationUtils.toBlockLocation(location));
|
||||
@@ -251,13 +236,13 @@ public class CropBlock extends AbstractCustomCropsBlock {
|
||||
}
|
||||
}
|
||||
|
||||
if (Objects.equals(afterStage, event.relatedID())) return;
|
||||
if (Objects.equals(nextStage.stageID(), event.relatedID())) return;
|
||||
Location bukkitLocation = location.toLocation(world.bukkitWorld());
|
||||
FurnitureRotation rotation = BukkitCustomCropsPlugin.getInstance().getItemManager().remove(bukkitLocation, ExistenceForm.ANY);
|
||||
if (rotation == FurnitureRotation.NONE && cropConfig.rotation()) {
|
||||
rotation = FurnitureRotation.random();
|
||||
}
|
||||
BukkitCustomCropsPlugin.getInstance().getItemManager().place(bukkitLocation, afterForm, afterStage, rotation);
|
||||
BukkitCustomCropsPlugin.getInstance().getItemManager().place(bukkitLocation, nextStage.existenceForm(), Objects.requireNonNull(nextStage.stageID()), rotation);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -363,39 +348,8 @@ public class CropBlock extends AbstractCustomCropsBlock {
|
||||
int afterPoints = Math.min(previousPoint + pointToAdd, config.maxPoints());
|
||||
point(state, afterPoints);
|
||||
|
||||
int tempPoints = previousPoint;
|
||||
String preStage = null;
|
||||
while (tempPoints >= 0) {
|
||||
Map.Entry<Integer, CropStageConfig> preEntry = config.getFloorStageEntry(tempPoints);
|
||||
CropStageConfig pre = preEntry.getValue();
|
||||
if (pre.stageID() != null) {
|
||||
preStage = pre.stageID();
|
||||
break;
|
||||
}
|
||||
tempPoints = pre.point() - 1;
|
||||
}
|
||||
|
||||
String afterStage = null;
|
||||
ExistenceForm afterForm = null;
|
||||
tempPoints = afterPoints;
|
||||
while (tempPoints >= 0) {
|
||||
Map.Entry<Integer, CropStageConfig> afterEntry = config.getFloorStageEntry(tempPoints);
|
||||
CropStageConfig after = afterEntry.getValue();
|
||||
if (after.stageID() != null) {
|
||||
afterStage = after.stageID();
|
||||
afterForm = after.existenceForm();
|
||||
break;
|
||||
}
|
||||
tempPoints = after.point() - 1;
|
||||
}
|
||||
|
||||
final String finalPreStage = preStage;
|
||||
final String finalAfterStage = afterStage;
|
||||
final ExistenceForm finalAfterForm = afterForm;
|
||||
|
||||
Objects.requireNonNull(finalAfterStage);
|
||||
Objects.requireNonNull(finalPreStage);
|
||||
Objects.requireNonNull(finalAfterForm);
|
||||
CropStageConfig currentStage = config.stageWithModelByPoint(previousPoint);
|
||||
CropStageConfig nextStage = config.stageWithModelByPoint(afterPoints);
|
||||
|
||||
BukkitCustomCropsPlugin.getInstance().getScheduler().sync().run(() -> {
|
||||
for (int i = previousPoint + 1; i <= afterPoints; i++) {
|
||||
@@ -404,12 +358,12 @@ public class CropBlock extends AbstractCustomCropsBlock {
|
||||
ActionManager.trigger(context, stage.growActions());
|
||||
}
|
||||
}
|
||||
if (Objects.equals(finalAfterStage, finalPreStage)) return;
|
||||
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, finalAfterForm, finalAfterStage, rotation);
|
||||
BukkitCustomCropsPlugin.getInstance().getItemManager().place(bukkitLocation, nextStage.existenceForm(), Objects.requireNonNull(nextStage.stageID()), rotation);
|
||||
}, bukkitLocation);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) <2024> <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.core.block;
|
||||
|
||||
import net.momirealms.customcrops.api.BukkitCustomCropsPlugin;
|
||||
import net.momirealms.customcrops.api.context.Context;
|
||||
import net.momirealms.customcrops.api.context.ContextKeys;
|
||||
import net.momirealms.customcrops.api.core.BuiltInBlockMechanics;
|
||||
import net.momirealms.customcrops.api.core.Registries;
|
||||
import net.momirealms.customcrops.api.core.world.CustomCropsBlockState;
|
||||
import net.momirealms.customcrops.api.core.world.CustomCropsWorld;
|
||||
import net.momirealms.customcrops.api.core.world.Pos3;
|
||||
import net.momirealms.customcrops.api.core.wrapper.WrappedInteractEvent;
|
||||
import net.momirealms.customcrops.api.util.LocationUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class DeadCrop extends AbstractCustomCropsBlock {
|
||||
|
||||
public DeadCrop() {
|
||||
super(BuiltInBlockMechanics.DEAD_CROP.key());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBlockInstance(String id) {
|
||||
return Registries.ITEM_TO_DEAD_CROP.containsKey(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInteract(WrappedInteractEvent event) {
|
||||
final Player player = event.player();
|
||||
Context<Player> context = Context.player(player);
|
||||
// data first
|
||||
CustomCropsWorld<?> world = event.world();
|
||||
Location location = event.location();
|
||||
context.arg(ContextKeys.SLOT, event.hand());
|
||||
// check pot below
|
||||
Location potLocation = location.clone().subtract(0,1,0);
|
||||
String blockBelowID = BukkitCustomCropsPlugin.getInstance().getItemManager().blockID(potLocation.getBlock());
|
||||
PotConfig potConfig = Registries.ITEM_TO_POT.get(blockBelowID);
|
||||
if (potConfig != null) {
|
||||
context.arg(ContextKeys.LOCATION, LocationUtils.toBlockLocation(potLocation));
|
||||
PotBlock potBlock = (PotBlock) BuiltInBlockMechanics.POT.mechanic();
|
||||
assert potBlock != null;
|
||||
// fix or get data
|
||||
CustomCropsBlockState potState = potBlock.fixOrGetState(world, Pos3.from(potLocation), potConfig, event.relatedID());
|
||||
if (potBlock.tryWateringPot(player, context, potState, event.hand(), event.itemID(), potConfig, potLocation, event.itemInHand()))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -245,6 +245,21 @@ public class PotBlock extends AbstractCustomCropsBlock {
|
||||
if (tryWateringPot(player, context, state, event.hand(), event.itemID(), potConfig, location, itemInHand))
|
||||
return;
|
||||
|
||||
int water = water(state);
|
||||
context.arg(ContextKeys.STORAGE, potConfig.storage());
|
||||
context.arg(ContextKeys.CURRENT_WATER, water);
|
||||
context.arg(ContextKeys.WATER_BAR, Optional.ofNullable(potConfig.waterBar()).map(it -> it.getWaterBar(water, potConfig.storage())).orElse(""));
|
||||
Fertilizer[] fertilizers = fertilizers(state);
|
||||
// for backward compatibility
|
||||
for (Fertilizer latest : fertilizers) {
|
||||
FertilizerConfig config = latest.config();
|
||||
if (config != null) {
|
||||
context.arg(ContextKeys.ICON, config.icon());
|
||||
context.arg(ContextKeys.MAX_TIMES, config.times());
|
||||
context.arg(ContextKeys.LEFT_TIMES, latest.times());
|
||||
break;
|
||||
}
|
||||
}
|
||||
ActionManager.trigger(context, potConfig.interactActions());
|
||||
}
|
||||
|
||||
|
||||
@@ -239,8 +239,8 @@ public class WateringCanItem extends AbstractCustomCropsItem {
|
||||
}
|
||||
|
||||
// if the clicked block is a crop, correct the target block
|
||||
List<CropConfig> cropConfigs = Registries.STAGE_TO_CROP_UNSAFE.get(event.relatedID());
|
||||
if (cropConfigs != null) {
|
||||
List<CropConfig> cropConfigs = Registries.STAGE_TO_CROP_UNSAFE.get(targetBlockID);
|
||||
if (cropConfigs != null || Registries.ITEM_TO_DEAD_CROP.containsKey(targetBlockID)) {
|
||||
// is a crop
|
||||
targetLocation = targetLocation.subtract(0,1,0);
|
||||
targetBlockID = BukkitCustomCropsPlugin.getInstance().getItemManager().blockID(targetLocation);
|
||||
|
||||
@@ -19,7 +19,6 @@ package net.momirealms.customcrops.api.core.world;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Set;
|
||||
|
||||
Reference in New Issue
Block a user