mirror of
https://github.com/Xiao-MoMi/Custom-Crops.git
synced 2025-12-22 00:19:24 +00:00
1.5.22
This commit is contained in:
@@ -58,13 +58,13 @@ public class ConfigReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void ReloadConfig(){
|
public static void ReloadConfig(){
|
||||||
|
Sounds.loadSound();
|
||||||
Config.loadConfig();
|
Config.loadConfig();
|
||||||
|
Season.loadSeason();
|
||||||
Message.loadMessage();
|
Message.loadMessage();
|
||||||
Basic.loadBasic();
|
Basic.loadBasic();
|
||||||
cropLoad();
|
|
||||||
fertilizerLoad();
|
fertilizerLoad();
|
||||||
Season.loadSeason();
|
cropLoad();
|
||||||
Sounds.loadSound();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Config{
|
public static class Config{
|
||||||
@@ -88,7 +88,7 @@ public class ConfigReader {
|
|||||||
public static int timeToGrow;
|
public static int timeToGrow;
|
||||||
public static int timeToWork;
|
public static int timeToWork;
|
||||||
public static boolean logTime;
|
public static boolean logTime;
|
||||||
public static boolean onlyLoadedGrow;
|
public static int growMode;
|
||||||
public static boolean quality;
|
public static boolean quality;
|
||||||
public static boolean canAddWater;
|
public static boolean canAddWater;
|
||||||
public static boolean allWorld;
|
public static boolean allWorld;
|
||||||
@@ -115,16 +115,16 @@ public class ConfigReader {
|
|||||||
cropGrowTimeList = config.getLongList("config.grow-time");
|
cropGrowTimeList = config.getLongList("config.grow-time");
|
||||||
cropGrowTimeList.forEach(time -> {
|
cropGrowTimeList.forEach(time -> {
|
||||||
if(time < 0 || time > 23999){
|
if(time < 0 || time > 23999){
|
||||||
AdventureManager.consoleMessage("<red>[CustomCrops] time should be between 0 and 23999");
|
AdventureManager.consoleMessage("<red>[CustomCrops] Grow time should be between 0 and 23999");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
timeToGrow = config.getInt("config.time-to-grow",60)*20;
|
timeToGrow = config.getInt("config.time-to-grow",60)*20;
|
||||||
timeToWork = config.getInt("config.time-to-work",30)*20;
|
timeToWork = config.getInt("config.time-to-work",30)*20;
|
||||||
|
|
||||||
asyncCheck = config.getBoolean("config.async-time-check",false);
|
asyncCheck = config.getBoolean("config.async-time-check",false);
|
||||||
logTime = config.getBoolean("config.log-time-consume",false);
|
logTime = config.getBoolean("config.log-time-consume",false);
|
||||||
onlyLoadedGrow = !config.getBoolean("config.only-grow-in-loaded-chunks",true);
|
growMode = config.getInt("config.grow-mode",3);
|
||||||
|
if (growMode > 4 || growMode < 1) growMode = 3;
|
||||||
allWorld = config.getBoolean("config.all-world-grow",false);
|
allWorld = config.getBoolean("config.all-world-grow",false);
|
||||||
hasParticle = config.getBoolean("config.water-particles", true);
|
hasParticle = config.getBoolean("config.water-particles", true);
|
||||||
rightClickHarvest = config.getBoolean("config.right-click-harvest", true);
|
rightClickHarvest = config.getBoolean("config.right-click-harvest", true);
|
||||||
|
|||||||
@@ -21,10 +21,7 @@ import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
|||||||
import net.momirealms.customcrops.commands.Executor;
|
import net.momirealms.customcrops.commands.Executor;
|
||||||
import net.momirealms.customcrops.commands.Completer;
|
import net.momirealms.customcrops.commands.Completer;
|
||||||
import net.momirealms.customcrops.datamanager.*;
|
import net.momirealms.customcrops.datamanager.*;
|
||||||
import net.momirealms.customcrops.listener.BreakBlock;
|
import net.momirealms.customcrops.listener.*;
|
||||||
import net.momirealms.customcrops.listener.InteractEntity;
|
|
||||||
import net.momirealms.customcrops.listener.ItemSpawn;
|
|
||||||
import net.momirealms.customcrops.listener.RightClick;
|
|
||||||
import net.momirealms.customcrops.timer.CropTimer;
|
import net.momirealms.customcrops.timer.CropTimer;
|
||||||
import net.momirealms.customcrops.utils.AdventureManager;
|
import net.momirealms.customcrops.utils.AdventureManager;
|
||||||
import net.momirealms.customcrops.utils.BackUp;
|
import net.momirealms.customcrops.utils.BackUp;
|
||||||
@@ -77,6 +74,8 @@ public final class CustomCrops extends JavaPlugin {
|
|||||||
Bukkit.getPluginManager().registerEvents(new ItemSpawn(), this);
|
Bukkit.getPluginManager().registerEvents(new ItemSpawn(), this);
|
||||||
Bukkit.getPluginManager().registerEvents(new RightClick(), this);
|
Bukkit.getPluginManager().registerEvents(new RightClick(), this);
|
||||||
Bukkit.getPluginManager().registerEvents(new BreakBlock(), this);
|
Bukkit.getPluginManager().registerEvents(new BreakBlock(), this);
|
||||||
|
Bukkit.getPluginManager().registerEvents(new JoinAndQuit(), this);
|
||||||
|
Bukkit.getPluginManager().registerEvents(new BreakFurniture(), this);
|
||||||
Bukkit.getPluginManager().registerEvents(new InteractEntity(this), this);
|
Bukkit.getPluginManager().registerEvents(new InteractEntity(this), this);
|
||||||
|
|
||||||
if (ConfigReader.Season.enable){
|
if (ConfigReader.Season.enable){
|
||||||
@@ -103,6 +102,7 @@ public final class CustomCrops extends JavaPlugin {
|
|||||||
|
|
||||||
if (this.cropManager != null){
|
if (this.cropManager != null){
|
||||||
this.cropManager.cleanData();
|
this.cropManager.cleanData();
|
||||||
|
this.cropManager.updateData();
|
||||||
this.cropManager.saveData();
|
this.cropManager.saveData();
|
||||||
this.cropManager = null;
|
this.cropManager = null;
|
||||||
}
|
}
|
||||||
@@ -112,6 +112,7 @@ public final class CustomCrops extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
if (this.sprinklerManager != null){
|
if (this.sprinklerManager != null){
|
||||||
this.sprinklerManager.cleanData();
|
this.sprinklerManager.cleanData();
|
||||||
|
this.sprinklerManager.updateData();
|
||||||
this.sprinklerManager.saveData();
|
this.sprinklerManager.saveData();
|
||||||
this.sprinklerManager = null;
|
this.sprinklerManager = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,12 @@ public class Executor implements CommandExecutor {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.instance, ()-> {
|
Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.instance, ()-> {
|
||||||
plugin.getCropManager().cropGrow(args[1]);
|
switch (ConfigReader.Config.growMode){
|
||||||
|
case 1 -> plugin.getCropManager().growModeOne(args[1]);
|
||||||
|
case 2 -> plugin.getCropManager().growModeTwo(args[1]);
|
||||||
|
case 3 -> plugin.getCropManager().growModeThree(args[1]);
|
||||||
|
case 4 -> plugin.getCropManager().growModeFour(args[1]);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
if (sender instanceof Player player){
|
if (sender instanceof Player player){
|
||||||
AdventureManager.playerMessage(player,ConfigReader.Message.prefix + ConfigReader.Message.forceGrow.replace("{world}",args[1]));
|
AdventureManager.playerMessage(player,ConfigReader.Message.prefix + ConfigReader.Message.forceGrow.replace("{world}",args[1]));
|
||||||
@@ -82,7 +87,12 @@ public class Executor implements CommandExecutor {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.instance, ()-> {
|
Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.instance, ()-> {
|
||||||
plugin.getSprinklerManager().sprinklerWork(args[1]);
|
switch (ConfigReader.Config.growMode){
|
||||||
|
case 1 -> plugin.getSprinklerManager().workModeOne(args[1]);
|
||||||
|
case 2 -> plugin.getSprinklerManager().workModeTwo(args[1]);
|
||||||
|
case 3 -> plugin.getSprinklerManager().workModeThree(args[1]);
|
||||||
|
case 4 -> plugin.getSprinklerManager().workModeFour(args[1]);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
if (sender instanceof Player player){
|
if (sender instanceof Player player){
|
||||||
AdventureManager.playerMessage(player,ConfigReader.Message.prefix + ConfigReader.Message.forceWater.replace("{world}",args[1]));
|
AdventureManager.playerMessage(player,ConfigReader.Message.prefix + ConfigReader.Message.forceWater.replace("{world}",args[1]));
|
||||||
|
|||||||
@@ -18,8 +18,8 @@
|
|||||||
package net.momirealms.customcrops.datamanager;
|
package net.momirealms.customcrops.datamanager;
|
||||||
|
|
||||||
import dev.lone.itemsadder.api.CustomBlock;
|
import dev.lone.itemsadder.api.CustomBlock;
|
||||||
import dev.lone.itemsadder.api.CustomStack;
|
|
||||||
import net.momirealms.customcrops.fertilizer.QualityCrop;
|
import net.momirealms.customcrops.fertilizer.QualityCrop;
|
||||||
|
import net.momirealms.customcrops.listener.JoinAndQuit;
|
||||||
import net.momirealms.customcrops.utils.AdventureManager;
|
import net.momirealms.customcrops.utils.AdventureManager;
|
||||||
import net.momirealms.customcrops.ConfigReader;
|
import net.momirealms.customcrops.ConfigReader;
|
||||||
import net.momirealms.customcrops.CustomCrops;
|
import net.momirealms.customcrops.CustomCrops;
|
||||||
@@ -37,8 +37,8 @@ import org.bukkit.scheduler.BukkitScheduler;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ public class CropManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将hashmap中的数据保存到data中
|
* 将数据保存到data中
|
||||||
*/
|
*/
|
||||||
public void updateData(){
|
public void updateData(){
|
||||||
Cache.forEach((location, String) -> {
|
Cache.forEach((location, String) -> {
|
||||||
@@ -108,139 +108,157 @@ public class CropManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 农作物生长
|
* 农作物生长,Mode 1
|
||||||
|
* 仅加载区块生长
|
||||||
* @param worldName 进行生长判定的世界名
|
* @param worldName 进行生长判定的世界名
|
||||||
*/
|
*/
|
||||||
public void cropGrow(String worldName){
|
public void growModeOne(String worldName){
|
||||||
|
|
||||||
Long time1 = System.currentTimeMillis();
|
Long time1 = System.currentTimeMillis();
|
||||||
|
if(!ConfigReader.Config.allWorld){
|
||||||
updateData();
|
updateData();
|
||||||
Long time2 = System.currentTimeMillis();
|
|
||||||
if(ConfigReader.Config.logTime){
|
|
||||||
AdventureManager.consoleMessage("性能监测: 农作物数据更新" + (time2-time1) + "ms");
|
|
||||||
}
|
}
|
||||||
|
Long time2 = System.currentTimeMillis();
|
||||||
|
if(ConfigReader.Config.logTime) AdventureManager.consoleMessage("性能监测: 农作物数据更新" + (time2-time1) + "ms");
|
||||||
if (data.contains(worldName)){
|
if (data.contains(worldName)){
|
||||||
|
World world = Bukkit.getWorld(worldName);
|
||||||
data.getConfigurationSection(worldName).getKeys(false).forEach(chunk ->{
|
data.getConfigurationSection(worldName).getKeys(false).forEach(chunk ->{
|
||||||
String[] split = StringUtils.split(chunk,",");
|
String[] split = StringUtils.split(chunk,",");
|
||||||
World world = Bukkit.getWorld(worldName);
|
if (world.isChunkLoaded(Integer.parseInt(split[0]), Integer.parseInt(split[1]))){
|
||||||
if (ConfigReader.Config.onlyLoadedGrow || world.isChunkLoaded(Integer.parseInt(split[0]), Integer.parseInt(split[1]))){
|
|
||||||
data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> {
|
data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> {
|
||||||
String[] coordinate = StringUtils.split(key, ",");
|
String[] coordinate = StringUtils.split(key, ",");
|
||||||
Location seedLocation = new Location(world,Double.parseDouble(coordinate[0]),Double.parseDouble(coordinate[1]),Double.parseDouble(coordinate[2]));
|
Location seedLocation = new Location(world,Double.parseDouble(coordinate[0]),Double.parseDouble(coordinate[1]),Double.parseDouble(coordinate[2]));
|
||||||
CustomBlock seedBlock = CustomBlock.byAlreadyPlaced(seedLocation.getBlock());
|
if (growJudge(worldName, seedLocation)){
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
data.set(worldName + "." + chunk + "." + key, null);
|
||||||
stringBuilder.append(worldName).append(".").append(chunk).append(".").append(key);
|
|
||||||
if(seedBlock == null) {
|
|
||||||
data.set(stringBuilder.toString(), null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String namespacedID = seedBlock.getNamespacedID();
|
|
||||||
String id = seedBlock.getId();
|
|
||||||
if(namespacedID.equals(ConfigReader.Basic.dead)) {
|
|
||||||
data.set(stringBuilder.toString(), null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(!namespacedID.contains("_stage_")) {
|
|
||||||
data.set(stringBuilder.toString(), null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Location potLocation = seedLocation.clone().subtract(0,1,0);
|
|
||||||
CustomBlock pot = CustomBlock.byAlreadyPlaced(potLocation.getBlock());
|
|
||||||
String potNamespacedID = pot.getNamespacedID();
|
|
||||||
String[] cropNameList = StringUtils.split(id,"_");
|
|
||||||
CropInstance cropInstance = ConfigReader.CROPS.get(cropNameList[0]);
|
|
||||||
if (pot == null || cropInstance == null){
|
|
||||||
data.set(stringBuilder.toString(), null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int random = new Random().nextInt(ConfigReader.Config.timeToGrow);
|
|
||||||
if (potNamespacedID.equals(ConfigReader.Basic.watered_pot)){
|
|
||||||
//如果启用季节限制且农作物有季节需求
|
|
||||||
if (ConfigReader.Season.enable && cropInstance.getSeasons() != null){
|
|
||||||
if (isWrongSeason(seedLocation, cropInstance.getSeasons(), worldName)){
|
|
||||||
data.set(stringBuilder.toString(), null);
|
|
||||||
bukkitScheduler.runTaskLater(CustomCrops.instance, () -> {
|
|
||||||
CustomBlock.remove(seedLocation);
|
|
||||||
CustomBlock.place(ConfigReader.Basic.dead, seedLocation);
|
|
||||||
}, random);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int nextStage = Integer.parseInt(cropNameList[2]) + 1;
|
|
||||||
if (CustomBlock.getInstance(StringUtils.chop(namespacedID) + nextStage) != null && cropInstance.getGrowChance() > Math.random()) {
|
|
||||||
Fertilizer fertilizer = PotManager.Cache.get(SimpleLocation.fromLocation(potLocation));
|
|
||||||
if (fertilizer != null){
|
|
||||||
int times = fertilizer.getTimes();
|
|
||||||
if (times > 0){
|
|
||||||
fertilizer.setTimes(times - 1);
|
|
||||||
if (fertilizer instanceof SpeedGrow speedGrow){
|
|
||||||
if (Math.random() < speedGrow.getChance() && CustomBlock.getInstance(StringUtils.chop(namespacedID) + (nextStage + 1)) != null){
|
|
||||||
addStage(potLocation, seedLocation, namespacedID, nextStage + 1, random);
|
|
||||||
}else {
|
|
||||||
addStage(potLocation, seedLocation, namespacedID, nextStage, random);
|
|
||||||
}
|
|
||||||
}else if(fertilizer instanceof RetainingSoil retainingSoil){
|
|
||||||
if (Math.random() < retainingSoil.getChance()){
|
|
||||||
addStage(seedLocation, namespacedID, nextStage, random);
|
|
||||||
}else {
|
|
||||||
addStage(potLocation, seedLocation, namespacedID, nextStage, random);
|
|
||||||
}
|
|
||||||
}else if(fertilizer instanceof QualityCrop){
|
|
||||||
addStage(potLocation, seedLocation, namespacedID, nextStage, random);
|
|
||||||
}else {
|
|
||||||
AdventureManager.consoleMessage("<red>[CustomCrops] 发现未知类型肥料,已自动清除错误数据!</red>");
|
|
||||||
PotManager.Cache.remove(SimpleLocation.fromLocation(potLocation));
|
|
||||||
}
|
|
||||||
}else {
|
|
||||||
PotManager.Cache.remove(SimpleLocation.fromLocation(potLocation));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
addStage(potLocation, seedLocation, namespacedID, nextStage, random);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(cropInstance.getGiant() != null){
|
|
||||||
bukkitScheduler.runTaskLater(CustomCrops.instance, () ->{
|
|
||||||
CustomBlock.remove(potLocation);
|
|
||||||
CustomBlock.place(ConfigReader.Basic.pot, potLocation);
|
|
||||||
if(cropInstance.getGiantChance() > Math.random()){
|
|
||||||
data.set(stringBuilder.toString(), null);
|
|
||||||
CustomBlock.remove(seedLocation);
|
|
||||||
CustomBlock.place(cropInstance.getGiant(), seedLocation);
|
|
||||||
}
|
|
||||||
}, random);
|
|
||||||
}else {
|
|
||||||
if (!ConfigReader.Season.enable) data.set(stringBuilder.toString(), null);
|
|
||||||
bukkitScheduler.runTaskLater(CustomCrops.instance, () -> {
|
|
||||||
CustomBlock.remove(potLocation);
|
|
||||||
CustomBlock.place(ConfigReader.Basic.pot, potLocation);
|
|
||||||
}, random);
|
|
||||||
}
|
|
||||||
}else if(potNamespacedID.equals(ConfigReader.Basic.pot)){
|
|
||||||
if(!ConfigReader.Season.enable || cropInstance.getSeasons() == null) return;
|
|
||||||
if(isWrongSeason(seedLocation, cropInstance.getSeasons(), worldName)){
|
|
||||||
data.set(stringBuilder.toString(), null);
|
|
||||||
bukkitScheduler.runTaskLater(CustomCrops.instance, () -> {
|
|
||||||
CustomBlock.remove(seedLocation);
|
|
||||||
CustomBlock.place(ConfigReader.Basic.dead, seedLocation);
|
|
||||||
}, random);
|
|
||||||
}
|
|
||||||
}else {
|
|
||||||
data.set(stringBuilder.toString(), null);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Long time3 = System.currentTimeMillis();
|
Long time3 = System.currentTimeMillis();
|
||||||
if(ConfigReader.Config.logTime){
|
if(ConfigReader.Config.logTime) AdventureManager.consoleMessage("性能监测: 农作物生长过程" + (time3-time2) + "ms");
|
||||||
AdventureManager.consoleMessage("性能监测: 农作物生长过程" + (time3-time2) + "ms");
|
if(!ConfigReader.Config.allWorld){
|
||||||
}
|
|
||||||
saveData();
|
saveData();
|
||||||
Long time4 = System.currentTimeMillis();
|
|
||||||
if(ConfigReader.Config.logTime){
|
|
||||||
AdventureManager.consoleMessage("性能监测: 农作物数据保存" + (time4-time3) + "ms");
|
|
||||||
}
|
}
|
||||||
|
Long time4 = System.currentTimeMillis();
|
||||||
|
if(ConfigReader.Config.logTime) AdventureManager.consoleMessage("性能监测: 农作物数据保存" + (time4-time3) + "ms");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 农作物生长,Mode 2
|
||||||
|
* 仅在线玩家的农作物生长
|
||||||
|
* @param worldName 进行生长判定的世界名
|
||||||
|
*/
|
||||||
|
public void growModeTwo(String worldName){
|
||||||
|
Long time1 = System.currentTimeMillis();
|
||||||
|
if(!ConfigReader.Config.allWorld){
|
||||||
|
updateData();
|
||||||
|
}
|
||||||
|
Long time2 = System.currentTimeMillis();
|
||||||
|
if(ConfigReader.Config.logTime) AdventureManager.consoleMessage("性能监测: 农作物数据更新" + (time2-time1) + "ms");
|
||||||
|
HashSet<String> players = new HashSet<>(JoinAndQuit.onlinePlayers);
|
||||||
|
if (data.contains(worldName)){
|
||||||
|
World world = Bukkit.getWorld(worldName);
|
||||||
|
data.getConfigurationSection(worldName).getKeys(false).forEach(chunk ->{
|
||||||
|
data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> {
|
||||||
|
if (!players.contains(value)) return;
|
||||||
|
String[] coordinate = StringUtils.split(key, ",");
|
||||||
|
Location seedLocation = new Location(world,Double.parseDouble(coordinate[0]),Double.parseDouble(coordinate[1]),Double.parseDouble(coordinate[2]));
|
||||||
|
if (growJudge(worldName, seedLocation)){
|
||||||
|
data.set(worldName + "." + chunk + "." + key, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Long time3 = System.currentTimeMillis();
|
||||||
|
if(ConfigReader.Config.logTime) AdventureManager.consoleMessage("性能监测: 农作物生长过程" + (time3-time2) + "ms");
|
||||||
|
if(!ConfigReader.Config.allWorld){
|
||||||
|
saveData();
|
||||||
|
}
|
||||||
|
Long time4 = System.currentTimeMillis();
|
||||||
|
if(ConfigReader.Config.logTime) AdventureManager.consoleMessage("性能监测: 农作物数据保存" + (time4-time3) + "ms");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 农作物生长,Mode 3
|
||||||
|
* 仅在线玩家和加载区块的农作物生长
|
||||||
|
* @param worldName 进行生长判定的世界名
|
||||||
|
*/
|
||||||
|
public void growModeThree(String worldName){
|
||||||
|
Long time1 = System.currentTimeMillis();
|
||||||
|
if(!ConfigReader.Config.allWorld){
|
||||||
|
updateData();
|
||||||
|
}
|
||||||
|
Long time2 = System.currentTimeMillis();
|
||||||
|
if(ConfigReader.Config.logTime) AdventureManager.consoleMessage("性能监测: 农作物数据更新" + (time2-time1) + "ms");
|
||||||
|
HashSet<String> players = new HashSet<>(JoinAndQuit.onlinePlayers);
|
||||||
|
if (data.contains(worldName)){
|
||||||
|
World world = Bukkit.getWorld(worldName);
|
||||||
|
data.getConfigurationSection(worldName).getKeys(false).forEach(chunk ->{
|
||||||
|
String[] split = StringUtils.split(chunk,",");
|
||||||
|
//区块被加载,则强行生长判定
|
||||||
|
if (world.isChunkLoaded(Integer.parseInt(split[0]), Integer.parseInt(split[1]))){
|
||||||
|
data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> {
|
||||||
|
String[] coordinate = StringUtils.split(key, ",");
|
||||||
|
Location seedLocation = new Location(world,Double.parseDouble(coordinate[0]),Double.parseDouble(coordinate[1]),Double.parseDouble(coordinate[2]));
|
||||||
|
if (growJudge(worldName, seedLocation)){
|
||||||
|
data.set(worldName + "." + chunk + "." + key, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//区块未加载,玩家在线
|
||||||
|
else{
|
||||||
|
data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> {
|
||||||
|
if (!players.contains(value)) return;
|
||||||
|
String[] coordinate = StringUtils.split(key, ",");
|
||||||
|
Location seedLocation = new Location(world,Double.parseDouble(coordinate[0]),Double.parseDouble(coordinate[1]),Double.parseDouble(coordinate[2]));
|
||||||
|
if (growJudge(worldName, seedLocation)){
|
||||||
|
data.set(worldName + "." + chunk + "." + key, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Long time3 = System.currentTimeMillis();
|
||||||
|
if(ConfigReader.Config.logTime) AdventureManager.consoleMessage("性能监测: 农作物生长过程" + (time3-time2) + "ms");
|
||||||
|
if(!ConfigReader.Config.allWorld){
|
||||||
|
saveData();
|
||||||
|
}
|
||||||
|
Long time4 = System.currentTimeMillis();
|
||||||
|
if(ConfigReader.Config.logTime) AdventureManager.consoleMessage("性能监测: 农作物数据保存" + (time4-time3) + "ms");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 农作物生长,Mode 4
|
||||||
|
* 全部农作物生长
|
||||||
|
* @param worldName 进行生长判定的世界名
|
||||||
|
*/
|
||||||
|
public void growModeFour(String worldName){
|
||||||
|
Long time1 = System.currentTimeMillis();
|
||||||
|
if(!ConfigReader.Config.allWorld){
|
||||||
|
updateData();
|
||||||
|
}
|
||||||
|
Long time2 = System.currentTimeMillis();
|
||||||
|
if(ConfigReader.Config.logTime) AdventureManager.consoleMessage("性能监测: 农作物数据更新" + (time2-time1) + "ms");
|
||||||
|
if (data.contains(worldName)){
|
||||||
|
World world = Bukkit.getWorld(worldName);
|
||||||
|
data.getConfigurationSection(worldName).getKeys(false).forEach(chunk ->{
|
||||||
|
String[] split = StringUtils.split(chunk,",");
|
||||||
|
data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> {
|
||||||
|
String[] coordinate = StringUtils.split(key, ",");
|
||||||
|
Location seedLocation = new Location(world,Double.parseDouble(coordinate[0]),Double.parseDouble(coordinate[1]),Double.parseDouble(coordinate[2]));
|
||||||
|
if (growJudge(worldName, seedLocation)){
|
||||||
|
data.set(worldName + "." + chunk + "." + key, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Long time3 = System.currentTimeMillis();
|
||||||
|
if(ConfigReader.Config.logTime) AdventureManager.consoleMessage("性能监测: 农作物生长过程" + (time3-time2) + "ms");
|
||||||
|
if(!ConfigReader.Config.allWorld){
|
||||||
|
saveData();
|
||||||
|
}
|
||||||
|
Long time4 = System.currentTimeMillis();
|
||||||
|
if(ConfigReader.Config.logTime) AdventureManager.consoleMessage("性能监测: 农作物数据保存" + (time4-time3) + "ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -248,135 +266,198 @@ public class CropManager {
|
|||||||
* 对于使用动态加载世界的服务器有效
|
* 对于使用动态加载世界的服务器有效
|
||||||
*/
|
*/
|
||||||
public void cropGrowAll(){
|
public void cropGrowAll(){
|
||||||
Long time1 = System.currentTimeMillis();
|
|
||||||
updateData();
|
updateData();
|
||||||
Long time2 = System.currentTimeMillis();
|
List<World> worlds = Bukkit.getWorlds();
|
||||||
if(ConfigReader.Config.logTime){
|
for (int i = 0; i < worlds.size(); i++){
|
||||||
AdventureManager.consoleMessage("性能监测: 农作物数据更新" + (time2-time1) + "ms");
|
String worldName = worlds.get(i).getName();
|
||||||
|
bukkitScheduler.runTaskLaterAsynchronously(CustomCrops.instance, () -> {
|
||||||
|
switch (ConfigReader.Config.growMode){
|
||||||
|
case 1 -> growModeOne(worldName);
|
||||||
|
case 2 -> growModeTwo(worldName);
|
||||||
|
case 3 -> growModeThree(worldName);
|
||||||
|
case 4 -> growModeFour(worldName);
|
||||||
}
|
}
|
||||||
Bukkit.getWorlds().forEach(world -> {
|
}, i * 40L);
|
||||||
String worldName = world.getName();
|
}
|
||||||
if (data.contains(worldName)){
|
saveData();
|
||||||
data.getConfigurationSection(worldName).getKeys(false).forEach(chunk ->{
|
}
|
||||||
String[] split = StringUtils.split(chunk,",");
|
|
||||||
if (ConfigReader.Config.onlyLoadedGrow || world.isChunkLoaded(Integer.parseInt(split[0]), Integer.parseInt(split[1]))){
|
/**
|
||||||
data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> {
|
* 对某个位置进行生长判定
|
||||||
String[] coordinate = StringUtils.split(key, ",");
|
* @param worldName 世界名
|
||||||
Location seedLocation = new Location(world,Double.parseDouble(coordinate[0]),Double.parseDouble(coordinate[1]),Double.parseDouble(coordinate[2]));
|
* @param seedLocation 种子位置
|
||||||
|
* @return 是否消除数据
|
||||||
|
*/
|
||||||
|
private boolean growJudge(String worldName, Location seedLocation) {
|
||||||
CustomBlock seedBlock = CustomBlock.byAlreadyPlaced(seedLocation.getBlock());
|
CustomBlock seedBlock = CustomBlock.byAlreadyPlaced(seedLocation.getBlock());
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
//自定义农作物方块不存在
|
||||||
stringBuilder.append(worldName).append(".").append(chunk).append(".").append(key);
|
|
||||||
if(seedBlock == null) {
|
if(seedBlock == null) {
|
||||||
data.set(stringBuilder.toString(), null);
|
return true;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
String namespacedID = seedBlock.getNamespacedID();
|
String namespacedID = seedBlock.getNamespacedID();
|
||||||
String id = seedBlock.getId();
|
String id = seedBlock.getId();
|
||||||
if(namespacedID.equals(ConfigReader.Basic.dead)) {
|
//已死亡或不是农作物
|
||||||
data.set(stringBuilder.toString(), null);
|
if(namespacedID.equals(ConfigReader.Basic.dead) || !namespacedID.contains("_stage_")) {
|
||||||
return;
|
return true;
|
||||||
}
|
|
||||||
if(!namespacedID.contains("_stage_")) {
|
|
||||||
data.set(stringBuilder.toString(), null);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
//农作物下方自定义方块不存在
|
||||||
Location potLocation = seedLocation.clone().subtract(0,1,0);
|
Location potLocation = seedLocation.clone().subtract(0,1,0);
|
||||||
CustomBlock pot = CustomBlock.byAlreadyPlaced(potLocation.getBlock());
|
CustomBlock pot = CustomBlock.byAlreadyPlaced(potLocation.getBlock());
|
||||||
String potNamespacedID = pot.getNamespacedID();
|
if (pot == null){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//农作物实例不存在
|
||||||
String[] cropNameList = StringUtils.split(id,"_");
|
String[] cropNameList = StringUtils.split(id,"_");
|
||||||
CropInstance cropInstance = ConfigReader.CROPS.get(cropNameList[0]);
|
CropInstance cropInstance = ConfigReader.CROPS.get(cropNameList[0]);
|
||||||
if (pot == null || cropInstance == null){
|
if (cropInstance == null){
|
||||||
data.set(stringBuilder.toString(), null);
|
return true;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
int random = new Random().nextInt(ConfigReader.Config.timeToGrow);
|
//获取自定义方块ID
|
||||||
|
String potNamespacedID = pot.getNamespacedID();
|
||||||
if (potNamespacedID.equals(ConfigReader.Basic.watered_pot)){
|
if (potNamespacedID.equals(ConfigReader.Basic.watered_pot)){
|
||||||
|
int random = new Random().nextInt(ConfigReader.Config.timeToGrow);
|
||||||
|
//如果启用季节限制且农作物有季节需求
|
||||||
if (ConfigReader.Season.enable && cropInstance.getSeasons() != null){
|
if (ConfigReader.Season.enable && cropInstance.getSeasons() != null){
|
||||||
if (isWrongSeason(seedLocation, cropInstance.getSeasons(), worldName)){
|
if (isWrongSeason(seedLocation, cropInstance.getSeasons(), worldName)){
|
||||||
data.set(stringBuilder.toString(), null);
|
|
||||||
bukkitScheduler.runTaskLater(CustomCrops.instance, () -> {
|
bukkitScheduler.runTaskLater(CustomCrops.instance, () -> {
|
||||||
CustomBlock.remove(seedLocation);
|
CustomBlock.remove(seedLocation);
|
||||||
CustomBlock.place(ConfigReader.Basic.dead, seedLocation);
|
CustomBlock.place(ConfigReader.Basic.dead, seedLocation);
|
||||||
}, random);
|
}, random);
|
||||||
return;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//获取下一阶段
|
||||||
int nextStage = Integer.parseInt(cropNameList[2]) + 1;
|
int nextStage = Integer.parseInt(cropNameList[2]) + 1;
|
||||||
if (CustomBlock.getInstance(StringUtils.chop(namespacedID) + nextStage) != null && cropInstance.getGrowChance() > Math.random()) {
|
//下一阶段存在
|
||||||
|
if (CustomBlock.getInstance(StringUtils.chop(namespacedID) + nextStage) != null) {
|
||||||
|
//尝试获取肥料类型
|
||||||
Fertilizer fertilizer = PotManager.Cache.get(SimpleLocation.fromLocation(potLocation));
|
Fertilizer fertilizer = PotManager.Cache.get(SimpleLocation.fromLocation(potLocation));
|
||||||
|
//有肥料
|
||||||
if (fertilizer != null){
|
if (fertilizer != null){
|
||||||
|
//查询剩余使用次数
|
||||||
int times = fertilizer.getTimes();
|
int times = fertilizer.getTimes();
|
||||||
if (times > 0){
|
if (times > 0){
|
||||||
fertilizer.setTimes(times - 1);
|
fertilizer.setTimes(times - 1);
|
||||||
|
//生长激素
|
||||||
if (fertilizer instanceof SpeedGrow speedGrow){
|
if (fertilizer instanceof SpeedGrow speedGrow){
|
||||||
|
if (cropInstance.getGrowChance() > Math.random()){
|
||||||
|
//农作物存在下两个阶段
|
||||||
if (Math.random() < speedGrow.getChance() && CustomBlock.getInstance(StringUtils.chop(namespacedID) + (nextStage + 1)) != null){
|
if (Math.random() < speedGrow.getChance() && CustomBlock.getInstance(StringUtils.chop(namespacedID) + (nextStage + 1)) != null){
|
||||||
addStage(potLocation, seedLocation, namespacedID, nextStage + 1, random);
|
addStage(potLocation, seedLocation, namespacedID, nextStage + 1, random);
|
||||||
}else {
|
}else {
|
||||||
addStage(potLocation, seedLocation, namespacedID, nextStage, random);
|
addStage(potLocation, seedLocation, namespacedID, nextStage, random);
|
||||||
}
|
}
|
||||||
}else if(fertilizer instanceof RetainingSoil retainingSoil){
|
}else {
|
||||||
|
notAddStage(potLocation, random);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//保湿土壤
|
||||||
|
else if(fertilizer instanceof RetainingSoil retainingSoil){
|
||||||
if (Math.random() < retainingSoil.getChance()){
|
if (Math.random() < retainingSoil.getChance()){
|
||||||
|
if (cropInstance.getGrowChance() > Math.random()){
|
||||||
addStage(seedLocation, namespacedID, nextStage, random);
|
addStage(seedLocation, namespacedID, nextStage, random);
|
||||||
}else {
|
|
||||||
addStage(potLocation, seedLocation, namespacedID, nextStage, random);
|
|
||||||
}
|
}
|
||||||
}else if(fertilizer instanceof QualityCrop){
|
}else {
|
||||||
|
if (cropInstance.getGrowChance() > Math.random()){
|
||||||
addStage(potLocation, seedLocation, namespacedID, nextStage, random);
|
addStage(potLocation, seedLocation, namespacedID, nextStage, random);
|
||||||
}else {
|
}else {
|
||||||
AdventureManager.consoleMessage("<red>[CustomCrops] 发现未知类型肥料,已自动清除错误数据!</red>");
|
notAddStage(potLocation, random);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//品质肥料
|
||||||
|
else if(fertilizer instanceof QualityCrop){
|
||||||
|
if (cropInstance.getGrowChance() > Math.random()){
|
||||||
|
addStage(potLocation, seedLocation, namespacedID, nextStage, random);
|
||||||
|
}else {
|
||||||
|
notAddStage(potLocation, random);
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
//未知肥料类型处理
|
||||||
|
AdventureManager.consoleMessage("<red>[CustomCrops] Unknown fertilizer, Auto removed!</red>");
|
||||||
PotManager.Cache.remove(SimpleLocation.fromLocation(potLocation));
|
PotManager.Cache.remove(SimpleLocation.fromLocation(potLocation));
|
||||||
}
|
|
||||||
|
if (cropInstance.getGrowChance() > Math.random()){
|
||||||
|
addStage(potLocation, seedLocation, namespacedID, nextStage, random);
|
||||||
}else {
|
}else {
|
||||||
|
notAddStage(potLocation, random);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//肥料的最后一次使用
|
||||||
|
if (times == 1){
|
||||||
PotManager.Cache.remove(SimpleLocation.fromLocation(potLocation));
|
PotManager.Cache.remove(SimpleLocation.fromLocation(potLocation));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
//移除肥料信息,一般不会出现此情况
|
||||||
|
PotManager.Cache.remove(SimpleLocation.fromLocation(potLocation));
|
||||||
|
if (cropInstance.getGrowChance() > Math.random()){
|
||||||
addStage(potLocation, seedLocation, namespacedID, nextStage, random);
|
addStage(potLocation, seedLocation, namespacedID, nextStage, random);
|
||||||
|
}else {
|
||||||
|
notAddStage(potLocation, random);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
//没有肥料
|
||||||
|
else {
|
||||||
|
if (cropInstance.getGrowChance() > Math.random()){
|
||||||
|
addStage(potLocation, seedLocation, namespacedID, nextStage, random);
|
||||||
|
}else {
|
||||||
|
notAddStage(potLocation, random);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//农作物是否存在巨大化
|
||||||
else if(cropInstance.getGiant() != null){
|
else if(cropInstance.getGiant() != null){
|
||||||
|
//巨大化判定
|
||||||
|
if (cropInstance.getGiantChance() > Math.random()){
|
||||||
|
//成功巨大化,移除数据
|
||||||
|
bukkitScheduler.runTaskLater(CustomCrops.instance, () ->{
|
||||||
|
CustomBlock.remove(seedLocation);
|
||||||
|
CustomBlock.place(cropInstance.getGiant(), seedLocation);
|
||||||
|
CustomBlock.remove(potLocation);
|
||||||
|
CustomBlock.place(ConfigReader.Basic.pot, potLocation);
|
||||||
|
}, random);
|
||||||
|
return true;
|
||||||
|
}else {
|
||||||
|
//失败,转湿为干
|
||||||
bukkitScheduler.runTaskLater(CustomCrops.instance, () ->{
|
bukkitScheduler.runTaskLater(CustomCrops.instance, () ->{
|
||||||
CustomBlock.remove(potLocation);
|
CustomBlock.remove(potLocation);
|
||||||
CustomBlock.place(ConfigReader.Basic.pot, potLocation);
|
CustomBlock.place(ConfigReader.Basic.pot, potLocation);
|
||||||
if(cropInstance.getGiantChance() > Math.random()){
|
|
||||||
data.set(stringBuilder.toString(), null);
|
|
||||||
CustomBlock.remove(seedLocation);
|
|
||||||
CustomBlock.place(cropInstance.getGiant(), seedLocation);
|
|
||||||
}
|
|
||||||
}, random);
|
}, random);
|
||||||
|
}
|
||||||
}else {
|
}else {
|
||||||
if (!ConfigReader.Season.enable) data.set(stringBuilder.toString(), null);
|
//若无下一阶段,无巨大化,未启用季节,则移除无用数据
|
||||||
|
if (!ConfigReader.Season.enable) return true;
|
||||||
bukkitScheduler.runTaskLater(CustomCrops.instance, () -> {
|
bukkitScheduler.runTaskLater(CustomCrops.instance, () -> {
|
||||||
CustomBlock.remove(potLocation);
|
CustomBlock.remove(potLocation);
|
||||||
CustomBlock.place(ConfigReader.Basic.pot, potLocation);
|
CustomBlock.place(ConfigReader.Basic.pot, potLocation);
|
||||||
}, random);
|
}, random);
|
||||||
}
|
}
|
||||||
}else if(potNamespacedID.equals(ConfigReader.Basic.pot)){
|
}
|
||||||
if(!ConfigReader.Season.enable || cropInstance.getSeasons() == null) return;
|
//干燥的种植盆
|
||||||
if(isWrongSeason(seedLocation, cropInstance.getSeasons(), worldName)){
|
else if(potNamespacedID.equals(ConfigReader.Basic.pot)){
|
||||||
data.set(stringBuilder.toString(), null);
|
//未启用季节
|
||||||
|
if(!ConfigReader.Season.enable) return false;
|
||||||
|
//农作物无视季节
|
||||||
|
List<String> seasons = cropInstance.getSeasons();
|
||||||
|
if(seasons == null) return false;
|
||||||
|
//错误季节
|
||||||
|
if(isWrongSeason(seedLocation, seasons, worldName)){
|
||||||
bukkitScheduler.runTaskLater(CustomCrops.instance, () -> {
|
bukkitScheduler.runTaskLater(CustomCrops.instance, () -> {
|
||||||
CustomBlock.remove(seedLocation);
|
CustomBlock.remove(seedLocation);
|
||||||
CustomBlock.place(ConfigReader.Basic.dead, seedLocation);
|
CustomBlock.place(ConfigReader.Basic.dead, seedLocation);
|
||||||
}, random);
|
}, new Random().nextInt(ConfigReader.Config.timeToGrow));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}else {
|
|
||||||
data.set(stringBuilder.toString(), null);
|
|
||||||
}
|
}
|
||||||
});
|
//不是种植盆
|
||||||
}
|
else {
|
||||||
});
|
return true;
|
||||||
}
|
|
||||||
});
|
|
||||||
Long time3 = System.currentTimeMillis();
|
|
||||||
if(ConfigReader.Config.logTime){
|
|
||||||
AdventureManager.consoleMessage("性能监测: 农作物生长过程" + (time3-time2) + "ms");
|
|
||||||
}
|
|
||||||
saveData();
|
|
||||||
Long time4 = System.currentTimeMillis();
|
|
||||||
if(ConfigReader.Config.logTime){
|
|
||||||
AdventureManager.consoleMessage("性能监测: 农作物数据保存" + (time4-time3) + "ms");
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -444,4 +525,16 @@ public class CropManager {
|
|||||||
CustomBlock.place(stage, seedLocation);
|
CustomBlock.place(stage, seedLocation);
|
||||||
}, random);
|
}, random);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 停滞阶段(消耗水)
|
||||||
|
* @param potLocation 种植盆位置
|
||||||
|
* @param random 随机生长时间
|
||||||
|
*/
|
||||||
|
private void notAddStage(Location potLocation, int random){
|
||||||
|
bukkitScheduler.runTaskLater(CustomCrops.instance, () ->{
|
||||||
|
CustomBlock.remove(potLocation);
|
||||||
|
CustomBlock.place(ConfigReader.Basic.pot, potLocation);
|
||||||
|
}, random);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package net.momirealms.customcrops.datamanager;
|
|
||||||
|
|
||||||
public class MushroomManager {
|
|
||||||
|
|
||||||
//A new feature coming
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -18,10 +18,12 @@
|
|||||||
package net.momirealms.customcrops.datamanager;
|
package net.momirealms.customcrops.datamanager;
|
||||||
|
|
||||||
import dev.lone.itemsadder.api.CustomBlock;
|
import dev.lone.itemsadder.api.CustomBlock;
|
||||||
|
import net.momirealms.customcrops.listener.JoinAndQuit;
|
||||||
import net.momirealms.customcrops.utils.AdventureManager;
|
import net.momirealms.customcrops.utils.AdventureManager;
|
||||||
import net.momirealms.customcrops.ConfigReader;
|
import net.momirealms.customcrops.ConfigReader;
|
||||||
import net.momirealms.customcrops.CustomCrops;
|
import net.momirealms.customcrops.CustomCrops;
|
||||||
import net.momirealms.customcrops.utils.IAFurniture;
|
import net.momirealms.customcrops.utils.IAFurniture;
|
||||||
|
import net.momirealms.customcrops.utils.SimpleLocation;
|
||||||
import net.momirealms.customcrops.utils.Sprinkler;
|
import net.momirealms.customcrops.utils.Sprinkler;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@@ -33,13 +35,19 @@ import org.bukkit.scheduler.BukkitScheduler;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Random;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
public class SprinklerManager {
|
public class SprinklerManager {
|
||||||
|
|
||||||
public YamlConfiguration data;
|
public YamlConfiguration data;
|
||||||
public static ConcurrentHashMap<Location, Sprinkler> Cache = new ConcurrentHashMap<>();
|
public static ConcurrentHashMap<SimpleLocation, Sprinkler> Cache = new ConcurrentHashMap<>();
|
||||||
|
public static HashSet<SimpleLocation> RemoveCache = new HashSet<>();
|
||||||
|
private final BukkitScheduler bukkitScheduler;
|
||||||
|
|
||||||
|
public SprinklerManager(){
|
||||||
|
this.bukkitScheduler = Bukkit.getScheduler();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 载入数据
|
* 载入数据
|
||||||
@@ -85,48 +93,55 @@ public class SprinklerManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将hashmap中的数据保存到data中
|
* 将数据保存到data中
|
||||||
*/
|
*/
|
||||||
public void updateData(){
|
public void updateData(){
|
||||||
Cache.forEach((location, sprinklerData) -> {
|
Cache.forEach((location, sprinklerData) -> {
|
||||||
String world = location.getWorld().getName();
|
String world = location.getWorldName();
|
||||||
int x = location.getBlockX();
|
int x = location.getX();
|
||||||
int z = location.getBlockZ();
|
int z = location.getZ();
|
||||||
StringBuilder stringBuilder = new StringBuilder().append(world).append(".").append(x/16).append(",").append(z/16).append(".").append(x).append(",").append(location.getBlockY()).append(",").append(z);
|
StringBuilder stringBuilder = new StringBuilder().append(world).append(".").append(x/16).append(",").append(z/16).append(".").append(x).append(",").append(location.getY()).append(",").append(z);
|
||||||
data.set(stringBuilder+".range", sprinklerData.getRange());
|
data.set(stringBuilder+".range", sprinklerData.getRange());
|
||||||
data.set(stringBuilder+".water", sprinklerData.getWater());
|
data.set(stringBuilder+".water", sprinklerData.getWater());
|
||||||
|
data.set(stringBuilder+".player", Optional.ofNullable(sprinklerData.getPlayer()).orElse("none"));
|
||||||
});
|
});
|
||||||
Cache.clear();
|
Cache.clear();
|
||||||
|
HashSet<SimpleLocation> set = new HashSet<>(RemoveCache);
|
||||||
|
for (SimpleLocation location : set) {
|
||||||
|
String world = location.getWorldName();
|
||||||
|
int x = location.getX();
|
||||||
|
int z = location.getZ();
|
||||||
|
data.set(world + "." + x / 16 + "," + z / 16 + "." + x + "," + location.getY() + "," + z, null);
|
||||||
|
}
|
||||||
|
RemoveCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 指定世界的洒水器工作
|
* 洒水器工作,Mode 1
|
||||||
* @param worldName 世界名
|
* @param worldName 世界名
|
||||||
*/
|
*/
|
||||||
public void sprinklerWork(String worldName){
|
public void workModeOne(String worldName){
|
||||||
Long time1 = System.currentTimeMillis();
|
Long time1 = System.currentTimeMillis();
|
||||||
|
if(!ConfigReader.Config.allWorld){
|
||||||
updateData();
|
updateData();
|
||||||
Long time2 = System.currentTimeMillis();
|
|
||||||
if (ConfigReader.Config.logTime){
|
|
||||||
AdventureManager.consoleMessage("性能监测: 洒水器数据更新" + (time2-time1) + "ms");
|
|
||||||
}
|
}
|
||||||
|
Long time2 = System.currentTimeMillis();
|
||||||
|
if (ConfigReader.Config.logTime) AdventureManager.consoleMessage("性能监测: 洒水器数据更新" + (time2-time1) + "ms");
|
||||||
if (data.contains(worldName)){
|
if (data.contains(worldName)){
|
||||||
BukkitScheduler bukkitScheduler = Bukkit.getScheduler();
|
World world = Bukkit.getWorld(worldName);
|
||||||
data.getConfigurationSection(worldName).getKeys(false).forEach(chunk ->{
|
data.getConfigurationSection(worldName).getKeys(false).forEach(chunk ->{
|
||||||
String[] split = StringUtils.split(chunk,",");
|
String[] split = StringUtils.split(chunk,",");
|
||||||
World world = Bukkit.getWorld(worldName);
|
if (world.isChunkLoaded(Integer.parseInt(split[0]), Integer.parseInt(split[1]))) {
|
||||||
if (ConfigReader.Config.onlyLoadedGrow || world.isChunkLoaded(Integer.parseInt(split[0]), Integer.parseInt(split[1]))) {
|
|
||||||
data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> {
|
data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> {
|
||||||
String[] coordinate = StringUtils.split(key, ",");
|
String[] coordinate = StringUtils.split(key, ",");
|
||||||
Location location = new Location(world,Double.parseDouble(coordinate[0])+0.5,Double.parseDouble(coordinate[1])+0.5,Double.parseDouble(coordinate[2])+0.5);
|
Location location = new Location(world,Double.parseDouble(coordinate[0])+0.5,Double.parseDouble(coordinate[1])+0.5,Double.parseDouble(coordinate[2])+0.5);
|
||||||
int random = new Random().nextInt(ConfigReader.Config.timeToWork);
|
|
||||||
if (value instanceof MemorySection map){
|
if (value instanceof MemorySection map){
|
||||||
bukkitScheduler.callSyncMethod(CustomCrops.instance, ()->{
|
bukkitScheduler.runTask(CustomCrops.instance, ()->{
|
||||||
int water = (int) map.get("water");
|
int water = (int) map.get("water");
|
||||||
int range = (int) map.get("range");
|
int range = (int) map.get("range");
|
||||||
if(!IAFurniture.getFromLocation(location, world)){
|
if(!IAFurniture.getFromLocation(location, world)){
|
||||||
data.set(worldName + "." + chunk + "." + key, null);
|
data.set(worldName + "." + chunk + "." + key, null);
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
if (water > 0){
|
if (water > 0){
|
||||||
data.set(worldName + "." + chunk + "." + key + ".water", water - 1);
|
data.set(worldName + "." + chunk + "." + key + ".water", water - 1);
|
||||||
@@ -136,10 +151,9 @@ public class SprinklerManager {
|
|||||||
waterPot(location.clone().add(i,-1,j));
|
waterPot(location.clone().add(i,-1,j));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, random);
|
}, new Random().nextInt(ConfigReader.Config.timeToWork));
|
||||||
}
|
}
|
||||||
if (range == 0) data.set(worldName + "." + chunk + "." + key, null);
|
if (range == 0) data.set(worldName + "." + chunk + "." + key, null);
|
||||||
return null;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -147,73 +161,211 @@ public class SprinklerManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
Long time3 = System.currentTimeMillis();
|
Long time3 = System.currentTimeMillis();
|
||||||
if(ConfigReader.Config.logTime){
|
if(ConfigReader.Config.logTime) AdventureManager.consoleMessage("性能监测: 洒水器工作过程" + (time3-time2) + "ms");
|
||||||
AdventureManager.consoleMessage("性能监测: 洒水器工作过程" + (time3-time2) + "ms");
|
if(!ConfigReader.Config.allWorld){
|
||||||
}
|
|
||||||
saveData();
|
saveData();
|
||||||
Long time4 = System.currentTimeMillis();
|
|
||||||
if(ConfigReader.Config.logTime){
|
|
||||||
AdventureManager.consoleMessage("性能监测: 洒水器数据保存" + (time4-time3) + "ms");
|
|
||||||
}
|
}
|
||||||
|
Long time4 = System.currentTimeMillis();
|
||||||
|
if(ConfigReader.Config.logTime) AdventureManager.consoleMessage("性能监测: 洒水器数据保存" + (time4-time3) + "ms");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 洒水器工作,Mode 2
|
||||||
|
* @param worldName 世界名
|
||||||
|
*/
|
||||||
|
public void workModeTwo(String worldName){
|
||||||
|
Long time1 = System.currentTimeMillis();
|
||||||
|
if(!ConfigReader.Config.allWorld){
|
||||||
|
updateData();
|
||||||
|
}
|
||||||
|
Long time2 = System.currentTimeMillis();
|
||||||
|
if (ConfigReader.Config.logTime) AdventureManager.consoleMessage("性能监测: 洒水器数据更新" + (time2-time1) + "ms");
|
||||||
|
HashSet<String> players = new HashSet<>(JoinAndQuit.onlinePlayers);
|
||||||
|
if (data.contains(worldName)){
|
||||||
|
World world = Bukkit.getWorld(worldName);
|
||||||
|
data.getConfigurationSection(worldName).getKeys(false).forEach(chunk ->{
|
||||||
|
data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> {
|
||||||
|
if (value instanceof MemorySection map){
|
||||||
|
String player = (String) map.get("player");
|
||||||
|
if (player == null) {
|
||||||
|
data.set(worldName + "." + chunk + "." + key + ".player", "none");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!players.contains(player)) return;
|
||||||
|
String[] coordinate = StringUtils.split(key, ",");
|
||||||
|
Location location = new Location(world,Double.parseDouble(coordinate[0])+0.5,Double.parseDouble(coordinate[1])+0.5,Double.parseDouble(coordinate[2])+0.5);
|
||||||
|
bukkitScheduler.callSyncMethod(CustomCrops.instance, ()->{
|
||||||
|
int water = (int) map.get("water");
|
||||||
|
int range = (int) map.get("range");
|
||||||
|
if (water > 0){
|
||||||
|
data.set(worldName + "." + chunk + "." + key + ".water", water - 1);
|
||||||
|
bukkitScheduler.runTaskLater(CustomCrops.instance, ()-> {
|
||||||
|
for(int i = -range; i <= range; i++){
|
||||||
|
for (int j = -range; j <= range; j++){
|
||||||
|
waterPot(location.clone().add(i,-1,j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, new Random().nextInt(ConfigReader.Config.timeToWork));
|
||||||
|
}
|
||||||
|
if (range == 0) data.set(worldName + "." + chunk + "." + key, null);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Long time3 = System.currentTimeMillis();
|
||||||
|
if(ConfigReader.Config.logTime) AdventureManager.consoleMessage("性能监测: 洒水器工作过程" + (time3-time2) + "ms");
|
||||||
|
if(!ConfigReader.Config.allWorld){
|
||||||
|
saveData();
|
||||||
|
}
|
||||||
|
Long time4 = System.currentTimeMillis();
|
||||||
|
if(ConfigReader.Config.logTime) AdventureManager.consoleMessage("性能监测: 洒水器数据保存" + (time4-time3) + "ms");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 洒水器工作,Mode 3
|
||||||
|
* @param worldName 世界名
|
||||||
|
*/
|
||||||
|
public void workModeThree(String worldName){
|
||||||
|
Long time1 = System.currentTimeMillis();
|
||||||
|
if(!ConfigReader.Config.allWorld){
|
||||||
|
updateData();
|
||||||
|
}
|
||||||
|
Long time2 = System.currentTimeMillis();
|
||||||
|
if (ConfigReader.Config.logTime) AdventureManager.consoleMessage("性能监测: 洒水器数据更新" + (time2-time1) + "ms");
|
||||||
|
HashSet<String> players = new HashSet<>(JoinAndQuit.onlinePlayers);
|
||||||
|
if (data.contains(worldName)){
|
||||||
|
World world = Bukkit.getWorld(worldName);
|
||||||
|
data.getConfigurationSection(worldName).getKeys(false).forEach(chunk ->{
|
||||||
|
String[] split = StringUtils.split(chunk,",");
|
||||||
|
if (world.isChunkLoaded(Integer.parseInt(split[0]), Integer.parseInt(split[1]))) {
|
||||||
|
data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> {
|
||||||
|
String[] coordinate = StringUtils.split(key, ",");
|
||||||
|
Location location = new Location(world,Double.parseDouble(coordinate[0])+0.5,Double.parseDouble(coordinate[1])+0.5,Double.parseDouble(coordinate[2])+0.5);
|
||||||
|
if (value instanceof MemorySection map){
|
||||||
|
int water = (int) map.get("water");
|
||||||
|
int range = (int) map.get("range");
|
||||||
|
bukkitScheduler.runTask(CustomCrops.instance, ()->{
|
||||||
|
if(!IAFurniture.getFromLocation(location, world)){
|
||||||
|
data.set(worldName + "." + chunk + "." + key, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (water > 0){
|
||||||
|
data.set(worldName + "." + chunk + "." + key + ".water", water - 1);
|
||||||
|
bukkitScheduler.runTaskLater(CustomCrops.instance, ()-> {
|
||||||
|
for(int i = -range; i <= range; i++){
|
||||||
|
for (int j = -range; j <= range; j++){
|
||||||
|
waterPot(location.clone().add(i,-1,j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, new Random().nextInt(ConfigReader.Config.timeToWork));
|
||||||
|
}
|
||||||
|
if (range == 0) data.set(worldName + "." + chunk + "." + key, null);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> {
|
||||||
|
if (value instanceof MemorySection map){
|
||||||
|
String player = (String) map.get("player");
|
||||||
|
if (player == null) {
|
||||||
|
data.set(worldName + "." + chunk + "." + key + ".player", "none");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!players.contains(player)) return;
|
||||||
|
String[] coordinate = StringUtils.split(key, ",");
|
||||||
|
Location location = new Location(world,Double.parseDouble(coordinate[0])+0.5,Double.parseDouble(coordinate[1])+0.5,Double.parseDouble(coordinate[2])+0.5);
|
||||||
|
int water = (int) map.get("water");
|
||||||
|
int range = (int) map.get("range");
|
||||||
|
if (water > 0){
|
||||||
|
data.set(worldName + "." + chunk + "." + key + ".water", water - 1);
|
||||||
|
bukkitScheduler.runTaskLater(CustomCrops.instance, ()-> {
|
||||||
|
for(int i = -range; i <= range; i++){
|
||||||
|
for (int j = -range; j <= range; j++){
|
||||||
|
waterPot(location.clone().add(i,-1,j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, new Random().nextInt(ConfigReader.Config.timeToWork));
|
||||||
|
}
|
||||||
|
if (range == 0) data.set(worldName + "." + chunk + "." + key, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Long time3 = System.currentTimeMillis();
|
||||||
|
if(ConfigReader.Config.logTime) AdventureManager.consoleMessage("性能监测: 洒水器工作过程" + (time3-time2) + "ms");
|
||||||
|
if(!ConfigReader.Config.allWorld){
|
||||||
|
saveData();
|
||||||
|
}
|
||||||
|
Long time4 = System.currentTimeMillis();
|
||||||
|
if(ConfigReader.Config.logTime) AdventureManager.consoleMessage("性能监测: 洒水器数据保存" + (time4-time3) + "ms");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 洒水器工作,Mode 4
|
||||||
|
* @param worldName 世界名
|
||||||
|
*/
|
||||||
|
public void workModeFour(String worldName){
|
||||||
|
Long time1 = System.currentTimeMillis();
|
||||||
|
if(!ConfigReader.Config.allWorld){
|
||||||
|
updateData();
|
||||||
|
}
|
||||||
|
Long time2 = System.currentTimeMillis();
|
||||||
|
if (ConfigReader.Config.logTime) AdventureManager.consoleMessage("性能监测: 洒水器数据更新" + (time2-time1) + "ms");
|
||||||
|
if (data.contains(worldName)){
|
||||||
|
World world = Bukkit.getWorld(worldName);
|
||||||
|
data.getConfigurationSection(worldName).getKeys(false).forEach(chunk ->{
|
||||||
|
data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> {
|
||||||
|
String[] coordinate = StringUtils.split(key, ",");
|
||||||
|
Location location = new Location(world,Double.parseDouble(coordinate[0])+0.5,Double.parseDouble(coordinate[1])+0.5,Double.parseDouble(coordinate[2])+0.5);
|
||||||
|
if (value instanceof MemorySection map){
|
||||||
|
int water = (int) map.get("water");
|
||||||
|
int range = (int) map.get("range");
|
||||||
|
if (water > 0){
|
||||||
|
data.set(worldName + "." + chunk + "." + key + ".water", water - 1);
|
||||||
|
bukkitScheduler.runTaskLater(CustomCrops.instance, ()-> {
|
||||||
|
for(int i = -range; i <= range; i++){
|
||||||
|
for (int j = -range; j <= range; j++){
|
||||||
|
waterPot(location.clone().add(i,-1,j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, new Random().nextInt(ConfigReader.Config.timeToWork));
|
||||||
|
}
|
||||||
|
if (range == 0) data.set(worldName + "." + chunk + "." + key, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Long time3 = System.currentTimeMillis();
|
||||||
|
if(ConfigReader.Config.logTime) AdventureManager.consoleMessage("性能监测: 洒水器工作过程" + (time3-time2) + "ms");
|
||||||
|
if(!ConfigReader.Config.allWorld){
|
||||||
|
saveData();
|
||||||
|
}
|
||||||
|
Long time4 = System.currentTimeMillis();
|
||||||
|
if(ConfigReader.Config.logTime) AdventureManager.consoleMessage("性能监测: 洒水器数据保存" + (time4-time3) + "ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 所有世界的洒水器工作
|
* 所有世界的洒水器工作
|
||||||
*/
|
*/
|
||||||
public void sprinklerWorkAll(){
|
public void sprinklerWorkAll(){
|
||||||
Long time1 = System.currentTimeMillis();
|
|
||||||
updateData();
|
updateData();
|
||||||
Long time2 = System.currentTimeMillis();
|
List<World> worlds = Bukkit.getWorlds();
|
||||||
if (ConfigReader.Config.logTime){
|
for (int i = 0; i < worlds.size(); i++){
|
||||||
AdventureManager.consoleMessage("性能监测: 洒水器数据更新" + (time2-time1) + "ms");
|
String worldName = worlds.get(i).getName();
|
||||||
|
bukkitScheduler.runTaskLaterAsynchronously(CustomCrops.instance, () -> {
|
||||||
|
switch (ConfigReader.Config.growMode){
|
||||||
|
case 1 -> workModeOne(worldName);
|
||||||
|
case 2 -> workModeTwo(worldName);
|
||||||
|
case 3 -> workModeThree(worldName);
|
||||||
|
case 4 -> workModeFour(worldName);
|
||||||
}
|
}
|
||||||
Bukkit.getWorlds().forEach(world -> {
|
}, i * 40L);
|
||||||
String worldName = world.getName();
|
|
||||||
if (data.contains(worldName)){
|
|
||||||
BukkitScheduler bukkitScheduler = Bukkit.getScheduler();
|
|
||||||
data.getConfigurationSection(worldName).getKeys(false).forEach(chunk ->{
|
|
||||||
String[] split = StringUtils.split(chunk,",");
|
|
||||||
if (ConfigReader.Config.onlyLoadedGrow || world.isChunkLoaded(Integer.parseInt(split[0]), Integer.parseInt(split[1]))) {
|
|
||||||
data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> {
|
|
||||||
String[] coordinate = StringUtils.split(key, ",");
|
|
||||||
Location location = new Location(world,Double.parseDouble(coordinate[0])+0.5,Double.parseDouble(coordinate[1])+0.5,Double.parseDouble(coordinate[2])+0.5);
|
|
||||||
int random = new Random().nextInt(ConfigReader.Config.timeToWork);
|
|
||||||
if (value instanceof MemorySection map){
|
|
||||||
bukkitScheduler.callSyncMethod(CustomCrops.instance, ()->{
|
|
||||||
int water = (int) map.get("water");
|
|
||||||
int range = (int) map.get("range");
|
|
||||||
if(!IAFurniture.getFromLocation(location, world)){
|
|
||||||
data.set(worldName + "." + chunk + "." + key, null);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (water > 0){
|
|
||||||
data.set(worldName + "." + chunk + "." + key + ".water", water - 1);
|
|
||||||
bukkitScheduler.runTaskLater(CustomCrops.instance, ()-> {
|
|
||||||
for(int i = -range; i <= range; i++){
|
|
||||||
for (int j = -range; j <= range; j++){
|
|
||||||
waterPot(location.clone().add(i,-1,j));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, random);
|
|
||||||
}
|
|
||||||
if (range == 0) data.set(worldName + "." + chunk + "." + key, null);
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Long time3 = System.currentTimeMillis();
|
|
||||||
if(ConfigReader.Config.logTime){
|
|
||||||
AdventureManager.consoleMessage("性能监测: 洒水器工作过程" + (time3-time2) + "ms");
|
|
||||||
}
|
}
|
||||||
saveData();
|
saveData();
|
||||||
Long time4 = System.currentTimeMillis();
|
|
||||||
if(ConfigReader.Config.logTime){
|
|
||||||
AdventureManager.consoleMessage("性能监测: 洒水器数据保存" + (time4-time3) + "ms");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package net.momirealms.customcrops.listener;
|
||||||
|
|
||||||
|
import dev.lone.itemsadder.api.Events.FurnitureBreakEvent;
|
||||||
|
import net.momirealms.customcrops.ConfigReader;
|
||||||
|
import net.momirealms.customcrops.datamanager.SprinklerManager;
|
||||||
|
import net.momirealms.customcrops.utils.SimpleLocation;
|
||||||
|
import net.momirealms.customcrops.utils.Sprinkler;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
|
public class BreakFurniture implements Listener {
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onBreakFurniture(FurnitureBreakEvent event){
|
||||||
|
Sprinkler config = ConfigReader.SPRINKLERS.get(StringUtils.split(event.getNamespacedID(),":")[1]);
|
||||||
|
if (config != null){
|
||||||
|
SimpleLocation simpleLocation = SimpleLocation.fromLocation(event.getBukkitEntity().getLocation());
|
||||||
|
SprinklerManager.Cache.remove(simpleLocation);
|
||||||
|
SprinklerManager.RemoveCache.add(simpleLocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,15 +20,15 @@ package net.momirealms.customcrops.listener;
|
|||||||
import de.tr7zw.changeme.nbtapi.NBTCompound;
|
import de.tr7zw.changeme.nbtapi.NBTCompound;
|
||||||
import de.tr7zw.changeme.nbtapi.NBTItem;
|
import de.tr7zw.changeme.nbtapi.NBTItem;
|
||||||
import dev.lone.itemsadder.api.CustomFurniture;
|
import dev.lone.itemsadder.api.CustomFurniture;
|
||||||
|
import dev.lone.itemsadder.api.Events.FurnitureBreakEvent;
|
||||||
|
import dev.lone.itemsadder.api.Events.FurnitureInteractEvent;
|
||||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||||
import net.momirealms.customcrops.ConfigReader;
|
import net.momirealms.customcrops.ConfigReader;
|
||||||
import net.momirealms.customcrops.CustomCrops;
|
import net.momirealms.customcrops.CustomCrops;
|
||||||
import net.momirealms.customcrops.datamanager.SprinklerManager;
|
import net.momirealms.customcrops.datamanager.SprinklerManager;
|
||||||
import net.momirealms.customcrops.utils.AdventureManager;
|
import net.momirealms.customcrops.utils.*;
|
||||||
import net.momirealms.customcrops.utils.HoloUtil;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import net.momirealms.customcrops.utils.Sprinkler;
|
|
||||||
import net.momirealms.customcrops.utils.WateringCan;
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.ArmorStand;
|
import org.bukkit.entity.ArmorStand;
|
||||||
@@ -54,27 +54,24 @@ public class InteractEntity implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onEntityInteract(PlayerInteractAtEntityEvent event){
|
public void onEntityInteract(FurnitureInteractEvent event){
|
||||||
Entity entity = event.getRightClicked();
|
Sprinkler config = ConfigReader.SPRINKLERS.get(StringUtils.split(event.getNamespacedID(),":")[1]);
|
||||||
if(entity instanceof ArmorStand armorStand){
|
|
||||||
if(CustomFurniture.byAlreadySpawned(armorStand) == null) return;
|
|
||||||
Sprinkler config = ConfigReader.SPRINKLERS.get(CustomFurniture.byAlreadySpawned(armorStand).getId());
|
|
||||||
if(config != null){
|
if(config != null){
|
||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
if (time - (coolDown.getOrDefault(player, time - 250)) < 250) {
|
if (time - (coolDown.getOrDefault(player, time - 200)) < 200) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
coolDown.put(player, time);
|
coolDown.put(player, time);
|
||||||
ItemStack itemStack = player.getInventory().getItemInMainHand();
|
ItemStack itemStack = player.getInventory().getItemInMainHand();
|
||||||
Location location = armorStand.getLocation();
|
Location location = event.getBukkitEntity().getLocation();
|
||||||
String world = location.getWorld().getName();
|
String world = location.getWorld().getName();
|
||||||
int x = location.getBlockX();
|
int x = location.getBlockX();
|
||||||
int z = location.getBlockZ();
|
int z = location.getBlockZ();
|
||||||
int maxWater = config.getWater();
|
int maxWater = config.getWater();
|
||||||
int currentWater = 0;
|
int currentWater = 0;
|
||||||
Location loc = location.clone().subtract(0,1,0).getBlock().getLocation().add(0,1,0);
|
Location loc = location.clone().subtract(0,1,0).getBlock().getLocation().add(0,1,0);
|
||||||
Sprinkler sprinkler = SprinklerManager.Cache.get(loc);
|
Sprinkler sprinkler = SprinklerManager.Cache.get(SimpleLocation.fromLocation(loc));
|
||||||
if (itemStack.getType() == Material.WATER_BUCKET){
|
if (itemStack.getType() == Material.WATER_BUCKET){
|
||||||
itemStack.setType(Material.BUCKET);
|
itemStack.setType(Material.BUCKET);
|
||||||
if (sprinkler != null){
|
if (sprinkler != null){
|
||||||
@@ -157,7 +154,6 @@ public class InteractEntity implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取某个洒水器的水量
|
* 获取某个洒水器的水量
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package net.momirealms.customcrops.listener;
|
||||||
|
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
public class JoinAndQuit implements Listener {
|
||||||
|
|
||||||
|
public static HashSet<String> onlinePlayers = new HashSet<>();
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onJoin(PlayerJoinEvent event){
|
||||||
|
onlinePlayers.add(event.getPlayer().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onQuit(PlayerQuitEvent event){
|
||||||
|
onlinePlayers.remove(event.getPlayer().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -138,7 +138,7 @@ public class RightClick implements Listener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
itemStack.setAmount(itemStack.getAmount() - 1);
|
itemStack.setAmount(itemStack.getAmount() - 1);
|
||||||
CropManager.Cache.put(location, cropName);
|
CropManager.Cache.put(location, player.getName());
|
||||||
CustomBlock.place((nbtCompound.getString("namespace") + ":" + cropName + "_stage_1"), location);
|
CustomBlock.place((nbtCompound.getString("namespace") + ":" + cropName + "_stage_1"), location);
|
||||||
AdventureManager.playerSound(player, ConfigReader.Sounds.plantSeedSource, ConfigReader.Sounds.plantSeedKey);
|
AdventureManager.playerSound(player, ConfigReader.Sounds.plantSeedSource, ConfigReader.Sounds.plantSeedKey);
|
||||||
return;
|
return;
|
||||||
@@ -279,8 +279,11 @@ public class RightClick implements Listener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Sprinkler sprinklerData = new Sprinkler(sprinkler.getRange(), 0);
|
Sprinkler sprinklerData = new Sprinkler(sprinkler.getRange(), 0);
|
||||||
|
sprinklerData.setPlayer(player.getName());
|
||||||
itemStack.setAmount(itemStack.getAmount() - 1);
|
itemStack.setAmount(itemStack.getAmount() - 1);
|
||||||
SprinklerManager.Cache.put(location.add(0,1,0), sprinklerData);
|
SimpleLocation simpleLocation = SimpleLocation.fromLocation(location.add(0,1,0));
|
||||||
|
SprinklerManager.Cache.put(simpleLocation, sprinklerData);
|
||||||
|
SprinklerManager.RemoveCache.remove(simpleLocation);
|
||||||
IAFurniture.placeFurniture(sprinkler.getNamespacedID_2(),location);
|
IAFurniture.placeFurniture(sprinkler.getNamespacedID_2(),location);
|
||||||
AdventureManager.playerSound(player, ConfigReader.Sounds.placeSprinklerSource, ConfigReader.Sounds.placeSprinklerKey);
|
AdventureManager.playerSound(player, ConfigReader.Sounds.placeSprinklerSource, ConfigReader.Sounds.placeSprinklerKey);
|
||||||
return;
|
return;
|
||||||
@@ -420,7 +423,7 @@ public class RightClick implements Listener {
|
|||||||
AdventureManager.playerSound(player, ConfigReader.Sounds.harvestSource, ConfigReader.Sounds.harvestKey);
|
AdventureManager.playerSound(player, ConfigReader.Sounds.harvestSource, ConfigReader.Sounds.harvestKey);
|
||||||
if(cropInstance.getReturnStage() != null){
|
if(cropInstance.getReturnStage() != null){
|
||||||
CustomBlock.place(cropInstance.getReturnStage(), location);
|
CustomBlock.place(cropInstance.getReturnStage(), location);
|
||||||
CropManager.Cache.put(location, cropNameList[0]);
|
CropManager.Cache.put(location, player.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,10 +49,20 @@ public class TimeCheck extends BukkitRunnable {
|
|||||||
}, ConfigReader.Config.timeToGrow);
|
}, ConfigReader.Config.timeToGrow);
|
||||||
}else {
|
}else {
|
||||||
Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.instance, () -> {
|
Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.instance, () -> {
|
||||||
plugin.getCropManager().cropGrow(world.getName());
|
switch (ConfigReader.Config.growMode){
|
||||||
|
case 1 -> plugin.getCropManager().growModeOne(world.getName());
|
||||||
|
case 2 -> plugin.getCropManager().growModeTwo(world.getName());
|
||||||
|
case 3 -> plugin.getCropManager().growModeThree(world.getName());
|
||||||
|
case 4 -> plugin.getCropManager().growModeFour(world.getName());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
Bukkit.getScheduler().runTaskLaterAsynchronously(CustomCrops.instance, ()->{
|
Bukkit.getScheduler().runTaskLaterAsynchronously(CustomCrops.instance, ()->{
|
||||||
plugin.getSprinklerManager().sprinklerWork(world.getName());
|
switch (ConfigReader.Config.growMode){
|
||||||
|
case 1 -> plugin.getSprinklerManager().workModeOne(world.getName());
|
||||||
|
case 2 -> plugin.getSprinklerManager().workModeTwo(world.getName());
|
||||||
|
case 3 -> plugin.getSprinklerManager().workModeThree(world.getName());
|
||||||
|
case 4 -> plugin.getSprinklerManager().workModeFour(world.getName());
|
||||||
|
}
|
||||||
}, ConfigReader.Config.timeToGrow);
|
}, ConfigReader.Config.timeToGrow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ public class IAFurniture {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断指定位置的盔甲架是不是洒水器
|
* 判断指定位置的盔甲架是不是洒水器
|
||||||
|
* 仅限加载中的区块
|
||||||
* @param location 位置
|
* @param location 位置
|
||||||
* @param world 世界
|
* @param world 世界
|
||||||
* @return 是/否
|
* @return 是/否
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ public class Sprinkler {
|
|||||||
|
|
||||||
private int water;
|
private int water;
|
||||||
private int range;
|
private int range;
|
||||||
|
private String player;
|
||||||
private String namespacedID_1;
|
private String namespacedID_1;
|
||||||
private String namespacedID_2;
|
private String namespacedID_2;
|
||||||
|
|
||||||
@@ -33,9 +34,11 @@ public class Sprinkler {
|
|||||||
public String getNamespacedID_1() {return namespacedID_1;}
|
public String getNamespacedID_1() {return namespacedID_1;}
|
||||||
public String getNamespacedID_2() {return namespacedID_2;}
|
public String getNamespacedID_2() {return namespacedID_2;}
|
||||||
public int getRange() {return range;}
|
public int getRange() {return range;}
|
||||||
|
public String getPlayer() {return player;}
|
||||||
|
|
||||||
public void setRange(int range) {this.range = range;}
|
public void setRange(int range) {this.range = range;}
|
||||||
public void setNamespacedID_2(String namespacedID_2) {this.namespacedID_2 = namespacedID_2;}
|
public void setNamespacedID_2(String namespacedID_2) {this.namespacedID_2 = namespacedID_2;}
|
||||||
public void setNamespacedID_1(String namespacedID_1) {this.namespacedID_1 = namespacedID_1;}
|
public void setNamespacedID_1(String namespacedID_1) {this.namespacedID_1 = namespacedID_1;}
|
||||||
public void setWater(int water) {this.water = water;}
|
public void setWater(int water) {this.water = water;}
|
||||||
|
public void setPlayer(String player) {this.player = player;}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#=============================================================#
|
||||||
#ItemsAdder items namespacedID
|
#ItemsAdder items namespacedID
|
||||||
basic:
|
basic:
|
||||||
pot: customcrops:pot
|
pot: customcrops:pot
|
||||||
@@ -5,7 +6,7 @@ basic:
|
|||||||
greenhouse-glass: customcrops:greenhouse_glass
|
greenhouse-glass: customcrops:greenhouse_glass
|
||||||
dead-crop: customcrops:crop_stage_death
|
dead-crop: customcrops:crop_stage_death
|
||||||
soil-detector: customcrops:soil_detector
|
soil-detector: customcrops:soil_detector
|
||||||
|
#=============================================================#
|
||||||
water-can:
|
water-can:
|
||||||
watering_can_1:
|
watering_can_1:
|
||||||
item: customcrops:watering_can_1
|
item: customcrops:watering_can_1
|
||||||
@@ -29,7 +30,7 @@ water-can:
|
|||||||
max: 6
|
max: 6
|
||||||
width: 3
|
width: 3
|
||||||
length: 5
|
length: 5
|
||||||
|
#=============================================================#
|
||||||
lore:
|
lore:
|
||||||
#Should lore be changed when using watering-can
|
#Should lore be changed when using watering-can
|
||||||
watering-can:
|
watering-can:
|
||||||
@@ -45,7 +46,7 @@ lore:
|
|||||||
full: '뀁뀃'
|
full: '뀁뀃'
|
||||||
empty: '뀁뀄'
|
empty: '뀁뀄'
|
||||||
right: '뀁뀅</font>'
|
right: '뀁뀅</font>'
|
||||||
|
#=============================================================#
|
||||||
sprinkler:
|
sprinkler:
|
||||||
sprinkler_1:
|
sprinkler_1:
|
||||||
range: 1
|
range: 1
|
||||||
@@ -58,3 +59,4 @@ sprinkler:
|
|||||||
max-water: 7
|
max-water: 7
|
||||||
3Ditem: customcrops:sprinkler_2
|
3Ditem: customcrops:sprinkler_2
|
||||||
2Ditem: customcrops:sprinkler_2_item
|
2Ditem: customcrops:sprinkler_2_item
|
||||||
|
#=============================================================#
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
config:
|
config:
|
||||||
|
#=============================================================#
|
||||||
#english spanish chinese
|
#english spanish chinese
|
||||||
lang: english
|
lang: english
|
||||||
|
#=============================================================#
|
||||||
integration:
|
integration:
|
||||||
#integration to prevent other players' grief
|
#integration to prevent other players' grief
|
||||||
Residence: false
|
Residence: false
|
||||||
@@ -16,31 +17,46 @@ config:
|
|||||||
AureliumSkills: false
|
AureliumSkills: false
|
||||||
mcMMO: false
|
mcMMO: false
|
||||||
MMOCore: false
|
MMOCore: false
|
||||||
|
#=============================================================#
|
||||||
|
#Mode 1:
|
||||||
|
# Crops in loaded chunks will grow
|
||||||
|
#Mode 2:
|
||||||
|
# Online players' crops will grow
|
||||||
|
#Mode 3:
|
||||||
|
# Mode 1 + Mode 2
|
||||||
|
#Mode 4:
|
||||||
|
# No support in this mode!
|
||||||
|
# All the crops will grow (May cause lag)
|
||||||
|
grow-mode: 3
|
||||||
#The time to start growing(ticks)
|
#The time to start growing(ticks)
|
||||||
#1000ticks is 7am in game. (0-23999)
|
#1000ticks is 7am in game. (0-23999)
|
||||||
#Sprinklers will work after all crops finish growing
|
#Sprinklers will work after all crops finish growing
|
||||||
grow-time:
|
grow-time:
|
||||||
- 1000
|
- 1000
|
||||||
|
|
||||||
#Time in random a single crop need to grow(seconds)
|
#Time in random a single crop need to grow(seconds)
|
||||||
#This prevents a large amount of crops grow at the same time
|
#This prevents a large amount of crops grow at the same time
|
||||||
#Large amount of block replacement would cause lag.
|
#Large amount of block replacement would cause lag.
|
||||||
time-to-grow: 60
|
time-to-grow: 60
|
||||||
#Similar to "time-to-grow", this prevent all sprinklers work at the same time
|
#Similar to "time-to-grow", this prevent all sprinklers work at the same time
|
||||||
time-to-work: 30
|
time-to-work: 30
|
||||||
|
#Async Time Check (requires restart)
|
||||||
|
#Crops might not grow when using async.
|
||||||
|
#It is not really necessary to be Async
|
||||||
|
async-time-check: false
|
||||||
|
#Worlds where crops would grow
|
||||||
|
whitelist-worlds:
|
||||||
|
- world
|
||||||
|
#Should all the worlds' crops grow?
|
||||||
|
#This is useful for per player per world server.
|
||||||
|
#In this mode, whitelist world can only have one as the standard of time & season judgment.
|
||||||
|
all-world-grow: false
|
||||||
|
#=============================================================#
|
||||||
quality:
|
quality:
|
||||||
#If disabled, you need to configurate the loot in ItemsAdder config
|
#If disabled, you need to configurate the loot in ItemsAdder config
|
||||||
enable: true
|
enable: true
|
||||||
#Default ratio
|
#Default ratio
|
||||||
default-ratio: 17/2/1
|
default-ratio: 17/2/1
|
||||||
|
#=============================================================#
|
||||||
#Async Time Check (requires restart)
|
|
||||||
#Crops might not grow when using async.
|
|
||||||
#It is not really necessary to be Async
|
|
||||||
async-time-check: false
|
|
||||||
|
|
||||||
#Water Amount to refill when using water bucket
|
#Water Amount to refill when using water bucket
|
||||||
sprinkler-refill: 2
|
sprinkler-refill: 2
|
||||||
#Water Amount to refill with a sigle click to water block
|
#Water Amount to refill with a sigle click to water block
|
||||||
@@ -49,11 +65,13 @@ config:
|
|||||||
water-can-add-water-to-sprinkler: true
|
water-can-add-water-to-sprinkler: true
|
||||||
#Should particles be displayed when using watering can?
|
#Should particles be displayed when using watering can?
|
||||||
water-particles: true
|
water-particles: true
|
||||||
|
#=============================================================#
|
||||||
#Worlds where crops would grow
|
#Will bone meal accelerate the growth of crop
|
||||||
whitelist-worlds:
|
bone-meal:
|
||||||
- world
|
enable: true
|
||||||
|
chance: 0.5
|
||||||
|
success-particle: VILLAGER_HAPPY
|
||||||
|
#=============================================================#
|
||||||
#Should we limit the max amount of crops and sprinkler in one chunk
|
#Should we limit the max amount of crops and sprinkler in one chunk
|
||||||
#Recommended to enable because ItemsAdder might throw StackOverFlow
|
#Recommended to enable because ItemsAdder might throw StackOverFlow
|
||||||
#when there are too many custom blocks in one chunk
|
#when there are too many custom blocks in one chunk
|
||||||
@@ -61,38 +79,15 @@ config:
|
|||||||
enable: true
|
enable: true
|
||||||
crop: 64
|
crop: 64
|
||||||
sprinkler: 8
|
sprinkler: 8
|
||||||
|
#=============================================================#
|
||||||
#Test performance
|
|
||||||
log-time-consume: false
|
|
||||||
|
|
||||||
#Defaultly crops will only grow in loaded chunks.
|
|
||||||
#If you want a mechanic similar to OriginRealms just DISABLE SEASON and REPEATED HARVESTING.
|
|
||||||
#In this way crops data will be removed from file when it comes to its final stage.
|
|
||||||
#In other words, plugin will only record the crops still on growing.
|
|
||||||
#NEVER SET "only-grow-in-loaded-chunks" FALSE IF YOU ARE USING THE FEATURES MENTIONED ABOVE.
|
|
||||||
#Otherwise it would be laggy because too many data in cache.
|
|
||||||
only-grow-in-loaded-chunks: true
|
|
||||||
|
|
||||||
#Should all the worlds' crops grow?
|
|
||||||
#This is useful for per player per world server.
|
|
||||||
#In this mode, whitelist world can only have one as the standard of time & season judgment.
|
|
||||||
all-world-grow: false
|
|
||||||
|
|
||||||
#can player harvest crops with right click?
|
#can player harvest crops with right click?
|
||||||
#if set "false" crops can't be harvested repeatedly
|
#if set "false" crops can't be harvested repeatedly
|
||||||
right-click-harvest: true
|
right-click-harvest: true
|
||||||
|
|
||||||
#If "right-click-harvest" is true
|
#If "right-click-harvest" is true
|
||||||
#Should player be allowed to harvest with items in hand
|
#Should player be allowed to harvest with items in hand
|
||||||
harvest-with-empty-hand: true
|
harvest-with-empty-hand: true
|
||||||
|
|
||||||
#Should player be prevented from planting if wrong season
|
#Should player be prevented from planting if wrong season
|
||||||
prevent-plant-if-wrong-season: true
|
prevent-plant-if-wrong-season: true
|
||||||
#Should notify player of the wrong season?
|
#Should notify player of the wrong season?
|
||||||
should-notify-if-wrong-season: true
|
should-notify-if-wrong-season: true
|
||||||
|
#=============================================================#
|
||||||
#Will bone meal accelerate the growth of crop
|
|
||||||
bone-meal:
|
|
||||||
enable: true
|
|
||||||
chance: 0.5
|
|
||||||
success-particle: VILLAGER_HAPPY
|
|
||||||
@@ -27,7 +27,7 @@ speed:
|
|||||||
times: 14
|
times: 14
|
||||||
item: customcrops:speed_3
|
item: customcrops:speed_3
|
||||||
before-plant: true
|
before-plant: true
|
||||||
|
#=============================================================#
|
||||||
#Pot have a small chance to retain its water after crops grow
|
#Pot have a small chance to retain its water after crops grow
|
||||||
retaining:
|
retaining:
|
||||||
retaining_1:
|
retaining_1:
|
||||||
@@ -50,7 +50,7 @@ retaining:
|
|||||||
times: 28
|
times: 28
|
||||||
item: customcrops:retaining_3
|
item: customcrops:retaining_3
|
||||||
before-plant: false
|
before-plant: false
|
||||||
|
#=============================================================#
|
||||||
#When haveresting, players have a higher chance to get high quality crops.
|
#When haveresting, players have a higher chance to get high quality crops.
|
||||||
quality:
|
quality:
|
||||||
quality_1:
|
quality_1:
|
||||||
@@ -73,3 +73,4 @@ quality:
|
|||||||
chance: 2/2/1
|
chance: 2/2/1
|
||||||
item: customcrops:quality_3
|
item: customcrops:quality_3
|
||||||
before-plant: true
|
before-plant: true
|
||||||
|
#=============================================================#
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
season:
|
season:
|
||||||
|
|
||||||
|
#require a restart to apply
|
||||||
enable: true
|
enable: true
|
||||||
|
|
||||||
auto-season-change:
|
auto-season-change:
|
||||||
|
|||||||
@@ -61,15 +61,16 @@ config:
|
|||||||
#记录生长判断和洒水所需的时间(测试性能用)
|
#记录生长判断和洒水所需的时间(测试性能用)
|
||||||
log-time-consume: false
|
log-time-consume: false
|
||||||
|
|
||||||
#是否只有加载中的区块农作物才会生长
|
#Mode 1:
|
||||||
#如果你不使用季节、可重复收获特性
|
# 加载中区块的农作物生长
|
||||||
#插件data只会记录正在生长中某个阶段的农作物数据
|
#Mode 2:
|
||||||
#生长到最后一阶段农作物生长数据就会清除
|
# 在线玩家的农作物生长
|
||||||
#那么可以尝试设置此值为false来让数据内全部农作物生长
|
#Mode 3:
|
||||||
#如果你使用上述特性中的任意一个,请不要设置为false
|
# Mode 1 + Mode 2
|
||||||
#否则农作物生长到最后一阶段不会从数据中清除,过大的数据量
|
#Mode 4:
|
||||||
#可能会导致服务器严重卡顿
|
# 所有农作物生长
|
||||||
only-grow-in-loaded-chunks: true
|
# 可能会造成卡顿!不建议使用此模式
|
||||||
|
grow-mode: 3
|
||||||
|
|
||||||
#是否所有加载中的世界都要进行生长判断
|
#是否所有加载中的世界都要进行生长判断
|
||||||
#本选项适用于使用玩家独立世界的服务器
|
#本选项适用于使用玩家独立世界的服务器
|
||||||
|
|||||||
Reference in New Issue
Block a user