mirror of
https://github.com/Xiao-MoMi/Custom-Crops.git
synced 2025-12-25 18:09:28 +00:00
3.4.2.0
This commit is contained in:
@@ -32,7 +32,6 @@ import net.momirealms.customcrops.compatibility.season.AdvancedSeasonsImpl;
|
||||
import net.momirealms.customcrops.compatibility.season.InBuiltSeason;
|
||||
import net.momirealms.customcrops.compatibility.season.RealisticSeasonsImpl;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -161,9 +160,4 @@ public class IntegrationManagerImpl implements IntegrationManager {
|
||||
public int getDate(World world) {
|
||||
return seasonInterface.getDate(world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack build(String itemID) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,4 +45,20 @@ public class AdvancedSeasonsImpl implements SeasonInterface {
|
||||
public int getDate(World world) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSeason(World world, Season season) {
|
||||
String seasonName = switch (season) {
|
||||
case AUTUMN -> "FALL";
|
||||
case WINTER -> "WINTER";
|
||||
case SUMMER -> "SUMMER";
|
||||
case SPRING -> "SPRING";
|
||||
};
|
||||
api.setSeason(seasonName, world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDate(World world, int date) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import net.momirealms.customcrops.api.integration.SeasonInterface;
|
||||
import net.momirealms.customcrops.api.manager.ConfigManager;
|
||||
import net.momirealms.customcrops.api.manager.WorldManager;
|
||||
import net.momirealms.customcrops.api.mechanic.world.level.CustomCropsWorld;
|
||||
import net.momirealms.customcrops.api.mechanic.world.level.WorldInfoData;
|
||||
import net.momirealms.customcrops.api.mechanic.world.season.Season;
|
||||
import org.bukkit.World;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -52,4 +53,22 @@ public class InBuiltSeason implements SeasonInterface {
|
||||
.map(cropsWorld -> cropsWorld.getInfoData().getDate())
|
||||
.orElse(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSeason(World world, Season season) {
|
||||
worldManager.getCustomCropsWorld(world)
|
||||
.ifPresent(customWorld -> {
|
||||
WorldInfoData infoData = customWorld.getInfoData();
|
||||
infoData.setSeason(season);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDate(World world, int date) {
|
||||
worldManager.getCustomCropsWorld(world)
|
||||
.ifPresent(customWorld -> {
|
||||
WorldInfoData infoData = customWorld.getInfoData();
|
||||
infoData.setDate(date);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@
|
||||
package net.momirealms.customcrops.compatibility.season;
|
||||
|
||||
import me.casperge.realisticseasons.api.SeasonsAPI;
|
||||
import me.casperge.realisticseasons.calendar.Date;
|
||||
import net.momirealms.customcrops.api.integration.SeasonInterface;
|
||||
import net.momirealms.customcrops.api.mechanic.world.season.Season;
|
||||
import org.bukkit.World;
|
||||
@@ -25,9 +26,15 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class RealisticSeasonsImpl implements SeasonInterface {
|
||||
|
||||
private final SeasonsAPI api;
|
||||
|
||||
public RealisticSeasonsImpl() {
|
||||
this.api = SeasonsAPI.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Season getSeason(World world) {
|
||||
return switch (SeasonsAPI.getInstance().getSeason(world)) {
|
||||
return switch (api.getSeason(world)) {
|
||||
case WINTER -> Season.WINTER;
|
||||
case SPRING -> Season.SPRING;
|
||||
case SUMMER -> Season.SUMMER;
|
||||
@@ -38,6 +45,23 @@ public class RealisticSeasonsImpl implements SeasonInterface {
|
||||
|
||||
@Override
|
||||
public int getDate(World world) {
|
||||
return SeasonsAPI.getInstance().getDate(world).getDay();
|
||||
return api.getDate(world).getDay();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSeason(World world, Season season) {
|
||||
me.casperge.realisticseasons.season.Season rsSeason = switch (season) {
|
||||
case AUTUMN -> me.casperge.realisticseasons.season.Season.FALL;
|
||||
case SUMMER -> me.casperge.realisticseasons.season.Season.SUMMER;
|
||||
case WINTER -> me.casperge.realisticseasons.season.Season.WINTER;
|
||||
case SPRING -> me.casperge.realisticseasons.season.Season.SPRING;
|
||||
};
|
||||
api.setSeason(world, rsSeason);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDate(World world, int date) {
|
||||
Date rsDate = api.getDate(world);
|
||||
api.setDate(world, new Date(date, rsDate.getMonth(), rsDate.getYear()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,10 @@ import net.momirealms.customcrops.api.CustomCropsPlugin;
|
||||
import net.momirealms.customcrops.api.common.Initable;
|
||||
import net.momirealms.customcrops.api.integration.SeasonInterface;
|
||||
import net.momirealms.customcrops.api.manager.MessageManager;
|
||||
import net.momirealms.customcrops.api.mechanic.item.ItemType;
|
||||
import net.momirealms.customcrops.api.mechanic.world.CustomCropsBlock;
|
||||
import net.momirealms.customcrops.api.mechanic.world.level.CustomCropsChunk;
|
||||
import net.momirealms.customcrops.api.mechanic.world.level.CustomCropsSection;
|
||||
import net.momirealms.customcrops.api.mechanic.world.level.CustomCropsWorld;
|
||||
import net.momirealms.customcrops.api.mechanic.world.season.Season;
|
||||
import net.momirealms.customcrops.compatibility.season.InBuiltSeason;
|
||||
@@ -54,8 +58,8 @@ public class CommandManager implements Initable {
|
||||
getReloadCommand(),
|
||||
getAboutCommand(),
|
||||
getSeasonCommand(),
|
||||
getDateCommand()
|
||||
//getStressTest()
|
||||
getDateCommand(),
|
||||
getForceTickCommand()
|
||||
)
|
||||
.register();
|
||||
}
|
||||
@@ -85,6 +89,32 @@ public class CommandManager implements Initable {
|
||||
});
|
||||
}
|
||||
|
||||
private CommandAPICommand getForceTickCommand() {
|
||||
return new CommandAPICommand("force-tick")
|
||||
.withArguments(new WorldArgument("world"))
|
||||
.withArguments(new StringArgument("type").replaceSuggestions(ArgumentSuggestions.strings("sprinkler", "crop", "pot", "scarecrow", "greenhouse")))
|
||||
.executes((sender, args) -> {
|
||||
World world = (World) args.get("world");
|
||||
ItemType itemType = ItemType.valueOf(((String) args.get("type")).toUpperCase(Locale.ENGLISH));
|
||||
Optional<CustomCropsWorld> customCropsWorld = plugin.getWorldManager().getCustomCropsWorld(world);
|
||||
if (customCropsWorld.isEmpty()) {
|
||||
plugin.getAdventure().sendMessageWithPrefix(sender, "CustomCrops is not enabled in that world");
|
||||
return;
|
||||
}
|
||||
plugin.getScheduler().runTaskAsync(() -> {
|
||||
for (CustomCropsChunk chunk : customCropsWorld.get().getChunkStorage()) {
|
||||
for (CustomCropsSection section : chunk.getSections()) {
|
||||
for (CustomCropsBlock block : section.getBlocks()) {
|
||||
if (block.getType() == itemType) {
|
||||
block.tick(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private CommandAPICommand getDateCommand() {
|
||||
return new CommandAPICommand("date")
|
||||
.withSubcommands(
|
||||
@@ -176,45 +206,4 @@ public class CommandManager implements Initable {
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// private CommandAPICommand getStressTest() {
|
||||
// return new CommandAPICommand("test").executes((sender, args) -> {
|
||||
// for (int i = 0; i < 16; i++) {
|
||||
// for (int j = 0; j < 16; j++) {
|
||||
// for (int k = -64; k < 0; k++) {
|
||||
// SimpleLocation location = new SimpleLocation("world", 1024 + i, k, 1024 + j);
|
||||
// plugin.getWorldManager().addCropAt(new MemoryCrop(location, "tomato", 0), location);
|
||||
// }
|
||||
// for (int k = 1; k < 64; k++) {
|
||||
// SimpleLocation location = new SimpleLocation("world", 1024 + i, k, 1024 + j);
|
||||
// plugin.getWorldManager().addCropAt(new MemoryCrop(location, "tomato", 1), location);
|
||||
// }
|
||||
// for (int k = 65; k < 128; k++) {
|
||||
// SimpleLocation location = new SimpleLocation("world", 1024 + i, k, 1024 + j);
|
||||
// plugin.getWorldManager().addCropAt(new MemoryCrop(location, "tomato", 2), location);
|
||||
// }
|
||||
// for (int k = 129; k < 165; k++) {
|
||||
// SimpleLocation location = new SimpleLocation("world", 1024 + i, k, 1024 + j);
|
||||
// plugin.getWorldManager().addPotAt(new MemoryPot(location, "default"), location);
|
||||
// }
|
||||
// for (int k = 166; k < 190; k++) {
|
||||
// SimpleLocation location = new SimpleLocation("world", 1024 + i, k, 1024 + j);
|
||||
// plugin.getWorldManager().addPotAt(new MemoryPot(location, "sprinkler"), location);
|
||||
// }
|
||||
// for (int k = 191; k < 250; k++) {
|
||||
// SimpleLocation location = new SimpleLocation("world", 1024 + i, k, 1024 + j);
|
||||
// plugin.getWorldManager().addCropAt(new MemoryCrop(location, "tomato", 3), location);
|
||||
// }
|
||||
// for (int k = 251; k < 300; k++) {
|
||||
// SimpleLocation location = new SimpleLocation("world", 1024 + i, k, 1024 + j);
|
||||
// plugin.getWorldManager().addCropAt(new MemoryCrop(location, "sbsbssbsb", 3), location);
|
||||
// }
|
||||
// for (int k = 301; k < 320; k++) {
|
||||
// SimpleLocation location = new SimpleLocation("world", 1024 + i, k, 1024 + j);
|
||||
// plugin.getWorldManager().addCropAt(new MemoryCrop(location, "sbsbssbsb", 2), location);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ public class ConfigManagerImpl extends ConfigManager {
|
||||
|
||||
syncSeasons = mechanics.getBoolean("sync-season.enable", true);
|
||||
if (syncSeasons) {
|
||||
referenceWorld = new WeakReference<>(Bukkit.getWorld(Objects.requireNonNull(mechanics.getString("sync-season.reference"))));
|
||||
referenceWorld = new WeakReference<>(Bukkit.getWorld(mechanics.getString("sync-season.reference", "world")));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ import net.momirealms.customcrops.api.mechanic.item.fertilizer.QualityCrop;
|
||||
import net.momirealms.customcrops.api.mechanic.item.fertilizer.Variation;
|
||||
import net.momirealms.customcrops.api.mechanic.item.fertilizer.YieldIncrease;
|
||||
import net.momirealms.customcrops.api.mechanic.misc.CRotation;
|
||||
import net.momirealms.customcrops.api.mechanic.misc.Reason;
|
||||
import net.momirealms.customcrops.api.mechanic.misc.Value;
|
||||
import net.momirealms.customcrops.api.mechanic.requirement.Requirement;
|
||||
import net.momirealms.customcrops.api.mechanic.world.ChunkCoordinate;
|
||||
@@ -696,7 +697,7 @@ public class ActionManagerImpl implements ActionManager {
|
||||
switch (removed.get().getType()) {
|
||||
case SPRINKLER -> {
|
||||
WorldSprinkler sprinkler = (WorldSprinkler) removed.get();
|
||||
SprinklerBreakEvent event = new SprinklerBreakEvent(state.getPlayer(), state.getLocation(), sprinkler);
|
||||
SprinklerBreakEvent event = new SprinklerBreakEvent(state.getPlayer(), state.getLocation(), sprinkler, Reason.ACTION);
|
||||
if (EventUtils.fireAndCheckCancel(event))
|
||||
return;
|
||||
if (arg) sprinkler.getConfig().trigger(ActionTrigger.BREAK, state);
|
||||
@@ -705,7 +706,7 @@ public class ActionManagerImpl implements ActionManager {
|
||||
}
|
||||
case CROP -> {
|
||||
WorldCrop crop = (WorldCrop) removed.get();
|
||||
CropBreakEvent event = new CropBreakEvent(state.getPlayer(), state.getLocation(), crop);
|
||||
CropBreakEvent event = new CropBreakEvent(state.getPlayer(), state.getLocation(), crop, Reason.ACTION);
|
||||
if (EventUtils.fireAndCheckCancel(event))
|
||||
return;
|
||||
Crop cropConfig = crop.getConfig();
|
||||
@@ -718,7 +719,7 @@ public class ActionManagerImpl implements ActionManager {
|
||||
}
|
||||
case POT -> {
|
||||
WorldPot pot = (WorldPot) removed.get();
|
||||
PotBreakEvent event = new PotBreakEvent(state.getPlayer(), state.getLocation(), pot);
|
||||
PotBreakEvent event = new PotBreakEvent(state.getPlayer(), state.getLocation(), pot, Reason.ACTION);
|
||||
if (EventUtils.fireAndCheckCancel(event))
|
||||
return;
|
||||
if (arg) pot.getConfig().trigger(ActionTrigger.BREAK, state);
|
||||
|
||||
@@ -32,12 +32,12 @@ import net.momirealms.customcrops.api.mechanic.item.*;
|
||||
import net.momirealms.customcrops.api.mechanic.item.water.PassiveFillMethod;
|
||||
import net.momirealms.customcrops.api.mechanic.item.water.PositiveFillMethod;
|
||||
import net.momirealms.customcrops.api.mechanic.misc.CRotation;
|
||||
import net.momirealms.customcrops.api.mechanic.misc.Reason;
|
||||
import net.momirealms.customcrops.api.mechanic.misc.image.WaterBar;
|
||||
import net.momirealms.customcrops.api.mechanic.requirement.State;
|
||||
import net.momirealms.customcrops.api.mechanic.world.CustomCropsBlock;
|
||||
import net.momirealms.customcrops.api.mechanic.world.SimpleLocation;
|
||||
import net.momirealms.customcrops.api.mechanic.world.level.WorldCrop;
|
||||
import net.momirealms.customcrops.api.mechanic.world.level.WorldPot;
|
||||
import net.momirealms.customcrops.api.mechanic.world.level.WorldSprinkler;
|
||||
import net.momirealms.customcrops.api.mechanic.world.level.*;
|
||||
import net.momirealms.customcrops.api.util.LogUtils;
|
||||
import net.momirealms.customcrops.mechanic.item.custom.AbstractCustomListener;
|
||||
import net.momirealms.customcrops.mechanic.item.custom.itemsadder.ItemsAdderListener;
|
||||
@@ -70,6 +70,7 @@ import org.bukkit.entity.ItemDisplay;
|
||||
import org.bukkit.entity.ItemFrame;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -629,12 +630,23 @@ public class ItemManagerImpl implements ItemManager {
|
||||
if (!(conditionWrapper instanceof BreakWrapper breakWrapper)) {
|
||||
return FunctionResult.PASS;
|
||||
}
|
||||
|
||||
// get or fix
|
||||
Location location = breakWrapper.getLocation();
|
||||
SimpleLocation simpleLocation = SimpleLocation.of(location);
|
||||
Optional<WorldGlass> optionalWorldGlass = plugin.getWorldManager().getGlassAt(simpleLocation);
|
||||
if (optionalWorldGlass.isEmpty()) {
|
||||
WorldGlass glass = new MemoryGlass(simpleLocation);
|
||||
optionalWorldGlass = Optional.of(glass);
|
||||
plugin.getWorldManager().addGlassAt(glass, simpleLocation);
|
||||
}
|
||||
|
||||
// fire event
|
||||
GreenhouseGlassBreakEvent event = new GreenhouseGlassBreakEvent(breakWrapper.getPlayer(), breakWrapper.getLocation());
|
||||
GreenhouseGlassBreakEvent event = new GreenhouseGlassBreakEvent(breakWrapper.getPlayer(), location, optionalWorldGlass.get(), Reason.BREAK);
|
||||
if (EventUtils.fireAndCheckCancel(event))
|
||||
return FunctionResult.CANCEL_EVENT_AND_RETURN;
|
||||
|
||||
plugin.getWorldManager().removeGlassAt(SimpleLocation.of(breakWrapper.getLocation()));
|
||||
plugin.getWorldManager().removeGlassAt(simpleLocation);
|
||||
return FunctionResult.RETURN;
|
||||
}, CFunction.FunctionPriority.NORMAL)
|
||||
);
|
||||
@@ -661,12 +673,23 @@ public class ItemManagerImpl implements ItemManager {
|
||||
if (!(conditionWrapper instanceof BreakWrapper breakWrapper)) {
|
||||
return FunctionResult.PASS;
|
||||
}
|
||||
|
||||
// get or fix
|
||||
Location location = breakWrapper.getLocation();
|
||||
SimpleLocation simpleLocation = SimpleLocation.of(location);
|
||||
Optional<WorldScarecrow> optionalWorldScarecrow = plugin.getWorldManager().getScarecrowAt(simpleLocation);
|
||||
if (optionalWorldScarecrow.isEmpty()) {
|
||||
WorldScarecrow scarecrow = new MemoryScarecrow(simpleLocation);
|
||||
optionalWorldScarecrow = Optional.of(scarecrow);
|
||||
plugin.getWorldManager().addScarecrowAt(scarecrow, simpleLocation);
|
||||
}
|
||||
|
||||
// fire event
|
||||
ScarecrowBreakEvent event = new ScarecrowBreakEvent(breakWrapper.getPlayer(), breakWrapper.getLocation());
|
||||
ScarecrowBreakEvent event = new ScarecrowBreakEvent(breakWrapper.getPlayer(), location, optionalWorldScarecrow.get(), Reason.BREAK);
|
||||
if (EventUtils.fireAndCheckCancel(event))
|
||||
return FunctionResult.CANCEL_EVENT_AND_RETURN;
|
||||
|
||||
plugin.getWorldManager().removeScarecrowAt(SimpleLocation.of(breakWrapper.getLocation()));
|
||||
plugin.getWorldManager().removeScarecrowAt(simpleLocation);
|
||||
return FunctionResult.RETURN;
|
||||
}, CFunction.FunctionPriority.NORMAL)
|
||||
);
|
||||
@@ -740,8 +763,20 @@ public class ItemManagerImpl implements ItemManager {
|
||||
int waterInCan = wateringCan.getCurrentWater(itemStack);
|
||||
|
||||
if (waterInCan > 0 || wateringCan.isInfinite()) {
|
||||
|
||||
Collection<Location> pots = getPotInRange(clicked, wateringCan.getWidth(), wateringCan.getLength(), player.getLocation().getYaw(), pot.getKey());
|
||||
// get or fix pot
|
||||
SimpleLocation simpleLocation = SimpleLocation.of(clicked);
|
||||
Optional<WorldPot> worldPot = plugin.getWorldManager().getPotAt(simpleLocation);
|
||||
if (worldPot.isEmpty()) {
|
||||
plugin.debug("Found pot data not exists at " + simpleLocation + ". Fixing it.");
|
||||
MemoryPot memoryPot = new MemoryPot(simpleLocation, pot.getKey());
|
||||
plugin.getWorldManager().addPotAt(memoryPot, simpleLocation);
|
||||
worldPot = Optional.of(memoryPot);
|
||||
}
|
||||
|
||||
// fire the event
|
||||
WateringCanWaterEvent waterEvent = new WateringCanWaterEvent(player, itemStack, wateringCan, clicked, pot);
|
||||
WateringCanWaterEvent waterEvent = new WateringCanWaterEvent(player, itemStack, new HashSet<>(pots), wateringCan, worldPot.get());
|
||||
if (EventUtils.fireAndCheckCancel(waterEvent))
|
||||
return FunctionResult.CANCEL_EVENT_AND_RETURN;
|
||||
|
||||
@@ -750,8 +785,8 @@ public class ItemManagerImpl implements ItemManager {
|
||||
state.setArg("{water_bar}", wateringCan.getWaterBar() == null ? "" : wateringCan.getWaterBar().getWaterBar(waterInCan - 1, wateringCan.getStorage()));
|
||||
wateringCan.updateItem(player, itemStack, waterInCan - 1, state.getArgs());
|
||||
wateringCan.trigger(ActionTrigger.CONSUME_WATER, state);
|
||||
Collection<Location> pots = getPotInRange(clicked, wateringCan.getWidth(), wateringCan.getLength(), player.getLocation().getYaw(), pot.getKey());
|
||||
for (Location location : pots) {
|
||||
|
||||
for (Location location : waterEvent.getLocation()) {
|
||||
plugin.getWorldManager().addWaterToPot(pot, SimpleLocation.of(location), wateringCan.getWater());
|
||||
pot.trigger(ActionTrigger.ADD_WATER, new State(player, itemStack, location));
|
||||
}
|
||||
@@ -809,8 +844,21 @@ public class ItemManagerImpl implements ItemManager {
|
||||
int waterInCan = wateringCan.getCurrentWater(itemStack);
|
||||
|
||||
if (waterInCan > 0 || wateringCan.isInfinite()) {
|
||||
|
||||
Collection<Location> pots = getPotInRange(potBlock.getLocation(), wateringCan.getWidth(), wateringCan.getLength(), player.getLocation().getYaw(), pot.getKey());
|
||||
|
||||
// get or fix pot
|
||||
SimpleLocation simpleLocation = SimpleLocation.of(potBlock.getLocation());
|
||||
Optional<WorldPot> worldPot = plugin.getWorldManager().getPotAt(simpleLocation);
|
||||
if (worldPot.isEmpty()) {
|
||||
plugin.debug("Found pot data not exists at " + simpleLocation + ". Fixing it.");
|
||||
MemoryPot memoryPot = new MemoryPot(simpleLocation, pot.getKey());
|
||||
plugin.getWorldManager().addPotAt(memoryPot, simpleLocation);
|
||||
worldPot = Optional.of(memoryPot);
|
||||
}
|
||||
|
||||
// fire the event
|
||||
WateringCanWaterEvent waterEvent = new WateringCanWaterEvent(player, itemStack, wateringCan, potBlock.getLocation(), pot);
|
||||
WateringCanWaterEvent waterEvent = new WateringCanWaterEvent(player, itemStack, new HashSet<>(pots), wateringCan, worldPot.get());
|
||||
if (EventUtils.fireAndCheckCancel(waterEvent))
|
||||
return FunctionResult.CANCEL_EVENT_AND_RETURN;
|
||||
|
||||
@@ -819,8 +867,8 @@ public class ItemManagerImpl implements ItemManager {
|
||||
state.setArg("{water_bar}", wateringCan.getWaterBar() == null ? "" : wateringCan.getWaterBar().getWaterBar(waterInCan - 1, wateringCan.getStorage()));
|
||||
wateringCan.updateItem(player, itemStack, waterInCan - 1, state.getArgs());
|
||||
wateringCan.trigger(ActionTrigger.CONSUME_WATER, state);
|
||||
Collection<Location> pots = getPotInRange(potBlock.getLocation(), wateringCan.getWidth(), wateringCan.getLength(), player.getLocation().getYaw(), pot.getKey());
|
||||
for (Location location : pots) {
|
||||
|
||||
for (Location location : waterEvent.getLocation()) {
|
||||
plugin.getWorldManager().addWaterToPot(pot, SimpleLocation.of(location), wateringCan.getWater());
|
||||
pot.trigger(ActionTrigger.ADD_WATER, new State(player, itemStack, location));
|
||||
}
|
||||
@@ -875,8 +923,21 @@ public class ItemManagerImpl implements ItemManager {
|
||||
int waterInCan = wateringCan.getCurrentWater(itemStack);
|
||||
|
||||
if (waterInCan > 0 || wateringCan.isInfinite()) {
|
||||
|
||||
Collection<Location> pots = getPotInRange(potBlock.getLocation(), wateringCan.getWidth(), wateringCan.getLength(), player.getLocation().getYaw(), pot.getKey());
|
||||
|
||||
// get or fix pot
|
||||
SimpleLocation simpleLocation = SimpleLocation.of(potBlock.getLocation());
|
||||
Optional<WorldPot> worldPot = plugin.getWorldManager().getPotAt(simpleLocation);
|
||||
if (worldPot.isEmpty()) {
|
||||
plugin.debug("Found pot data not exists at " + simpleLocation + ". Fixing it.");
|
||||
MemoryPot memoryPot = new MemoryPot(simpleLocation, pot.getKey());
|
||||
plugin.getWorldManager().addPotAt(memoryPot, simpleLocation);
|
||||
worldPot = Optional.of(memoryPot);
|
||||
}
|
||||
|
||||
// fire the event
|
||||
WateringCanWaterEvent waterEvent = new WateringCanWaterEvent(player, itemStack, wateringCan, clicked, pot);
|
||||
WateringCanWaterEvent waterEvent = new WateringCanWaterEvent(player, itemStack, new HashSet<>(pots), wateringCan, worldPot.get());
|
||||
if (EventUtils.fireAndCheckCancel(waterEvent))
|
||||
return FunctionResult.CANCEL_EVENT_AND_RETURN;
|
||||
|
||||
@@ -885,8 +946,8 @@ public class ItemManagerImpl implements ItemManager {
|
||||
state.setArg("{water_bar}", wateringCan.getWaterBar() == null ? "" : wateringCan.getWaterBar().getWaterBar(waterInCan - 1, wateringCan.getStorage()));
|
||||
wateringCan.updateItem(player, itemStack, waterInCan - 1, state.getArgs());
|
||||
wateringCan.trigger(ActionTrigger.CONSUME_WATER, state);
|
||||
Collection<Location> pots = getPotInRange(potBlock.getLocation(), wateringCan.getWidth(), wateringCan.getLength(), player.getLocation().getYaw(), pot.getKey());
|
||||
for (Location location : pots) {
|
||||
|
||||
for (Location location : waterEvent.getLocation()) {
|
||||
plugin.getWorldManager().addWaterToPot(pot, SimpleLocation.of(location), wateringCan.getWater());
|
||||
pot.trigger(ActionTrigger.ADD_WATER, new State(player, itemStack, location));
|
||||
}
|
||||
@@ -936,6 +997,9 @@ public class ItemManagerImpl implements ItemManager {
|
||||
Optional<WorldSprinkler> worldSprinkler = plugin.getWorldManager().getSprinklerAt(simpleLocation);
|
||||
if (worldSprinkler.isEmpty()) {
|
||||
plugin.debug("Player " + player.getName() + " tried to interact a sprinkler which not exists in memory. Fixing the data...");
|
||||
WorldSprinkler sp = new MemorySprinkler(simpleLocation, sprinkler.getKey(), 0);
|
||||
plugin.getWorldManager().addSprinklerAt(sp, simpleLocation);
|
||||
worldSprinkler = Optional.of(sp);
|
||||
} else {
|
||||
if (sprinkler.getStorage() <= worldSprinkler.get().getWater()) {
|
||||
return FunctionResult.RETURN;
|
||||
@@ -943,7 +1007,7 @@ public class ItemManagerImpl implements ItemManager {
|
||||
}
|
||||
|
||||
// fire the event
|
||||
WateringCanWaterEvent waterEvent = new WateringCanWaterEvent(player, itemInHand, wateringCan, location, sprinkler);
|
||||
WateringCanWaterEvent waterEvent = new WateringCanWaterEvent(player, itemInHand, new HashSet<>(Set.of(location)), wateringCan, worldSprinkler.get());
|
||||
if (EventUtils.fireAndCheckCancel(waterEvent))
|
||||
return FunctionResult.CANCEL_EVENT_AND_RETURN;
|
||||
|
||||
@@ -969,7 +1033,7 @@ public class ItemManagerImpl implements ItemManager {
|
||||
if (method.getId().equals(clickedFurnitureID)) {
|
||||
if (method.canFill(state)) {
|
||||
// fire the event
|
||||
WateringCanFillEvent fillEvent = new WateringCanFillEvent(player, itemInHand, wateringCan, location, method);
|
||||
WateringCanFillEvent fillEvent = new WateringCanFillEvent(player, itemInHand, location, wateringCan, method);
|
||||
if (EventUtils.fireAndCheckCancel(fillEvent))
|
||||
return FunctionResult.CANCEL_EVENT_AND_RETURN;
|
||||
|
||||
@@ -1029,7 +1093,7 @@ public class ItemManagerImpl implements ItemManager {
|
||||
if (method.canFill(state)) {
|
||||
if (water < wateringCan.getStorage()) {
|
||||
// fire the event
|
||||
WateringCanFillEvent fillEvent = new WateringCanFillEvent(player, itemInHand, wateringCan, state.getLocation(), method);
|
||||
WateringCanFillEvent fillEvent = new WateringCanFillEvent(player, itemInHand, state.getLocation(), wateringCan, method);
|
||||
if (EventUtils.fireAndCheckCancel(fillEvent))
|
||||
return FunctionResult.CANCEL_EVENT_AND_RETURN;
|
||||
|
||||
@@ -1083,7 +1147,7 @@ public class ItemManagerImpl implements ItemManager {
|
||||
if (method.canFill(state)) {
|
||||
if (water < wateringCan.getStorage()) {
|
||||
// fire the event
|
||||
WateringCanFillEvent fillEvent = new WateringCanFillEvent(player, itemInHand, wateringCan, state.getLocation(), method);
|
||||
WateringCanFillEvent fillEvent = new WateringCanFillEvent(player, itemInHand, state.getLocation(), wateringCan, method);
|
||||
if (EventUtils.fireAndCheckCancel(fillEvent))
|
||||
return FunctionResult.CANCEL_EVENT_AND_RETURN;
|
||||
|
||||
@@ -1367,7 +1431,7 @@ public class ItemManagerImpl implements ItemManager {
|
||||
return FunctionResult.RETURN;
|
||||
}
|
||||
// fire event
|
||||
SprinklerBreakEvent breakEvent = new SprinklerBreakEvent(breakFurnitureWrapper.getPlayer(), location, optionalSprinkler.get());
|
||||
SprinklerBreakEvent breakEvent = new SprinklerBreakEvent(breakFurnitureWrapper.getPlayer(), location, optionalSprinkler.get(), Reason.BREAK);
|
||||
if (EventUtils.fireAndCheckCancel(breakEvent)) {
|
||||
return FunctionResult.CANCEL_EVENT_AND_RETURN;
|
||||
}
|
||||
@@ -1487,10 +1551,17 @@ public class ItemManagerImpl implements ItemManager {
|
||||
Optional<WorldPot> worldPot = plugin.getWorldManager().getPotAt(simpleLocation);
|
||||
boolean hasWater = false;
|
||||
if (worldPot.isEmpty()) {
|
||||
plugin.debug("Found pot data not exists at " + simpleLocation);
|
||||
plugin.debug("Found pot data not exists at " + simpleLocation + ". Fixing it.");
|
||||
MemoryPot memoryPot = new MemoryPot(simpleLocation, pot.getKey());
|
||||
plugin.getWorldManager().addPotAt(memoryPot, simpleLocation);
|
||||
worldPot = Optional.of(memoryPot);
|
||||
} else {
|
||||
hasWater = worldPot.get().getWater() > 0;
|
||||
}
|
||||
// fire the event
|
||||
FertilizerUseEvent useEvent = new FertilizerUseEvent(state.getPlayer(), itemInHand, fertilizer, location, worldPot.get());
|
||||
if (EventUtils.fireAndCheckCancel(useEvent))
|
||||
return FunctionResult.CANCEL_EVENT_AND_RETURN;
|
||||
|
||||
// add data
|
||||
plugin.getWorldManager().addFertilizerToPot(pot, fertilizer, simpleLocation);
|
||||
@@ -1548,10 +1619,17 @@ public class ItemManagerImpl implements ItemManager {
|
||||
Optional<WorldPot> worldPot = plugin.getWorldManager().getPotAt(simpleLocation);
|
||||
boolean hasWater = false;
|
||||
if (worldPot.isEmpty()) {
|
||||
plugin.debug("Found pot data not exists at " + potLocation);
|
||||
plugin.debug("Found pot data not exists at " + simpleLocation + ". Fixing it.");
|
||||
MemoryPot memoryPot = new MemoryPot(simpleLocation, pot.getKey());
|
||||
plugin.getWorldManager().addPotAt(memoryPot, simpleLocation);
|
||||
worldPot = Optional.of(memoryPot);
|
||||
} else {
|
||||
hasWater = worldPot.get().getWater() > 0;
|
||||
}
|
||||
// fire the event
|
||||
FertilizerUseEvent useEvent = new FertilizerUseEvent(state.getPlayer(), itemInHand, fertilizer, location, worldPot.get());
|
||||
if (EventUtils.fireAndCheckCancel(useEvent))
|
||||
return FunctionResult.CANCEL_EVENT_AND_RETURN;
|
||||
|
||||
// add data
|
||||
plugin.getWorldManager().addFertilizerToPot(pot, fertilizer, simpleLocation);
|
||||
@@ -1808,6 +1886,11 @@ public class ItemManagerImpl implements ItemManager {
|
||||
if (optionalCrop.get().getPoint() < crop.getMaxPoints()) {
|
||||
for (BoneMeal boneMeal : crop.getBoneMeals()) {
|
||||
if (boneMeal.getItem().equals(itemID)) {
|
||||
// fire the event
|
||||
BoneMealUseEvent useEvent = new BoneMealUseEvent(player, itemInHand, cropLocation, boneMeal, optionalCrop.get());
|
||||
if (EventUtils.fireAndCheckCancel(useEvent))
|
||||
return FunctionResult.CANCEL_EVENT_AND_RETURN;
|
||||
|
||||
if (player.getGameMode() != GameMode.CREATIVE) {
|
||||
itemInHand.setAmount(itemAmount - boneMeal.getUsedAmount());
|
||||
if (boneMeal.getReturned() != null) {
|
||||
@@ -1852,6 +1935,9 @@ public class ItemManagerImpl implements ItemManager {
|
||||
SimpleLocation simpleLocation = SimpleLocation.of(cropLocation);
|
||||
Optional<WorldCrop> optionalWorldCrop = plugin.getWorldManager().getCropAt(simpleLocation);
|
||||
if (optionalWorldCrop.isEmpty()) {
|
||||
WorldCrop worldCrop = new MemoryCrop(simpleLocation, crop.getKey(), stage.getPoint());
|
||||
plugin.getWorldManager().addCropAt(worldCrop, simpleLocation);
|
||||
optionalWorldCrop = Optional.of(worldCrop);
|
||||
plugin.debug("Found a crop without data broken by " + player.getName() + " at " + cropLocation + ". " +
|
||||
"You can safely ignore this if the crop is spawned in the wild.");
|
||||
} else {
|
||||
@@ -1862,7 +1948,7 @@ public class ItemManagerImpl implements ItemManager {
|
||||
}
|
||||
}
|
||||
// fire event
|
||||
CropBreakEvent breakEvent = new CropBreakEvent(player, cropLocation, optionalWorldCrop.orElse(null));
|
||||
CropBreakEvent breakEvent = new CropBreakEvent(player, cropLocation, optionalWorldCrop.get(), Reason.BREAK);
|
||||
if (EventUtils.fireAndCheckCancel(breakEvent))
|
||||
return FunctionResult.CANCEL_EVENT_AND_RETURN;
|
||||
// trigger actions
|
||||
@@ -2036,23 +2122,27 @@ public class ItemManagerImpl implements ItemManager {
|
||||
if (!RequirementManager.isRequirementMet(cropState, stage.getBreakRequirements())) {
|
||||
return FunctionResult.CANCEL_EVENT_AND_RETURN;
|
||||
}
|
||||
Optional<WorldCrop> optionalWorldCrop = plugin.getWorldManager().getCropAt(SimpleLocation.of(cropLocation));
|
||||
SimpleLocation simpleLocation = SimpleLocation.of(cropLocation);
|
||||
Optional<WorldCrop> optionalWorldCrop = plugin.getWorldManager().getCropAt(simpleLocation);
|
||||
if (optionalWorldCrop.isPresent()) {
|
||||
if (!optionalWorldCrop.get().getKey().equals(crop.getKey())) {
|
||||
LogUtils.warn("Found a crop having inconsistent data broken by " + player.getName() + " at " + cropLocation + ".");
|
||||
}
|
||||
} else {
|
||||
WorldCrop worldCrop = new MemoryCrop(simpleLocation, crop.getKey(), stage.getPoint());
|
||||
optionalWorldCrop = Optional.of(worldCrop);
|
||||
plugin.getWorldManager().addCropAt(worldCrop, simpleLocation);
|
||||
plugin.debug("Found a crop without data broken by " + player.getName() + " at " + cropLocation + ". " +
|
||||
"You can safely ignore this if the crop is spawned in the wild.");
|
||||
}
|
||||
// fire event
|
||||
CropBreakEvent breakEvent = new CropBreakEvent(player, cropLocation, optionalWorldCrop.orElse(null));
|
||||
CropBreakEvent breakEvent = new CropBreakEvent(player, cropLocation, optionalWorldCrop.get(), Reason.BREAK);
|
||||
if (EventUtils.fireAndCheckCancel(breakEvent))
|
||||
return FunctionResult.CANCEL_EVENT_AND_RETURN;
|
||||
// trigger actions
|
||||
stage.trigger(ActionTrigger.BREAK, cropState);
|
||||
crop.trigger(ActionTrigger.BREAK, cropState);
|
||||
plugin.getWorldManager().removeCropAt(SimpleLocation.of(cropLocation));
|
||||
plugin.getWorldManager().removeCropAt(simpleLocation);
|
||||
customProvider.removeAnythingAt(cropLocation);
|
||||
} else {
|
||||
LogUtils.warn("Invalid crop stage: " + cropStageID);
|
||||
@@ -2076,7 +2166,7 @@ public class ItemManagerImpl implements ItemManager {
|
||||
return FunctionResult.RETURN;
|
||||
}
|
||||
// fire event
|
||||
PotBreakEvent breakEvent = new PotBreakEvent(blockWrapper.getPlayer(), location, optionalPot.get());
|
||||
PotBreakEvent breakEvent = new PotBreakEvent(blockWrapper.getPlayer(), location, optionalPot.get(), Reason.BREAK);
|
||||
if (EventUtils.fireAndCheckCancel(breakEvent)) {
|
||||
return FunctionResult.CANCEL_EVENT_AND_RETURN;
|
||||
}
|
||||
@@ -2297,47 +2387,139 @@ public class ItemManagerImpl implements ItemManager {
|
||||
if (entity instanceof Player player) {
|
||||
handlePlayerBreakBlock(player, block, event);
|
||||
} else {
|
||||
// if the block is a pot
|
||||
Pot pot = getPotByBlock(block);
|
||||
if (pot != null) {
|
||||
// prevent entities from breaking pots with requirements
|
||||
if (pot.getBreakRequirements().length != 0) {
|
||||
Location potLocation = block.getLocation();
|
||||
// get or fix pot
|
||||
SimpleLocation potSimpleLocation = SimpleLocation.of(potLocation);
|
||||
Optional<WorldPot> worldPot = plugin.getWorldManager().getPotAt(potSimpleLocation);
|
||||
if (worldPot.isEmpty()) {
|
||||
plugin.debug("Found pot data not exists at " + potSimpleLocation + ". Fixing it.");
|
||||
MemoryPot memoryPot = new MemoryPot(potSimpleLocation, pot.getKey());
|
||||
plugin.getWorldManager().addPotAt(memoryPot, potSimpleLocation);
|
||||
worldPot = Optional.of(memoryPot);
|
||||
}
|
||||
// fire the event
|
||||
PotBreakEvent potBreakEvent = new PotBreakEvent(entity, potLocation, worldPot.get(), Reason.TRAMPLE);
|
||||
if (EventUtils.fireAndCheckCancel(potBreakEvent)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.getWorldManager().removePotAt(SimpleLocation.of(block.getLocation()));
|
||||
pot.trigger(ActionTrigger.BREAK, new State(null, new ItemStack(Material.AIR), block.getLocation()));
|
||||
|
||||
Location cropLocation = block.getLocation().clone().add(0,1,0);
|
||||
String cropStageID = customProvider.getSomethingAt(cropLocation);
|
||||
Crop.Stage stage = stage2CropStageMap.get(cropStageID);
|
||||
if (stage != null) {
|
||||
//State state = new State(null, new ItemStack(Material.AIR), cropLocation);
|
||||
// if crops are above, check the break requirements for crops
|
||||
Crop crop = getCropByStageID(cropStageID);
|
||||
if (crop.getBreakRequirements().length != 0 || stage.getBreakRequirements().length != 0) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
Optional<WorldCrop> optionalWorldCrop = plugin.getWorldManager().getCropAt(SimpleLocation.of(cropLocation));
|
||||
SimpleLocation simpleLocation = SimpleLocation.of(cropLocation);
|
||||
Optional<WorldCrop> optionalWorldCrop = plugin.getWorldManager().getCropAt(simpleLocation);
|
||||
if (optionalWorldCrop.isPresent()) {
|
||||
if (!optionalWorldCrop.get().getKey().equals(crop.getKey())) {
|
||||
LogUtils.warn("Found a crop having inconsistent data broken by " + entity.getType() + " at " + cropLocation + ".");
|
||||
}
|
||||
} else {
|
||||
WorldCrop worldCrop = new MemoryCrop(simpleLocation, crop.getKey(), stage.getPoint());
|
||||
plugin.getWorldManager().addCropAt(worldCrop, simpleLocation);
|
||||
optionalWorldCrop = Optional.of(worldCrop);
|
||||
plugin.debug("Found a crop without data broken by " + entity.getType() + " at " + cropLocation + ". " +
|
||||
"You can safely ignore this if the crop is spawned in the wild.");
|
||||
}
|
||||
// fire the event
|
||||
CropBreakEvent breakEvent = new CropBreakEvent(entity, cropLocation, optionalWorldCrop.get(), Reason.TRAMPLE);
|
||||
if (EventUtils.fireAndCheckCancel(breakEvent)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
State state = new State(null, new ItemStack(Material.AIR), cropLocation);
|
||||
// trigger actions
|
||||
//stage.trigger(ActionTrigger.BREAK, state);
|
||||
//crop.trigger(ActionTrigger.BREAK, state);
|
||||
plugin.getWorldManager().removeCropAt(SimpleLocation.of(cropLocation));
|
||||
stage.trigger(ActionTrigger.BREAK, state);
|
||||
crop.trigger(ActionTrigger.BREAK, state);
|
||||
plugin.getWorldManager().removeCropAt(simpleLocation);
|
||||
customProvider.removeAnythingAt(cropLocation);
|
||||
}
|
||||
|
||||
if (deadCrops.contains(cropStageID)) {
|
||||
customProvider.removeAnythingAt(cropLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
plugin.getWorldManager().removePotAt(SimpleLocation.of(block.getLocation()));
|
||||
//pot.trigger(ActionTrigger.BREAK, new State(null, new ItemStack(Material.AIR), block.getLocation()));
|
||||
public void handleExplosion(Entity entity, List<Block> blocks, Cancellable event) {
|
||||
List<Location> locationsToRemove = new ArrayList<>();
|
||||
List<Location> locationsToRemoveBlock = new ArrayList<>();
|
||||
HashSet<Location> blockLocations = new HashSet<>(blocks.stream().map(Block::getLocation).toList());
|
||||
List<Location> aboveLocations = new ArrayList<>();
|
||||
for (Location location : blockLocations) {
|
||||
Optional<CustomCropsBlock> optionalCustomCropsBlock = plugin.getWorldManager().getBlockAt(SimpleLocation.of(location));
|
||||
if (optionalCustomCropsBlock.isPresent()) {
|
||||
Event customEvent = null;
|
||||
CustomCropsBlock customCropsBlock = optionalCustomCropsBlock.get();
|
||||
switch (customCropsBlock.getType()) {
|
||||
case POT -> {
|
||||
customEvent = new PotBreakEvent(entity, location, (WorldPot) customCropsBlock, Reason.EXPLODE);
|
||||
Location above = location.clone().add(0,1,0);
|
||||
if (!blockLocations.contains(above)) {
|
||||
aboveLocations.add(above);
|
||||
}
|
||||
}
|
||||
case SPRINKLER -> customEvent = new SprinklerBreakEvent(entity, location, (WorldSprinkler) customCropsBlock, Reason.EXPLODE);
|
||||
case CROP -> customEvent = new CropBreakEvent(entity, location, (WorldCrop) customCropsBlock, Reason.EXPLODE);
|
||||
case GREENHOUSE -> customEvent = new GreenhouseGlassBreakEvent(entity, location, (WorldGlass) customCropsBlock, Reason.EXPLODE);
|
||||
case SCARECROW -> customEvent = new ScarecrowBreakEvent(entity, location, (WorldScarecrow) customCropsBlock, Reason.EXPLODE);
|
||||
}
|
||||
if (customEvent != null && EventUtils.fireAndCheckCancel(customEvent)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
locationsToRemove.add(location);
|
||||
}
|
||||
}
|
||||
|
||||
for (Location location : aboveLocations) {
|
||||
Optional<CustomCropsBlock> optionalCustomCropsBlock = plugin.getWorldManager().getBlockAt(SimpleLocation.of(location));
|
||||
if (optionalCustomCropsBlock.isPresent()) {
|
||||
CustomCropsBlock customCropsBlock = optionalCustomCropsBlock.get();
|
||||
if (customCropsBlock.getType() == ItemType.CROP) {
|
||||
if (EventUtils.fireAndCheckCancel(new CropBreakEvent(entity, location, (WorldCrop) customCropsBlock, Reason.EXPLODE))) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
locationsToRemove.add(location);
|
||||
locationsToRemoveBlock.add(location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Location location : locationsToRemoveBlock) {
|
||||
removeAnythingAt(location);
|
||||
}
|
||||
|
||||
for (Location location : locationsToRemove) {
|
||||
CustomCropsBlock customCropsBlock = plugin.getWorldManager().removeAnythingAt(SimpleLocation.of(location));
|
||||
if (customCropsBlock != null) {
|
||||
State state = new State(null, new ItemStack(Material.AIR), location);
|
||||
switch (customCropsBlock.getType()) {
|
||||
case POT -> {
|
||||
Pot pot = ((WorldPot) customCropsBlock).getConfig();
|
||||
pot.trigger(ActionTrigger.BREAK, state);
|
||||
}
|
||||
case CROP -> {
|
||||
Crop crop = ((WorldCrop) customCropsBlock).getConfig();
|
||||
Crop.Stage stage = crop.getStageByItemID(crop.getStageItemByPoint(((WorldCrop) customCropsBlock).getPoint()));
|
||||
crop.trigger(ActionTrigger.BREAK, state);
|
||||
stage.trigger(ActionTrigger.BREAK, state);
|
||||
}
|
||||
case SPRINKLER -> {
|
||||
Sprinkler sprinkler = ((WorldSprinkler) customCropsBlock).getConfig();
|
||||
sprinkler.trigger(ActionTrigger.BREAK, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,17 +18,19 @@
|
||||
package net.momirealms.customcrops.mechanic.item.custom;
|
||||
|
||||
import net.momirealms.customcrops.api.CustomCropsPlugin;
|
||||
import net.momirealms.customcrops.api.event.BoneMealDispenseEvent;
|
||||
import net.momirealms.customcrops.api.manager.ConfigManager;
|
||||
import net.momirealms.customcrops.api.manager.WorldManager;
|
||||
import net.momirealms.customcrops.api.mechanic.item.Crop;
|
||||
import net.momirealms.customcrops.api.mechanic.item.Pot;
|
||||
import net.momirealms.customcrops.api.mechanic.item.Sprinkler;
|
||||
import net.momirealms.customcrops.api.mechanic.item.WateringCan;
|
||||
import net.momirealms.customcrops.api.mechanic.item.*;
|
||||
import net.momirealms.customcrops.api.mechanic.requirement.State;
|
||||
import net.momirealms.customcrops.api.mechanic.world.SimpleLocation;
|
||||
import net.momirealms.customcrops.api.mechanic.world.level.WorldCrop;
|
||||
import net.momirealms.customcrops.mechanic.item.ItemManagerImpl;
|
||||
import net.momirealms.customcrops.utils.EventUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Dispenser;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -38,13 +40,17 @@ import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.*;
|
||||
import org.bukkit.event.entity.EntityChangeBlockEvent;
|
||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
import org.bukkit.event.entity.ItemSpawnEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerItemDamageEvent;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public abstract class AbstractCustomListener implements Listener {
|
||||
|
||||
protected ItemManagerImpl itemManager;
|
||||
@@ -195,19 +201,76 @@ public abstract class AbstractCustomListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler (ignoreCancelled = true)
|
||||
public void onExplosion(EntityExplodeEvent event) {
|
||||
this.itemManager.handleExplosion(event.getEntity(), event.blockList(), event);
|
||||
}
|
||||
|
||||
@EventHandler (ignoreCancelled = true)
|
||||
public void onExplosion(BlockExplodeEvent event) {
|
||||
this.itemManager.handleExplosion(null, event.blockList(), event);
|
||||
}
|
||||
|
||||
@EventHandler (ignoreCancelled = true)
|
||||
public void onDispenser(BlockDispenseEvent event) {
|
||||
Block block = event.getBlock();
|
||||
if (block.getBlockData() instanceof org.bukkit.block.data.type.Dispenser directional) {
|
||||
Block relative = block.getRelative(directional.getFacing());
|
||||
Location location = relative.getLocation();
|
||||
SimpleLocation simpleLocation = SimpleLocation.of(location);
|
||||
Optional<WorldCrop> worldCropOptional = CustomCropsPlugin.get().getWorldManager().getCropAt(simpleLocation);
|
||||
if (worldCropOptional.isPresent()) {
|
||||
WorldCrop crop = worldCropOptional.get();
|
||||
Crop config = crop.getConfig();
|
||||
ItemStack itemStack = event.getItem();
|
||||
String itemID = itemManager.getItemID(itemStack);
|
||||
if (crop.getPoint() < config.getMaxPoints()) {
|
||||
for (BoneMeal boneMeal : config.getBoneMeals()) {
|
||||
if (boneMeal.getItem().equals(itemID)) {
|
||||
// fire the event
|
||||
if (EventUtils.fireAndCheckCancel(new BoneMealDispenseEvent(block, itemStack, location, boneMeal, crop))) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (block.getState() instanceof Dispenser dispenser) {
|
||||
event.setCancelled(true);
|
||||
Inventory inventory = dispenser.getInventory();
|
||||
for (ItemStack storage : inventory.getStorageContents()) {
|
||||
if (storage == null) continue;
|
||||
String id = itemManager.getItemID(storage);
|
||||
if (id.equals(itemID)) {
|
||||
storage.setAmount(storage.getAmount() - 1);
|
||||
boneMeal.trigger(new State(null, itemStack, location));
|
||||
CustomCropsPlugin.get().getWorldManager().addPointToCrop(config, simpleLocation, boneMeal.getPoint());
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onPlaceBlock(Player player, Block block, String blockID, Cancellable event) {
|
||||
if (player == null) return;
|
||||
this.itemManager.handlePlayerPlaceBlock(player, block, blockID, event);
|
||||
}
|
||||
|
||||
public void onBreakFurniture(Player player, Location location, String id, Cancellable event) {
|
||||
if (player == null) return;
|
||||
this.itemManager.handlePlayerBreakFurniture(player, location, id, event);
|
||||
}
|
||||
|
||||
public void onPlaceFurniture(Player player, Location location, String id, Cancellable event) {
|
||||
if (player == null) return;
|
||||
this.itemManager.handlePlayerPlaceFurniture(player, location, id, event);
|
||||
}
|
||||
|
||||
public void onInteractFurniture(Player player, Location location, String id, @Nullable Entity baseEntity, Cancellable event) {
|
||||
if (player == null) return;
|
||||
this.itemManager.handlePlayerInteractFurniture(player, location, id, baseEntity, event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,6 +125,7 @@ public class RequirementManagerImpl implements RequirementManager {
|
||||
this.registerTemperatureRequirement();
|
||||
this.registerFertilizerRequirement();
|
||||
this.registerLightRequirement();
|
||||
this.registerGameModeRequirement();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -228,6 +229,21 @@ public class RequirementManagerImpl implements RequirementManager {
|
||||
});
|
||||
}
|
||||
|
||||
private void registerGameModeRequirement() {
|
||||
registerRequirement("gamemode", (args, actions, advanced) -> {
|
||||
List<String> modes = ConfigUtils.stringListArgs(args);
|
||||
return condition -> {
|
||||
if (condition.getPlayer() == null) return true;
|
||||
var name = condition.getPlayer().getGameMode().name().toLowerCase(Locale.ENGLISH);
|
||||
if (modes.contains(name)) {
|
||||
return true;
|
||||
}
|
||||
if (advanced) triggerActions(actions, condition);
|
||||
return false;
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
private void registerTemperatureRequirement() {
|
||||
registerRequirement("temperature", (args, actions, advanced) -> {
|
||||
List<Pair<Integer, Integer>> tempPairs = ConfigUtils.stringListArgs(args).stream().map(it -> ConfigUtils.splitStringIntegerArgs(it, "~")).toList();
|
||||
@@ -317,6 +333,7 @@ public class RequirementManagerImpl implements RequirementManager {
|
||||
registerRequirement("level", (args, actions, advanced) -> {
|
||||
int level = (int) args;
|
||||
return state -> {
|
||||
if (state.getPlayer() == null) return true;
|
||||
int current = state.getPlayer().getLevel();
|
||||
if (current >= level)
|
||||
return true;
|
||||
@@ -330,6 +347,7 @@ public class RequirementManagerImpl implements RequirementManager {
|
||||
registerRequirement("money", (args, actions, advanced) -> {
|
||||
double money = ConfigUtils.getDoubleValue(args);
|
||||
return state -> {
|
||||
if (state.getPlayer() == null) return true;
|
||||
double current = VaultHook.getEconomy().getBalance(state.getPlayer());
|
||||
if (current >= money)
|
||||
return true;
|
||||
@@ -420,6 +438,7 @@ public class RequirementManagerImpl implements RequirementManager {
|
||||
String key = section.getString("key");
|
||||
int time = section.getInt("time");
|
||||
return state -> {
|
||||
if (state.getPlayer() == null) return true;
|
||||
if (!plugin.getCoolDownManager().isCoolDown(state.getPlayer().getUniqueId(), key, time)) {
|
||||
return true;
|
||||
}
|
||||
@@ -451,6 +470,7 @@ public class RequirementManagerImpl implements RequirementManager {
|
||||
registerRequirement("sneak", (args, actions, advanced) -> {
|
||||
boolean sneak = (boolean) args;
|
||||
return state -> {
|
||||
if (state.getPlayer() == null) return true;
|
||||
if (sneak) {
|
||||
if (state.getPlayer().isSneaking())
|
||||
return true;
|
||||
@@ -468,6 +488,7 @@ public class RequirementManagerImpl implements RequirementManager {
|
||||
registerRequirement("permission", (args, actions, advanced) -> {
|
||||
List<String> perms = ConfigUtils.stringListArgs(args);
|
||||
return state -> {
|
||||
if (state.getPlayer() == null) return true;
|
||||
for (String perm : perms)
|
||||
if (state.getPlayer().hasPermission(perm))
|
||||
return true;
|
||||
@@ -478,6 +499,7 @@ public class RequirementManagerImpl implements RequirementManager {
|
||||
registerRequirement("!permission", (args, actions, advanced) -> {
|
||||
List<String> perms = ConfigUtils.stringListArgs(args);
|
||||
return state -> {
|
||||
if (state.getPlayer() == null) return true;
|
||||
for (String perm : perms)
|
||||
if (state.getPlayer().hasPermission(perm)) {
|
||||
if (advanced) triggerActions(actions, state);
|
||||
@@ -934,6 +956,7 @@ public class RequirementManagerImpl implements RequirementManager {
|
||||
int required = Integer.parseInt(split[1]);
|
||||
String operator = potions.substring(split[0].length(), potions.length() - split[1].length());
|
||||
return state -> {
|
||||
if (state.getPlayer() == null) return true;
|
||||
int level = -1;
|
||||
PotionEffect potionEffect = state.getPlayer().getPotionEffect(type);
|
||||
if (potionEffect != null) {
|
||||
|
||||
@@ -88,9 +88,7 @@ public class CChunk implements CustomCropsChunk {
|
||||
|
||||
@Override
|
||||
public void notifyOfflineUpdates() {
|
||||
long delta = this.lastLoadedTime - System.currentTimeMillis();
|
||||
int seconds = (int) (delta / 1000);
|
||||
|
||||
this.lastLoadedTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public void setWorld(CWorld cWorld) {
|
||||
|
||||
@@ -94,8 +94,10 @@ public class CWorld implements CustomCropsWorld {
|
||||
if (setting.isAutoSeasonChange()) {
|
||||
this.updateSeasonAndDate();
|
||||
}
|
||||
for (CChunk chunk : loadedChunks.values()) {
|
||||
chunk.secondTimer();
|
||||
if (setting.isSchedulerEnabled()) {
|
||||
for (CChunk chunk : loadedChunks.values()) {
|
||||
chunk.secondTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -328,6 +328,7 @@ public class ConfigUtils {
|
||||
innerSection.getInt("item-amount",1),
|
||||
innerSection.getString("return"),
|
||||
innerSection.getInt("return-amount",1),
|
||||
innerSection.getBoolean("dispenser",true),
|
||||
getIntChancePair(innerSection.getConfigurationSection("chance")),
|
||||
getActions(innerSection.getConfigurationSection("actions"))
|
||||
);
|
||||
|
||||
@@ -259,6 +259,8 @@ tomato:
|
||||
custom-bone-meal:
|
||||
bone_meal_1:
|
||||
item: BONE_MEAL
|
||||
# Allow to be used with dispenser
|
||||
dispenser: true
|
||||
chance:
|
||||
2: 0.2
|
||||
1: 0.6
|
||||
|
||||
Reference in New Issue
Block a user