mirror of
https://github.com/Xiao-MoMi/Custom-Crops.git
synced 2025-12-27 02:49:11 +00:00
3.0.0-beta1
This commit is contained in:
14
build.gradle
14
build.gradle
@@ -42,7 +42,7 @@ dependencies {
|
||||
implementation ("de.tr7zw:item-nbt-api:2.11.2")
|
||||
implementation ('org.bstats:bstats-bukkit:3.0.1')
|
||||
implementation ('org.apache.commons:commons-pool2:2.11.1')
|
||||
implementation fileTree(dir:'libs',includes:['BiomeAPI.jar'])
|
||||
implementation fileTree(dir:'libs',includes:['BiomeAPI.jar','ProtectionLib.jar'])
|
||||
}
|
||||
|
||||
def targetJavaVersion = 17
|
||||
@@ -55,23 +55,18 @@ java {
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
if (targetJavaVersion >= 10 || JavaVersion.current().isJava10Compatible()) {
|
||||
options.release = targetJavaVersion
|
||||
}
|
||||
}
|
||||
|
||||
processResources {
|
||||
def props = [version: version]
|
||||
inputs.properties props
|
||||
filteringCharset 'UTF-8'
|
||||
filesMatching('plugin.yml') {
|
||||
filesMatching(['paper-plugin.yml', 'plugin.yml']) {
|
||||
expand props
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
options.encoding = "UTF-8"
|
||||
options.release = targetJavaVersion
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
@@ -80,6 +75,7 @@ shadowJar {
|
||||
relocate ('org.bstats', 'net.momirealms.customcrops.libs.org.bstats')
|
||||
relocate ('org.apache.commons.pool2', 'net.momirealms.customcrops.libs.org.apache.commons.pool2')
|
||||
relocate ('net.momirealms.biomeapi', 'net.momirealms.customcrops.libs.net.momirealms.biomeapi')
|
||||
relocate ('net.momirealms.protectionlib', 'net.momirealms.customcrops.libs.net.momirealms.protectionlib')
|
||||
}
|
||||
|
||||
tasks.register("delete", Delete).get().delete("build/libs/"+project.name+"-"+project.version+".jar")
|
||||
|
||||
@@ -26,11 +26,11 @@ import net.momirealms.customcrops.api.customplugin.PlatformInterface;
|
||||
import net.momirealms.customcrops.api.customplugin.PlatformManager;
|
||||
import net.momirealms.customcrops.api.customplugin.itemsadder.ItemsAdderPluginImpl;
|
||||
import net.momirealms.customcrops.api.customplugin.oraxen.OraxenPluginImpl;
|
||||
import net.momirealms.customcrops.api.object.HologramManager;
|
||||
import net.momirealms.customcrops.api.object.basic.ConfigManager;
|
||||
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.hologram.HologramManager;
|
||||
import net.momirealms.customcrops.api.object.pot.PotManager;
|
||||
import net.momirealms.customcrops.api.object.scheduler.Scheduler;
|
||||
import net.momirealms.customcrops.api.object.season.SeasonManager;
|
||||
@@ -42,6 +42,7 @@ import net.momirealms.customcrops.command.CustomCropsCommand;
|
||||
import net.momirealms.customcrops.helper.LibraryLoader;
|
||||
import net.momirealms.customcrops.helper.VersionHelper;
|
||||
import net.momirealms.customcrops.integration.IntegrationManager;
|
||||
import net.momirealms.protectionlib.ProtectionLib;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
@@ -78,11 +79,23 @@ public final class CustomCrops extends JavaPlugin {
|
||||
public void onLoad(){
|
||||
plugin = this;
|
||||
this.loadLibs();
|
||||
ProtectionLib.initialize(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
adventure = BukkitAudiences.create(this);
|
||||
this.versionHelper = new VersionHelper(this);
|
||||
if (versionHelper.isSpigot()) {
|
||||
AdventureUtils.consoleMessage("<red>========================[CustomCrops]=========================");
|
||||
AdventureUtils.consoleMessage("<red> Spigot is not officially supported by CustomCrops");
|
||||
AdventureUtils.consoleMessage("<red> Please use Paper or its forks");
|
||||
AdventureUtils.consoleMessage("<red> Paper download link: https://papermc.io/downloads");
|
||||
AdventureUtils.consoleMessage("<red>==============================================================");
|
||||
Bukkit.getPluginManager().disablePlugin(this);
|
||||
return;
|
||||
}
|
||||
|
||||
protocolManager = ProtocolLibrary.getProtocolManager();
|
||||
AdventureUtils.consoleMessage("[CustomCrops] Running on <white>" + Bukkit.getVersion());
|
||||
this.registerCommands();
|
||||
@@ -91,7 +104,6 @@ public final class CustomCrops extends JavaPlugin {
|
||||
this.scheduler = new Scheduler(this);
|
||||
this.configManager = new ConfigManager(this);
|
||||
this.messageManager = new MessageManager(this);
|
||||
this.versionHelper = new VersionHelper(this);
|
||||
this.cropManager = new CropManager(this);
|
||||
this.integrationManager = new IntegrationManager(this);
|
||||
this.seasonManager = new SeasonManager(this);
|
||||
|
||||
@@ -18,19 +18,6 @@
|
||||
package net.momirealms.customcrops.api;
|
||||
|
||||
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 {
|
||||
|
||||
@@ -45,77 +32,4 @@ public class CustomCropsAPI {
|
||||
public static CustomCropsAPI getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public boolean isCrop(String stage_id) {
|
||||
return plugin.getCropManager().getCropConfigByStage(stage_id) != null;
|
||||
}
|
||||
|
||||
public CropConfig getCropConfig(String crop_config_id) {
|
||||
return plugin.getCropManager().getCropConfigByID(crop_config_id);
|
||||
}
|
||||
|
||||
public ItemStack buildItem(String id) {
|
||||
return plugin.getIntegrationManager().build(id);
|
||||
}
|
||||
|
||||
public boolean removeCustomItem(Location location, ItemMode itemMode) {
|
||||
if (itemMode == ItemMode.TRIPWIRE || itemMode == ItemMode.CHORUS)
|
||||
return plugin.getPlatformInterface().removeCustomBlock(location);
|
||||
else if (itemMode == ItemMode.ITEM_FRAME)
|
||||
return plugin.getPlatformInterface().removeItemFrame(location);
|
||||
else if (itemMode == ItemMode.ITEM_DISPLAY)
|
||||
return plugin.getPlatformInterface().removeItemDisplay(location);
|
||||
return false;
|
||||
}
|
||||
|
||||
public void placeCustomItem(Location location, String id, ItemMode itemMode) {
|
||||
if (itemMode == ItemMode.TRIPWIRE)
|
||||
plugin.getPlatformInterface().placeTripWire(location, id);
|
||||
else if (itemMode == ItemMode.ITEM_FRAME)
|
||||
plugin.getPlatformInterface().placeItemFrame(location, id);
|
||||
else if (itemMode == ItemMode.ITEM_DISPLAY)
|
||||
plugin.getPlatformInterface().placeItemDisplay(location, id);
|
||||
else if (itemMode == ItemMode.CHORUS)
|
||||
plugin.getPlatformInterface().placeChorus(location, id);
|
||||
}
|
||||
|
||||
public void changePotModel(SimpleLocation simpleLocation, Pot pot) {
|
||||
Location location = simpleLocation.getBukkitLocation();
|
||||
if (location == null) return;
|
||||
PlatformInterface platform = plugin.getPlatformInterface();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isGreenhouse(SimpleLocation simpleLocation) {
|
||||
return plugin.getWorldDataManager().isGreenhouse(simpleLocation);
|
||||
}
|
||||
|
||||
public CCSeason getCurrentSeason(String world) {
|
||||
return plugin.getIntegrationManager().getSeasonInterface().getSeason(world);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ 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;
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
package net.momirealms.customcrops.api.customplugin;
|
||||
|
||||
import net.momirealms.customcrops.CustomCrops;
|
||||
import net.momirealms.customcrops.api.object.ItemMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
@@ -73,8 +74,6 @@ public interface PlatformInterface {
|
||||
|
||||
void placeChorus(Location location, String id);
|
||||
|
||||
Location getItemFrameLocation(Location location);
|
||||
|
||||
@NotNull
|
||||
default String getAnyItemIDAt(Location location) {
|
||||
String block = getBlockID(location.getBlock());
|
||||
@@ -124,7 +123,7 @@ public interface PlatformInterface {
|
||||
|
||||
@Nullable
|
||||
default ItemFrame getItemFrameAt(Location location) {
|
||||
Collection<ItemFrame> itemFrames = getItemFrameLocation(location).getNearbyEntitiesByType(ItemFrame.class, 0.5, 0.5, 0.5);
|
||||
Collection<ItemFrame> itemFrames = location.clone().add(0.5,0.5,0.5).getNearbyEntitiesByType(ItemFrame.class, 0.5, 0.5, 0.5);
|
||||
int i = itemFrames.size();
|
||||
int j = 1;
|
||||
for (ItemFrame itemFrame : itemFrames) {
|
||||
@@ -139,7 +138,7 @@ public interface PlatformInterface {
|
||||
|
||||
@Nullable
|
||||
default ItemDisplay getItemDisplayAt(Location location) {
|
||||
Collection<ItemDisplay> itemDisplays = getItemFrameLocation(location).getNearbyEntitiesByType(ItemDisplay.class, 0.5, 0.5, 0.5);
|
||||
Collection<ItemDisplay> itemDisplays = location.clone().add(0.5,0.5,0.5).getNearbyEntitiesByType(ItemDisplay.class, 0.5, 0.5, 0.5);
|
||||
int i = itemDisplays.size();
|
||||
int j = 1;
|
||||
for (ItemDisplay itemDisplay : itemDisplays) {
|
||||
@@ -181,4 +180,25 @@ public interface PlatformInterface {
|
||||
Collection<Entity> entities = location.clone().add(0.5,0.5,0.5).getNearbyEntitiesByType(ItemDisplay.class, 0.5, 0.5, 0.5);
|
||||
return entities.size() != 0;
|
||||
}
|
||||
|
||||
default boolean removeCustomItem(Location location, ItemMode itemMode) {
|
||||
if (itemMode == ItemMode.TRIPWIRE || itemMode == ItemMode.CHORUS)
|
||||
return removeCustomBlock(location);
|
||||
else if (itemMode == ItemMode.ITEM_FRAME)
|
||||
return removeItemFrame(location);
|
||||
else if (itemMode == ItemMode.ITEM_DISPLAY)
|
||||
return removeItemDisplay(location);
|
||||
return false;
|
||||
}
|
||||
|
||||
default void placeCustomItem(Location location, String id, ItemMode itemMode) {
|
||||
if (itemMode == ItemMode.TRIPWIRE)
|
||||
placeTripWire(location, id);
|
||||
else if (itemMode == ItemMode.ITEM_FRAME)
|
||||
placeItemFrame(location, id);
|
||||
else if (itemMode == ItemMode.ITEM_DISPLAY)
|
||||
placeItemDisplay(location, id);
|
||||
else if (itemMode == ItemMode.CHORUS)
|
||||
placeChorus(location, id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,14 +18,12 @@
|
||||
package net.momirealms.customcrops.api.customplugin;
|
||||
|
||||
import net.momirealms.customcrops.CustomCrops;
|
||||
import net.momirealms.customcrops.api.CustomCropsAPI;
|
||||
import net.momirealms.customcrops.api.customplugin.itemsadder.ItemsAdderHandler;
|
||||
import net.momirealms.customcrops.api.customplugin.oraxen.OraxenHandler;
|
||||
import net.momirealms.customcrops.api.event.*;
|
||||
import net.momirealms.customcrops.api.object.BoneMeal;
|
||||
import net.momirealms.customcrops.api.object.Function;
|
||||
import net.momirealms.customcrops.api.object.InteractWithItem;
|
||||
import net.momirealms.customcrops.api.object.ItemType;
|
||||
import net.momirealms.customcrops.api.object.action.Action;
|
||||
import net.momirealms.customcrops.api.object.basic.ConfigManager;
|
||||
import net.momirealms.customcrops.api.object.basic.MessageManager;
|
||||
@@ -36,13 +34,14 @@ import net.momirealms.customcrops.api.object.fertilizer.Fertilizer;
|
||||
import net.momirealms.customcrops.api.object.fertilizer.FertilizerConfig;
|
||||
import net.momirealms.customcrops.api.object.fill.PassiveFillMethod;
|
||||
import net.momirealms.customcrops.api.object.fill.PositiveFillMethod;
|
||||
import net.momirealms.customcrops.api.object.hologram.FertilizerHologram;
|
||||
import net.momirealms.customcrops.api.object.hologram.WaterAmountHologram;
|
||||
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;
|
||||
@@ -59,7 +58,6 @@ import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
@@ -146,88 +144,78 @@ public class PlatformManager extends Function {
|
||||
onInteractSomething(player, entity.getLocation().getBlock().getLocation(), id, event);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ItemType onInteractAir(Player player) {
|
||||
public void onInteractAir(Player player) {
|
||||
ItemStack item_in_hand = player.getInventory().getItemInMainHand();
|
||||
String id = plugin.getPlatformInterface().getItemStackID(item_in_hand);
|
||||
|
||||
if (onInteractWithWateringCan(player, id, item_in_hand)) {
|
||||
return ItemType.WATERING_CAN;
|
||||
if (onInteractWithWateringCan(player, id, item_in_hand, null, null)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return ItemType.UNKNOWN;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ItemType onBreakSomething(Player player, Location location, String id, Cancellable event) {
|
||||
public void onBreakSomething(Player player, Location location, String id, Cancellable event) {
|
||||
|
||||
if (onBreakGlass(id, location)) {
|
||||
return ItemType.GLASS;
|
||||
return;
|
||||
}
|
||||
|
||||
if (onBreakPot(player, id, location, event)) {
|
||||
return ItemType.POT;
|
||||
return;
|
||||
}
|
||||
|
||||
if (onBreakCrop(player, id, location, event)) {
|
||||
return ItemType.CROP;
|
||||
return;
|
||||
}
|
||||
|
||||
if (onBreakSprinkler(id, location)) {
|
||||
return ItemType.SPRINKLER;
|
||||
return;
|
||||
}
|
||||
|
||||
if (onBreakScarecrow(id, location)) {
|
||||
return ItemType.SCARECROW;
|
||||
return;
|
||||
}
|
||||
|
||||
return ItemType.UNKNOWN;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ItemType onPlaceSomething(Location location, String id) {
|
||||
public void onPlaceSomething(Location location, String id) {
|
||||
|
||||
if (onPlaceGlass(id, location)) {
|
||||
return ItemType.GLASS;
|
||||
return;
|
||||
}
|
||||
|
||||
if (onPlacePot(id, location)) {
|
||||
return ItemType.POT;
|
||||
return;
|
||||
}
|
||||
|
||||
if (onPlaceScarecrow(id, location)) {
|
||||
return ItemType.SCARECROW;
|
||||
return;
|
||||
}
|
||||
|
||||
return ItemType.UNKNOWN;
|
||||
}
|
||||
|
||||
@NotNull ItemType onInteractSomething(Player player, Location location, String id, Cancellable event) {
|
||||
void onInteractSomething(Player player, Location location, String id, Cancellable event) {
|
||||
|
||||
ItemStack item_in_hand = player.getInventory().getItemInMainHand();
|
||||
String item_in_hand_id = plugin.getPlatformInterface().getItemStackID(item_in_hand);
|
||||
|
||||
if (onInteractWithSprinkler(player, location, item_in_hand, item_in_hand_id)) {
|
||||
return ItemType.SPRINKLER;
|
||||
return;
|
||||
}
|
||||
|
||||
if (onInteractSprinkler(player, id, location, item_in_hand, item_in_hand_id)) {
|
||||
return ItemType.SPRINKLER;
|
||||
if (onInteractSprinkler(player, id, location, item_in_hand, item_in_hand_id, event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (onInteractPot(player, id, location, item_in_hand, item_in_hand_id, event)) {
|
||||
return ItemType.POT;
|
||||
return;
|
||||
}
|
||||
|
||||
if (onInteractCrop(player, id, location, item_in_hand, item_in_hand_id, event)) {
|
||||
return ItemType.CROP;
|
||||
return;
|
||||
}
|
||||
|
||||
if (onInteractWithWateringCan(player, item_in_hand_id, item_in_hand)) {
|
||||
return ItemType.WATERING_CAN;
|
||||
if (onInteractWithWateringCan(player, item_in_hand_id, item_in_hand, id, location)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return ItemType.UNKNOWN;
|
||||
}
|
||||
|
||||
public boolean onBreakGlass(String id, Location location) {
|
||||
@@ -274,7 +262,7 @@ public class PlatformManager extends Function {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean onInteractSprinkler(Player player, String id, Location location, ItemStack item_in_hand, String item_in_hand_id) {
|
||||
public boolean onInteractSprinkler(Player player, String id, Location location, ItemStack item_in_hand, String item_in_hand_id, Cancellable event) {
|
||||
SprinklerConfig sprinklerConfig = plugin.getSprinklerManager().getConfigByItemID(id);
|
||||
if (sprinklerConfig == null) {
|
||||
return false;
|
||||
@@ -292,6 +280,7 @@ public class PlatformManager extends Function {
|
||||
return true;
|
||||
}
|
||||
|
||||
event.setCancelled(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;
|
||||
@@ -338,12 +327,17 @@ public class PlatformManager extends Function {
|
||||
}
|
||||
|
||||
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());
|
||||
if (sprinkler != null) {
|
||||
WaterAmountHologram waterAmountHologram = sprinklerConfig.getSprinklerHologram();
|
||||
if (waterAmountHologram != null) {
|
||||
String content = waterAmountHologram.getContent(sprinkler.getWater(), sprinklerConfig.getStorage());
|
||||
plugin.getHologramManager().showHologram(player,
|
||||
location.clone().add(0.5, waterAmountHologram.getOffset(),0.5),
|
||||
AdventureUtils.getComponentFromMiniMessage(content),
|
||||
waterAmountHologram.getDuration() * 1000,
|
||||
waterAmountHologram.getMode(),
|
||||
waterAmountHologram.getTextDisplayMeta()
|
||||
);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -381,7 +375,7 @@ public class PlatformManager extends Function {
|
||||
}
|
||||
|
||||
if (player.getGameMode() != GameMode.CREATIVE) item_in_hand.setAmount(item_in_hand.getAmount() - 1);
|
||||
CustomCropsAPI.getInstance().placeCustomItem(sprinkler_loc, sprinklerConfig.getThreeD(), sprinklerConfig.getItemMode());
|
||||
CustomCrops.getInstance().getPlatformInterface().placeCustomItem(sprinkler_loc, sprinklerConfig.getThreeD(), sprinklerConfig.getItemMode());
|
||||
if (sprinklerConfig.getSound() != null) {
|
||||
AdventureUtils.playerSound(player, sprinklerConfig.getSound());
|
||||
}
|
||||
@@ -409,20 +403,21 @@ public class PlatformManager extends Function {
|
||||
return true;
|
||||
}
|
||||
|
||||
Pot potData = plugin.getWorldDataManager().getPotData(SimpleLocation.getByBukkitLocation(location).add(0,-1,0));
|
||||
Location pot_loc = location.clone().subtract(0, 1, 0);
|
||||
Pot potData = plugin.getWorldDataManager().getPotData(SimpleLocation.getByBukkitLocation(pot_loc));
|
||||
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);
|
||||
PotWaterEvent potWaterEvent = new PotWaterEvent(player, item_in_hand, passiveFillMethod.getAmount(), pot_loc);
|
||||
Bukkit.getPluginManager().callEvent(potWaterEvent);
|
||||
if (potWaterEvent.isCancelled()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
doPassiveFillAction(player, item_in_hand, passiveFillMethod, location);
|
||||
doPassiveFillAction(player, item_in_hand, passiveFillMethod, pot_loc);
|
||||
potData.addWater(potWaterEvent.getWater());
|
||||
return true;
|
||||
}
|
||||
@@ -444,7 +439,6 @@ public class PlatformManager extends Function {
|
||||
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()) {
|
||||
@@ -571,7 +565,7 @@ public class PlatformManager extends Function {
|
||||
|
||||
if (player.getGameMode() != GameMode.CREATIVE) item_in_hand.setAmount(item_in_hand.getAmount() - 1);
|
||||
player.swingMainHand();
|
||||
CustomCropsAPI.getInstance().placeCustomItem(crop_loc, cropPlantEvent.getCropModel(), cropConfig.getCropMode());
|
||||
CustomCrops.getInstance().getPlatformInterface().placeCustomItem(crop_loc, cropPlantEvent.getCropModel(), cropConfig.getCropMode());
|
||||
plugin.getWorldDataManager().addCropData(SimpleLocation.getByBukkitLocation(crop_loc), new GrowingCrop(cropConfig.getKey(), cropPlantEvent.getPoint()));
|
||||
return true;
|
||||
}
|
||||
@@ -658,13 +652,35 @@ public class PlatformManager extends Function {
|
||||
PotInfoEvent potInfoEvent = new PotInfoEvent(player, location, item_in_hand, potConfig, potData == null ? null : potData.getFertilizer(), potData == null ? 0 : potData.getWater(), growingCrop);
|
||||
Bukkit.getPluginManager().callEvent(potInfoEvent);
|
||||
|
||||
if (potConfig.isHologramEnabled() && potData != null) {
|
||||
if (potConfig.getRequiredItem() != null && !item_in_hand_id.equals(potConfig.getRequiredItem())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
WaterAmountHologram waterAmountHologram = potConfig.getWaterAmountHologram();
|
||||
if (waterAmountHologram != null && potData != null) {
|
||||
plugin.getHologramManager().showHologram(player,
|
||||
location.clone().add(0.5,waterAmountHologram.getOffset(),0.5),
|
||||
AdventureUtils.getComponentFromMiniMessage(waterAmountHologram.getContent(potData.getWater(), potConfig.getMaxStorage())),
|
||||
waterAmountHologram.getDuration() * 1000,
|
||||
waterAmountHologram.getMode(),
|
||||
waterAmountHologram.getTextDisplayMeta()
|
||||
);
|
||||
}
|
||||
|
||||
FertilizerHologram fertilizerHologram = potConfig.getFertilizerHologram();
|
||||
if (fertilizerHologram != null && potData != null && potData.getFertilizer() != null) {
|
||||
double offset = 0;
|
||||
StageConfig stageConfig = plugin.getCropManager().getStageConfig(plugin.getPlatformInterface().getAnyItemIDAt(location.clone().add(0,1,0)));
|
||||
if (stageConfig != null) {
|
||||
offset = stageConfig.getOffsetCorrection();
|
||||
}
|
||||
potConfig.getPotHologram().show(player, potData, location.clone().add(0.5,0,0.5), offset);
|
||||
plugin.getHologramManager().showHologram(player,
|
||||
location.clone().add(0.5,fertilizerHologram.getOffset() + offset,0.5),
|
||||
AdventureUtils.getComponentFromMiniMessage(fertilizerHologram.getContent(potData.getFertilizer())),
|
||||
fertilizerHologram.getDuration() * 1000,
|
||||
fertilizerHologram.getMode(),
|
||||
fertilizerHologram.getTextDisplayMeta()
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -701,7 +717,7 @@ public class PlatformManager extends Function {
|
||||
}
|
||||
|
||||
private boolean onBreakSprinkler(String id, Location location) {
|
||||
if (!plugin.getSprinklerManager().containsSprinkler(id)) {
|
||||
if (plugin.getSprinklerManager().getConfigKeyByItemID(id) == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -804,7 +820,7 @@ public class PlatformManager extends Function {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean onInteractWithWateringCan(Player player, String item_in_hand_id, ItemStack item_in_hand) {
|
||||
public boolean onInteractWithWateringCan(Player player, String item_in_hand_id, ItemStack item_in_hand, @Nullable String id, @Nullable Location location) {
|
||||
WateringCanConfig wateringCanConfig = plugin.getWateringCanManager().getConfigByItemID(item_in_hand_id);
|
||||
if (wateringCanConfig == null) {
|
||||
return false;
|
||||
@@ -812,12 +828,27 @@ public class PlatformManager extends Function {
|
||||
|
||||
int current = plugin.getWateringCanManager().getCurrentWater(item_in_hand);
|
||||
if (current >= wateringCanConfig.getStorage()) return true;
|
||||
List<Block> lineOfSight = player.getLineOfSight(null, 5);
|
||||
List<String> blockIds = lineOfSight.stream().map(block -> plugin.getPlatformInterface().getBlockID(block)).toList();
|
||||
|
||||
int add = 0;
|
||||
for (PositiveFillMethod positiveFillMethod : wateringCanConfig.getPositiveFillMethods()) {
|
||||
if (positiveFillMethod.getType() == PositiveFillMethod.InteractType.BLOCK) {
|
||||
|
||||
if (id != null && location != null) {
|
||||
for (PositiveFillMethod positiveFillMethod : wateringCanConfig.getPositiveFillMethods()) {
|
||||
if (positiveFillMethod.getId().equals(id)) {
|
||||
add = positiveFillMethod.getAmount();
|
||||
if (positiveFillMethod.getSound() != null) {
|
||||
AdventureUtils.playerSound(player, positiveFillMethod.getSound());
|
||||
}
|
||||
if (positiveFillMethod.getParticle() != null) {
|
||||
location.getWorld().spawnParticle(positiveFillMethod.getParticle(), location.clone().add(0.5,1.1, 0.5),5,0.1,0.1,0.1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
List<Block> lineOfSight = player.getLineOfSight(null, 5);
|
||||
List<String> blockIds = lineOfSight.stream().map(block -> plugin.getPlatformInterface().getBlockID(block)).toList();
|
||||
|
||||
for (PositiveFillMethod positiveFillMethod : wateringCanConfig.getPositiveFillMethods()) {
|
||||
int index = 0;
|
||||
for (String blockId : blockIds) {
|
||||
if (positiveFillMethod.getId().equals(blockId)) {
|
||||
@@ -827,7 +858,7 @@ public class PlatformManager extends Function {
|
||||
}
|
||||
if (positiveFillMethod.getParticle() != null) {
|
||||
Block block = lineOfSight.get(index);
|
||||
block.getWorld().spawnParticle(positiveFillMethod.getParticle(), block.getLocation().add(0.5,1, 0.5),5,0.1,0.1,0.1);
|
||||
block.getWorld().spawnParticle(positiveFillMethod.getParticle(), block.getLocation().add(0.5,1.1, 0.5),5,0.1,0.1,0.1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -844,5 +875,4 @@ public class PlatformManager extends Function {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -67,6 +67,7 @@ public class ItemsAdderPluginImpl implements PlatformInterface {
|
||||
if (entity instanceof ItemFrame itemFrame)
|
||||
return itemFrame;
|
||||
else {
|
||||
AdventureUtils.consoleMessage("<red>[CustomCrops] Item Frame not exists: " + id);
|
||||
customFurniture.remove(false);
|
||||
}
|
||||
return null;
|
||||
@@ -75,7 +76,18 @@ public class ItemsAdderPluginImpl implements PlatformInterface {
|
||||
@Nullable
|
||||
@Override
|
||||
public ItemDisplay placeItemDisplay(Location location, String id) {
|
||||
//TODO Not implemented
|
||||
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 ItemDisplay itemDisplay)
|
||||
return itemDisplay;
|
||||
else {
|
||||
AdventureUtils.consoleMessage("<red>[CustomCrops] Item Display not exists: " + id);
|
||||
customFurniture.remove(false);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -116,11 +128,6 @@ public class ItemsAdderPluginImpl implements PlatformInterface {
|
||||
CustomBlock.place(id, location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getItemFrameLocation(Location location) {
|
||||
return location.clone().add(0.5, 0.5, 0.5);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getItemStackID(@NotNull ItemStack itemStack) {
|
||||
@@ -135,8 +142,9 @@ public class ItemsAdderPluginImpl implements PlatformInterface {
|
||||
@Nullable
|
||||
@Override
|
||||
public String getItemDisplayID(ItemDisplay itemDisplay) {
|
||||
//TODO Not implemented
|
||||
return null;
|
||||
CustomFurniture customFurniture = CustomFurniture.byAlreadySpawned(itemDisplay);
|
||||
if (customFurniture == null) return null;
|
||||
return customFurniture.getNamespacedID();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -71,7 +71,7 @@ public class OraxenPluginImpl implements PlatformInterface {
|
||||
public ItemFrame placeItemFrame(Location location, String id) {
|
||||
FurnitureMechanic mechanic = (FurnitureMechanic) FurnitureFactory.getInstance().getMechanic(id);
|
||||
if (mechanic == null) {
|
||||
AdventureUtils.consoleMessage("<red>[CustomCrops] Item Frame not exists: " + id);
|
||||
AdventureUtils.consoleMessage("<red>[CustomCrops] Furniture not exists: " + id);
|
||||
return null;
|
||||
}
|
||||
Entity entity = mechanic.place(location, 0, Rotation.NONE, BlockFace.UP);
|
||||
@@ -89,7 +89,7 @@ public class OraxenPluginImpl implements PlatformInterface {
|
||||
public ItemDisplay placeItemDisplay(Location location, String id) {
|
||||
FurnitureMechanic mechanic = (FurnitureMechanic) FurnitureFactory.getInstance().getMechanic(id);
|
||||
if (mechanic == null) {
|
||||
AdventureUtils.consoleMessage("<red>[CustomCrops] Item Display not exists: " + id);
|
||||
AdventureUtils.consoleMessage("<red>[CustomCrops] Furniture not exists: " + id);
|
||||
return null;
|
||||
}
|
||||
Entity entity = mechanic.place(location);
|
||||
@@ -135,15 +135,9 @@ public class OraxenPluginImpl implements PlatformInterface {
|
||||
|
||||
@Override
|
||||
public void placeChorus(Location location, String id) {
|
||||
//TODO Not implemented, so use tripwire instead
|
||||
StringBlockMechanicFactory.setBlockModel(location.getBlock(), id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getItemFrameLocation(Location location) {
|
||||
return location.clone().add(0.5,0.5,0.5);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getItemDisplayID(ItemDisplay itemDisplay) {
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package net.momirealms.customcrops.api.event;
|
||||
|
||||
import net.momirealms.customcrops.api.object.crop.CropConfig;
|
||||
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.jetbrains.annotations.NotNull;
|
||||
|
||||
public class CropBreakEvent extends PlayerEvent implements Cancellable {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private boolean cancelled;
|
||||
private final CropConfig cropConfig;
|
||||
private final String crop_id;
|
||||
private final Location location;
|
||||
|
||||
public CropBreakEvent(@NotNull Player who, CropConfig cropConfig, String crop_id, Location location) {
|
||||
super(who);
|
||||
this.cropConfig = cropConfig;
|
||||
this.crop_id = crop_id;
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
@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 CropConfig getCropConfig() {
|
||||
return cropConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the crop item id in IA/Oraxen
|
||||
* @return item id
|
||||
*/
|
||||
public String getCropItemID() {
|
||||
return crop_id;
|
||||
}
|
||||
|
||||
public Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,10 @@ package net.momirealms.customcrops.api.object;
|
||||
|
||||
public class Function {
|
||||
|
||||
public void init() {
|
||||
|
||||
}
|
||||
|
||||
public void load() {
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package net.momirealms.customcrops.api.object.action;
|
||||
|
||||
import net.momirealms.customcrops.CustomCrops;
|
||||
import net.momirealms.customcrops.api.CustomCropsAPI;
|
||||
import net.momirealms.customcrops.api.object.ItemMode;
|
||||
import net.momirealms.customcrops.api.object.crop.StageConfig;
|
||||
import net.momirealms.customcrops.api.object.world.SimpleLocation;
|
||||
@@ -39,7 +38,7 @@ public class BreakImpl implements Action {
|
||||
public void doOn(@Nullable Player player, @Nullable SimpleLocation crop_loc, ItemMode itemMode) {
|
||||
if (crop_loc == null) return;
|
||||
CustomCrops.getInstance().getScheduler().callSyncMethod(() -> {
|
||||
CustomCropsAPI.getInstance().removeCustomItem(crop_loc.getBukkitLocation(), itemMode);
|
||||
CustomCrops.getInstance().getPlatformInterface().removeCustomItem(crop_loc.getBukkitLocation(), itemMode);
|
||||
CustomCrops.getInstance().getWorldDataManager().removeCropData(crop_loc);
|
||||
return null;
|
||||
});
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package net.momirealms.customcrops.api.object.action;
|
||||
|
||||
import net.momirealms.customcrops.CustomCrops;
|
||||
import net.momirealms.customcrops.api.CustomCropsAPI;
|
||||
import net.momirealms.customcrops.api.object.ItemMode;
|
||||
import net.momirealms.customcrops.api.object.basic.ConfigManager;
|
||||
import net.momirealms.customcrops.api.object.basic.MessageManager;
|
||||
@@ -55,7 +54,7 @@ public class ReplantImpl implements Action {
|
||||
return null;
|
||||
}
|
||||
if (!CustomCrops.getInstance().getPlatformInterface().detectAnyThing(location)) {
|
||||
CustomCropsAPI.getInstance().placeCustomItem(location, model, newCMode);
|
||||
CustomCrops.getInstance().getPlatformInterface().placeCustomItem(location, model, newCMode);
|
||||
CustomCrops.getInstance().getWorldDataManager().addCropData(crop_loc, new GrowingCrop(crop, point));
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package net.momirealms.customcrops.api.object.action;
|
||||
|
||||
import net.momirealms.customcrops.CustomCrops;
|
||||
import net.momirealms.customcrops.api.CustomCropsAPI;
|
||||
import net.momirealms.customcrops.api.object.ItemMode;
|
||||
import net.momirealms.customcrops.api.object.crop.VariationCrop;
|
||||
import net.momirealms.customcrops.api.object.fertilizer.Variation;
|
||||
@@ -66,8 +65,8 @@ public record VariationImpl(VariationCrop[] variationCrops) implements Action {
|
||||
private void doVariation(@NotNull SimpleLocation crop_loc, ItemMode itemMode, VariationCrop variationCrop) {
|
||||
CustomCrops.getInstance().getScheduler().callSyncMethod(() -> {
|
||||
Location location = crop_loc.getBukkitLocation();
|
||||
if (CustomCropsAPI.getInstance().removeCustomItem(location, itemMode)) {
|
||||
CustomCropsAPI.getInstance().placeCustomItem(location, variationCrop.getId(), variationCrop.getCropMode());
|
||||
if (CustomCrops.getInstance().getPlatformInterface().removeCustomItem(location, itemMode)) {
|
||||
CustomCrops.getInstance().getPlatformInterface().placeCustomItem(location, variationCrop.getId(), variationCrop.getCropMode());
|
||||
}
|
||||
CustomCrops.getInstance().getWorldDataManager().removeCropData(crop_loc);
|
||||
return null;
|
||||
|
||||
@@ -76,11 +76,17 @@ public class ConfigManager extends Function {
|
||||
debug = config.getBoolean("debug");
|
||||
setUpMode = config.getBoolean("set-up-mode", true);
|
||||
loadWorlds(Objects.requireNonNull(config.getConfigurationSection("worlds")));
|
||||
loadOptimization(Objects.requireNonNull(config.getConfigurationSection("optimization")));
|
||||
loadScheduleSystem(Objects.requireNonNull(config.getConfigurationSection("schedule-system")));
|
||||
loadMechanic(Objects.requireNonNull(config.getConfigurationSection("mechanics")));
|
||||
loadOtherSetting(Objects.requireNonNull(config.getConfigurationSection("other-settings")));
|
||||
}
|
||||
|
||||
private void loadOptimization(ConfigurationSection section) {
|
||||
enableLimitation = section.getBoolean("limitation.enable");
|
||||
maxCropPerChunk = section.getInt("limitation.valid-crop-amount");
|
||||
}
|
||||
|
||||
private void loadWorlds(ConfigurationSection section) {
|
||||
worldFolderPath = section.getString("folder", "");
|
||||
whiteListWorlds = section.getString("mode", "whitelist").equalsIgnoreCase("whitelist");
|
||||
@@ -105,6 +111,7 @@ public class ConfigManager extends Function {
|
||||
enableGreenhouse = section.getBoolean("season.greenhouse.enable", true);
|
||||
greenhouseRange = section.getInt("season.greenhouse.range", 5);
|
||||
greenhouseBlock = section.getString("season.greenhouse.block");
|
||||
scarecrow = section.getString("scarecrow");
|
||||
}
|
||||
|
||||
private void loadOtherSetting(ConfigurationSection section) {
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package net.momirealms.customcrops.api.object.condition;
|
||||
|
||||
import net.momirealms.customcrops.CustomCrops;
|
||||
import net.momirealms.customcrops.api.CustomCropsAPI;
|
||||
import net.momirealms.customcrops.api.object.ItemMode;
|
||||
import net.momirealms.customcrops.api.object.world.SimpleLocation;
|
||||
import org.bukkit.Location;
|
||||
@@ -48,9 +47,9 @@ public class DeathCondition {
|
||||
Location location = simpleLocation.getBukkitLocation();
|
||||
if (location == null) return;
|
||||
CustomCrops.getInstance().getScheduler().callSyncMethod(() -> {
|
||||
CustomCropsAPI.getInstance().removeCustomItem(location, itemMode);
|
||||
CustomCrops.getInstance().getPlatformInterface().removeCustomItem(location, itemMode);
|
||||
if (dead_model != null) {
|
||||
CustomCropsAPI.getInstance().placeCustomItem(location, dead_model, itemMode);
|
||||
CustomCrops.getInstance().getPlatformInterface().placeCustomItem(location, dead_model, itemMode);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
@@ -86,7 +86,7 @@ public class CropManager extends Function implements Listener {
|
||||
for (String key : config.getKeys(false)) {
|
||||
ConfigurationSection cropSec = config.getConfigurationSection(key);
|
||||
if (cropSec == null) continue;
|
||||
ItemMode itemMode = ItemMode.valueOf(cropSec.getString("crop-mode", "TripWire").toUpperCase());
|
||||
ItemMode itemMode = ItemMode.valueOf(cropSec.getString("type", "TripWire").toUpperCase());
|
||||
String[] bottomBlocks = cropSec.getStringList("pot-whitelist").toArray(new String[0]);
|
||||
if (bottomBlocks.length == 0) {
|
||||
AdventureUtils.consoleMessage("<red>[CustomCrops] pot-whitelist is not set for crop: " + key);
|
||||
|
||||
@@ -55,4 +55,8 @@ public class Fertilizer implements Serializable {
|
||||
public int getLeftTimes() {
|
||||
return times;
|
||||
}
|
||||
|
||||
public void setTimes(int times) {
|
||||
this.times = times;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,26 +22,14 @@ import org.bukkit.Particle;
|
||||
|
||||
public class PositiveFillMethod extends AbstractFillMethod {
|
||||
|
||||
private final InteractType type;
|
||||
private final String id;
|
||||
|
||||
public PositiveFillMethod(InteractType type, String id, int amount, Particle particle, Sound sound) {
|
||||
public PositiveFillMethod(String id, int amount, Particle particle, Sound sound) {
|
||||
super(amount, particle, sound);
|
||||
this.type = type;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public InteractType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public enum InteractType {
|
||||
BLOCK,
|
||||
ENTITY,
|
||||
MM
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.api.object.hologram;
|
||||
|
||||
public abstract class AbstractHologram {
|
||||
|
||||
protected final String content;
|
||||
private final double offset;
|
||||
private final HologramManager.Mode mode;
|
||||
private final int duration;
|
||||
private TextDisplayMeta textDisplayMeta;
|
||||
|
||||
public AbstractHologram(String content, double offset, HologramManager.Mode mode, int duration, TextDisplayMeta textDisplayMeta) {
|
||||
this.content = content;
|
||||
this.offset = offset;
|
||||
this.mode = mode;
|
||||
this.duration = duration;
|
||||
this.textDisplayMeta = textDisplayMeta;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public double getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public HologramManager.Mode getMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
public int getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public TextDisplayMeta getTextDisplayMeta() {
|
||||
return textDisplayMeta;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.api.object.hologram;
|
||||
|
||||
|
||||
import net.momirealms.customcrops.api.object.fertilizer.Fertilizer;
|
||||
import net.momirealms.customcrops.api.object.fertilizer.FertilizerConfig;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class FertilizerHologram extends AbstractHologram {
|
||||
|
||||
public FertilizerHologram(@NotNull String content, double offset, HologramManager.Mode mode, int duration, TextDisplayMeta textDisplayMeta) {
|
||||
super(content, offset, mode, duration, textDisplayMeta);
|
||||
}
|
||||
|
||||
public String getContent(Fertilizer fertilizer) {
|
||||
FertilizerConfig fertilizerConfig = fertilizer.getConfig();
|
||||
return content.replace("{icon}", String.valueOf(fertilizerConfig.getIcon()))
|
||||
.replace("{left_times}", String.valueOf(fertilizer.getLeftTimes()))
|
||||
.replace("{max_times}", String.valueOf(fertilizerConfig.getTimes()));
|
||||
}
|
||||
}
|
||||
@@ -15,10 +15,12 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.api.object;
|
||||
package net.momirealms.customcrops.api.object.hologram;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.momirealms.customcrops.CustomCrops;
|
||||
import net.momirealms.customcrops.api.object.Function;
|
||||
import net.momirealms.customcrops.api.object.Tuple;
|
||||
import net.momirealms.customcrops.api.util.FakeEntityUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
@@ -86,13 +88,13 @@ public class HologramManager extends Function implements Listener {
|
||||
this.hologramMap.remove(event.getPlayer().getUniqueId());
|
||||
}
|
||||
|
||||
public void showHologram(Player player, Location location, Component component, int millis, Mode mode) {
|
||||
public void showHologram(Player player, Location location, Component component, int millis, Mode mode, TextDisplayMeta textDisplayMeta) {
|
||||
HologramCache hologramCache = hologramMap.get(player.getUniqueId());
|
||||
if (hologramCache != null) {
|
||||
hologramCache.showHologram(player, location, component, millis, mode);
|
||||
hologramCache.showHologram(player, location, component, millis, mode, textDisplayMeta);
|
||||
} else {
|
||||
hologramCache = new HologramCache();
|
||||
hologramCache.showHologram(player, location, component, millis, mode);
|
||||
hologramCache.showHologram(player, location, component, millis, mode, textDisplayMeta);
|
||||
hologramMap.put(player.getUniqueId(), hologramCache);
|
||||
}
|
||||
}
|
||||
@@ -133,7 +135,7 @@ public class HologramManager extends Function implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
public void showHologram(Player player, Location location, Component component, int millis, Mode mode) {
|
||||
public void showHologram(Player player, Location location, Component component, int millis, Mode mode, TextDisplayMeta textDisplayMeta) {
|
||||
int entity_id = push(location, millis);
|
||||
if (entity_id == 0) {
|
||||
int random = ThreadLocalRandom.current().nextInt(Integer.MAX_VALUE);
|
||||
@@ -143,14 +145,14 @@ public class HologramManager extends Function implements Listener {
|
||||
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));
|
||||
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getSpawnPacket(random, location.clone().add(0,1,0), EntityType.TEXT_DISPLAY));
|
||||
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getTextDisplayMetaPacket(random, component, textDisplayMeta));
|
||||
}
|
||||
} else {
|
||||
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));
|
||||
CustomCrops.getProtocolManager().sendServerPacket(player, FakeEntityUtils.getTextDisplayMetaPacket(entity_id, component, textDisplayMeta));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package net.momirealms.customcrops.api.object.hologram;
|
||||
|
||||
public class TextDisplayMeta {
|
||||
|
||||
private final boolean hasShadow;
|
||||
private final boolean isSeeThrough;
|
||||
private final boolean useDefaultBackground;
|
||||
private final int backgroundColor;
|
||||
private final byte opacity;
|
||||
|
||||
public TextDisplayMeta(boolean hasShadow, boolean isSeeThrough, boolean useDefaultBackground, int backgroundColor, byte opacity) {
|
||||
this.hasShadow = hasShadow;
|
||||
this.isSeeThrough = isSeeThrough;
|
||||
this.useDefaultBackground = useDefaultBackground;
|
||||
this.backgroundColor = backgroundColor;
|
||||
this.opacity = opacity;
|
||||
}
|
||||
|
||||
public boolean isHasShadow() {
|
||||
return hasShadow;
|
||||
}
|
||||
|
||||
public boolean isSeeThrough() {
|
||||
return isSeeThrough;
|
||||
}
|
||||
|
||||
public boolean isUseDefaultBackground() {
|
||||
return useDefaultBackground;
|
||||
}
|
||||
|
||||
public int getBackgroundColor() {
|
||||
return backgroundColor;
|
||||
}
|
||||
|
||||
public byte getOpacity() {
|
||||
return opacity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.api.object.hologram;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class WaterAmountHologram extends AbstractHologram {
|
||||
|
||||
private final String bar_left;
|
||||
private final String bar_full;
|
||||
private final String bar_empty;
|
||||
private final String bar_right;
|
||||
|
||||
|
||||
public WaterAmountHologram(@NotNull String content, double offset, HologramManager.Mode mode, int duration,
|
||||
String bar_left, String bar_full, String bar_empty, String bar_right, TextDisplayMeta textDisplayMeta) {
|
||||
super(content, offset, mode, duration, textDisplayMeta);
|
||||
this.bar_left = bar_left;
|
||||
this.bar_full = bar_full;
|
||||
this.bar_empty = bar_empty;
|
||||
this.bar_right = bar_right;
|
||||
}
|
||||
|
||||
public String getContent(int current, int storage) {
|
||||
return super.content.replace("{current}", String.valueOf(current))
|
||||
.replace("{storage}", String.valueOf(storage))
|
||||
.replace("{water_bar}", getWaterBar(current, storage));
|
||||
}
|
||||
|
||||
private 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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.api.object.migrate;
|
||||
|
||||
import net.momirealms.customcrops.CustomCrops;
|
||||
import net.momirealms.customcrops.api.object.Function;
|
||||
import net.momirealms.customcrops.api.object.basic.ConfigManager;
|
||||
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.world.CCChunk;
|
||||
import net.momirealms.customcrops.api.object.world.ChunkCoordinate;
|
||||
import net.momirealms.customcrops.api.object.world.SimpleLocation;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class MigrateWorld extends Function {
|
||||
|
||||
private final String worldName;
|
||||
private final ConcurrentHashMap<ChunkCoordinate, CCChunk> chunkMap;
|
||||
|
||||
public MigrateWorld(String world) {
|
||||
this.worldName = world;
|
||||
this.chunkMap = new ConcurrentHashMap<>(64);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
public void init() {
|
||||
File chunks_folder = new File(CustomCrops.getInstance().getDataFolder().getParentFile().getParentFile(), ConfigManager.worldFolderPath + worldName + File.separator + "customcrops" + File.separator + "chunks");
|
||||
if (!chunks_folder.exists()) chunks_folder.mkdirs();
|
||||
File[] data_files = chunks_folder.listFiles();
|
||||
if (data_files == null) return;
|
||||
for (File file : data_files) {
|
||||
ChunkCoordinate chunkCoordinate = ChunkCoordinate.getByString(file.getName().substring(0, file.getName().length() - 7));
|
||||
try (FileInputStream fis = new FileInputStream(file); ObjectInputStream ois = new ObjectInputStream(fis)) {
|
||||
CCChunk chunk = (CCChunk) ois.readObject();
|
||||
if (chunk.isUseless()) {
|
||||
file.delete();
|
||||
continue;
|
||||
}
|
||||
if (chunkCoordinate != null) chunkMap.put(chunkCoordinate, chunk);
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
public void disable() {
|
||||
File chunks_folder = new File(CustomCrops.getInstance().getDataFolder().getParentFile().getParentFile(), ConfigManager.worldFolderPath + worldName + File.separator + "customcrops" + File.separator + "chunks");
|
||||
if (!chunks_folder.exists()) chunks_folder.mkdirs();
|
||||
for (Map.Entry<ChunkCoordinate, CCChunk> entry : chunkMap.entrySet()) {
|
||||
ChunkCoordinate chunkCoordinate = entry.getKey();
|
||||
CCChunk chunk = entry.getValue();
|
||||
String fileName = chunkCoordinate.getFileName() + ".ccdata";
|
||||
File file = new File(chunks_folder, fileName);
|
||||
if (chunk.isUseless() && file.exists()) {
|
||||
file.delete();
|
||||
continue;
|
||||
}
|
||||
try (FileOutputStream fos = new FileOutputStream(file); ObjectOutputStream oos = new ObjectOutputStream(fos)) {
|
||||
oos.writeObject(chunk);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getWorldName() {
|
||||
return worldName;
|
||||
}
|
||||
|
||||
public void removePotData(SimpleLocation simpleLocation) {
|
||||
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
|
||||
if (chunk == null) return;
|
||||
chunk.removePotData(simpleLocation);
|
||||
}
|
||||
|
||||
public void removeCropData(SimpleLocation simpleLocation) {
|
||||
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
|
||||
if (chunk == null) return;
|
||||
chunk.removeCropData(simpleLocation);
|
||||
}
|
||||
|
||||
public void addCropData(SimpleLocation simpleLocation, GrowingCrop growingCrop) {
|
||||
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
|
||||
if (chunk != null) {
|
||||
chunk.addCropData(simpleLocation, growingCrop);
|
||||
return;
|
||||
}
|
||||
chunk = createNewChunk(simpleLocation);
|
||||
chunk.addCropData(simpleLocation, growingCrop);
|
||||
}
|
||||
|
||||
public GrowingCrop getCropData(SimpleLocation simpleLocation) {
|
||||
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
|
||||
if (chunk != null) {
|
||||
return chunk.getCropData(simpleLocation);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getChunkCropAmount(SimpleLocation simpleLocation) {
|
||||
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
|
||||
if (chunk == null) return 0;
|
||||
return chunk.getCropAmount();
|
||||
}
|
||||
|
||||
public void removeGreenhouse(SimpleLocation simpleLocation) {
|
||||
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
|
||||
if (chunk == null) return;
|
||||
chunk.removeGreenhouse(simpleLocation);
|
||||
}
|
||||
|
||||
public void addGreenhouse(SimpleLocation simpleLocation) {
|
||||
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
|
||||
if (chunk != null) {
|
||||
chunk.addGreenhouse(simpleLocation);
|
||||
return;
|
||||
}
|
||||
chunk = createNewChunk(simpleLocation);
|
||||
chunk.addGreenhouse(simpleLocation);
|
||||
}
|
||||
|
||||
public boolean isGreenhouse(SimpleLocation simpleLocation) {
|
||||
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
|
||||
if (chunk == null) return false;
|
||||
return chunk.isGreenhouse(simpleLocation);
|
||||
}
|
||||
|
||||
public void removeScarecrow(SimpleLocation simpleLocation) {
|
||||
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
|
||||
if (chunk == null) return;
|
||||
chunk.removeScarecrow(simpleLocation);
|
||||
}
|
||||
|
||||
public void addScarecrow(SimpleLocation simpleLocation) {
|
||||
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
|
||||
if (chunk != null) {
|
||||
chunk.addScarecrow(simpleLocation);
|
||||
return;
|
||||
}
|
||||
chunk = createNewChunk(simpleLocation);
|
||||
chunk.addScarecrow(simpleLocation);
|
||||
}
|
||||
|
||||
public boolean hasScarecrow(SimpleLocation simpleLocation) {
|
||||
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
|
||||
if (chunk == null) return false;
|
||||
return chunk.hasScarecrow();
|
||||
}
|
||||
|
||||
public void removeSprinklerData(SimpleLocation simpleLocation) {
|
||||
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
|
||||
if (chunk == null) return;
|
||||
chunk.removeSprinklerData(simpleLocation);
|
||||
}
|
||||
|
||||
public void addSprinklerData(SimpleLocation simpleLocation, Sprinkler sprinkler) {
|
||||
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
|
||||
if (chunk != null) {
|
||||
chunk.addSprinklerData(simpleLocation, sprinkler);
|
||||
return;
|
||||
}
|
||||
chunk = createNewChunk(simpleLocation);
|
||||
chunk.addSprinklerData(simpleLocation, sprinkler);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Sprinkler getSprinklerData(SimpleLocation simpleLocation) {
|
||||
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
|
||||
if (chunk == null) return null;
|
||||
return chunk.getSprinklerData(simpleLocation);
|
||||
}
|
||||
|
||||
public void addWaterToPot(SimpleLocation simpleLocation, int amount, @Nullable String pot_id) {
|
||||
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
|
||||
if (chunk != null) {
|
||||
chunk.addWaterToPot(simpleLocation, amount, pot_id);
|
||||
return;
|
||||
}
|
||||
chunk = createNewChunk(simpleLocation);
|
||||
chunk.addWaterToPot(simpleLocation, amount, pot_id);
|
||||
}
|
||||
|
||||
public void addFertilizerToPot(SimpleLocation simpleLocation, Fertilizer fertilizer, @NotNull String pot_id) {
|
||||
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
|
||||
if (chunk != null) {
|
||||
chunk.addFertilizerToPot(simpleLocation, fertilizer, pot_id);
|
||||
return;
|
||||
}
|
||||
chunk = createNewChunk(simpleLocation);
|
||||
chunk.addFertilizerToPot(simpleLocation, fertilizer, pot_id);
|
||||
}
|
||||
|
||||
public Pot getPotData(SimpleLocation simpleLocation) {
|
||||
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
|
||||
if (chunk == null) return null;
|
||||
return chunk.getPotData(simpleLocation);
|
||||
}
|
||||
|
||||
public void addPotData(SimpleLocation simpleLocation, Pot pot) {
|
||||
CCChunk chunk = chunkMap.get(simpleLocation.getChunkCoordinate());
|
||||
if (chunk != null) {
|
||||
chunk.addPotData(simpleLocation, pot);
|
||||
return;
|
||||
}
|
||||
chunk = createNewChunk(simpleLocation);
|
||||
chunk.addPotData(simpleLocation, pot);
|
||||
}
|
||||
|
||||
public CCChunk createNewChunk(SimpleLocation simpleLocation) {
|
||||
CCChunk newChunk = new CCChunk();
|
||||
chunkMap.put(simpleLocation.getChunkCoordinate(), newChunk);
|
||||
return newChunk;
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,8 @@ import net.momirealms.customcrops.api.object.fertilizer.Fertilizer;
|
||||
import net.momirealms.customcrops.api.object.fertilizer.FertilizerConfig;
|
||||
import net.momirealms.customcrops.api.object.fertilizer.FertilizerType;
|
||||
import net.momirealms.customcrops.api.object.fill.PassiveFillMethod;
|
||||
import net.momirealms.customcrops.api.object.hologram.FertilizerHologram;
|
||||
import net.momirealms.customcrops.api.object.hologram.WaterAmountHologram;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -34,18 +36,23 @@ public class PotConfig {
|
||||
private final Pair<String, String> pot;
|
||||
private final boolean enableFertilized;
|
||||
private final PassiveFillMethod[] passiveFillMethods;
|
||||
private final boolean enableHologram;
|
||||
private final PotHologram potHologram;
|
||||
private final FertilizerHologram fertilizerHologram;
|
||||
private final WaterAmountHologram waterAmountHologram;
|
||||
private final String requiredItem;
|
||||
|
||||
public PotConfig(int max_storage, String dry_pot, String wet_pot, boolean enableFertilized,
|
||||
@NotNull PassiveFillMethod[] passiveFillMethods, boolean enableHologram, @Nullable PotHologram potHologram) {
|
||||
@NotNull PassiveFillMethod[] passiveFillMethods,
|
||||
@Nullable FertilizerHologram fertilizerHologram,
|
||||
@Nullable WaterAmountHologram waterAmountHologram,
|
||||
String requiredItem) {
|
||||
this.max_storage = max_storage;
|
||||
this.pot = Pair.of(dry_pot, wet_pot);
|
||||
this.enableFertilized = enableFertilized;
|
||||
this.fertilizerConvertMap = new HashMap<>();
|
||||
this.passiveFillMethods = passiveFillMethods;
|
||||
this.enableHologram = enableHologram;
|
||||
this.potHologram = potHologram;
|
||||
this.fertilizerHologram = fertilizerHologram;
|
||||
this.waterAmountHologram = waterAmountHologram;
|
||||
this.requiredItem = requiredItem;
|
||||
}
|
||||
|
||||
public void registerFertilizedPot(FertilizerType fertilizerType, String dry_pot, String wet_pot) {
|
||||
@@ -81,11 +88,18 @@ public class PotConfig {
|
||||
return passiveFillMethods;
|
||||
}
|
||||
|
||||
public boolean isHologramEnabled() {
|
||||
return enableHologram;
|
||||
@Nullable
|
||||
public FertilizerHologram getFertilizerHologram() {
|
||||
return fertilizerHologram;
|
||||
}
|
||||
|
||||
public PotHologram getPotHologram() {
|
||||
return potHologram;
|
||||
@Nullable
|
||||
public WaterAmountHologram getWaterAmountHologram() {
|
||||
return waterAmountHologram;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getRequiredItem() {
|
||||
return requiredItem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,122 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.api.object.pot;
|
||||
|
||||
import net.momirealms.customcrops.CustomCrops;
|
||||
import net.momirealms.customcrops.api.object.HologramManager;
|
||||
import net.momirealms.customcrops.api.object.fertilizer.Fertilizer;
|
||||
import net.momirealms.customcrops.api.util.AdventureUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class PotHologram {
|
||||
|
||||
private final String fertilizerText;
|
||||
private final double fertilizerOffset;
|
||||
private final String waterText;
|
||||
private final double waterOffset;
|
||||
private final HologramManager.Mode mode;
|
||||
private final int duration;
|
||||
private final String bar_left;
|
||||
private final String bar_full;
|
||||
private final String bar_empty;
|
||||
private final String bar_right;
|
||||
private final Pattern betterPattern = Pattern.compile("\\{(.+?)\\}");
|
||||
|
||||
public PotHologram(String fertilizerText, double fertilizerOffset, String waterText, double waterOffset, HologramManager.Mode mode, int duration,
|
||||
String bar_left, String bar_full, String bar_empty, String bar_right) {
|
||||
this.mode = mode;
|
||||
this.duration = duration;
|
||||
this.fertilizerText = fertilizerText;
|
||||
this.waterText = waterText;
|
||||
this.fertilizerOffset = fertilizerOffset;
|
||||
this.waterOffset = waterOffset;
|
||||
this.bar_left = bar_left;
|
||||
this.bar_full = bar_full;
|
||||
this.bar_empty = bar_empty;
|
||||
this.bar_right = bar_right;
|
||||
}
|
||||
|
||||
private List<String> detectBetterPlaceholders(String text) {
|
||||
List<String> placeholders = new ArrayList<>();
|
||||
Matcher matcher = betterPattern.matcher(text);
|
||||
while (matcher.find()) placeholders.add(matcher.group());
|
||||
return placeholders;
|
||||
}
|
||||
|
||||
public void show(Player player, Pot pot, Location location, double offset) {
|
||||
if (fertilizerText != null && pot.getFertilizer() != null) {
|
||||
String parsed = CustomCrops.getInstance().getIntegrationManager().getPlaceholderManager().parse(player, fertilizerText);
|
||||
parseAndSend(parsed, player, pot, location, offset + fertilizerOffset);
|
||||
}
|
||||
if (waterText != null) {
|
||||
String parsed = CustomCrops.getInstance().getIntegrationManager().getPlaceholderManager().parse(player, waterText);
|
||||
parseAndSend(parsed, player, pot, location, offset + waterOffset);
|
||||
}
|
||||
}
|
||||
|
||||
public void parseAndSend(String parsed, Player player, Pot pot, Location location, double offset) {
|
||||
for (String detected : detectBetterPlaceholders(parsed)) {
|
||||
String replacer = getReplacer(detected, pot);
|
||||
parsed = parsed.replace(detected, replacer);
|
||||
}
|
||||
CustomCrops.getInstance().getHologramManager().showHologram(player, location.clone().add(0, offset, 0), AdventureUtils.getComponentFromMiniMessage(parsed), duration * 1000, mode);
|
||||
}
|
||||
|
||||
public String getReplacer(String text, Pot pot) {
|
||||
switch (text) {
|
||||
case "{icon}" -> {
|
||||
Fertilizer fertilizer = pot.getFertilizer();
|
||||
if (fertilizer == null) return "";
|
||||
return fertilizer.getConfig().getIcon();
|
||||
}
|
||||
case "{left_times}" -> {
|
||||
Fertilizer fertilizer = pot.getFertilizer();
|
||||
if (fertilizer == null) return "";
|
||||
return String.valueOf(fertilizer.getLeftTimes());
|
||||
}
|
||||
case "{max_times}" -> {
|
||||
Fertilizer fertilizer = pot.getFertilizer();
|
||||
if (fertilizer == null) return "";
|
||||
return String.valueOf(fertilizer.getConfig().getTimes());
|
||||
}
|
||||
case "{current}" -> {
|
||||
return String.valueOf(pot.getWater());
|
||||
}
|
||||
case "{storage}" -> {
|
||||
return String.valueOf(pot.getConfig().getMaxStorage());
|
||||
}
|
||||
case "{water_bar}" -> {
|
||||
return getWaterBar(pot.getWater(), pot.getConfig().getMaxStorage());
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -19,9 +19,12 @@ package net.momirealms.customcrops.api.object.pot;
|
||||
|
||||
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.fertilizer.FertilizerType;
|
||||
import net.momirealms.customcrops.api.object.fill.PassiveFillMethod;
|
||||
import net.momirealms.customcrops.api.object.hologram.FertilizerHologram;
|
||||
import net.momirealms.customcrops.api.object.hologram.HologramManager;
|
||||
import net.momirealms.customcrops.api.object.hologram.TextDisplayMeta;
|
||||
import net.momirealms.customcrops.api.object.hologram.WaterAmountHologram;
|
||||
import net.momirealms.customcrops.api.util.AdventureUtils;
|
||||
import net.momirealms.customcrops.api.util.ConfigUtils;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
@@ -81,26 +84,43 @@ public class PotManager extends Function {
|
||||
}
|
||||
blockToPotKey.put(base_wet, key);
|
||||
blockToPotKey.put(base_dry, key);
|
||||
boolean enableHolo = section.getBoolean("hologram.enable", false);
|
||||
PotConfig potConfig = new PotConfig(
|
||||
section.getInt("max-water-storage"),
|
||||
base_dry,
|
||||
base_wet,
|
||||
enableFertilized,
|
||||
methods,
|
||||
enableHolo,
|
||||
enableHolo ? new PotHologram(
|
||||
section.getString("hologram.fertilizer.text"),
|
||||
section.getBoolean("hologram.fertilizer.enable", false) ? new FertilizerHologram(
|
||||
section.getString("hologram.fertilizer.content", ""),
|
||||
section.getDouble("hologram.fertilizer.vertical-offset"),
|
||||
section.getString("hologram.water.text"),
|
||||
HologramManager.Mode.valueOf(section.getString("hologram.type", "ARMOR_STAND").toUpperCase()),
|
||||
section.getInt("hologram.duration"),
|
||||
new TextDisplayMeta(
|
||||
section.getBoolean("hologram.text-display-options.has-shadow", false),
|
||||
section.getBoolean("hologram.text-display-options.is-see-through", false),
|
||||
section.getBoolean("hologram.text-display-options.use-default-background-color", false),
|
||||
ConfigUtils.rgbToDecimal(section.getString("hologram.text-display-options.background-color", "0,0,0,128")),
|
||||
(byte) section.getInt("hologram.text-display-options.text-opacity")
|
||||
)
|
||||
) : null,
|
||||
section.getBoolean("hologram.water.enable", false) ? new WaterAmountHologram(
|
||||
section.getString("hologram.water.content", ""),
|
||||
section.getDouble("hologram.water.vertical-offset"),
|
||||
HologramManager.Mode.valueOf(section.getString("hologram.type", "ARMOR_STAND").toUpperCase()),
|
||||
section.getInt("hologram.duration"),
|
||||
section.getString("hologram.water.water-bar.left"),
|
||||
section.getString("hologram.water.water-bar.full"),
|
||||
section.getString("hologram.water.water-bar.empty"),
|
||||
section.getString("hologram.water.water-bar.right")
|
||||
) : null
|
||||
section.getString("hologram.water.water-bar.right"),
|
||||
new TextDisplayMeta(
|
||||
section.getBoolean("hologram.text-display-options.has-shadow", false),
|
||||
section.getBoolean("hologram.text-display-options.is-see-through", false),
|
||||
section.getBoolean("hologram.text-display-options.use-default-background-color", false),
|
||||
ConfigUtils.rgbToDecimal(section.getString("hologram.text-display-options.background-color", "0,0,0,128")),
|
||||
(byte) section.getInt("hologram.text-display-options.text-opacity")
|
||||
)
|
||||
) : null,
|
||||
section.getString("hologram.require-item")
|
||||
);
|
||||
if (enableFertilized) {
|
||||
ConfigurationSection fertilizedSec = section.getConfigurationSection("fertilized-pots");
|
||||
|
||||
@@ -20,6 +20,7 @@ package net.momirealms.customcrops.api.object.sprinkler;
|
||||
import net.kyori.adventure.sound.Sound;
|
||||
import net.momirealms.customcrops.api.object.ItemMode;
|
||||
import net.momirealms.customcrops.api.object.fill.PassiveFillMethod;
|
||||
import net.momirealms.customcrops.api.object.hologram.WaterAmountHologram;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -33,13 +34,11 @@ 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 WaterAmountHologram waterAmountHologram;
|
||||
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, boolean hasHologram, boolean hasAnimation, @Nullable SprinklerHologram sprinklerHologram, SprinklerAnimation sprinklerAnimation) {
|
||||
@NotNull PassiveFillMethod[] passiveFillMethods, @Nullable WaterAmountHologram waterAmountHologram, SprinklerAnimation sprinklerAnimation) {
|
||||
this.key = key;
|
||||
this.storage = storage;
|
||||
this.range = range;
|
||||
@@ -48,10 +47,8 @@ public class SprinklerConfig {
|
||||
this.threeD = threeD;
|
||||
this.twoD = twoD;
|
||||
this.passiveFillMethods = passiveFillMethods;
|
||||
this.hasAnimation = hasAnimation;
|
||||
this.hasHologram = hasHologram;
|
||||
this.sprinklerAnimation = sprinklerAnimation;
|
||||
this.sprinklerHologram = sprinklerHologram;
|
||||
this.waterAmountHologram = waterAmountHologram;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
@@ -91,17 +88,9 @@ public class SprinklerConfig {
|
||||
return passiveFillMethods;
|
||||
}
|
||||
|
||||
public boolean hasAnimation() {
|
||||
return hasAnimation;
|
||||
}
|
||||
|
||||
public boolean hasHologram() {
|
||||
return hasHologram;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public SprinklerHologram getSprinklerHologram() {
|
||||
return sprinklerHologram;
|
||||
public WaterAmountHologram getSprinklerHologram() {
|
||||
return waterAmountHologram;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,9 +21,11 @@ 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.object.hologram.HologramManager;
|
||||
import net.momirealms.customcrops.api.object.hologram.TextDisplayMeta;
|
||||
import net.momirealms.customcrops.api.object.hologram.WaterAmountHologram;
|
||||
import net.momirealms.customcrops.api.util.AdventureUtils;
|
||||
import net.momirealms.customcrops.api.util.ConfigUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -93,8 +95,6 @@ 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),
|
||||
@@ -104,9 +104,7 @@ public class SprinklerManager extends Function implements Listener {
|
||||
threeD,
|
||||
twoD,
|
||||
methods,
|
||||
hasHologram,
|
||||
hasAnimation,
|
||||
hasHologram ? new SprinklerHologram(
|
||||
sprinklerSec.getBoolean("hologram.enable") ? new WaterAmountHologram(
|
||||
sprinklerSec.getString("hologram.content",""),
|
||||
sprinklerSec.getDouble("hologram.vertical-offset"),
|
||||
HologramManager.Mode.valueOf(sprinklerSec.getString("hologram.type", "ARMOR_STAND").toUpperCase()),
|
||||
@@ -114,9 +112,16 @@ public class SprinklerManager extends Function implements Listener {
|
||||
sprinklerSec.getString("hologram.water-bar.left"),
|
||||
sprinklerSec.getString("hologram.water-bar.full"),
|
||||
sprinklerSec.getString("hologram.water-bar.empty"),
|
||||
sprinklerSec.getString("hologram.water-bar.right")
|
||||
sprinklerSec.getString("hologram.water-bar.right"),
|
||||
new TextDisplayMeta(
|
||||
sprinklerSec.getBoolean("hologram.text-display-options.has-shadow", false),
|
||||
sprinklerSec.getBoolean("hologram.text-display-options.is-see-through", false),
|
||||
sprinklerSec.getBoolean("hologram.text-display-options.use-default-background-color", false),
|
||||
ConfigUtils.rgbToDecimal(sprinklerSec.getString("hologram.text-display-options.background-color", "0,0,0,128")),
|
||||
(byte) sprinklerSec.getInt("hologram.text-display-options.text-opacity")
|
||||
)
|
||||
) : null,
|
||||
hasAnimation ? new SprinklerAnimation(
|
||||
sprinklerSec.getBoolean("animation.enable") ? new SprinklerAnimation(
|
||||
sprinklerSec.getInt("animation.duration"),
|
||||
sprinklerSec.getString("animation.item"),
|
||||
sprinklerSec.getDouble("animation.vertical-offset"),
|
||||
@@ -148,10 +153,6 @@ public class SprinklerManager extends Function implements Listener {
|
||||
return sprinklerConfigMap.get(key);
|
||||
}
|
||||
|
||||
public boolean containsSprinkler(String key) {
|
||||
return sprinklerConfigMap.containsKey(key);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onItemSpawn(ItemSpawnEvent event) {
|
||||
if (event.isCancelled()) return;
|
||||
|
||||
@@ -18,12 +18,14 @@
|
||||
package net.momirealms.customcrops.api.object.world;
|
||||
|
||||
import net.momirealms.customcrops.CustomCrops;
|
||||
import net.momirealms.customcrops.api.CustomCropsAPI;
|
||||
import net.momirealms.customcrops.api.object.basic.ConfigManager;
|
||||
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.util.ConfigUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -127,7 +129,7 @@ public class CCChunk implements Serializable {
|
||||
if (pot != null) {
|
||||
if (pot.addWater(amount)) {
|
||||
CustomCrops.getInstance().getScheduler().callSyncMethod(() -> {
|
||||
CustomCropsAPI.getInstance().changePotModel(simpleLocation, pot);
|
||||
changePotModel(simpleLocation, pot);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
@@ -136,7 +138,7 @@ public class CCChunk implements Serializable {
|
||||
Pot newPot = new Pot(pot_id, null, amount);
|
||||
potMap.put(simpleLocation, newPot);
|
||||
CustomCrops.getInstance().getScheduler().callSyncMethod(() -> {
|
||||
CustomCropsAPI.getInstance().changePotModel(simpleLocation, newPot);
|
||||
changePotModel(simpleLocation, newPot);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
@@ -147,7 +149,7 @@ public class CCChunk implements Serializable {
|
||||
if (pot != null) {
|
||||
pot.setFertilizer(fertilizer);
|
||||
CustomCrops.getInstance().getScheduler().callSyncMethod(() -> {
|
||||
CustomCropsAPI.getInstance().changePotModel(simpleLocation, pot);
|
||||
changePotModel(simpleLocation, pot);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
@@ -155,7 +157,7 @@ public class CCChunk implements Serializable {
|
||||
Pot newPot = new Pot(pot_id, fertilizer, 0);
|
||||
potMap.put(simpleLocation, newPot);
|
||||
CustomCrops.getInstance().getScheduler().callSyncMethod(() -> {
|
||||
CustomCropsAPI.getInstance().changePotModel(simpleLocation, newPot);
|
||||
changePotModel(simpleLocation, newPot);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
@@ -181,4 +183,16 @@ public class CCChunk implements Serializable {
|
||||
ccWorld.pushConsumeTask(simpleLocation, randomGenerator.nextInt(60));
|
||||
}
|
||||
}
|
||||
|
||||
public void changePotModel(SimpleLocation simpleLocation, Pot pot) {
|
||||
Location location = simpleLocation.getBukkitLocation();
|
||||
if (location == null) return;
|
||||
if (CustomCrops.getInstance().getPlatformInterface().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 CustomCrops.getInstance().getPlatformInterface().placeNoteBlock(location, replacer);
|
||||
} else {
|
||||
CustomCrops.getInstance().getWorldDataManager().removePotData(simpleLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,8 +18,6 @@
|
||||
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;
|
||||
@@ -50,10 +48,7 @@ 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.*;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -74,8 +69,9 @@ public class CCWorld extends Function {
|
||||
private final GenericObjectPool<CropCheckTask> cropTaskPool;
|
||||
private final GenericObjectPool<SprinklerCheckTask> sprinklerTaskPool;
|
||||
private final GenericObjectPool<ConsumeCheckTask> consumeTaskPool;
|
||||
private boolean hasWorkedToday;
|
||||
private boolean hasConsumedToday;
|
||||
private long lastWorkDay;
|
||||
private long lastConsumeDay;
|
||||
private ScheduledFuture<?> scheduledTimerTask;
|
||||
|
||||
public CCWorld(World world) {
|
||||
this.world = new WeakReference<>(world);
|
||||
@@ -94,12 +90,11 @@ public class CCWorld extends Function {
|
||||
this.consumeTaskPool = new GenericObjectPool<>(new ConsumeTaskFactory(), new GenericObjectPoolConfig<>());
|
||||
this.consumeTaskPool.setMaxTotal(10);
|
||||
this.consumeTaskPool.setMinIdle(1);
|
||||
this.hasConsumedToday = false;
|
||||
this.hasWorkedToday = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
public void load() {
|
||||
public void init() {
|
||||
File chunks_folder = new File(CustomCrops.getInstance().getDataFolder().getParentFile().getParentFile(), ConfigManager.worldFolderPath + worldName + File.separator + "customcrops" + File.separator + "chunks");
|
||||
if (!chunks_folder.exists()) chunks_folder.mkdirs();
|
||||
File[] data_files = chunks_folder.listFiles();
|
||||
@@ -117,21 +112,24 @@ public class CCWorld extends Function {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
YamlConfiguration dataFile = ConfigUtils.readData(new File(CustomCrops.getInstance().getDataFolder().getParentFile().getParentFile(), ConfigManager.worldFolderPath + worldName + File.separator + "customcrops" + File.separator + "data.yml"));
|
||||
if (ConfigManager.enableSeason && !ConfigManager.rsHook) {
|
||||
YamlConfiguration seasonDataFile = ConfigUtils.readData(new File(CustomCrops.getInstance().getDataFolder().getParentFile().getParentFile(), ConfigManager.worldFolderPath + worldName + File.separator + "customcrops" + File.separator + "data.yml"));
|
||||
SeasonData seasonData;
|
||||
if (seasonDataFile.contains("season") && seasonDataFile.contains("date")) {
|
||||
seasonData = new SeasonData(worldName, CCSeason.valueOf(seasonDataFile.getString("season")), seasonDataFile.getInt("date"));
|
||||
if (dataFile.contains("season") && dataFile.contains("date")) {
|
||||
seasonData = new SeasonData(worldName, CCSeason.valueOf(dataFile.getString("season")), dataFile.getInt("date"));
|
||||
} else {
|
||||
seasonData = new SeasonData(worldName);
|
||||
}
|
||||
CustomCrops.getInstance().getSeasonManager().loadSeasonData(seasonData);
|
||||
}
|
||||
this.lastConsumeDay = dataFile.getLong("last-consume-day", 0);
|
||||
this.lastWorkDay = dataFile.getLong("last-work-day", 0);
|
||||
this.arrangeTask();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
public void unload() {
|
||||
public void disable() {
|
||||
closePool();
|
||||
File chunks_folder = new File(CustomCrops.getInstance().getDataFolder().getParentFile().getParentFile(), ConfigManager.worldFolderPath + worldName + File.separator + "customcrops" + File.separator + "chunks");
|
||||
if (!chunks_folder.exists()) chunks_folder.mkdirs();
|
||||
@@ -150,22 +148,41 @@ public class CCWorld extends Function {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
YamlConfiguration dataFile = new YamlConfiguration();
|
||||
if (ConfigManager.enableSeason && !ConfigManager.rsHook) {
|
||||
YamlConfiguration seasonDataFile = new YamlConfiguration();
|
||||
SeasonData seasonData = CustomCrops.getInstance().getSeasonManager().unloadSeasonData(worldName);
|
||||
if (seasonData == null) {
|
||||
seasonDataFile.set("season", "SPRING");
|
||||
seasonDataFile.set("date", 1);
|
||||
dataFile.set("season", "SPRING");
|
||||
dataFile.set("date", 1);
|
||||
} else {
|
||||
seasonDataFile.set("season", seasonData.getSeason().name());
|
||||
seasonDataFile.set("date", seasonData.getDate());
|
||||
}
|
||||
try {
|
||||
seasonDataFile.save(new File(CustomCrops.getInstance().getDataFolder().getParentFile().getParentFile(), ConfigManager.worldFolderPath + worldName + File.separator + "customcrops" + File.separator + "data.yml"));
|
||||
} catch (IOException e) {
|
||||
AdventureUtils.consoleMessage("<red>[CustomCrops] Failed to save season data for world: " + worldName);
|
||||
dataFile.set("season", seasonData.getSeason().name());
|
||||
dataFile.set("date", seasonData.getDate());
|
||||
}
|
||||
}
|
||||
dataFile.set("last-consume-day", lastConsumeDay);
|
||||
dataFile.set("last-work-day", lastWorkDay);
|
||||
try {
|
||||
dataFile.save(new File(CustomCrops.getInstance().getDataFolder().getParentFile().getParentFile(), ConfigManager.worldFolderPath + worldName + File.separator + "customcrops" + File.separator + "data.yml"));
|
||||
} catch (IOException e) {
|
||||
AdventureUtils.consoleMessage("<red>[CustomCrops] Failed to save season data for world: " + worldName);
|
||||
}
|
||||
}
|
||||
|
||||
public void load() {
|
||||
if (this.scheduledTimerTask == null) {
|
||||
this.scheduledTimerTask = this.schedule.scheduleAtFixedRate(() -> {
|
||||
for (CCChunk chunk : chunkMap.values()) {
|
||||
chunk.scheduleGrowTask(this);
|
||||
}
|
||||
}, ThreadLocalRandom.current().nextInt(20), ConfigManager.pointGainInterval, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
public void unload() {
|
||||
if (this.scheduledTimerTask != null) {
|
||||
this.scheduledTimerTask.cancel(false);
|
||||
this.scheduledTimerTask = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -176,45 +193,29 @@ public class CCWorld extends Function {
|
||||
this.schedule.scheduleAtFixedRate(() -> {
|
||||
World current = world.get();
|
||||
if (current != null) {
|
||||
long fullTime = current.getFullTime();
|
||||
long day = fullTime / 24000;
|
||||
long time = current.getTime();
|
||||
if (time < 100 && !hasConsumedToday) {
|
||||
hasConsumedToday = true;
|
||||
if (time < 100 && day != lastConsumeDay) {
|
||||
lastConsumeDay = day;
|
||||
if (ConfigManager.enableSeason && !ConfigManager.rsHook && ConfigManager.autoSeasonChange) {
|
||||
CustomCrops.getInstance().getSeasonManager().addDate(worldName);
|
||||
}
|
||||
if (ConfigManager.enableScheduleSystem) {
|
||||
schedule.schedule(() -> {
|
||||
for (CCChunk chunk : chunkMap.values()) {
|
||||
chunk.scheduleConsumeTask(this);
|
||||
}
|
||||
}, 0, TimeUnit.SECONDS);
|
||||
scheduleConsumeTask();
|
||||
}
|
||||
}
|
||||
else if (time > 1950 && time < 2050 && !hasWorkedToday) {
|
||||
hasWorkedToday = true;
|
||||
else if (time > 1950 && time < 2050 && lastWorkDay != day) {
|
||||
lastWorkDay = day;
|
||||
if (ConfigManager.enableScheduleSystem) {
|
||||
schedule.schedule(() -> {
|
||||
for (CCChunk chunk : chunkMap.values()) {
|
||||
chunk.scheduleSprinklerTask(this);
|
||||
}
|
||||
}, 0, TimeUnit.SECONDS);
|
||||
scheduleSprinklerWork();
|
||||
}
|
||||
}
|
||||
else if (time > 23900) {
|
||||
hasConsumedToday = false;
|
||||
hasWorkedToday = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.schedule.shutdown();
|
||||
}
|
||||
}, 2, 2, TimeUnit.SECONDS);
|
||||
|
||||
this.schedule.scheduleAtFixedRate(() -> {
|
||||
for (CCChunk chunk : chunkMap.values()) {
|
||||
chunk.scheduleGrowTask(this);
|
||||
}
|
||||
}, 1, ConfigManager.pointGainInterval, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
private void closePool() {
|
||||
@@ -327,12 +328,19 @@ 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();
|
||||
Location location = simpleLocation.getBukkitLocation();
|
||||
if (location == null) return;
|
||||
CustomCrops.getInstance().getScheduler().callSyncMethod(() -> {
|
||||
CustomCropsAPI.getInstance().changePotModel(temp, potConfig, fertilizer, wet);
|
||||
if (CustomCrops.getInstance().getPlatformInterface().removeAnyBlock(location)) {
|
||||
String replacer = wet ? potConfig.getWetPot(fertilizer) : potConfig.getDryPot(fertilizer);
|
||||
if (ConfigUtils.isVanillaItem(replacer)) location.getBlock().setType(Material.valueOf(replacer));
|
||||
else CustomCrops.getInstance().getPlatformInterface().placeNoteBlock(location, replacer);
|
||||
} else {
|
||||
CustomCrops.getInstance().getWorldDataManager().removePotData(SimpleLocation.getByBukkitLocation(location));
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
@@ -366,18 +374,18 @@ public class CCWorld extends Function {
|
||||
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());
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sprinkler.setWater(--water);
|
||||
if (water == 0) {
|
||||
removeSprinklerData(simpleLocation);
|
||||
@@ -512,8 +520,8 @@ public class CCWorld extends Function {
|
||||
});
|
||||
loadEntities.whenComplete((result, throwable) ->
|
||||
CustomCrops.getInstance().getScheduler().callSyncMethod(() -> {
|
||||
if (CustomCropsAPI.getInstance().removeCustomItem(location, itemMode)) {
|
||||
CustomCropsAPI.getInstance().placeCustomItem(location, finalNextModel, itemMode);
|
||||
if (CustomCrops.getInstance().getPlatformInterface().removeCustomItem(location, itemMode)) {
|
||||
CustomCrops.getInstance().getPlatformInterface().placeCustomItem(location, finalNextModel, itemMode);
|
||||
} else {
|
||||
removeCropData(simpleLocation);
|
||||
}
|
||||
@@ -523,8 +531,8 @@ public class CCWorld extends Function {
|
||||
else {
|
||||
asyncGetChunk.whenComplete((result, throwable) ->
|
||||
CustomCrops.getInstance().getScheduler().callSyncMethod(() -> {
|
||||
if (CustomCropsAPI.getInstance().removeCustomItem(location, itemMode)) {
|
||||
CustomCropsAPI.getInstance().placeCustomItem(location, finalNextModel, itemMode);
|
||||
if (CustomCrops.getInstance().getPlatformInterface().removeCustomItem(location, itemMode)) {
|
||||
CustomCrops.getInstance().getPlatformInterface().placeCustomItem(location, finalNextModel, itemMode);
|
||||
} else {
|
||||
removeCropData(simpleLocation);
|
||||
}
|
||||
@@ -739,4 +747,20 @@ public class CCWorld extends Function {
|
||||
chunkMap.put(simpleLocation.getChunkCoordinate(), newChunk);
|
||||
return newChunk;
|
||||
}
|
||||
|
||||
public void scheduleSprinklerWork() {
|
||||
schedule.execute(() -> {
|
||||
for (CCChunk chunk : chunkMap.values()) {
|
||||
chunk.scheduleSprinklerTask(this);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void scheduleConsumeTask() {
|
||||
schedule.schedule(() -> {
|
||||
for (CCChunk chunk : chunkMap.values()) {
|
||||
chunk.scheduleConsumeTask(this);
|
||||
}
|
||||
}, 0, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
@@ -47,18 +47,24 @@ public class WorldDataManager extends Function {
|
||||
@Override
|
||||
public void load() {
|
||||
Bukkit.getPluginManager().registerEvents(worldListener, plugin);
|
||||
for (CCWorld ccWorld : worldMap.values()) {
|
||||
ccWorld.load();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unload() {
|
||||
HandlerList.unregisterAll(worldListener);
|
||||
for (CCWorld ccWorld : worldMap.values()) {
|
||||
ccWorld.unload();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable() {
|
||||
this.unload();
|
||||
for (CCWorld ccWorld : worldMap.values()) {
|
||||
ccWorld.unload();
|
||||
ccWorld.disable();
|
||||
}
|
||||
this.worldMap.clear();
|
||||
}
|
||||
@@ -66,6 +72,7 @@ public class WorldDataManager extends Function {
|
||||
public void loadWorld(World world) {
|
||||
if (!isWorldAllowed(world)) return;
|
||||
CCWorld ccWorld = new CCWorld(world);
|
||||
ccWorld.init();
|
||||
ccWorld.load();
|
||||
worldMap.put(world.getName(), ccWorld);
|
||||
}
|
||||
@@ -73,7 +80,7 @@ public class WorldDataManager extends Function {
|
||||
public void unloadWorld(World world) {
|
||||
CCWorld ccWorld = worldMap.remove(world.getName());
|
||||
if (ccWorld != null) {
|
||||
ccWorld.unload();
|
||||
ccWorld.disable();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,4 +241,9 @@ public class WorldDataManager extends Function {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CCWorld getWorld(String world) {
|
||||
return worldMap.get(world);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -389,11 +389,9 @@ public class ConfigUtils {
|
||||
ConfigurationSection methodSec = section.getConfigurationSection(key);
|
||||
if (methodSec == null) continue;
|
||||
String id = methodSec.getString("target", "WATER");
|
||||
PositiveFillMethod.InteractType type = PositiveFillMethod.InteractType.valueOf(methodSec.getString("type", "block").toUpperCase());
|
||||
@Subst("namespace:key") String soundKey = methodSec.getString("sound", "minecraft:item.bucket.fill");
|
||||
Sound sound = Sound.sound(Key.key(soundKey), Sound.Source.PLAYER, 1, 1);
|
||||
PositiveFillMethod method = new PositiveFillMethod(
|
||||
type,
|
||||
id,
|
||||
methodSec.getInt("amount"),
|
||||
methodSec.contains("particle") ? Particle.valueOf(methodSec.getString("particle", "WATER_SPLASH").toUpperCase()) : null,
|
||||
@@ -420,4 +418,13 @@ public class ConfigUtils {
|
||||
}
|
||||
return interactWithItems.toArray(new InteractWithItem[0]);
|
||||
}
|
||||
|
||||
public static int rgbToDecimal(String rgba) {
|
||||
String[] split = rgba.split(",");
|
||||
int r = Integer.parseInt(split[0]);
|
||||
int g = Integer.parseInt(split[1]);
|
||||
int b = Integer.parseInt(split[2]);
|
||||
int a = Integer.parseInt(split[3]);
|
||||
return (a << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@ 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 net.momirealms.customcrops.api.object.hologram.TextDisplayMeta;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -44,9 +45,7 @@ public class FakeEntityUtils {
|
||||
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));
|
||||
}, 1000L * duration);
|
||||
CustomCrops.getInstance().getScheduler().runTaskAsyncLater(() -> CustomCrops.getProtocolManager().sendServerPacket(player, getDestroyPacket(id)), 1000L * duration);
|
||||
}
|
||||
|
||||
public static WrappedDataWatcher createInvisibleDataWatcher() {
|
||||
@@ -110,15 +109,13 @@ public class FakeEntityUtils {
|
||||
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);
|
||||
WrappedDataWatcher.Serializer serializer2 = WrappedDataWatcher.Registry.get(Byte.class);
|
||||
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(2, WrappedDataWatcher.Registry.getChatComponentSerializer(true)), Optional.of(WrappedChatComponent.fromJson(GsonComponentSerializer.gson().serialize(component)).getHandle()));
|
||||
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(3, serializer1), true);
|
||||
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(5, serializer1), true);
|
||||
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(3, WrappedDataWatcher.Registry.get(Boolean.class)), true);
|
||||
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(5, WrappedDataWatcher.Registry.get(Boolean.class)), true);
|
||||
byte mask1 = 0x20;
|
||||
byte mask2 = 0x01;
|
||||
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, serializer2), mask1);
|
||||
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(15, serializer2), mask2);
|
||||
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, WrappedDataWatcher.Registry.get(Byte.class)), mask1);
|
||||
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(15, WrappedDataWatcher.Registry.get(Byte.class)), mask2);
|
||||
metaPacket.getModifier().write(0, id);
|
||||
if (CustomCrops.getInstance().getVersionHelper().isVersionNewerThan1_19_R2()) {
|
||||
setWrappedDataValue(metaPacket, wrappedDataWatcher);
|
||||
@@ -132,16 +129,24 @@ public class FakeEntityUtils {
|
||||
PacketContainer metaPacket = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
metaPacket.getModifier().write(0, id);
|
||||
WrappedDataWatcher wrappedDataWatcher = new WrappedDataWatcher();
|
||||
wrappedDataWatcher.setObject(22, itemStack);
|
||||
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(22, WrappedDataWatcher.Registry.getItemStackSerializer(false)), itemStack);
|
||||
setWrappedDataValue(metaPacket, wrappedDataWatcher);
|
||||
return metaPacket;
|
||||
}
|
||||
|
||||
public static PacketContainer getTextDisplayMetaPacket(int id, Component component) {
|
||||
public static PacketContainer getTextDisplayMetaPacket(int id, Component component, TextDisplayMeta textDisplayMeta) {
|
||||
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()));
|
||||
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(22, WrappedDataWatcher.Registry.getChatComponentSerializer(false)), WrappedChatComponent.fromJson(GsonComponentSerializer.gson().serialize(component)));
|
||||
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(24, WrappedDataWatcher.Registry.get(Integer.class)), textDisplayMeta.getBackgroundColor());
|
||||
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(14, WrappedDataWatcher.Registry.get(Byte.class)), (byte) 3);
|
||||
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(25, WrappedDataWatcher.Registry.get(Byte.class)), textDisplayMeta.getOpacity());
|
||||
int mask = 0;
|
||||
if (textDisplayMeta.isHasShadow()) mask += 1;
|
||||
if (textDisplayMeta.isSeeThrough()) mask += 2;
|
||||
if (textDisplayMeta.isUseDefaultBackground()) mask += 4;
|
||||
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(26, WrappedDataWatcher.Registry.get(Byte.class)), (byte) mask);
|
||||
setWrappedDataValue(metaPacket, wrappedDataWatcher);
|
||||
return metaPacket;
|
||||
}
|
||||
|
||||
@@ -27,5 +27,7 @@ public class CustomCropsCommand extends AbstractMainCommand {
|
||||
regSubCommand(HelpCommand.INSTANCE);
|
||||
regSubCommand(AboutCommand.INSTANCE);
|
||||
regSubCommand(SetDateCommand.INSTANCE);
|
||||
regSubCommand(ForceCommand.INSTANCE);
|
||||
regSubCommand(MigrateCommand.INSTANCE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.command.subcmd;
|
||||
|
||||
import net.momirealms.customcrops.command.AbstractSubCommand;
|
||||
import net.momirealms.customcrops.command.subcmd.force.ConsumeTaskCommand;
|
||||
import net.momirealms.customcrops.command.subcmd.force.SprinklerWorkCommand;
|
||||
|
||||
public class ForceCommand extends AbstractSubCommand {
|
||||
|
||||
public static final ForceCommand INSTANCE = new ForceCommand();
|
||||
|
||||
public ForceCommand() {
|
||||
super("force");
|
||||
regSubCommand(SprinklerWorkCommand.INSTANCE);
|
||||
regSubCommand(ConsumeTaskCommand.INSTANCE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.command.subcmd;
|
||||
|
||||
import com.google.gson.*;
|
||||
import net.momirealms.customcrops.CustomCrops;
|
||||
import net.momirealms.customcrops.api.object.basic.ConfigManager;
|
||||
import net.momirealms.customcrops.api.object.crop.GrowingCrop;
|
||||
import net.momirealms.customcrops.api.object.fertilizer.Fertilizer;
|
||||
import net.momirealms.customcrops.api.object.fertilizer.FertilizerConfig;
|
||||
import net.momirealms.customcrops.api.object.migrate.MigrateWorld;
|
||||
import net.momirealms.customcrops.api.object.season.CCSeason;
|
||||
import net.momirealms.customcrops.api.object.season.SeasonData;
|
||||
import net.momirealms.customcrops.api.object.world.SimpleLocation;
|
||||
import net.momirealms.customcrops.api.util.AdventureUtils;
|
||||
import net.momirealms.customcrops.command.AbstractSubCommand;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class MigrateCommand extends AbstractSubCommand {
|
||||
|
||||
public static final MigrateCommand INSTANCE = new MigrateCommand();
|
||||
|
||||
public MigrateCommand() {
|
||||
super("migrate");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, List<String> args) {
|
||||
if (sender instanceof Player player) {
|
||||
AdventureUtils.playerMessage(player, "Migration started. See the console for more information.");
|
||||
}
|
||||
AdventureUtils.consoleMessage("[CustomCrops] Migration has started.");
|
||||
Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.getInstance(), new MigrationTask());
|
||||
return true;
|
||||
}
|
||||
|
||||
public static class MigrationTask implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
File outer_folder = new File(CustomCrops.getInstance().getDataFolder().getAbsoluteFile().getParentFile().getParentFile() + ConfigManager.worldFolderPath);
|
||||
if (!outer_folder.isDirectory()) {
|
||||
AdventureUtils.consoleMessage("<red>[CustomCrops] World folder is not detected");
|
||||
return;
|
||||
}
|
||||
|
||||
File[] files = outer_folder.listFiles();
|
||||
if (files == null) return;
|
||||
|
||||
List<File> world_folders = Arrays.stream(files).filter(File::isDirectory).toList();
|
||||
for (File world_folder : world_folders) {
|
||||
File ccDataFolder = new File(world_folder, "customcrops_data");
|
||||
if (!ccDataFolder.isDirectory()) continue;
|
||||
String worldName = world_folder.getName();
|
||||
AdventureUtils.consoleMessage("<green>[CustomCrops] Migrating world: " + worldName);
|
||||
MigrateWorld migrateWorld = new MigrateWorld(worldName);
|
||||
migrateWorld.init();
|
||||
|
||||
try {
|
||||
JsonElement json = JsonParser.parseReader(new FileReader(new File(ccDataFolder, "season.json")));
|
||||
if (json.isJsonObject()) {
|
||||
JsonObject jsonObject = json.getAsJsonObject();
|
||||
if (jsonObject.has("season")) {
|
||||
JsonPrimitive jsonPrimitive = jsonObject.getAsJsonPrimitive("season");
|
||||
String season = jsonPrimitive.getAsString();
|
||||
CustomCrops.getInstance().getSeasonManager().loadSeasonData(new SeasonData(worldName, CCSeason.valueOf(season), 1));
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException ignored) {
|
||||
}
|
||||
|
||||
AdventureUtils.consoleMessage("<white>[CustomCrops] Migrated " + worldName + "'s season");
|
||||
|
||||
try {
|
||||
JsonElement json= JsonParser.parseReader(new FileReader(new File(ccDataFolder, "pot.json")));
|
||||
if (json.isJsonObject()) {
|
||||
JsonObject jsonObject = json.getAsJsonObject();
|
||||
if (jsonObject.has("pot")) {
|
||||
JsonArray jsonArray = jsonObject.getAsJsonArray("pot");
|
||||
for (JsonElement jsonElement : jsonArray) {
|
||||
String loc = jsonElement.getAsString();
|
||||
String[] locs = StringUtils.split(loc, ",");
|
||||
SimpleLocation simpleLocation = new SimpleLocation(worldName, Integer.parseInt(locs[0]), Integer.parseInt(locs[1]), Integer.parseInt(locs[2]));
|
||||
migrateWorld.addWaterToPot(simpleLocation, 1, "default");
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException ignored) {
|
||||
}
|
||||
|
||||
AdventureUtils.consoleMessage("<white>[CustomCrops] Migrated " + worldName + "'s pots");
|
||||
|
||||
YamlConfiguration data = YamlConfiguration.loadConfiguration(new File(ccDataFolder, "fertilizers.yml"));
|
||||
for (String key : data.getKeys(false)) {
|
||||
String[] loc = StringUtils.split(key, ",");
|
||||
SimpleLocation location = new SimpleLocation(worldName, Integer.parseInt(loc[0]), Integer.parseInt(loc[1]), Integer.parseInt(loc[2]));
|
||||
String fertilizer = data.getString(key + ".type");
|
||||
int times = data.getInt(key + ".times");
|
||||
FertilizerConfig fertilizerConfig = CustomCrops.getInstance().getFertilizerManager().getConfigByKey(fertilizer);
|
||||
if (fertilizerConfig != null) {
|
||||
Fertilizer fertilizer1 = new Fertilizer(fertilizerConfig);
|
||||
fertilizer1.setTimes(times);
|
||||
migrateWorld.addFertilizerToPot(location, fertilizer1, "default");
|
||||
}
|
||||
}
|
||||
|
||||
AdventureUtils.consoleMessage("<white>[CustomCrops] Migrated " + worldName + "'s fertilizers");
|
||||
|
||||
try {
|
||||
JsonElement json= JsonParser.parseReader(new FileReader(new File(ccDataFolder, "scarecrow.json")));
|
||||
if (json.isJsonObject()) {
|
||||
JsonObject jsonObject = json.getAsJsonObject();
|
||||
for (Map.Entry<String, JsonElement> en : jsonObject.entrySet()) {
|
||||
JsonArray jsonArray = en.getValue().getAsJsonArray();
|
||||
int size = jsonArray.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
String[] loc = StringUtils.split(jsonArray.get(i).getAsString(), ",");
|
||||
migrateWorld.addScarecrow(new SimpleLocation(worldName, Integer.parseInt(loc[0]), Integer.parseInt(loc[1]), Integer.parseInt(loc[2])));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (FileNotFoundException ignore) {
|
||||
}
|
||||
|
||||
AdventureUtils.consoleMessage("<white>[CustomCrops] Migrated " + worldName + "'s scarecrows");
|
||||
|
||||
YamlConfiguration cropData = YamlConfiguration.loadConfiguration(new File(ccDataFolder, "crops.yml"));
|
||||
for (Map.Entry<String, Object> entry : cropData.getValues(false).entrySet()) {
|
||||
String crop = (String) entry.getValue();
|
||||
GrowingCrop growingCrop;
|
||||
if (crop.contains("_")) {
|
||||
String stageStr = crop.substring(crop.indexOf("_stage_") + 7);
|
||||
int stage = Integer.parseInt(stageStr);
|
||||
growingCrop = new GrowingCrop(crop.substring(0, crop.indexOf("_stage_")), stage);
|
||||
String[] loc = StringUtils.split(entry.getKey(), ",");
|
||||
SimpleLocation simpleLocation = new SimpleLocation(worldName, Integer.parseInt(loc[0]), Integer.parseInt(loc[1]), Integer.parseInt(loc[2]));
|
||||
migrateWorld.addCropData(simpleLocation, growingCrop);
|
||||
}
|
||||
}
|
||||
|
||||
AdventureUtils.consoleMessage("<white>[CustomCrops] Migrated " + worldName + "'s crops");
|
||||
migrateWorld.disable();
|
||||
}
|
||||
|
||||
AdventureUtils.consoleMessage("<green>[CustomCrops] Migration finished!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.command.subcmd.force;
|
||||
|
||||
import net.momirealms.customcrops.CustomCrops;
|
||||
import net.momirealms.customcrops.api.object.basic.MessageManager;
|
||||
import net.momirealms.customcrops.api.object.world.CCWorld;
|
||||
import net.momirealms.customcrops.api.util.AdventureUtils;
|
||||
import net.momirealms.customcrops.command.AbstractSubCommand;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.generator.WorldInfo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ConsumeTaskCommand extends AbstractSubCommand {
|
||||
|
||||
public static final ConsumeTaskCommand INSTANCE = new ConsumeTaskCommand();
|
||||
|
||||
public ConsumeTaskCommand() {
|
||||
super("consume");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, List<String> args) {
|
||||
if (lackArgs(sender, 1, args.size())) return true;
|
||||
World world = Bukkit.getWorld(args.get(0));
|
||||
if (world == null) {
|
||||
AdventureUtils.sendMessage(sender, MessageManager.prefix + MessageManager.worldNotExist.replace("{world}", args.get(0)));
|
||||
return true;
|
||||
}
|
||||
CustomCrops.getInstance().getScheduler().runTaskAsync(() -> {
|
||||
CCWorld ccworld = CustomCrops.getInstance().getWorldDataManager().getWorld(args.get(0));
|
||||
if (ccworld != null) {
|
||||
ccworld.scheduleConsumeTask();
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender sender, List<String> args) {
|
||||
if (args.size() == 1) {
|
||||
return super.filterStartingWith(Bukkit.getWorlds().stream().filter(world -> CustomCrops.getInstance().getWorldDataManager().isWorldAllowed(world)).map(WorldInfo::getName).collect(Collectors.toList()), args.get(0));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.command.subcmd.force;
|
||||
|
||||
import net.momirealms.customcrops.CustomCrops;
|
||||
import net.momirealms.customcrops.api.object.basic.MessageManager;
|
||||
import net.momirealms.customcrops.api.object.world.CCWorld;
|
||||
import net.momirealms.customcrops.api.util.AdventureUtils;
|
||||
import net.momirealms.customcrops.command.AbstractSubCommand;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.generator.WorldInfo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SprinklerWorkCommand extends AbstractSubCommand {
|
||||
|
||||
public static final SprinklerWorkCommand INSTANCE = new SprinklerWorkCommand();
|
||||
|
||||
public SprinklerWorkCommand() {
|
||||
super("sprinklerwork");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, List<String> args) {
|
||||
if (lackArgs(sender, 1, args.size())) return true;
|
||||
World world = Bukkit.getWorld(args.get(0));
|
||||
if (world == null) {
|
||||
AdventureUtils.sendMessage(sender, MessageManager.prefix + MessageManager.worldNotExist.replace("{world}", args.get(0)));
|
||||
return true;
|
||||
}
|
||||
CustomCrops.getInstance().getScheduler().runTaskAsync(() -> {
|
||||
CCWorld ccworld = CustomCrops.getInstance().getWorldDataManager().getWorld(args.get(0));
|
||||
if (ccworld != null) {
|
||||
ccworld.scheduleSprinklerWork();
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender sender, List<String> args) {
|
||||
if (args.size() == 1) {
|
||||
return super.filterStartingWith(Bukkit.getWorlds().stream().filter(world -> CustomCrops.getInstance().getWorldDataManager().isWorldAllowed(world)).map(WorldInfo::getName).collect(Collectors.toList()), args.get(0));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,10 @@ import net.momirealms.customcrops.integration.item.MMOItemsItemImpl;
|
||||
import net.momirealms.customcrops.integration.job.EcoJobsImpl;
|
||||
import net.momirealms.customcrops.integration.job.JobsRebornImpl;
|
||||
import net.momirealms.customcrops.integration.papi.PlaceholderManager;
|
||||
import net.momirealms.customcrops.integration.quest.BattlePassCCQuest;
|
||||
import net.momirealms.customcrops.integration.quest.BetonQuestCCQuest;
|
||||
import net.momirealms.customcrops.integration.quest.ClueScrollCCQuest;
|
||||
import net.momirealms.customcrops.integration.quest.LegacyBetonQuestCCQuest;
|
||||
import net.momirealms.customcrops.integration.season.CustomCropsSeasonImpl;
|
||||
import net.momirealms.customcrops.integration.season.RealisticSeasonsImpl;
|
||||
import net.momirealms.customcrops.integration.skill.AureliumsImpl;
|
||||
@@ -56,6 +60,7 @@ public class IntegrationManager extends Function {
|
||||
this.plugin = plugin;
|
||||
this.pluginManager = Bukkit.getPluginManager();
|
||||
this.placeholderManager = new PlaceholderManager(plugin);
|
||||
this.registerQuests();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -141,6 +146,21 @@ public class IntegrationManager extends Function {
|
||||
return new ItemStack(Material.AIR);
|
||||
}
|
||||
|
||||
private void registerQuests() {
|
||||
PluginManager pluginManager = Bukkit.getPluginManager();
|
||||
if (pluginManager.isPluginEnabled("ClueScrolls")) {
|
||||
ClueScrollCCQuest quest = new ClueScrollCCQuest(plugin);
|
||||
Bukkit.getPluginManager().registerEvents(quest, plugin);
|
||||
}
|
||||
if (pluginManager.isPluginEnabled("BetonQuest")) {
|
||||
if (Bukkit.getPluginManager().getPlugin("BetonQuest").getDescription().getVersion().startsWith("2")) BetonQuestCCQuest.register();
|
||||
else LegacyBetonQuestCCQuest.register();
|
||||
}
|
||||
if (pluginManager.isPluginEnabled("BattlePass")) {
|
||||
BattlePassCCQuest.register();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public SkillInterface getSkillInterface() {
|
||||
return skillInterface;
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.integration.quest;
|
||||
|
||||
import io.github.battlepass.BattlePlugin;
|
||||
import io.github.battlepass.quests.quests.external.executor.ExternalQuestExecutor;
|
||||
import io.github.battlepass.registry.quest.QuestRegistry;
|
||||
import net.momirealms.customcrops.api.event.CropBreakEvent;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
public class BattlePassCCQuest extends ExternalQuestExecutor implements Listener {
|
||||
|
||||
public static void register() {
|
||||
QuestRegistry questRegistry = BattlePlugin.getApi().getQuestRegistry();
|
||||
questRegistry.hook("customcrops", BattlePassCCQuest::new);
|
||||
}
|
||||
|
||||
public BattlePassCCQuest(BattlePlugin battlePlugin) {
|
||||
super(battlePlugin, "customcrops");
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onHarvest(CropBreakEvent event) {
|
||||
if (event.isCancelled()) return;
|
||||
Player player = event.getPlayer();
|
||||
this.execute("harvest", player, (var1x) -> var1x.root(event.getCropItemID()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.integration.quest;
|
||||
|
||||
import net.momirealms.customcrops.api.event.CropBreakEvent;
|
||||
import net.momirealms.customcrops.api.util.AdventureUtils;
|
||||
import org.betonquest.betonquest.BetonQuest;
|
||||
import org.betonquest.betonquest.Instruction;
|
||||
import org.betonquest.betonquest.VariableNumber;
|
||||
import org.betonquest.betonquest.api.CountingObjective;
|
||||
import org.betonquest.betonquest.api.profiles.OnlineProfile;
|
||||
import org.betonquest.betonquest.api.profiles.Profile;
|
||||
import org.betonquest.betonquest.exceptions.InstructionParseException;
|
||||
import org.betonquest.betonquest.utils.PlayerConverter;
|
||||
import org.betonquest.betonquest.utils.location.CompoundLocation;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class BetonQuestCCQuest extends CountingObjective implements Listener {
|
||||
|
||||
private final CompoundLocation playerLocation;
|
||||
private final VariableNumber rangeVar;
|
||||
private final HashSet<String> crop_ids;
|
||||
|
||||
public BetonQuestCCQuest(Instruction instruction) throws InstructionParseException {
|
||||
super(instruction, "crop_to_harvest");
|
||||
crop_ids = new HashSet<>();
|
||||
Collections.addAll(crop_ids, instruction.getArray());
|
||||
targetAmount = instruction.getInt();
|
||||
|
||||
final String pack = instruction.getPackage().getQuestPath();
|
||||
final String loc = instruction.getOptional("playerLocation");
|
||||
final String range = instruction.getOptional("range");
|
||||
if (loc != null && range != null) {
|
||||
playerLocation = new CompoundLocation(pack, loc);
|
||||
rangeVar = new VariableNumber(pack, range);
|
||||
} else {
|
||||
playerLocation = null;
|
||||
rangeVar = null;
|
||||
}
|
||||
|
||||
if (targetAmount <= 0) {
|
||||
throw new InstructionParseException("Crop amount cannot be less than 0");
|
||||
}
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
BetonQuest.getInstance().registerObjectives("customcrops", BetonQuestCCQuest.class);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onHarvest(CropBreakEvent event) {
|
||||
OnlineProfile onlineProfile = PlayerConverter.getID(event.getPlayer());
|
||||
if (!containsPlayer(onlineProfile)) {
|
||||
return;
|
||||
}
|
||||
if (isInvalidLocation(event, onlineProfile)) {
|
||||
return;
|
||||
}
|
||||
if (this.crop_ids.contains(event.getCropItemID()) && this.checkConditions(onlineProfile)) {
|
||||
getCountingData(onlineProfile).progress(1);
|
||||
completeIfDoneOrNotify(onlineProfile);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isInvalidLocation(CropBreakEvent event, final Profile profile) {
|
||||
if (playerLocation == null || rangeVar == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Location targetLocation;
|
||||
try {
|
||||
targetLocation = playerLocation.getLocation(profile);
|
||||
} catch (final org.betonquest.betonquest.exceptions.QuestRuntimeException e) {
|
||||
AdventureUtils.consoleMessage(e.getMessage());
|
||||
return true;
|
||||
}
|
||||
final int range = rangeVar.getInt(profile);
|
||||
final Location playerLoc = event.getPlayer().getLocation();
|
||||
return !playerLoc.getWorld().equals(targetLocation.getWorld()) || targetLocation.distanceSquared(playerLoc) > range * range;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
Bukkit.getPluginManager().registerEvents(this, BetonQuest.getInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
HandlerList.unregisterAll(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.integration.quest;
|
||||
|
||||
import com.electro2560.dev.cluescrolls.api.*;
|
||||
import net.momirealms.customcrops.api.event.CropBreakEvent;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class ClueScrollCCQuest implements Listener {
|
||||
|
||||
private final CustomClue commonClue;
|
||||
|
||||
public ClueScrollCCQuest(Plugin plugin) {
|
||||
commonClue = ClueScrollsAPI.getInstance().registerCustomClue(plugin, "harvest", new ClueConfigData("crop_id", DataType.STRING));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onHarvest(CropBreakEvent event) {
|
||||
if (event.isCancelled()) return;
|
||||
commonClue.handle(event.getPlayer(), 1, new ClueDataPair("crop_id", event.getCropItemID()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.integration.quest;
|
||||
|
||||
import net.momirealms.customcrops.api.event.CropBreakEvent;
|
||||
import net.momirealms.customcrops.api.util.AdventureUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import pl.betoncraft.betonquest.BetonQuest;
|
||||
import pl.betoncraft.betonquest.Instruction;
|
||||
import pl.betoncraft.betonquest.api.Objective;
|
||||
import pl.betoncraft.betonquest.config.Config;
|
||||
import pl.betoncraft.betonquest.exceptions.InstructionParseException;
|
||||
import pl.betoncraft.betonquest.exceptions.QuestRuntimeException;
|
||||
import pl.betoncraft.betonquest.utils.LogUtils;
|
||||
import pl.betoncraft.betonquest.utils.PlayerConverter;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class LegacyBetonQuestCCQuest extends Objective implements Listener {
|
||||
|
||||
private final HashSet<String> crop_ids = new HashSet<>();
|
||||
private final int amount;
|
||||
private final boolean notify;
|
||||
private final int notifyInterval;
|
||||
|
||||
public LegacyBetonQuestCCQuest(Instruction instruction) throws InstructionParseException {
|
||||
super(instruction);
|
||||
this.template = CropData.class;
|
||||
this.notifyInterval = instruction.getInt(instruction.getOptional("notify"), 1);
|
||||
this.notify = instruction.hasArgument("notify") || this.notifyInterval > 1;
|
||||
this.amount = instruction.getInt(instruction.getOptional("amount"), 1);
|
||||
Collections.addAll(this.crop_ids, instruction.getArray());
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
BetonQuest.getInstance().registerObjectives("customfishing", LegacyBetonQuestCCQuest.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
Bukkit.getPluginManager().registerEvents(this, BetonQuest.getInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
HandlerList.unregisterAll(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultDataInstruction() {
|
||||
return Integer.toString(this.amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProperty(String name, String playerID) {
|
||||
return switch (name.toLowerCase(Locale.ROOT)) {
|
||||
case "amount" ->
|
||||
Integer.toString(this.amount - ((LegacyBetonQuestCCQuest.CropData) this.dataMap.get(playerID)).getAmount());
|
||||
case "left" -> Integer.toString(((LegacyBetonQuestCCQuest.CropData) this.dataMap.get(playerID)).getAmount());
|
||||
case "total" -> Integer.toString(this.amount);
|
||||
default -> "";
|
||||
};
|
||||
}
|
||||
|
||||
private boolean isValidPlayer(Player player) {
|
||||
if (player == null) {
|
||||
return false;
|
||||
} else {
|
||||
return player.isOnline() && player.isValid();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onHarvest(CropBreakEvent event) {
|
||||
String playerID = PlayerConverter.getID(event.getPlayer());
|
||||
if (this.containsPlayer(playerID)) {
|
||||
if (this.crop_ids.contains(event.getCropItemID())) {
|
||||
if (this.checkConditions(playerID)) {
|
||||
if (!isValidPlayer(event.getPlayer())) {
|
||||
return;
|
||||
}
|
||||
CropData cropData = (CropData) this.dataMap.get(playerID);
|
||||
cropData.harvest(1);
|
||||
if (cropData.finished()) {
|
||||
this.completeObjective(playerID);
|
||||
}
|
||||
else if (this.notify && cropData.getAmount() % this.notifyInterval == 0) {
|
||||
try {
|
||||
Config.sendNotify(this.instruction.getPackage().getName(), playerID, "crop_to_harvest", new String[]{String.valueOf(cropData.getAmount())}, "crop_to_harvest,info");
|
||||
} catch (QuestRuntimeException e1) {
|
||||
try {
|
||||
LogUtils.getLogger().log(Level.WARNING, "The notify system was unable to play a sound for the 'crop_to_harvest' category in '" + this.instruction.getObjective().getFullID() + "'. Error was: '" + e1.getMessage() + "'");
|
||||
} catch (InstructionParseException e2) {
|
||||
LogUtils.logThrowableReport(e2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class CropData extends Objective.ObjectiveData {
|
||||
private int amount;
|
||||
|
||||
public CropData(String instruction, String playerID, String objID) {
|
||||
super(instruction, playerID, objID);
|
||||
try {
|
||||
this.amount = Integer.parseInt(instruction);
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
AdventureUtils.consoleMessage("[CustomCrops] NumberFormatException");
|
||||
this.amount = 1;
|
||||
}
|
||||
}
|
||||
|
||||
public void harvest(int caughtAmount) {
|
||||
this.amount -= caughtAmount;
|
||||
this.update();
|
||||
}
|
||||
|
||||
public int getAmount() {
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return String.valueOf(this.amount);
|
||||
}
|
||||
|
||||
public boolean finished() {
|
||||
return this.amount <= 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,20 +4,6 @@ config-version: '25'
|
||||
metrics: true
|
||||
# Language: english / spanish / chinese / turkish
|
||||
lang: english
|
||||
# AntiGrief
|
||||
integrations:
|
||||
Residence: false
|
||||
WorldGuard: false
|
||||
Kingdoms: false
|
||||
GriefDefender: false
|
||||
PlotSquared: false
|
||||
Towny: false
|
||||
Lands: false
|
||||
GriefPrevention: false
|
||||
CrashClaim: false
|
||||
BentoBox: false
|
||||
IridiumSkyBlock: false
|
||||
SuperiorSkyBlock: false
|
||||
|
||||
worlds:
|
||||
# This is designed for servers that using a separate folder for worlds
|
||||
@@ -84,6 +70,9 @@ mechanics:
|
||||
# effective range (Y axis)
|
||||
# Y轴有效范围
|
||||
range: 5
|
||||
# scarecrow item id
|
||||
# 稻草人物品id
|
||||
scarecrow: customcrops:scarecrow
|
||||
|
||||
other-settings:
|
||||
# This option requires a skill-plugin hook
|
||||
|
||||
@@ -1,20 +1,33 @@
|
||||
# Crop key name
|
||||
# 农作物配置名
|
||||
tomato:
|
||||
# TripWire / Item_Frame / Item_Display (1.19.4+)
|
||||
crop-mode: Item_Frame
|
||||
# Crop mode, make sure that type is consistent with IA/Oraxen configs
|
||||
# Otherwise some unexpected problems would occur
|
||||
# TRIPWIRE / ITEM_FRAME / ITEM_DISPLAY (1.19.4+)
|
||||
# 农作物模式,请确保和你的资源包配置等一致,否则会出现bug
|
||||
type: ITEM_FRAME
|
||||
|
||||
# The crop can only be planted on certain pots
|
||||
# Pot are stored in /CustomCrops/contents/pots
|
||||
# 农作物只能在指定的种植盆中种植
|
||||
pot-whitelist:
|
||||
- default
|
||||
|
||||
# Seed
|
||||
# Crop's seed, if you want to use Vanilla items, just use Capital letters. (Example APPLE)
|
||||
# 农作物的种子,如果你想用原版物品做种子,就使用大写字母
|
||||
seed: customcrops:tomato_seeds
|
||||
|
||||
# break/plant requirements
|
||||
# 破坏/种植农作物的需求
|
||||
requirements:
|
||||
break:
|
||||
requirement_1:
|
||||
# Requirement type, you can get a full list of requirements on wiki page
|
||||
# 需求类型,wiki中有详细的全部需求类型和示范
|
||||
type: permission
|
||||
value: tomato.break
|
||||
# The message to show when not meeting the requirement(Supports multiple lines)
|
||||
# 不满足需求的提示,支持多行
|
||||
message: "You don't have permission to harvest the tomato"
|
||||
plant:
|
||||
requirement_1:
|
||||
@@ -29,8 +42,11 @@ tomato:
|
||||
message: "It's not a good season to plant tomato"
|
||||
|
||||
# plant actions
|
||||
# 种植时发生的动作
|
||||
plant-actions:
|
||||
action_1:
|
||||
# Requirement type, you can get a full list of actions on wiki page
|
||||
# 动作类型,wiki中有详细的全部动作类型和示范
|
||||
type: sound
|
||||
value:
|
||||
source: player
|
||||
@@ -39,11 +55,23 @@ tomato:
|
||||
pitch: 1
|
||||
|
||||
# This decides when the crop data would be removed from cache
|
||||
# 这决定了农作物数据什么时候从缓存中移除
|
||||
max-points: 6
|
||||
# What should a crop do when gaining a certain amount of points
|
||||
# 农作物在获取指定生长点数时候执行的动作
|
||||
points:
|
||||
0:
|
||||
# change the crop's model
|
||||
# 改变农作物的模型
|
||||
model: customcrops:tomato_stage_1
|
||||
# As crop's models are different and have various height
|
||||
# So sometimes the pot information hologram can't show in a proper place
|
||||
# Set "hologram-offset-correction" to a high value would increase the
|
||||
# vertical position of the hologram
|
||||
# 因为不同农作物有不同的模型高度,所以在显示悬浮信息的时候,可能会导致模型遮挡了悬浮信息
|
||||
# 因此设置 "hologram-offset-correction" 为更大值可以提升悬浮字的高度,以免遮挡
|
||||
hologram-offset-correction: 0.2
|
||||
# Available events: break/grow/interact-by-hand/interact-with-item
|
||||
events:
|
||||
break:
|
||||
action_1:
|
||||
@@ -51,9 +79,13 @@ tomato:
|
||||
value:
|
||||
other-items:
|
||||
loot_1:
|
||||
# Other plugin item compatibility(Can also be used in quality-crops)
|
||||
# MMOItems:TYPE:ID
|
||||
# MythicMobs:id
|
||||
item: customcrops:tomato_seeds
|
||||
min: 1
|
||||
max: 1
|
||||
# 0-1
|
||||
chance: 0.3
|
||||
action_2:
|
||||
type: sound
|
||||
@@ -128,9 +160,6 @@ tomato:
|
||||
min: 1
|
||||
max: 4
|
||||
items:
|
||||
# Other plugin item compatibility(Can also be used in other-items)
|
||||
# MMOItems:TYPE:ID
|
||||
# MythicMobs:id
|
||||
1: customcrops:tomato
|
||||
2: customcrops:tomato_silver_star
|
||||
3: customcrops:tomato_golden_star
|
||||
@@ -146,22 +175,31 @@ tomato:
|
||||
value:
|
||||
golden:
|
||||
item: customcrops:tomato_stage_golden
|
||||
type: TripWire
|
||||
type: TRIPWIRE
|
||||
chance: 0.01
|
||||
interact-by-hand:
|
||||
action_1:
|
||||
type: break
|
||||
value: true # whether to trigger break event too 是否触发break事件
|
||||
action_2:
|
||||
type: replant
|
||||
value:
|
||||
point: 0
|
||||
crop: tomato # Replant the crop
|
||||
model: customcrops:tomato_stage_1
|
||||
crop: tomato # Replant the crop 重新种植农作物
|
||||
model: customcrops:tomato_stage_1 # crop model 农作物模型
|
||||
interact-with-item:
|
||||
interact_1:
|
||||
# the item to use
|
||||
# 使用的物品
|
||||
item: customcrops:i_want_overgrown_tomato_right_now
|
||||
# whether to reduce the amount
|
||||
# 是否减少数量
|
||||
reduce-amount: true
|
||||
# the item to return, remove this section if you don't want item back
|
||||
# 返还的物品,如果你不想要返还物品,请删除此项目
|
||||
return: customcrops:returned_item
|
||||
# actions to perform
|
||||
# 执行的动作
|
||||
actions:
|
||||
action_1:
|
||||
type: variation
|
||||
@@ -171,6 +209,13 @@ tomato:
|
||||
type: CHORUS
|
||||
chance: 1
|
||||
6:
|
||||
# In this example, the model is not set, so the crop would not change its model
|
||||
# when reaching this point. But here's a section called variation, which means that
|
||||
# the crop has a little chance to be gigantic when it's already ripe. Since it reaches
|
||||
# "max-points", the crop data would be removed from data and no longer affect server performance
|
||||
# 在这个示范中,model没有被设置,因此,农作物不会在此生长点数时替换模型
|
||||
# 但是这里有一个生长时候触发的变异动作,意味着农作物有小概率在此阶段发生变异
|
||||
# 因为农作物已经达到了最大生长点数,农作物数据将自此从数据中移除,不再对服务器性能造成影响
|
||||
events:
|
||||
grow:
|
||||
action_1:
|
||||
@@ -182,7 +227,9 @@ tomato:
|
||||
chance: 0.02
|
||||
|
||||
# The crop would actually not gain so many points
|
||||
999:
|
||||
# But you can set some special crops' loots here
|
||||
# 农作物实际上并不会获取这么多生长点数,但是你可以在此设置一些特殊掉落物
|
||||
99:
|
||||
model: customcrops:tomato_stage_golden
|
||||
events:
|
||||
break:
|
||||
@@ -205,15 +252,6 @@ tomato:
|
||||
min: 1
|
||||
max: 2
|
||||
chance: 0.3
|
||||
interact-by-hand:
|
||||
action_1:
|
||||
type: break
|
||||
action_2:
|
||||
type: replant
|
||||
value:
|
||||
point: 0
|
||||
crop: tomato # Replant the crop
|
||||
model: customcrops:tomato_stage_1
|
||||
interact-with-item:
|
||||
interact_1:
|
||||
item: GOLDEN_HOE
|
||||
@@ -228,7 +266,13 @@ tomato:
|
||||
crop: tomato
|
||||
model: customcrops:tomato_stage_1
|
||||
|
||||
# grow conditions
|
||||
# Custom grow conditions
|
||||
# You can get a full list of grow conditions on wiki page.
|
||||
# The default config tells that the crop would only grow in Spring and Autumn,
|
||||
# and it requires at least a certain amount of water to grow.
|
||||
# Though it would not grow in Summer, but it would still be alive. If you want
|
||||
# the crop to die, see the "death-conditions" below.
|
||||
# 自定义生长条件,默认配置是:农作物会在春和秋两个季节生长,并且要求种植盆水量大于3
|
||||
grow-conditions:
|
||||
condition_1:
|
||||
type: suitable_season
|
||||
@@ -237,20 +281,27 @@ tomato:
|
||||
- Autumn
|
||||
condition_2:
|
||||
type: water_more_than
|
||||
value: 3
|
||||
value: 2
|
||||
|
||||
# death conditions
|
||||
# Custom death conditions
|
||||
# 自定义死亡条件
|
||||
death-conditions:
|
||||
no_water:
|
||||
# You can customize the dead models according to the reasons
|
||||
# 你可以根据死因设置不同的死亡模型
|
||||
model: customcrops:crop_stage_death
|
||||
conditions:
|
||||
# "&&" represents "And"
|
||||
# "||" represents "Or"
|
||||
# the default config tells that the crop would have 70% chance to die if the pot is dry
|
||||
# 默认配置:农作物有70%概率在种植盆干燥情况下死亡
|
||||
'&&':
|
||||
condition_1:
|
||||
type: water_less_than
|
||||
value: 1
|
||||
condition_2:
|
||||
type: random
|
||||
value: 0.7 # 70% chance to die if the pot is not wet
|
||||
value: 0.7
|
||||
unsuitable_season:
|
||||
model: customcrops:crop_stage_death
|
||||
conditions:
|
||||
@@ -259,7 +310,8 @@ tomato:
|
||||
value:
|
||||
- Winter
|
||||
crow_attack:
|
||||
# crop would be removed if dead-model is not set
|
||||
# Crop would be removed if "model" is not set
|
||||
# 如果没有设置model,农作物会直接被移除,而不是替换模型
|
||||
conditions:
|
||||
condition_1:
|
||||
type: crow_attack
|
||||
@@ -268,12 +320,17 @@ tomato:
|
||||
fly-model: customcrops:crow_fly
|
||||
stand-model: customcrops:crow_stand
|
||||
|
||||
# custom bone meal
|
||||
# Custom bone meal
|
||||
# 自定义骨粉
|
||||
custom-bone-meal:
|
||||
bone_meal_1:
|
||||
item: BONE_MEAL
|
||||
particle: VILLAGER_HAPPY
|
||||
sound: minecraft:item.bone_meal.use
|
||||
# 20% chance to grow 2 points
|
||||
# (100% - 20%) * 60% = 48% chance to grow 1 point
|
||||
# 20%概率获得两个生长点数
|
||||
# (100% - 20%) * 60% = 48% 概率获得一个生长点数
|
||||
chance:
|
||||
2: 0.2
|
||||
1: 0.6
|
||||
|
||||
@@ -3,6 +3,7 @@ quality_1:
|
||||
icon: '뀆'
|
||||
chance: 1
|
||||
times: 28
|
||||
# 70%/20%/10%
|
||||
ratio: 7/2/1
|
||||
item: customcrops:quality_1
|
||||
before-plant: true
|
||||
@@ -15,6 +16,7 @@ quality_2:
|
||||
icon: '뀇'
|
||||
chance: 1
|
||||
times: 28
|
||||
# 55%/30%/15%
|
||||
ratio: 11/6/3
|
||||
item: customcrops:quality_2
|
||||
before-plant: true
|
||||
@@ -27,6 +29,7 @@ quality_3:
|
||||
icon: '뀈'
|
||||
chance: 1
|
||||
times: 28
|
||||
# 40%/40%/20%
|
||||
ratio: 2/2/1
|
||||
item: customcrops:quality_3
|
||||
before-plant: true
|
||||
|
||||
@@ -1,19 +1,29 @@
|
||||
speed_grow_1:
|
||||
type: SPEED_GROW
|
||||
# Fertilizer Hologram display name
|
||||
# Fertilizer Hologram display icon
|
||||
# 肥料在悬浮字中显示的图标
|
||||
icon: '뀌'
|
||||
# How many days can this fertilizer stay in pot
|
||||
# 肥料有效时间(游戏日)
|
||||
times: 14
|
||||
# ItemsAdder item namespacedID
|
||||
# item id
|
||||
# 物品ID
|
||||
item: customcrops:speed_grow_1
|
||||
# Should this fertilizer be used before planting
|
||||
# 肥料是否只能在种植前使用
|
||||
before-plant: true
|
||||
# The particle to be displayed when using fertilizer
|
||||
# 使用肥料的粒子效果
|
||||
# https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Particle.html
|
||||
particle: SPELL_WITCH
|
||||
# The sound to play when using
|
||||
# 使用肥料的声音
|
||||
sound: minecraft:item.hoe.till
|
||||
# Pot whitelist
|
||||
# 种植盆白名单
|
||||
pot-whitelist:
|
||||
- default
|
||||
# 50% chance to gain another 1 points
|
||||
chance:
|
||||
1: 0.5
|
||||
speed_grow_2:
|
||||
@@ -26,8 +36,11 @@ speed_grow_2:
|
||||
sound: minecraft:item.hoe.till
|
||||
pot-whitelist:
|
||||
- default
|
||||
# 10% chance to gain another 2 points
|
||||
# (100% - 10%) * 70% = 63% chance to gain another 1 point
|
||||
chance:
|
||||
1: 0.9
|
||||
2: 0.1
|
||||
1: 0.7
|
||||
speed_grow_3:
|
||||
type: SPEED_GROW
|
||||
icon: '뀎'
|
||||
@@ -38,8 +51,10 @@ speed_grow_3:
|
||||
sound: minecraft:item.hoe.till
|
||||
pot-whitelist:
|
||||
- default
|
||||
# 40% chance to gain another 2 points
|
||||
# 100% chance to gain another 1 point
|
||||
# 10% chance to gain another 3 points
|
||||
# (100% - 10%) * 40% = 36% chance to gain another 2 points
|
||||
# (100% - (36% + 10%)) * 80% = 43.2% chance to gain another 1 point
|
||||
chance:
|
||||
3: 0.1
|
||||
2: 0.4
|
||||
1: 1
|
||||
1: 0.8
|
||||
@@ -3,6 +3,7 @@ variation_1:
|
||||
icon: '뀒'
|
||||
times: 14
|
||||
# If a crop's default variation chance is 0.01, now it's 0.03
|
||||
# 如果农作物的变异概率是0.01,那么使用肥料后变成了0.03
|
||||
chance: 0.02
|
||||
item: customcrops:variation_1
|
||||
before-plant: true
|
||||
|
||||
@@ -8,6 +8,9 @@ yield_increase_1:
|
||||
sound: minecraft:item.hoe.till
|
||||
pot-whitelist:
|
||||
- default
|
||||
# 10% chance to gain another 3 crops
|
||||
# (100% - 10%) * 40% = 36% chance to gain another 2 crops
|
||||
# (100% - (10% + 36%)) * 80% = 43.2% chance to gain another 1 crop
|
||||
chance:
|
||||
3: 0.1
|
||||
2: 0.4
|
||||
@@ -22,6 +25,9 @@ yield_increase_2:
|
||||
sound: minecraft:item.hoe.till
|
||||
pot-whitelist:
|
||||
- default
|
||||
# 20% chance to gain another 3 crops
|
||||
# (100% - 20%) * 60% = 48% chance to gain another 2 crops
|
||||
# (100% - (20% + 48%)) * 80% = 25.6% chance to gain another 1 crop
|
||||
chance:
|
||||
3: 0.2
|
||||
2: 0.6
|
||||
@@ -36,6 +42,8 @@ yield_increase_3:
|
||||
sound: minecraft:item.hoe.till
|
||||
pot-whitelist:
|
||||
- default
|
||||
# 40% chance to gain another 3 crops
|
||||
# (100% - 40%) * 100% = 60% chance to gain another 2 crops
|
||||
chance:
|
||||
3: 0.4
|
||||
2: 1
|
||||
@@ -1,11 +1,16 @@
|
||||
# Pot key name
|
||||
default:
|
||||
max-water-storage: 4
|
||||
# The max water storage
|
||||
# 最大储水量
|
||||
max-water-storage: 5
|
||||
base:
|
||||
# basic models
|
||||
# basic models, use capital letters if you want to use vanilla blocks
|
||||
# Example: FARMLAND
|
||||
# 基础模型,如果你想要使用原版方块请使用大写字母,例如FARMLAND(耕地)
|
||||
dry: customcrops:dry_pot
|
||||
wet: customcrops:wet_pot
|
||||
# If you want fertilized pots to have different looks
|
||||
# Don't forget to set more bottom-block types in crop's config
|
||||
# 如果你想让施肥的种植盆有不同的外观
|
||||
fertilized-pots:
|
||||
enable: false
|
||||
quality:
|
||||
@@ -23,12 +28,22 @@ default:
|
||||
speed-grow:
|
||||
dry: customcrops:dry_pot
|
||||
wet: customcrops:wet_pot
|
||||
# Methods to fill the pot
|
||||
# 浇水的方法
|
||||
fill-method:
|
||||
method_1:
|
||||
# The item to use
|
||||
# 使用的物品
|
||||
item: WATER_BUCKET
|
||||
# The item returned
|
||||
# 返还的物品
|
||||
return: BUCKET
|
||||
# water amount to add
|
||||
# 增加的水量
|
||||
amount: 3
|
||||
# 粒子效果
|
||||
particle: WATER_SPLASH
|
||||
# 声音
|
||||
sound: minecraft:block.water.ambient
|
||||
method_2:
|
||||
item: WATER
|
||||
@@ -42,24 +57,49 @@ default:
|
||||
particle: WATER_SPLASH
|
||||
sound: minecraft:block.water.ambient
|
||||
method_4:
|
||||
# This is just an example
|
||||
# "customcrops:magic_water" actually not exists
|
||||
# 这只是个示例, "customcrops:magic_water"事实上不存在
|
||||
item: customcrops:magic_water
|
||||
amount: 10
|
||||
amount: 5
|
||||
particle: WATER_SPLASH
|
||||
sound: minecraft:block.water.ambient
|
||||
# Pot info hologram
|
||||
# 种植盆悬浮信息
|
||||
hologram:
|
||||
enable: true
|
||||
# ARMOR_STAND / TEXT_DISPLAY (1.19.4+)
|
||||
# 显示载体
|
||||
type: ARMOR_STAND
|
||||
# in seconds
|
||||
# 持续时间
|
||||
duration: 2
|
||||
# remove this if you want players can see the pot info even with empty hands
|
||||
# 如果你想要空手也能查看种植盆信息,那么移除这个项目
|
||||
require-item: customcrops:soil_surveyor
|
||||
# Fertilizer info
|
||||
# 肥料信息
|
||||
fertilizer:
|
||||
enable: true
|
||||
vertical-offset: 0.8
|
||||
text: '<font:customcrops:default>{icon}</font> {left_times}/{max_times}'
|
||||
content: '<font:customcrops:default>{icon}</font> {left_times}/{max_times}'
|
||||
# Water info
|
||||
# 水分信息
|
||||
water:
|
||||
enable: true
|
||||
vertical-offset: 1.05
|
||||
text: '<font:customcrops:default>{water_bar}</font>'
|
||||
#text: '{current}/{storage}'
|
||||
# Available placeholders
|
||||
# {current} current water 当前水量
|
||||
# {storage} max water 最大储水量
|
||||
# {water_bar} water bar image 水条
|
||||
content: '<font:customcrops:default>{water_bar}</font>'
|
||||
water-bar:
|
||||
left: '뀂'
|
||||
full: '뀁뀃'
|
||||
empty: '뀁뀄'
|
||||
right: '뀁뀅'
|
||||
right: '뀁뀅'
|
||||
text-display-options:
|
||||
background-color: 0,0,0,0
|
||||
has-shadow: false
|
||||
is-see-through: false
|
||||
use-default-background-color: false
|
||||
text-opacity: -1
|
||||
@@ -1,20 +1,51 @@
|
||||
# Sprinkler key name
|
||||
sprinkler_1:
|
||||
# This decides the work range
|
||||
# (1+1x2)²=9
|
||||
# 洒水器工作范围 3x3
|
||||
range: 1
|
||||
storage: 5
|
||||
# max water storage
|
||||
# 最大储水量
|
||||
storage: 4
|
||||
# 2/3D物品
|
||||
3D-item: customcrops:sprinkler_1
|
||||
2D-item: customcrops:sprinkler_1_item
|
||||
# Item_Frame / Tripwire / Item_Display (1.19.4+)
|
||||
type: Item_Frame
|
||||
# ITEM_FRAME / TRIPWIRE / ITEM_DISPLAY (1.19.4+)
|
||||
# Sprinkler item type
|
||||
type: ITEM_FRAME
|
||||
# The sprinkler can only add water to certain pots
|
||||
# 洒水器只能对指定种植盆浇水
|
||||
pot-whitelist:
|
||||
- default
|
||||
# see how fill-method works in /CustomCrops/contents/pots/default.yml
|
||||
# 请在CustomCrops/contents/pots/default.yml查看"fill-method"如何使用
|
||||
fill-method:
|
||||
method_1:
|
||||
item: WATER_BUCKET
|
||||
return: BUCKET
|
||||
amount: 3
|
||||
particle: WATER_SPLASH
|
||||
sound: minecraft:block.water.ambient
|
||||
method_2:
|
||||
item: WATER
|
||||
return: GLASS_BOTTLE
|
||||
amount: 1
|
||||
particle: WATER_SPLASH
|
||||
sound: minecraft:block.water.ambient
|
||||
# The sound to play when placing
|
||||
# 放置时候的声音
|
||||
place-sound: minecraft:block.bone_block.place
|
||||
# The hologram to show when interacting
|
||||
# 交互时候产生的悬浮信息
|
||||
hologram:
|
||||
enable: true
|
||||
# ARMOR_STAND / TEXT_DISPLAY (1.19.4+)
|
||||
type: ARMOR_STAND
|
||||
vertical-offset: -0.3
|
||||
# vertical offset(change this according to your model size)
|
||||
# 竖直方向的偏移
|
||||
vertical-offset: -0.1
|
||||
duration: 1
|
||||
# Available variables:
|
||||
# Available placeholders:
|
||||
# {water_bar} water bar image
|
||||
# {current} current water
|
||||
# {storage} max storage
|
||||
@@ -24,29 +55,23 @@ sprinkler_1:
|
||||
full: '뀁뀃'
|
||||
empty: '뀁뀄'
|
||||
right: '뀁뀅'
|
||||
text-display-options:
|
||||
background-color: 0,0,0,0
|
||||
has-shadow: false
|
||||
is-see-through: false
|
||||
use-default-background-color: false
|
||||
text-opacity: -1
|
||||
# Water splash animation when sprinkler works
|
||||
# 洒水器在工作时候的洒水效果
|
||||
animation:
|
||||
enable: true
|
||||
# in seconds
|
||||
# 持续时间
|
||||
duration: 10
|
||||
vertical-offset: 0.4
|
||||
item: customcrops:water_effect
|
||||
# ARMOR_STAND / ITEM_DISPLAY (1.19.4+)
|
||||
type: ARMOR_STAND
|
||||
pot-whitelist:
|
||||
- default
|
||||
fill-method:
|
||||
method_1:
|
||||
item: WATER_BUCKET
|
||||
return: BUCKET
|
||||
amount: 3
|
||||
particle: WATER_SPLASH
|
||||
sound: minecraft:block.water.ambient
|
||||
method_2:
|
||||
item: WATER
|
||||
return: GLASS_BOTTLE
|
||||
amount: 1
|
||||
particle: WATER_SPLASH
|
||||
sound: minecraft:block.water.ambient
|
||||
|
||||
sprinkler_2:
|
||||
# (1+2x2)²=25
|
||||
@@ -54,24 +79,7 @@ sprinkler_2:
|
||||
storage: 5
|
||||
3D-item: customcrops:sprinkler_2
|
||||
2D-item: customcrops:sprinkler_2_item
|
||||
type: Item_Frame
|
||||
place-sound: minecraft:block.bone_block.place
|
||||
hologram:
|
||||
enable: true
|
||||
type: ARMOR_STAND
|
||||
vertical-offset: -0.3
|
||||
duration: 1
|
||||
content: '<font:customcrops:default>{water_bar}</font>'
|
||||
water-bar:
|
||||
left: '뀂'
|
||||
full: '뀁뀃'
|
||||
empty: '뀁뀄'
|
||||
right: '뀁뀅'
|
||||
animation:
|
||||
enable: true
|
||||
vertical-offset: 0.4
|
||||
item: customcrops:water_effect
|
||||
type: ARMOR_STAND
|
||||
type: ITEM_FRAME
|
||||
pot-whitelist:
|
||||
- default
|
||||
fill-method:
|
||||
@@ -87,30 +95,37 @@ sprinkler_2:
|
||||
amount: 1
|
||||
particle: WATER_SPLASH
|
||||
sound: minecraft:block.water.ambient
|
||||
place-sound: minecraft:block.bone_block.place
|
||||
hologram:
|
||||
enable: true
|
||||
type: ARMOR_STAND
|
||||
vertical-offset: -0.1
|
||||
duration: 1
|
||||
content: '<font:customcrops:default>{water_bar}</font>'
|
||||
water-bar:
|
||||
left: '뀂'
|
||||
full: '뀁뀃'
|
||||
empty: '뀁뀄'
|
||||
right: '뀁뀅'
|
||||
text-display-options:
|
||||
background-color: 0,0,0,0
|
||||
has-shadow: false
|
||||
is-see-through: false
|
||||
use-default-background-color: false
|
||||
text-opacity: -1
|
||||
animation:
|
||||
enable: true
|
||||
duration: 10
|
||||
vertical-offset: 0.4
|
||||
item: customcrops:water_effect
|
||||
type: ARMOR_STAND
|
||||
|
||||
sprinkler_3:
|
||||
range: 2
|
||||
storage: 7
|
||||
3D-item: customcrops:sprinkler_3
|
||||
2D-item: customcrops:sprinkler_3_item
|
||||
type: Item_Frame
|
||||
place-sound: minecraft:block.bone_block.place
|
||||
hologram:
|
||||
enable: true
|
||||
type: ARMOR_STAND
|
||||
vertical-offset: -0.3
|
||||
duration: 1
|
||||
content: '<font:customcrops:default>{water_bar}</font>'
|
||||
water-bar:
|
||||
left: '뀂'
|
||||
full: '뀁뀃'
|
||||
empty: '뀁뀄'
|
||||
right: '뀁뀅'
|
||||
animation:
|
||||
enable: true
|
||||
vertical-offset: 0.4
|
||||
item: customcrops:water_effect
|
||||
type: ARMOR_STAND
|
||||
type: ITEM_FRAME
|
||||
pot-whitelist:
|
||||
- default
|
||||
fill-method:
|
||||
@@ -125,4 +140,28 @@ sprinkler_3:
|
||||
return: GLASS_BOTTLE
|
||||
amount: 1
|
||||
particle: WATER_SPLASH
|
||||
sound: minecraft:block.water.ambient
|
||||
sound: minecraft:block.water.ambient
|
||||
place-sound: minecraft:block.bone_block.place
|
||||
hologram:
|
||||
enable: true
|
||||
type: ARMOR_STAND
|
||||
vertical-offset: -0.1
|
||||
duration: 1
|
||||
content: '<font:customcrops:default>{water_bar}</font>'
|
||||
water-bar:
|
||||
left: '뀂'
|
||||
full: '뀁뀃'
|
||||
empty: '뀁뀄'
|
||||
right: '뀁뀅'
|
||||
text-display-options:
|
||||
background-color: 0,0,0,0
|
||||
has-shadow: false
|
||||
is-see-through: false
|
||||
use-default-background-color: false
|
||||
text-opacity: -1
|
||||
animation:
|
||||
enable: true
|
||||
duration: 10
|
||||
vertical-offset: 0.4
|
||||
item: customcrops:water_effect
|
||||
type: ARMOR_STAND
|
||||
@@ -1,22 +1,34 @@
|
||||
watering_can_1:
|
||||
# 物品 id
|
||||
item: customcrops:watering_can_1
|
||||
# 储水量
|
||||
capacity: 3
|
||||
# Effective Range
|
||||
# 有效范围
|
||||
effective-range:
|
||||
width: 1
|
||||
length: 1
|
||||
# 粒子效果
|
||||
particle: WATER_SPLASH
|
||||
# 声音
|
||||
sound: minecraft:block.water.ambient
|
||||
# Methods to fill the watering can
|
||||
fill-method:
|
||||
method_1:
|
||||
# The target block/furniture id
|
||||
# use capital letters for vanilla items
|
||||
target: WATER
|
||||
type: block
|
||||
# water amount to add
|
||||
# 加水量
|
||||
amount: 1
|
||||
particle: WATER_SPLASH
|
||||
sound: minecraft:item.bucket.fill
|
||||
# This decides where the watering can can be used
|
||||
# 这决定了水壶能使用在哪些种植盆上
|
||||
pot-whitelist:
|
||||
- default
|
||||
# allows you to add water to sprinkler by clicking with a watering can
|
||||
# 允许水壶对洒水器加水
|
||||
sprinkler-whitelist:
|
||||
- sprinkler_1
|
||||
- sprinkler_2
|
||||
@@ -25,23 +37,24 @@ watering_can_1:
|
||||
# Should watering-can has dynamic lore according to the water amount
|
||||
# 水壶是否有根据水量变化的动态lore
|
||||
enable: true
|
||||
# Available variables:
|
||||
# Available placeholders:
|
||||
# {water_bar} water bar image
|
||||
# {current} current water
|
||||
# {storage} max storage
|
||||
lore:
|
||||
- '<italic:false><white>{water_bar}'
|
||||
- '<italic:false><white><font:customcrops:default>{water_bar}</font>'
|
||||
- '<italic:false><gray>Right click water to add water to the can.'
|
||||
actionbar:
|
||||
# Should actionbar be sent when using watering-can
|
||||
# 是否发送动作栏信息
|
||||
enable: true
|
||||
# Available variables {current} {storage} {water_bar}
|
||||
content: '{water_bar}'
|
||||
# Available placeholders {current} {storage} {water_bar}
|
||||
content: '<font:customcrops:default>{water_bar}</font>'
|
||||
water-bar:
|
||||
left: '<font:customcrops:default>뀂'
|
||||
left: '뀂'
|
||||
full: '뀁뀃'
|
||||
empty: '뀁뀄'
|
||||
right: '뀁뀅</font>'
|
||||
right: '뀁뀅'
|
||||
|
||||
watering_can_2:
|
||||
item: customcrops:watering_can_2
|
||||
@@ -54,7 +67,6 @@ watering_can_2:
|
||||
fill-method:
|
||||
method_1:
|
||||
target: WATER
|
||||
type: block
|
||||
amount: 1
|
||||
particle: WATER_SPLASH
|
||||
pot-whitelist:
|
||||
@@ -66,16 +78,16 @@ watering_can_2:
|
||||
dynamic-lore:
|
||||
enable: true
|
||||
lore:
|
||||
- '<italic:false><white>{water_bar}'
|
||||
- '<italic:false><white><font:customcrops:default>{water_bar}</font>'
|
||||
- '<italic:false><gray>Right click water to add water to the can.'
|
||||
actionbar:
|
||||
enable: true
|
||||
content: '{water_bar}'
|
||||
content: '<font:customcrops:default>{water_bar}</font>'
|
||||
water-bar:
|
||||
left: '<font:customcrops:default>뀂'
|
||||
left: '뀂'
|
||||
full: '뀁뀃'
|
||||
empty: '뀁뀄'
|
||||
right: '뀁뀅</font>'
|
||||
right: '뀁뀅'
|
||||
|
||||
watering_can_3:
|
||||
item: customcrops:watering_can_3
|
||||
@@ -88,7 +100,6 @@ watering_can_3:
|
||||
fill-method:
|
||||
method_1:
|
||||
target: WATER
|
||||
type: block
|
||||
amount: 1
|
||||
particle: WATER_SPLASH
|
||||
pot-whitelist:
|
||||
@@ -100,16 +111,16 @@ watering_can_3:
|
||||
dynamic-lore:
|
||||
enable: true
|
||||
lore:
|
||||
- '<italic:false><white>{water_bar}'
|
||||
- '<italic:false><white><font:customcrops:default>{water_bar}</font>'
|
||||
- '<italic:false><gray>Right click water to add water to the can.'
|
||||
actionbar:
|
||||
enable: true
|
||||
content: '{water_bar}'
|
||||
content: '<font:customcrops:default>{water_bar}</font>'
|
||||
water-bar:
|
||||
left: '<font:customcrops:default>뀂'
|
||||
left: '뀂'
|
||||
full: '뀁뀃'
|
||||
empty: '뀁뀄'
|
||||
right: '뀁뀅</font>'
|
||||
right: '뀁뀅'
|
||||
|
||||
watering_can_4:
|
||||
item: customcrops:watering_can_4
|
||||
@@ -122,7 +133,6 @@ watering_can_4:
|
||||
fill-method:
|
||||
method_1:
|
||||
target: WATER
|
||||
type: block
|
||||
amount: 1
|
||||
particle: WATER_SPLASH
|
||||
pot-whitelist:
|
||||
@@ -134,13 +144,13 @@ watering_can_4:
|
||||
dynamic-lore:
|
||||
enable: true
|
||||
lore:
|
||||
- '<italic:false><white>{water_bar}'
|
||||
- '<italic:false><white><font:customcrops:default>{water_bar}</font>'
|
||||
- '<italic:false><gray>Right click water to add water to the can.'
|
||||
actionbar:
|
||||
enable: true
|
||||
content: '{water_bar}'
|
||||
content: '<font:customcrops:default>{water_bar}</font>'
|
||||
water-bar:
|
||||
left: '<font:customcrops:default>뀂'
|
||||
left: '뀂'
|
||||
full: '뀁뀃'
|
||||
empty: '뀁뀄'
|
||||
right: '뀁뀅</font>'
|
||||
right: '뀁뀅'
|
||||
|
||||
@@ -19,4 +19,6 @@ messages:
|
||||
set-season: "<white>成功将 {world} 世界的季节设置为 {season}."
|
||||
set-date: "<white>成功将 {world} 世界的日期设置为 {date}."
|
||||
world-not-exist: '<white>世界 {world} 不存在.'
|
||||
season-not-exist: '<white>{season} 不是一个有效的季节.'
|
||||
season-not-exist: '<white>{season} 不是一个有效的季节.'
|
||||
force-sprinkler-work: '<white>已强制世界 {world} 的洒水器进行工作.'
|
||||
force-consume: '<white>已强制世界 {world} 的肥料、水分消耗.'
|
||||
@@ -19,4 +19,6 @@ messages:
|
||||
set-season: "<white>Successfully set {world}'s season to {season}."
|
||||
set-date: "<white>Successfully set {world}'s date to {date}."
|
||||
world-not-exist: '<white>World {world} does not exist.'
|
||||
season-not-exist: '<white>Season {season} does not exist.'
|
||||
season-not-exist: '<white>Season {season} does not exist.'
|
||||
force-sprinkler-work: "<white>Forced {world}'s sprinklers to work"
|
||||
force-consume: "<white>Forced {world}'s pot to reduce water amount and the remaining use of fertilizers"
|
||||
@@ -19,4 +19,6 @@ messages:
|
||||
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ı.'
|
||||
season-not-exist: '<white>{season} adında bir mevsim bulunamadı.'
|
||||
force-sprinkler-work: "<white>{world}'nin sulama sistemlerinin çalışmasını zorladı"
|
||||
force-consume: "<white>{world}'nin tenceresindeki su miktarını azaltmayı ve kalan gübre kullanımını zorladı"
|
||||
@@ -2,6 +2,7 @@ name: CustomCrops
|
||||
version: '${version}'
|
||||
main: net.momirealms.customcrops.CustomCrops
|
||||
api-version: 1.17
|
||||
load: POSTWORLD
|
||||
authors: [ XiaoMoMi ]
|
||||
depend:
|
||||
- ProtocolLib
|
||||
@@ -31,9 +32,30 @@ softdepend:
|
||||
- BattlePass
|
||||
- BetonQuest
|
||||
- ClueScrolls
|
||||
- HuskTowns
|
||||
commands:
|
||||
customcrops:
|
||||
usage: /customcrops <args>
|
||||
permission: customcrops.admin
|
||||
aliases:
|
||||
- ccrops
|
||||
- ccrops
|
||||
permissions :
|
||||
customcrops.*:
|
||||
default: op
|
||||
children:
|
||||
customcrops.admin: true
|
||||
customcrops.reload: true
|
||||
customcrops.help: true
|
||||
customcrops.about: true
|
||||
customcrops.setdate: true
|
||||
customcrops.setseason: true
|
||||
customcrops.reload:
|
||||
default: op
|
||||
customcrops.help:
|
||||
default: op
|
||||
customcrops.about:
|
||||
default: op
|
||||
customcrops.setdate:
|
||||
default: op
|
||||
customcrops.setseason:
|
||||
default: op
|
||||
Reference in New Issue
Block a user