9
0
mirror of https://github.com/Xiao-MoMi/Custom-Crops.git synced 2025-12-26 10:29:10 +00:00

3.0.0-beta

This commit is contained in:
Xiao-MoMi
2023-04-18 00:02:06 +08:00
parent 9092ee0fdc
commit 34f0e51908
31 changed files with 543 additions and 149 deletions

View File

@@ -32,7 +32,7 @@ import net.momirealms.customcrops.api.object.basic.MessageManager;
import net.momirealms.customcrops.api.object.crop.CropManager;
import net.momirealms.customcrops.api.object.fertilizer.FertilizerManager;
import net.momirealms.customcrops.api.object.pot.PotManager;
import net.momirealms.customcrops.api.object.schedule.Scheduler;
import net.momirealms.customcrops.api.object.scheduler.Scheduler;
import net.momirealms.customcrops.api.object.season.SeasonManager;
import net.momirealms.customcrops.api.object.sprinkler.SprinklerManager;
import net.momirealms.customcrops.api.object.wateringcan.WateringCanManager;

View File

@@ -21,10 +21,15 @@ import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.api.customplugin.PlatformInterface;
import net.momirealms.customcrops.api.object.ItemMode;
import net.momirealms.customcrops.api.object.crop.CropConfig;
import net.momirealms.customcrops.api.object.fertilizer.Fertilizer;
import net.momirealms.customcrops.api.object.pot.Pot;
import net.momirealms.customcrops.api.object.pot.PotConfig;
import net.momirealms.customcrops.api.object.season.CCSeason;
import net.momirealms.customcrops.api.object.world.SimpleLocation;
import net.momirealms.customcrops.api.util.ConfigUtils;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.inventory.ItemStack;
public class CustomCropsAPI {
@@ -78,8 +83,29 @@ public class CustomCropsAPI {
Location location = simpleLocation.getBukkitLocation();
if (location == null) return;
PlatformInterface platform = plugin.getPlatformInterface();
if (platform.removeCustomBlock(location)) {
platform.placeNoteBlock(location, pot.isWet() ? pot.getConfig().getWetPot(pot.getFertilizer()) : pot.getConfig().getDryPot(pot.getFertilizer()));
if (platform.removeAnyBlock(location)) {
String replacer = pot.isWet() ? pot.getConfig().getWetPot(pot.getFertilizer()) : pot.getConfig().getDryPot(pot.getFertilizer());
if (ConfigUtils.isVanillaItem(replacer)) {
location.getBlock().setType(Material.valueOf(replacer));
} else {
platform.placeNoteBlock(location, replacer);
}
} else {
CustomCrops.getInstance().getWorldDataManager().removePotData(simpleLocation);
}
}
public void changePotModel(SimpleLocation simpleLocation, PotConfig potConfig, Fertilizer fertilizer, boolean wet) {
Location location = simpleLocation.getBukkitLocation();
if (location == null) return;
PlatformInterface platform = plugin.getPlatformInterface();
if (platform.removeAnyBlock(location)) {
String replacer = wet ? potConfig.getWetPot(fertilizer) : potConfig.getDryPot(fertilizer);
if (ConfigUtils.isVanillaItem(replacer)) {
location.getBlock().setType(Material.valueOf(replacer));
} else {
platform.placeNoteBlock(location, replacer);
}
} else {
CustomCrops.getInstance().getWorldDataManager().removePotData(simpleLocation);
}

View File

@@ -23,6 +23,9 @@ import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockFromToEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerInteractEvent;
public abstract class Handler extends Function implements Listener {
@@ -47,4 +50,14 @@ public abstract class Handler extends Function implements Listener {
public void onInteract(PlayerInteractEvent event) {
platformManager.onInteractBlock(event);
}
@EventHandler
public void onBreak(BlockBreakEvent event) {
platformManager.onBreakVanilla(event);
}
@EventHandler
public void onPlace(BlockPlaceEvent event) {
platformManager.onPlaceVanilla(event);
}
}

View File

@@ -34,6 +34,20 @@ public interface PlatformInterface {
boolean removeCustomBlock(Location location);
default boolean removeAnyBlock(Location location) {
String id = getCustomBlockID(location);
if (id != null) {
return removeCustomBlock(location);
}
Block block = location.getBlock();
if (block.getType() == Material.AIR) {
return false;
} else {
block.setType(Material.AIR);
return true;
}
}
@Nullable
String getCustomBlockID(Location location);

View File

@@ -40,7 +40,9 @@ import net.momirealms.customcrops.api.object.pot.Pot;
import net.momirealms.customcrops.api.object.pot.PotConfig;
import net.momirealms.customcrops.api.object.requirement.CurrentState;
import net.momirealms.customcrops.api.object.requirement.Requirement;
import net.momirealms.customcrops.api.object.sprinkler.Sprinkler;
import net.momirealms.customcrops.api.object.sprinkler.SprinklerConfig;
import net.momirealms.customcrops.api.object.sprinkler.SprinklerHologram;
import net.momirealms.customcrops.api.object.wateringcan.WateringCanConfig;
import net.momirealms.customcrops.api.object.world.SimpleLocation;
import net.momirealms.customcrops.api.util.AdventureUtils;
@@ -52,6 +54,8 @@ import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
@@ -84,6 +88,18 @@ public class PlatformManager extends Function {
this.handler.unload();
}
public void onBreakVanilla(BlockBreakEvent event) {
if (event.isCancelled()) return;
Block block = event.getBlock();
onBreakSomething(event.getPlayer(), block.getLocation(), block.getType().name(), event);
}
public void onPlaceVanilla(BlockPlaceEvent event) {
if (event.isCancelled()) return;
Block block = event.getBlock();
onPlaceSomething(block.getLocation(), block.getType().name());
}
public void onBreakTripWire(Player player, Block block, String id, Cancellable event) {
if (event.isCancelled()) return;
onBreakSomething(player, block.getLocation(), id, event);
@@ -199,11 +215,11 @@ public class PlatformManager extends Function {
return ItemType.SPRINKLER;
}
if (onInteractPot(player, id, location, item_in_hand, item_in_hand_id)) {
if (onInteractPot(player, id, location, item_in_hand, item_in_hand_id, event)) {
return ItemType.POT;
}
if (onInteractCrop(player, id, location, item_in_hand, item_in_hand_id)) {
if (onInteractCrop(player, id, location, item_in_hand, item_in_hand_id, event)) {
return ItemType.CROP;
}
@@ -264,61 +280,72 @@ public class PlatformManager extends Function {
return false;
}
// water
PassiveFillMethod[] passiveFillMethods = sprinklerConfig.getPassiveFillMethods();
for (PassiveFillMethod passiveFillMethod : passiveFillMethods) {
if (passiveFillMethod.isRightItem(item_in_hand_id)) {
outer: {
// water
PassiveFillMethod[] passiveFillMethods = sprinklerConfig.getPassiveFillMethods();
for (PassiveFillMethod passiveFillMethod : passiveFillMethods) {
if (passiveFillMethod.isRightItem(item_in_hand_id)) {
SprinklerFillEvent sprinklerFillEvent = new SprinklerFillEvent(player, item_in_hand, passiveFillMethod.getAmount(), location);
SprinklerFillEvent sprinklerFillEvent = new SprinklerFillEvent(player, item_in_hand, passiveFillMethod.getAmount(), location);
Bukkit.getPluginManager().callEvent(sprinklerFillEvent);
if (sprinklerFillEvent.isCancelled()) {
return true;
}
doPassiveFillAction(player, item_in_hand, passiveFillMethod, location.clone().add(0,0.2,0));
plugin.getWorldDataManager().addWaterToSprinkler(SimpleLocation.getByBukkitLocation(location), sprinklerFillEvent.getWater(), sprinklerConfig);
break outer;
}
}
WateringCanConfig wateringCanConfig = plugin.getWateringCanManager().getConfigByItemID(item_in_hand_id);
if (wateringCanConfig != null) {
String[] sprinkler_whitelist = wateringCanConfig.getSprinklerWhitelist();
if (sprinkler_whitelist != null) {
inner: {
for (String sprinkler_allowed : sprinkler_whitelist) {
if (sprinkler_allowed.equals(plugin.getSprinklerManager().getConfigKeyByItemID(id))) {
break inner;
}
}
return true;
}
}
int current_water = plugin.getWateringCanManager().getCurrentWater(item_in_hand);
if (current_water <= 0) return true;
SprinklerFillEvent sprinklerFillEvent = new SprinklerFillEvent(player, item_in_hand, 1, location);
Bukkit.getPluginManager().callEvent(sprinklerFillEvent);
if (sprinklerFillEvent.isCancelled()) {
return true;
}
doPassiveFillAction(player, item_in_hand, passiveFillMethod, location.clone().add(0,0.2,0));
plugin.getWorldDataManager().addWaterToSprinkler(SimpleLocation.getByBukkitLocation(location), sprinklerFillEvent.getWater(), sprinklerConfig.getRange(), sprinklerConfig.getStorage());
return true;
}
}
WateringCanConfig wateringCanConfig = plugin.getWateringCanManager().getConfigByItemID(item_in_hand_id);
if (wateringCanConfig != null) {
String[] sprinkler_whitelist = wateringCanConfig.getSprinklerWhitelist();
if (sprinkler_whitelist != null) {
outer: {
for (String sprinkler_allowed : sprinkler_whitelist) {
if (sprinkler_allowed.equals(plugin.getSprinklerManager().getConfigKeyByItemID(id))) {
break outer;
}
}
return true;
current_water--;
if (wateringCanConfig.hasActionBar()) {
AdventureUtils.playerActionbar(player, wateringCanConfig.getActionBarMsg(current_water));
}
if (wateringCanConfig.getSound() != null) {
AdventureUtils.playerSound(player, wateringCanConfig.getSound());
}
if (wateringCanConfig.getParticle() != null) {
location.getWorld().spawnParticle(wateringCanConfig.getParticle(), location.clone().add(0.5,0.4, 0.5),5,0.3,0.1,0.3);
}
}
int current_water = plugin.getWateringCanManager().getCurrentWater(item_in_hand);
if (current_water <= 0) return true;
SprinklerFillEvent sprinklerFillEvent = new SprinklerFillEvent(player, item_in_hand, 1, location);
Bukkit.getPluginManager().callEvent(sprinklerFillEvent);
if (sprinklerFillEvent.isCancelled()) {
return true;
plugin.getWateringCanManager().setWater(item_in_hand, current_water, wateringCanConfig);
plugin.getWorldDataManager().addWaterToSprinkler(SimpleLocation.getByBukkitLocation(location), 1, sprinklerConfig);
break outer;
}
current_water--;
if (wateringCanConfig.hasActionBar()) {
AdventureUtils.playerActionbar(player, wateringCanConfig.getActionBarMsg(current_water));
}
if (wateringCanConfig.getSound() != null) {
AdventureUtils.playerSound(player, wateringCanConfig.getSound());
}
if (wateringCanConfig.getParticle() != null) {
location.getWorld().spawnParticle(wateringCanConfig.getParticle(), location.clone().add(0.5,0.4, 0.5),5,0.3,0.1,0.3);
}
plugin.getWateringCanManager().setWater(item_in_hand, current_water, wateringCanConfig);
plugin.getWorldDataManager().addWaterToSprinkler(SimpleLocation.getByBukkitLocation(location), 1, sprinklerConfig.getRange(), sprinklerConfig.getStorage());
return true;
}
Sprinkler sprinkler = plugin.getWorldDataManager().getSprinklerData(SimpleLocation.getByBukkitLocation(location));
if (sprinkler != null && sprinklerConfig.hasHologram()) {
SprinklerHologram sprinklerHologram = sprinklerConfig.getSprinklerHologram();
if (sprinklerHologram != null) {
String content = sprinklerHologram.getContent(sprinkler.getWater(), sprinklerConfig.getStorage());
plugin.getHologramManager().showHologram(player, location.clone().add(0.5,sprinklerHologram.getOffset(),0.5), AdventureUtils.getComponentFromMiniMessage(content),
sprinklerHologram.getDuration() * 1000, sprinklerHologram.getMode());
}
}
return true;
}
@@ -347,6 +374,12 @@ public class PlatformManager extends Function {
Location sprinkler_loc = location.clone().add(0,1,0);
if (plugin.getPlatformInterface().detectAnyThing(sprinkler_loc)) return true;
SprinklerPlaceEvent sprinklerPlaceEvent = new SprinklerPlaceEvent(player, item_in_hand, sprinkler_loc, sprinklerConfig);
Bukkit.getPluginManager().callEvent(sprinklerPlaceEvent);
if (sprinklerPlaceEvent.isCancelled()) {
return true;
}
if (player.getGameMode() != GameMode.CREATIVE) item_in_hand.setAmount(item_in_hand.getAmount() - 1);
CustomCropsAPI.getInstance().placeCustomItem(sprinkler_loc, sprinklerConfig.getThreeD(), sprinklerConfig.getItemMode());
if (sprinklerConfig.getSound() != null) {
@@ -355,7 +388,7 @@ public class PlatformManager extends Function {
return true;
}
public boolean onInteractCrop(Player player, String id, Location location, ItemStack item_in_hand, String item_in_hand_id) {
public boolean onInteractCrop(Player player, String id, Location location, ItemStack item_in_hand, String item_in_hand_id, Cancellable event) {
CropConfig cropConfig = plugin.getCropManager().getCropConfigByStage(id);
if (cropConfig == null) {
return false;
@@ -376,34 +409,53 @@ public class PlatformManager extends Function {
return true;
}
WateringCanConfig wateringCanConfig = plugin.getWateringCanManager().getConfigByItemID(item_in_hand_id);
Pot potData = plugin.getWorldDataManager().getPotData(SimpleLocation.getByBukkitLocation(location).add(0,-1,0));
if (wateringCanConfig != null && potData != null) {
String[] pot_whitelist = wateringCanConfig.getPotWhitelist();
if (pot_whitelist != null) {
outer: {
for (String pot : pot_whitelist) {
if (pot.equals(potData.getPotKey())) {
break outer;
}
if (potData != null) {
PassiveFillMethod[] passiveFillMethods = potData.getConfig().getPassiveFillMethods();
for (PassiveFillMethod passiveFillMethod : passiveFillMethods) {
if (passiveFillMethod.isRightItem(item_in_hand_id)) {
PotWaterEvent potWaterEvent = new PotWaterEvent(player, item_in_hand, passiveFillMethod.getAmount(), location);
Bukkit.getPluginManager().callEvent(potWaterEvent);
if (potWaterEvent.isCancelled()) {
return true;
}
event.setCancelled(true);
doPassiveFillAction(player, item_in_hand, passiveFillMethod, location);
potData.addWater(potWaterEvent.getWater());
return true;
}
}
int current_water = plugin.getWateringCanManager().getCurrentWater(item_in_hand);
if (current_water <= 0) return true;
Location pot_loc = location.clone().subtract(0,1,0);
PotWaterEvent potWaterEvent = new PotWaterEvent(player, item_in_hand, 1, pot_loc);
Bukkit.getPluginManager().callEvent(potWaterEvent);
if (potWaterEvent.isCancelled()) {
WateringCanConfig wateringCanConfig = plugin.getWateringCanManager().getConfigByItemID(item_in_hand_id);
if (wateringCanConfig != null) {
String[] pot_whitelist = wateringCanConfig.getPotWhitelist();
if (pot_whitelist != null) {
outer: {
for (String pot : pot_whitelist) {
if (pot.equals(potData.getPotKey())) {
break outer;
}
}
return true;
}
}
int current_water = plugin.getWateringCanManager().getCurrentWater(item_in_hand);
if (current_water <= 0) return true;
Location pot_loc = location.clone().subtract(0,1,0);
PotWaterEvent potWaterEvent = new PotWaterEvent(player, item_in_hand, 1, pot_loc);
Bukkit.getPluginManager().callEvent(potWaterEvent);
if (potWaterEvent.isCancelled()) {
return true;
}
current_water--;
this.waterPot(wateringCanConfig.getWidth(), wateringCanConfig.getLength(), pot_loc, player.getLocation().getYaw(), potData.getPotKey(), wateringCanConfig.getParticle(), potWaterEvent.getWater());
this.doWateringCanActions(player, item_in_hand, wateringCanConfig, current_water);
return true;
}
current_water--;
this.waterPot(wateringCanConfig.getWidth(), wateringCanConfig.getLength(), pot_loc, player.getLocation().getYaw(), potData.getPotKey(), wateringCanConfig.getParticle(), potWaterEvent.getWater());
this.doWateringCanActions(player, item_in_hand, wateringCanConfig, current_water);
return true;
}
BoneMeal[] boneMeals = cropConfig.getBoneMeals();
@@ -454,7 +506,7 @@ public class PlatformManager extends Function {
return true;
}
public boolean onInteractPot(Player player, String id, Location location, ItemStack item_in_hand, String item_in_hand_id) {
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) {
return false;
@@ -535,6 +587,7 @@ public class PlatformManager extends Function {
return true;
}
event.setCancelled(true);
doPassiveFillAction(player, item_in_hand, passiveFillMethod, location);
plugin.getWorldDataManager().addWaterToPot(SimpleLocation.getByBukkitLocation(location), potWaterEvent.getWater(), pot_id);
break outer;
@@ -791,4 +844,5 @@ public class PlatformManager extends Function {
}
return true;
}
}

View File

@@ -23,6 +23,7 @@ import dev.lone.itemsadder.api.CustomBlock;
import dev.lone.itemsadder.api.CustomFurniture;
import dev.lone.itemsadder.api.CustomStack;
import net.momirealms.customcrops.api.customplugin.PlatformInterface;
import net.momirealms.customcrops.api.util.AdventureUtils;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
@@ -58,6 +59,10 @@ public class ItemsAdderPluginImpl implements PlatformInterface {
@Override
public ItemFrame placeItemFrame(Location location, String id) {
CustomFurniture customFurniture = CustomFurniture.spawn(id, location.getBlock());
if (customFurniture == null) {
AdventureUtils.consoleMessage("<red>[CustomCrops] Furniture not exists: " + id);
return null;
}
Entity entity = customFurniture.getArmorstand();
if (entity instanceof ItemFrame itemFrame)
return itemFrame;

View File

@@ -0,0 +1,59 @@
package net.momirealms.customcrops.api.event;
import net.momirealms.customcrops.api.object.sprinkler.SprinklerConfig;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
public class SprinklerPlaceEvent extends PlayerEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private boolean cancelled;
private final ItemStack hand;
private final Location location;
private final SprinklerConfig sprinklerConfig;
public SprinklerPlaceEvent(@NotNull Player who, ItemStack hand, Location location, SprinklerConfig sprinklerConfig) {
super(who);
this.hand = hand;
this.location = location;
this.sprinklerConfig = sprinklerConfig;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}
@NotNull
@Override
public HandlerList getHandlers() {
return getHandlerList();
}
public ItemStack getHand() {
return hand;
}
public Location getLocation() {
return location;
}
public SprinklerConfig getSprinklerConfig() {
return sprinklerConfig;
}
}

View File

@@ -53,7 +53,7 @@ public class CrowTask implements Runnable {
this.vectorDown = new Vector(relative.getX() / 100, -0.1, relative.getZ() / 100);
this.vectorUp = new Vector(relative.getX() / 100, 0.1, relative.getZ() / 100);
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getSpawnPacket(entityID, from, EntityType.ARMOR_STAND));
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getMetaPacket(entityID));
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getVanishArmorStandMetaPacket(entityID));
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getEquipPacket(entityID, fly));
}

View File

@@ -139,10 +139,19 @@ public class HologramManager extends Function implements Listener {
int random = ThreadLocalRandom.current().nextInt(Integer.MAX_VALUE);
tupleList.add(Tuple.of(location, random, System.currentTimeMillis() + millis));
this.tuples = tupleList.toArray(new Tuple[0]);
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getSpawnPacket(random, location, EntityType.ARMOR_STAND));
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getMetaPacket(random, component));
if (mode == Mode.ARMOR_STAND) {
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getSpawnPacket(random, location, EntityType.ARMOR_STAND));
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getVanishArmorStandMetaPacket(random, component));
} else if (mode == Mode.TEXT_DISPLAY) {
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getSpawnPacket(random, location, EntityType.TEXT_DISPLAY));
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getTextDisplayMetaPacket(random, component));
}
} else {
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getMetaPacket(entity_id, component));
if (mode == Mode.ARMOR_STAND) {
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getVanishArmorStandMetaPacket(entity_id, component));
} else if (mode == Mode.TEXT_DISPLAY) {
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getTextDisplayMetaPacket(entity_id, component));
}
}
}

View File

@@ -19,6 +19,7 @@ package net.momirealms.customcrops.api.object;
public enum ItemMode {
ARMOR_STAND,
TRIPWIRE,
ITEM_FRAME,
ITEM_DISPLAY,

View File

@@ -61,25 +61,25 @@ public class MessageManager extends Function {
private void loadMessage() {
YamlConfiguration config = ConfigUtils.getConfig("messages" + File.separator + "messages_" + ConfigManager.lang + ".yml");
prefix = config.getString("prefix","<gradient:#ff206c:#fdee55>[CustomCrops] </gradient>");
reload = config.getString("reload", "<white>Reloaded! Took <green>{time}ms.");
unavailableArgs = config.getString("invalid-args", "<white>Invalid arguments.");
noConsole = config.getString("no-console", "This command can only be executed by a player.");
notOnline = config.getString("not-online", "<white>Player {player} is not online.");
lackArgs = config.getString("lack-args", "<white>Arguments are insufficient.");
nonArgs = config.getString("not-none-args", "<white>Not a none argument command.");
beforePlant = config.getString("before-plant", "<white>This fertilizer can only be used before planting.");
unsuitablePot = config.getString("unsuitable-pot", "<white>You can't plant the seed in this pot.");
reachChunkLimit = config.getString("reach-crop-limit", "<white>The number of crops has reached the limitation.");
noPerm = config.getString("no-perm", "<red>You don't have permission to do that.");
spring = config.getString("spring", "Spring");
summer = config.getString("summer", "Summer");
autumn = config.getString("autumn", "Autumn");
winter = config.getString("winter", "Winter");
noSeason = config.getString("no-season", "SEASON DISABLED IN THIS WORLD");
setSeason = config.getString("set-season", "<white>Successfully set {world}'s season to {season}.");
setDate = config.getString("set-date", "<white>Successfully set {world}'s date to {date}.");
worldNotExist = config.getString("world-not-exist", "<white>World {world} does not exist.");
seasonNotExist = config.getString("season-not-exist", "<white>Season {season} does not exist.");
prefix = config.getString("messages.prefix","<gradient:#ff206c:#fdee55>[CustomCrops] </gradient>");
reload = config.getString("messages.reload", "<white>Reloaded! Took <green>{time}ms.");
unavailableArgs = config.getString("messages.invalid-args", "<white>Invalid arguments.");
noConsole = config.getString("messages.no-console", "This command can only be executed by a player.");
notOnline = config.getString("messages.not-online", "<white>Player {player} is not online.");
lackArgs = config.getString("messages.lack-args", "<white>Arguments are insufficient.");
nonArgs = config.getString("messages.not-none-args", "<white>Not a none argument command.");
beforePlant = config.getString("messages.before-plant", "<white>This fertilizer can only be used before planting.");
unsuitablePot = config.getString("messages.unsuitable-pot", "<white>You can't plant the seed in this pot.");
reachChunkLimit = config.getString("messages.reach-crop-limit", "<white>The number of crops has reached the limitation.");
noPerm = config.getString("messages.no-perm", "<red>You don't have permission to do that.");
spring = config.getString("messages.spring", "Spring");
summer = config.getString("messages.summer", "Summer");
autumn = config.getString("messages.autumn", "Autumn");
winter = config.getString("messages.winter", "Winter");
noSeason = config.getString("messages.no-season", "SEASON DISABLED IN THIS WORLD");
setSeason = config.getString("messages.set-season", "<white>Successfully set {world}'s season to {season}.");
setDate = config.getString("messages.set-date", "<white>Successfully set {world}'s date to {date}.");
worldNotExist = config.getString("messages.world-not-exist", "<white>World {world} does not exist.");
seasonNotExist = config.getString("messages.season-not-exist", "<white>Season {season} does not exist.");
}
}

View File

@@ -70,7 +70,8 @@ public class Pot implements Serializable {
*/
public boolean reduceWater() {
water--;
return water <= 0;
water = Math.max(0, water);
return water == 0;
}
/*

View File

@@ -116,7 +116,7 @@ public class PotHologram {
public String getWaterBar(int current, int storage) {
return bar_left +
String.valueOf(bar_full).repeat(current) +
String.valueOf(bar_empty).repeat(storage - current) +
String.valueOf(bar_empty).repeat(Math.max(storage - current, 0)) +
bar_right;
}
}

View File

@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customcrops.api.object.schedule;
package net.momirealms.customcrops.api.object.scheduler;
import net.momirealms.customcrops.CustomCrops;
import org.bukkit.Bukkit;

View File

@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customcrops.api.object.schedule;
package net.momirealms.customcrops.api.object.scheduler;
import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.api.object.Function;

View File

@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customcrops.api.object.schedule;
package net.momirealms.customcrops.api.object.scheduler;
import org.jetbrains.annotations.NotNull;

View File

@@ -17,16 +17,19 @@
package net.momirealms.customcrops.api.object.sprinkler;
import net.momirealms.customcrops.CustomCrops;
import org.jetbrains.annotations.Nullable;
import java.io.Serializable;
public class Sprinkler implements Serializable {
private int water;
private int range;
private final String key;
public Sprinkler(int water, int range) {
public Sprinkler(String key, int water) {
this.water = water;
this.range = range;
this.key = key;
}
public int getWater() {
@@ -37,11 +40,12 @@ public class Sprinkler implements Serializable {
this.water = water;
}
public void setRange(int range) {
this.range = range;
public String getKey() {
return key;
}
public int getRange() {
return range;
@Nullable
public SprinklerConfig getConfig() {
return CustomCrops.getInstance().getSprinklerManager().getConfigByKey(key);
}
}

View File

@@ -0,0 +1,7 @@
package net.momirealms.customcrops.api.object.sprinkler;
import net.momirealms.customcrops.api.object.ItemMode;
public record SprinklerAnimation(int duration, String id, double offset, ItemMode itemMode) {
}

View File

@@ -33,8 +33,13 @@ public class SprinklerConfig {
private final String threeD;
private final String twoD;
private final PassiveFillMethod[] passiveFillMethods;
private final boolean hasAnimation;
private final boolean hasHologram;
private final SprinklerHologram sprinklerHologram;
private final SprinklerAnimation sprinklerAnimation;
public SprinklerConfig(String key, int storage, int range, @Nullable Sound sound, @NotNull ItemMode itemMode, @NotNull String threeD, @NotNull String twoD, @NotNull PassiveFillMethod[] passiveFillMethods) {
public SprinklerConfig(String key, int storage, int range, @Nullable Sound sound, @NotNull ItemMode itemMode, @NotNull String threeD, @NotNull String twoD,
@NotNull PassiveFillMethod[] passiveFillMethods, boolean hasHologram, boolean hasAnimation, @Nullable SprinklerHologram sprinklerHologram, SprinklerAnimation sprinklerAnimation) {
this.key = key;
this.storage = storage;
this.range = range;
@@ -43,6 +48,10 @@ public class SprinklerConfig {
this.threeD = threeD;
this.twoD = twoD;
this.passiveFillMethods = passiveFillMethods;
this.hasAnimation = hasAnimation;
this.hasHologram = hasHologram;
this.sprinklerAnimation = sprinklerAnimation;
this.sprinklerHologram = sprinklerHologram;
}
public String getKey() {
@@ -81,4 +90,22 @@ public class SprinklerConfig {
public PassiveFillMethod[] getPassiveFillMethods() {
return passiveFillMethods;
}
public boolean hasAnimation() {
return hasAnimation;
}
public boolean hasHologram() {
return hasHologram;
}
@Nullable
public SprinklerHologram getSprinklerHologram() {
return sprinklerHologram;
}
@Nullable
public SprinklerAnimation getSprinklerAnimation() {
return sprinklerAnimation;
}
}

View File

@@ -0,0 +1,53 @@
package net.momirealms.customcrops.api.object.sprinkler;
import net.momirealms.customcrops.api.object.HologramManager;
import org.jetbrains.annotations.NotNull;
public class SprinklerHologram {
private final double offset;
private final HologramManager.Mode mode;
private final String content;
private final int duration;
private final String bar_left;
private final String bar_full;
private final String bar_empty;
private final String bar_right;
public SprinklerHologram(@NotNull String content, double offset, HologramManager.Mode mode, int duration, String bar_left, String bar_full, String bar_empty, String bar_right) {
this.offset = offset;
this.content = content;
this.mode = mode;
this.duration = duration;
this.bar_left = bar_left;
this.bar_full = bar_full;
this.bar_empty = bar_empty;
this.bar_right = bar_right;
}
public double getOffset() {
return offset;
}
public HologramManager.Mode getMode() {
return mode;
}
public int getDuration() {
return duration;
}
public String getContent(int current, int storage) {
return content.replace("{current}", String.valueOf(current))
.replace("{storage}", String.valueOf(storage))
.replace("{water_bar}", getWaterBar(current, storage));
}
public String getWaterBar(int current, int storage) {
return bar_left +
String.valueOf(bar_full).repeat(current) +
String.valueOf(bar_empty).repeat(Math.max(storage - current, 0)) +
bar_right;
}
}

View File

@@ -21,6 +21,7 @@ import net.kyori.adventure.key.Key;
import net.kyori.adventure.sound.Sound;
import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.api.object.Function;
import net.momirealms.customcrops.api.object.HologramManager;
import net.momirealms.customcrops.api.object.ItemMode;
import net.momirealms.customcrops.api.object.fill.PassiveFillMethod;
import net.momirealms.customcrops.api.util.AdventureUtils;
@@ -92,6 +93,8 @@ public class SprinklerManager extends Function implements Listener {
@Subst("namespace:key") String soundKey = sprinklerSec.getString("place-sound", "minecraft:block.bone_block.place");
Sound sound = sprinklerSec.contains("place-sound") ? Sound.sound(Key.key(soundKey), Sound.Source.PLAYER, 1, 1) : null;
ItemMode itemMode = ItemMode.valueOf(sprinklerSec.getString("type","ITEM_FRAME").toUpperCase());
boolean hasAnimation = sprinklerSec.getBoolean("animation.enable");
boolean hasHologram = sprinklerSec.getBoolean("hologram.enable");
SprinklerConfig sprinklerConfig = new SprinklerConfig(
key,
sprinklerSec.getInt("storage", 3),
@@ -100,7 +103,25 @@ public class SprinklerManager extends Function implements Listener {
itemMode,
threeD,
twoD,
methods
methods,
hasHologram,
hasAnimation,
hasHologram ? new SprinklerHologram(
sprinklerSec.getString("hologram.content",""),
sprinklerSec.getDouble("hologram.vertical-offset"),
HologramManager.Mode.valueOf(sprinklerSec.getString("hologram.type", "ARMOR_STAND").toUpperCase()),
sprinklerSec.getInt("hologram.duration"),
sprinklerSec.getString("hologram.water-bar.left"),
sprinklerSec.getString("hologram.water-bar.full"),
sprinklerSec.getString("hologram.water-bar.empty"),
sprinklerSec.getString("hologram.water-bar.right")
) : null,
hasAnimation ? new SprinklerAnimation(
sprinklerSec.getInt("animation.duration"),
sprinklerSec.getString("animation.item"),
sprinklerSec.getDouble("animation.vertical-offset"),
ItemMode.valueOf(sprinklerSec.getString("animation.type", "ARMOR_STAND").toUpperCase())
) : null
);
this.itemToKey.put(threeD, key);
this.itemToKey.put(twoD, key);
@@ -122,6 +143,11 @@ public class SprinklerManager extends Function implements Listener {
return itemToKey.get(id);
}
@Nullable
public SprinklerConfig getConfigByKey(String key) {
return sprinklerConfigMap.get(key);
}
public boolean containsSprinkler(String key) {
return sprinklerConfigMap.containsKey(key);
}

View File

@@ -83,7 +83,7 @@ public class WateringCanConfig {
public String getWaterBar(int current) {
return bar_left +
String.valueOf(bar_full).repeat(current) +
String.valueOf(bar_empty).repeat(storage - current) +
String.valueOf(bar_empty).repeat(Math.max(storage - current, 0)) +
bar_right;
}

View File

@@ -19,6 +19,7 @@ package net.momirealms.customcrops.api.object.world;
import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.api.CustomCropsAPI;
import net.momirealms.customcrops.api.object.CrowTask;
import net.momirealms.customcrops.api.object.Function;
import net.momirealms.customcrops.api.object.ItemMode;
import net.momirealms.customcrops.api.object.action.Action;
@@ -34,21 +35,27 @@ import net.momirealms.customcrops.api.object.fertilizer.FertilizerConfig;
import net.momirealms.customcrops.api.object.fertilizer.SoilRetain;
import net.momirealms.customcrops.api.object.fertilizer.SpeedGrow;
import net.momirealms.customcrops.api.object.pot.Pot;
import net.momirealms.customcrops.api.object.pot.PotConfig;
import net.momirealms.customcrops.api.object.season.CCSeason;
import net.momirealms.customcrops.api.object.season.SeasonData;
import net.momirealms.customcrops.api.object.sprinkler.Sprinkler;
import net.momirealms.customcrops.api.object.sprinkler.SprinklerAnimation;
import net.momirealms.customcrops.api.object.sprinkler.SprinklerConfig;
import net.momirealms.customcrops.api.util.AdventureUtils;
import net.momirealms.customcrops.api.util.ConfigUtils;
import net.momirealms.customcrops.api.util.FakeEntityUtils;
import net.momirealms.customcrops.helper.Log;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -320,8 +327,12 @@ public class CCWorld extends Function {
pot.setWater(pot.getWater() + 1);
}
if (pot.reduceWater() | pot.reduceFertilizer()) {
SimpleLocation temp = simpleLocation.copy();
PotConfig potConfig = pot.getConfig();
Fertilizer fertilizer = pot.getFertilizer();
boolean wet = pot.isWet();
CustomCrops.getInstance().getScheduler().callSyncMethod(() -> {
CustomCropsAPI.getInstance().changePotModel(simpleLocation, pot);
CustomCropsAPI.getInstance().changePotModel(temp, potConfig, fertilizer, wet);
return null;
});
}
@@ -345,22 +356,38 @@ public class CCWorld extends Function {
}
public void execute() {
SprinklerConfig sprinklerConfig = sprinkler.getConfig();
if (sprinklerConfig == null) {
removeSprinklerData(simpleLocation);
return;
}
int water = sprinkler.getWater();
if (water > 0) {
sprinkler.setWater(--water);
if (water == 0) {
removeSprinklerData(simpleLocation);
}
int range = sprinkler.getRange();
for (int i = -range; i <= range; i++) {
for (int j = -range; j <= range; j++) {
addWaterToPot(simpleLocation.add(i, -1, j), 1, null);
if (water < 1) {
removeSprinklerData(simpleLocation);
return;
}
if (sprinklerConfig.hasAnimation()) {
SprinklerAnimation sprinklerAnimation = sprinklerConfig.getSprinklerAnimation();
Location location = simpleLocation.getBukkitLocation();
if (location != null && sprinklerAnimation != null) {
for (Player player : Bukkit.getOnlinePlayers()) {
SimpleLocation playerLoc = SimpleLocation.getByBukkitLocation(player.getLocation());
if (playerLoc.isNear(simpleLocation, 48)) {
FakeEntityUtils.playWaterAnimation(player, location.clone().add(0.5, sprinklerAnimation.offset(), 0.5), sprinklerAnimation.id(), sprinklerAnimation.duration(), sprinklerAnimation.itemMode());
}
}
}
}
else {
sprinkler.setWater(--water);
if (water == 0) {
removeSprinklerData(simpleLocation);
}
int range = sprinklerConfig.getRange();
for (int i = -range; i <= range; i++) {
for (int j = -range; j <= range; j++) {
addWaterToPot(simpleLocation.add(i, -1, j), 1, null);
}
}
}
public void clear() {

View File

@@ -24,6 +24,7 @@ import net.momirealms.customcrops.api.object.crop.GrowingCrop;
import net.momirealms.customcrops.api.object.fertilizer.Fertilizer;
import net.momirealms.customcrops.api.object.pot.Pot;
import net.momirealms.customcrops.api.object.sprinkler.Sprinkler;
import net.momirealms.customcrops.api.object.sprinkler.SprinklerConfig;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.event.HandlerList;
@@ -206,14 +207,13 @@ public class WorldDataManager extends Function {
}
}
public void addWaterToSprinkler(SimpleLocation simpleLocation, int add, int range, int max) {
public void addWaterToSprinkler(SimpleLocation simpleLocation, int add, SprinklerConfig sprinklerConfig) {
Sprinkler sprinkler = getSprinklerData(simpleLocation);
if (sprinkler != null) {
sprinkler.setWater(Math.min(add + sprinkler.getWater(), max));
sprinkler.setRange(range);
sprinkler.setWater(Math.min(add + sprinkler.getWater(), sprinklerConfig.getStorage()));
}
else {
Sprinkler newSprinkler = new Sprinkler(Math.min(add, max), range);
Sprinkler newSprinkler = new Sprinkler(sprinklerConfig.getKey(), Math.min(add, sprinklerConfig.getStorage()));
addSprinklerData(simpleLocation, newSprinkler);
}
}

View File

@@ -24,6 +24,7 @@ import com.google.common.collect.Lists;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.api.object.ItemMode;
import org.bukkit.Location;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
@@ -33,14 +34,19 @@ import java.util.*;
public class FakeEntityUtils {
public static void playWaterAnimation(Player player, Location location, String animation_id) {
public static void playWaterAnimation(Player player, Location location, String animation_id, int duration, ItemMode itemMode) {
int id = new Random().nextInt(Integer.MAX_VALUE);
CustomCrops.getProtocolManager().sendServerPacket(player, getSpawnPacket(id, location, EntityType.ARMOR_STAND));
CustomCrops.getProtocolManager().sendServerPacket(player, getMetaPacket(id));
CustomCrops.getProtocolManager().sendServerPacket(player, getEquipPacket(id, CustomCrops.getInstance().getIntegrationManager().build(animation_id)));
if (itemMode == ItemMode.ARMOR_STAND) {
CustomCrops.getProtocolManager().sendServerPacket(player, getSpawnPacket(id, location, EntityType.ARMOR_STAND));
CustomCrops.getProtocolManager().sendServerPacket(player, getVanishArmorStandMetaPacket(id));
CustomCrops.getProtocolManager().sendServerPacket(player, getEquipPacket(id, CustomCrops.getInstance().getIntegrationManager().build(animation_id)));
} else if (itemMode == ItemMode.ITEM_DISPLAY) {
CustomCrops.getProtocolManager().sendServerPacket(player, getSpawnPacket(id, location, EntityType.ITEM_DISPLAY));
CustomCrops.getProtocolManager().sendServerPacket(player, getItemDisplayMetaPacket(id, CustomCrops.getInstance().getIntegrationManager().build(animation_id)));
}
CustomCrops.getInstance().getScheduler().runTaskAsyncLater(() -> {
CustomCrops.getProtocolManager().sendServerPacket(player, getDestroyPacket(id));
}, 10000);
}, 1000L * duration);
}
public static WrappedDataWatcher createInvisibleDataWatcher() {
@@ -70,7 +76,7 @@ public class FakeEntityUtils {
return entityPacket;
}
public static PacketContainer getMetaPacket(int id) {
public static PacketContainer getVanishArmorStandMetaPacket(int id) {
PacketContainer metaPacket = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
metaPacket.getIntegers().write(0, id);
if (CustomCrops.getInstance().getVersionHelper().isVersionNewerThan1_19_R2()) {
@@ -101,7 +107,7 @@ public class FakeEntityUtils {
return packet;
}
public static PacketContainer getMetaPacket(int id, Component component) {
public static PacketContainer getVanishArmorStandMetaPacket(int id, Component component) {
PacketContainer metaPacket = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
WrappedDataWatcher wrappedDataWatcher = new WrappedDataWatcher();
WrappedDataWatcher.Serializer serializer1 = WrappedDataWatcher.Registry.get(Boolean.class);
@@ -122,6 +128,24 @@ public class FakeEntityUtils {
return metaPacket;
}
public static PacketContainer getItemDisplayMetaPacket(int id, ItemStack itemStack) {
PacketContainer metaPacket = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
metaPacket.getModifier().write(0, id);
WrappedDataWatcher wrappedDataWatcher = new WrappedDataWatcher();
wrappedDataWatcher.setObject(22, itemStack);
setWrappedDataValue(metaPacket, wrappedDataWatcher);
return metaPacket;
}
public static PacketContainer getTextDisplayMetaPacket(int id, Component component) {
PacketContainer metaPacket = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
metaPacket.getModifier().write(0, id);
WrappedDataWatcher wrappedDataWatcher = new WrappedDataWatcher();
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(22, WrappedDataWatcher.Registry.getChatComponentSerializer(true)), Optional.of(WrappedChatComponent.fromJson(GsonComponentSerializer.gson().serialize(component)).getHandle()));
setWrappedDataValue(metaPacket, wrappedDataWatcher);
return metaPacket;
}
private static void setWrappedDataValue(PacketContainer metaPacket, WrappedDataWatcher wrappedDataWatcher) {
List<WrappedDataValue> wrappedDataValueList = Lists.newArrayList();
wrappedDataWatcher.getWatchableObjects().stream().filter(Objects::nonNull).forEach(entry -> {

View File

@@ -4,8 +4,6 @@ config-version: '25'
metrics: true
# Language: english / spanish / chinese / turkish
lang: english
# Set up mode
set-up-mode: true
# AntiGrief
integrations:
Residence: false
@@ -38,7 +36,7 @@ schedule-system:
enable: true
# The average interval for a crop to gain one point (measured in seconds)
# 平均每个农作物获得一生长点的时间间隔(秒)
point-gain-interval: 10
point-gain-interval: 1200
# Thread pool settings
# 线程池设置
thread-pool-settings:

View File

@@ -145,7 +145,7 @@ tomato:
type: variation
value:
golden:
model: tomato_stage_golden
item: customcrops:tomato_stage_golden
type: TripWire
chance: 0.01
interact-by-hand:

View File

@@ -12,7 +12,7 @@ sprinkler_1:
enable: true
# ARMOR_STAND / TEXT_DISPLAY (1.19.4+)
type: ARMOR_STAND
y-offset: 0.8
vertical-offset: -0.3
duration: 1
# Available variables:
# {water_bar} water bar image
@@ -25,10 +25,11 @@ sprinkler_1:
empty: '뀁뀄'
right: '뀁뀅'
# Water splash animation when sprinkler works
sprinkler-animation:
animation:
enable: true
y-offset: 0.4
item: customcrops:water_animation
duration: 10
vertical-offset: 0.4
item: customcrops:water_effect
# ARMOR_STAND / ITEM_DISPLAY (1.19.4+)
type: ARMOR_STAND
pot-whitelist:
@@ -58,7 +59,7 @@ sprinkler_2:
hologram:
enable: true
type: ARMOR_STAND
y-offset: 0.8
vertical-offset: -0.3
duration: 1
content: '<font:customcrops:default>{water_bar}</font>'
water-bar:
@@ -66,10 +67,10 @@ sprinkler_2:
full: '뀁뀃'
empty: '뀁뀄'
right: '뀁뀅'
sprinkler-animation:
animation:
enable: true
y-offset: 0.4
item: customcrops:water_animation
vertical-offset: 0.4
item: customcrops:water_effect
type: ARMOR_STAND
pot-whitelist:
- default
@@ -97,7 +98,7 @@ sprinkler_3:
hologram:
enable: true
type: ARMOR_STAND
y-offset: 0.8
vertical-offset: -0.3
duration: 1
content: '<font:customcrops:default>{water_bar}</font>'
water-bar:
@@ -105,10 +106,10 @@ sprinkler_3:
full: '뀁뀃'
empty: '뀁뀄'
right: '뀁뀅'
sprinkler-animation:
animation:
enable: true
y-offset: 0.4
item: customcrops:water_animation
vertical-offset: 0.4
item: customcrops:water_effect
type: ARMOR_STAND
pot-whitelist:
- default

View File

@@ -0,0 +1,22 @@
# https://docs.advntr.dev/minimessage/format.html
messages:
prefix: '<gradient:#ff206c:#fdee55>[CustomCrops] </gradient>'
reload: '<white>已重载! 用时 <green>{time}ms.'
invalid-args: '<white>无效参数.'
no-console: '<white>这个命令只能由玩家使用.'
not-online: '<white>玩家 {player} 当前不在线.'
lack-args: '<white>缺少参数.'
not-none-args: '<white>你需要输入一个参数.'
before-plant: '<white>这种肥料必须在种植之前使用.'
unsuitable-pot: "<white>你不能在这里面种植它."
reach-crop-limit: '<white>农作物数量已达上限.'
no-perm: "<red>你没有权限这样做."
spring: '春季'
summer: '夏季'
autumn: '秋季'
winter: '冬季'
no-season: '这个世界禁用了季节'
set-season: "<white>成功将 {world} 世界的季节设置为 {season}."
set-date: "<white>成功将 {world} 世界的日期设置为 {date}."
world-not-exist: '<white>世界 {world} 不存在.'
season-not-exist: '<white>{season} 不是一个有效的季节.'

View File

@@ -1,3 +1,4 @@
# https://docs.advntr.dev/minimessage/format.html
messages:
prefix: '<gradient:#ff206c:#fdee55>[CustomCrops] </gradient>'
reload: '<white>Reloaded! Took <green>{time}ms.'
@@ -6,7 +7,7 @@ messages:
not-online: '<white>Player {player} is not online.'
lack-args: '<white>Arguments are insufficient.'
not-none-args: '<white>Not a none argument command.'
before-plant: '<white>This fertilizer must be used before planting!'
before-plant: '<white>This fertilizer should be used before planting.'
unsuitable-pot: "<white>You can't plant the seed in this pot."
reach-crop-limit: '<white>The number of crops has reached the limitation.'
no-perm: "<red>You don't have permission to do that."

View File

@@ -0,0 +1,22 @@
# https://docs.advntr.dev/minimessage/format.html
messages:
prefix: '<gradient:#ff206c:#fdee55>[CustomCrops] </gradient>'
reload: '<white>Yenilendi <green>{time}ms <white>sürdü.'
invalid-args: '<white>Geçersiz argümanlar. (argüman örneği: /customcrops <argüman>)'
no-console: '<white>Bu komut sadece bir oyuncu tarafından kullanılabilir.'
not-online: '<white>{player} adındaki oyuncu aktif değil.'
lack-args: '<white>Yetersiz argümanlar. Geçersiz argümanlar. (argüman örneği: /customcrops <argüman>)'
not-none-args: '<white>Bu komut için bir argüman belirtmelisin. (argüman örneği: /customcrops <argüman>)'
before-plant: '<white>Bu gübre, ekimden önce kullanılmalıdır!'
unsuitable-pot: "<white>Tohumu bu saksıya ekemezsin."
reach-crop-limit: '<white>Ekinlerin sayısı sınıra ulaştı.'
no-perm: "<red>Bunu yapmak için yetkin yok."
spring: 'Bahar'
summer: 'Yaz'
autumn: 'Sonbahar'
winter: 'Kış'
no-season: 'MEVSİMLER BU DÜNYADA DEVRE DIŞI BIRAKILDI'
set-season: "<white>{world} adlı dünyanın mevsimi başarıyla {season} ile değiştirildi."
set-date: "<white>{world} adlı dünyanın tarihi başarıyla {date} ile değiştirildi."
world-not-exist: '<white>{world} adında bir dünya bulunamadı.'
season-not-exist: '<white>{season} adında bir mevsim bulunamadı.'