mirror of
https://github.com/Xiao-MoMi/Custom-Crops.git
synced 2025-12-21 16:09:21 +00:00
1.5.22
This commit is contained in:
@@ -58,13 +58,13 @@ public class ConfigReader {
|
||||
}
|
||||
|
||||
public static void ReloadConfig(){
|
||||
Sounds.loadSound();
|
||||
Config.loadConfig();
|
||||
Season.loadSeason();
|
||||
Message.loadMessage();
|
||||
Basic.loadBasic();
|
||||
cropLoad();
|
||||
fertilizerLoad();
|
||||
Season.loadSeason();
|
||||
Sounds.loadSound();
|
||||
cropLoad();
|
||||
}
|
||||
|
||||
public static class Config{
|
||||
@@ -88,7 +88,7 @@ public class ConfigReader {
|
||||
public static int timeToGrow;
|
||||
public static int timeToWork;
|
||||
public static boolean logTime;
|
||||
public static boolean onlyLoadedGrow;
|
||||
public static int growMode;
|
||||
public static boolean quality;
|
||||
public static boolean canAddWater;
|
||||
public static boolean allWorld;
|
||||
@@ -115,16 +115,16 @@ public class ConfigReader {
|
||||
cropGrowTimeList = config.getLongList("config.grow-time");
|
||||
cropGrowTimeList.forEach(time -> {
|
||||
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;
|
||||
timeToWork = config.getInt("config.time-to-work",30)*20;
|
||||
|
||||
asyncCheck = config.getBoolean("config.async-time-check",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);
|
||||
hasParticle = config.getBoolean("config.water-particles", 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.Completer;
|
||||
import net.momirealms.customcrops.datamanager.*;
|
||||
import net.momirealms.customcrops.listener.BreakBlock;
|
||||
import net.momirealms.customcrops.listener.InteractEntity;
|
||||
import net.momirealms.customcrops.listener.ItemSpawn;
|
||||
import net.momirealms.customcrops.listener.RightClick;
|
||||
import net.momirealms.customcrops.listener.*;
|
||||
import net.momirealms.customcrops.timer.CropTimer;
|
||||
import net.momirealms.customcrops.utils.AdventureManager;
|
||||
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 RightClick(), 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);
|
||||
|
||||
if (ConfigReader.Season.enable){
|
||||
@@ -103,6 +102,7 @@ public final class CustomCrops extends JavaPlugin {
|
||||
|
||||
if (this.cropManager != null){
|
||||
this.cropManager.cleanData();
|
||||
this.cropManager.updateData();
|
||||
this.cropManager.saveData();
|
||||
this.cropManager = null;
|
||||
}
|
||||
@@ -112,6 +112,7 @@ public final class CustomCrops extends JavaPlugin {
|
||||
}
|
||||
if (this.sprinklerManager != null){
|
||||
this.sprinklerManager.cleanData();
|
||||
this.sprinklerManager.updateData();
|
||||
this.sprinklerManager.saveData();
|
||||
this.sprinklerManager = null;
|
||||
}
|
||||
|
||||
@@ -67,7 +67,12 @@ public class Executor implements CommandExecutor {
|
||||
return true;
|
||||
}
|
||||
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){
|
||||
AdventureManager.playerMessage(player,ConfigReader.Message.prefix + ConfigReader.Message.forceGrow.replace("{world}",args[1]));
|
||||
@@ -82,7 +87,12 @@ public class Executor implements CommandExecutor {
|
||||
return true;
|
||||
}
|
||||
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){
|
||||
AdventureManager.playerMessage(player,ConfigReader.Message.prefix + ConfigReader.Message.forceWater.replace("{world}",args[1]));
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
package net.momirealms.customcrops.datamanager;
|
||||
|
||||
import dev.lone.itemsadder.api.CustomBlock;
|
||||
import dev.lone.itemsadder.api.CustomStack;
|
||||
import net.momirealms.customcrops.fertilizer.QualityCrop;
|
||||
import net.momirealms.customcrops.listener.JoinAndQuit;
|
||||
import net.momirealms.customcrops.utils.AdventureManager;
|
||||
import net.momirealms.customcrops.ConfigReader;
|
||||
import net.momirealms.customcrops.CustomCrops;
|
||||
@@ -37,8 +37,8 @@ import org.bukkit.scheduler.BukkitScheduler;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@@ -83,7 +83,7 @@ public class CropManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* 将hashmap中的数据保存到data中
|
||||
* 将数据保存到data中
|
||||
*/
|
||||
public void updateData(){
|
||||
Cache.forEach((location, String) -> {
|
||||
@@ -108,139 +108,157 @@ public class CropManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* 农作物生长
|
||||
* 农作物生长,Mode 1
|
||||
* 仅加载区块生长
|
||||
* @param worldName 进行生长判定的世界名
|
||||
*/
|
||||
public void cropGrow(String worldName){
|
||||
|
||||
public void growModeOne(String worldName){
|
||||
Long time1 = System.currentTimeMillis();
|
||||
updateData();
|
||||
Long time2 = System.currentTimeMillis();
|
||||
if(ConfigReader.Config.logTime){
|
||||
AdventureManager.consoleMessage("性能监测: 农作物数据更新" + (time2-time1) + "ms");
|
||||
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,",");
|
||||
World world = Bukkit.getWorld(worldName);
|
||||
if (ConfigReader.Config.onlyLoadedGrow || world.isChunkLoaded(Integer.parseInt(split[0]), Integer.parseInt(split[1]))){
|
||||
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]));
|
||||
CustomBlock seedBlock = CustomBlock.byAlreadyPlaced(seedLocation.getBlock());
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
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);
|
||||
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.logTime) AdventureManager.consoleMessage("性能监测: 农作物生长过程" + (time3-time2) + "ms");
|
||||
if(!ConfigReader.Config.allWorld){
|
||||
saveData();
|
||||
}
|
||||
saveData();
|
||||
Long time4 = System.currentTimeMillis();
|
||||
if(ConfigReader.Config.logTime){
|
||||
AdventureManager.consoleMessage("性能监测: 农作物数据保存" + (time4-time3) + "ms");
|
||||
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(){
|
||||
Long time1 = System.currentTimeMillis();
|
||||
updateData();
|
||||
Long time2 = System.currentTimeMillis();
|
||||
if(ConfigReader.Config.logTime){
|
||||
AdventureManager.consoleMessage("性能监测: 农作物数据更新" + (time2-time1) + "ms");
|
||||
}
|
||||
Bukkit.getWorlds().forEach(world -> {
|
||||
String worldName = world.getName();
|
||||
if (data.contains(worldName)){
|
||||
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 seedLocation = new Location(world,Double.parseDouble(coordinate[0]),Double.parseDouble(coordinate[1]),Double.parseDouble(coordinate[2]));
|
||||
CustomBlock seedBlock = CustomBlock.byAlreadyPlaced(seedLocation.getBlock());
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
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();
|
||||
if(ConfigReader.Config.logTime){
|
||||
AdventureManager.consoleMessage("性能监测: 农作物生长过程" + (time3-time2) + "ms");
|
||||
List<World> worlds = Bukkit.getWorlds();
|
||||
for (int i = 0; i < worlds.size(); i++){
|
||||
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);
|
||||
}
|
||||
}, i * 40L);
|
||||
}
|
||||
saveData();
|
||||
Long time4 = System.currentTimeMillis();
|
||||
if(ConfigReader.Config.logTime){
|
||||
AdventureManager.consoleMessage("性能监测: 农作物数据保存" + (time4-time3) + "ms");
|
||||
}
|
||||
|
||||
/**
|
||||
* 对某个位置进行生长判定
|
||||
* @param worldName 世界名
|
||||
* @param seedLocation 种子位置
|
||||
* @return 是否消除数据
|
||||
*/
|
||||
private boolean growJudge(String worldName, Location seedLocation) {
|
||||
CustomBlock seedBlock = CustomBlock.byAlreadyPlaced(seedLocation.getBlock());
|
||||
//自定义农作物方块不存在
|
||||
if(seedBlock == null) {
|
||||
return true;
|
||||
}
|
||||
String namespacedID = seedBlock.getNamespacedID();
|
||||
String id = seedBlock.getId();
|
||||
//已死亡或不是农作物
|
||||
if(namespacedID.equals(ConfigReader.Basic.dead) || !namespacedID.contains("_stage_")) {
|
||||
return true;
|
||||
}
|
||||
//农作物下方自定义方块不存在
|
||||
Location potLocation = seedLocation.clone().subtract(0,1,0);
|
||||
CustomBlock pot = CustomBlock.byAlreadyPlaced(potLocation.getBlock());
|
||||
if (pot == null){
|
||||
return true;
|
||||
}
|
||||
//农作物实例不存在
|
||||
String[] cropNameList = StringUtils.split(id,"_");
|
||||
CropInstance cropInstance = ConfigReader.CROPS.get(cropNameList[0]);
|
||||
if (cropInstance == null){
|
||||
return true;
|
||||
}
|
||||
//获取自定义方块ID
|
||||
String potNamespacedID = pot.getNamespacedID();
|
||||
if (potNamespacedID.equals(ConfigReader.Basic.watered_pot)){
|
||||
int random = new Random().nextInt(ConfigReader.Config.timeToGrow);
|
||||
//如果启用季节限制且农作物有季节需求
|
||||
if (ConfigReader.Season.enable && cropInstance.getSeasons() != null){
|
||||
if (isWrongSeason(seedLocation, cropInstance.getSeasons(), worldName)){
|
||||
|
||||
bukkitScheduler.runTaskLater(CustomCrops.instance, () -> {
|
||||
CustomBlock.remove(seedLocation);
|
||||
CustomBlock.place(ConfigReader.Basic.dead, seedLocation);
|
||||
}, random);
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
//获取下一阶段
|
||||
int nextStage = Integer.parseInt(cropNameList[2]) + 1;
|
||||
//下一阶段存在
|
||||
if (CustomBlock.getInstance(StringUtils.chop(namespacedID) + nextStage) != null) {
|
||||
//尝试获取肥料类型
|
||||
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 (cropInstance.getGrowChance() > Math.random()){
|
||||
//农作物存在下两个阶段
|
||||
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 {
|
||||
notAddStage(potLocation, random);
|
||||
}
|
||||
}
|
||||
//保湿土壤
|
||||
else if(fertilizer instanceof RetainingSoil retainingSoil){
|
||||
if (Math.random() < retainingSoil.getChance()){
|
||||
if (cropInstance.getGrowChance() > Math.random()){
|
||||
addStage(seedLocation, namespacedID, nextStage, random);
|
||||
}
|
||||
}else {
|
||||
if (cropInstance.getGrowChance() > Math.random()){
|
||||
addStage(potLocation, seedLocation, namespacedID, nextStage, random);
|
||||
}else {
|
||||
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));
|
||||
|
||||
if (cropInstance.getGrowChance() > Math.random()){
|
||||
addStage(potLocation, seedLocation, namespacedID, nextStage, random);
|
||||
}else {
|
||||
notAddStage(potLocation, random);
|
||||
}
|
||||
}
|
||||
//肥料的最后一次使用
|
||||
if (times == 1){
|
||||
PotManager.Cache.remove(SimpleLocation.fromLocation(potLocation));
|
||||
}
|
||||
}
|
||||
else {
|
||||
//移除肥料信息,一般不会出现此情况
|
||||
PotManager.Cache.remove(SimpleLocation.fromLocation(potLocation));
|
||||
if (cropInstance.getGrowChance() > Math.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){
|
||||
//巨大化判定
|
||||
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, () ->{
|
||||
CustomBlock.remove(potLocation);
|
||||
CustomBlock.place(ConfigReader.Basic.pot, potLocation);
|
||||
}, random);
|
||||
}
|
||||
}else {
|
||||
//若无下一阶段,无巨大化,未启用季节,则移除无用数据
|
||||
if (!ConfigReader.Season.enable) return true;
|
||||
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) return false;
|
||||
//农作物无视季节
|
||||
List<String> seasons = cropInstance.getSeasons();
|
||||
if(seasons == null) return false;
|
||||
//错误季节
|
||||
if(isWrongSeason(seedLocation, seasons, worldName)){
|
||||
bukkitScheduler.runTaskLater(CustomCrops.instance, () -> {
|
||||
CustomBlock.remove(seedLocation);
|
||||
CustomBlock.place(ConfigReader.Basic.dead, seedLocation);
|
||||
}, new Random().nextInt(ConfigReader.Config.timeToGrow));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//不是种植盆
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -444,4 +525,16 @@ public class CropManager {
|
||||
CustomBlock.place(stage, seedLocation);
|
||||
}, 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;
|
||||
|
||||
import dev.lone.itemsadder.api.CustomBlock;
|
||||
import net.momirealms.customcrops.listener.JoinAndQuit;
|
||||
import net.momirealms.customcrops.utils.AdventureManager;
|
||||
import net.momirealms.customcrops.ConfigReader;
|
||||
import net.momirealms.customcrops.CustomCrops;
|
||||
import net.momirealms.customcrops.utils.IAFurniture;
|
||||
import net.momirealms.customcrops.utils.SimpleLocation;
|
||||
import net.momirealms.customcrops.utils.Sprinkler;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -33,13 +35,19 @@ import org.bukkit.scheduler.BukkitScheduler;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Random;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class SprinklerManager {
|
||||
|
||||
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(){
|
||||
Cache.forEach((location, sprinklerData) -> {
|
||||
String world = location.getWorld().getName();
|
||||
int x = location.getBlockX();
|
||||
int z = location.getBlockZ();
|
||||
StringBuilder stringBuilder = new StringBuilder().append(world).append(".").append(x/16).append(",").append(z/16).append(".").append(x).append(",").append(location.getBlockY()).append(",").append(z);
|
||||
String world = location.getWorldName();
|
||||
int x = location.getX();
|
||||
int z = location.getZ();
|
||||
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+".water", sprinklerData.getWater());
|
||||
data.set(stringBuilder+".player", Optional.ofNullable(sprinklerData.getPlayer()).orElse("none"));
|
||||
});
|
||||
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 世界名
|
||||
*/
|
||||
public void sprinklerWork(String worldName){
|
||||
public void workModeOne(String worldName){
|
||||
Long time1 = System.currentTimeMillis();
|
||||
updateData();
|
||||
Long time2 = System.currentTimeMillis();
|
||||
if (ConfigReader.Config.logTime){
|
||||
AdventureManager.consoleMessage("性能监测: 洒水器数据更新" + (time2-time1) + "ms");
|
||||
if(!ConfigReader.Config.allWorld){
|
||||
updateData();
|
||||
}
|
||||
Long time2 = System.currentTimeMillis();
|
||||
if (ConfigReader.Config.logTime) AdventureManager.consoleMessage("性能监测: 洒水器数据更新" + (time2-time1) + "ms");
|
||||
if (data.contains(worldName)){
|
||||
BukkitScheduler bukkitScheduler = Bukkit.getScheduler();
|
||||
World world = Bukkit.getWorld(worldName);
|
||||
data.getConfigurationSection(worldName).getKeys(false).forEach(chunk ->{
|
||||
String[] split = StringUtils.split(chunk,",");
|
||||
World world = Bukkit.getWorld(worldName);
|
||||
if (ConfigReader.Config.onlyLoadedGrow || world.isChunkLoaded(Integer.parseInt(split[0]), Integer.parseInt(split[1]))) {
|
||||
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);
|
||||
int random = new Random().nextInt(ConfigReader.Config.timeToWork);
|
||||
if (value instanceof MemorySection map){
|
||||
bukkitScheduler.callSyncMethod(CustomCrops.instance, ()->{
|
||||
bukkitScheduler.runTask(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;
|
||||
return;
|
||||
}
|
||||
if (water > 0){
|
||||
data.set(worldName + "." + chunk + "." + key + ".water", water - 1);
|
||||
@@ -136,10 +151,9 @@ public class SprinklerManager {
|
||||
waterPot(location.clone().add(i,-1,j));
|
||||
}
|
||||
}
|
||||
}, random);
|
||||
}, new Random().nextInt(ConfigReader.Config.timeToWork));
|
||||
}
|
||||
if (range == 0) data.set(worldName + "." + chunk + "." + key, null);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -147,73 +161,211 @@ public class SprinklerManager {
|
||||
});
|
||||
}
|
||||
Long time3 = System.currentTimeMillis();
|
||||
if(ConfigReader.Config.logTime){
|
||||
AdventureManager.consoleMessage("性能监测: 洒水器工作过程" + (time3-time2) + "ms");
|
||||
if(ConfigReader.Config.logTime) AdventureManager.consoleMessage("性能监测: 洒水器工作过程" + (time3-time2) + "ms");
|
||||
if(!ConfigReader.Config.allWorld){
|
||||
saveData();
|
||||
}
|
||||
saveData();
|
||||
Long time4 = System.currentTimeMillis();
|
||||
if(ConfigReader.Config.logTime){
|
||||
AdventureManager.consoleMessage("性能监测: 洒水器数据保存" + (time4-time3) + "ms");
|
||||
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(){
|
||||
Long time1 = System.currentTimeMillis();
|
||||
updateData();
|
||||
Long time2 = System.currentTimeMillis();
|
||||
if (ConfigReader.Config.logTime){
|
||||
AdventureManager.consoleMessage("性能监测: 洒水器数据更新" + (time2-time1) + "ms");
|
||||
}
|
||||
Bukkit.getWorlds().forEach(world -> {
|
||||
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");
|
||||
List<World> worlds = Bukkit.getWorlds();
|
||||
for (int i = 0; i < worlds.size(); i++){
|
||||
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);
|
||||
}
|
||||
}, i * 40L);
|
||||
}
|
||||
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.NBTItem;
|
||||
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.serializer.gson.GsonComponentSerializer;
|
||||
import net.momirealms.customcrops.ConfigReader;
|
||||
import net.momirealms.customcrops.CustomCrops;
|
||||
import net.momirealms.customcrops.datamanager.SprinklerManager;
|
||||
import net.momirealms.customcrops.utils.AdventureManager;
|
||||
import net.momirealms.customcrops.utils.HoloUtil;
|
||||
import net.momirealms.customcrops.utils.Sprinkler;
|
||||
import net.momirealms.customcrops.utils.WateringCan;
|
||||
import net.momirealms.customcrops.utils.*;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
@@ -54,106 +54,102 @@ public class InteractEntity implements Listener {
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onEntityInteract(PlayerInteractAtEntityEvent event){
|
||||
Entity entity = event.getRightClicked();
|
||||
if(entity instanceof ArmorStand armorStand){
|
||||
if(CustomFurniture.byAlreadySpawned(armorStand) == null) return;
|
||||
Sprinkler config = ConfigReader.SPRINKLERS.get(CustomFurniture.byAlreadySpawned(armorStand).getId());
|
||||
if(config != null){
|
||||
long time = System.currentTimeMillis();
|
||||
Player player = event.getPlayer();
|
||||
if (time - (coolDown.getOrDefault(player, time - 250)) < 250) {
|
||||
return;
|
||||
}
|
||||
coolDown.put(player, time);
|
||||
ItemStack itemStack = player.getInventory().getItemInMainHand();
|
||||
Location location = armorStand.getLocation();
|
||||
String world = location.getWorld().getName();
|
||||
int x = location.getBlockX();
|
||||
int z = location.getBlockZ();
|
||||
int maxWater = config.getWater();
|
||||
int currentWater = 0;
|
||||
Location loc = location.clone().subtract(0,1,0).getBlock().getLocation().add(0,1,0);
|
||||
Sprinkler sprinkler = SprinklerManager.Cache.get(loc);
|
||||
if (itemStack.getType() == Material.WATER_BUCKET){
|
||||
itemStack.setType(Material.BUCKET);
|
||||
if (sprinkler != null){
|
||||
currentWater = sprinkler.getWater();
|
||||
currentWater += ConfigReader.Config.sprinklerRefill;
|
||||
if (currentWater > maxWater){
|
||||
currentWater = maxWater;
|
||||
}
|
||||
sprinkler.setWater(currentWater);
|
||||
}else {
|
||||
String path = world + "." + x / 16 + "," + z / 16 + "." + x + "," + location.getBlockY() + "," + z + ".water";
|
||||
currentWater = plugin.getSprinklerManager().data.getInt(path);
|
||||
currentWater += ConfigReader.Config.sprinklerRefill;
|
||||
if (currentWater > maxWater){
|
||||
currentWater = maxWater;
|
||||
}
|
||||
plugin.getSprinklerManager().data.set(path, currentWater);
|
||||
public void onEntityInteract(FurnitureInteractEvent event){
|
||||
Sprinkler config = ConfigReader.SPRINKLERS.get(StringUtils.split(event.getNamespacedID(),":")[1]);
|
||||
if(config != null){
|
||||
long time = System.currentTimeMillis();
|
||||
Player player = event.getPlayer();
|
||||
if (time - (coolDown.getOrDefault(player, time - 200)) < 200) {
|
||||
return;
|
||||
}
|
||||
coolDown.put(player, time);
|
||||
ItemStack itemStack = player.getInventory().getItemInMainHand();
|
||||
Location location = event.getBukkitEntity().getLocation();
|
||||
String world = location.getWorld().getName();
|
||||
int x = location.getBlockX();
|
||||
int z = location.getBlockZ();
|
||||
int maxWater = config.getWater();
|
||||
int currentWater = 0;
|
||||
Location loc = location.clone().subtract(0,1,0).getBlock().getLocation().add(0,1,0);
|
||||
Sprinkler sprinkler = SprinklerManager.Cache.get(SimpleLocation.fromLocation(loc));
|
||||
if (itemStack.getType() == Material.WATER_BUCKET){
|
||||
itemStack.setType(Material.BUCKET);
|
||||
if (sprinkler != null){
|
||||
currentWater = sprinkler.getWater();
|
||||
currentWater += ConfigReader.Config.sprinklerRefill;
|
||||
if (currentWater > maxWater){
|
||||
currentWater = maxWater;
|
||||
}
|
||||
AdventureManager.playerSound(player, ConfigReader.Sounds.addWaterToSprinklerSource, ConfigReader.Sounds.addWaterToSprinklerKey);
|
||||
sprinkler.setWater(currentWater);
|
||||
}else {
|
||||
String path = world + "." + x / 16 + "," + z / 16 + "." + x + "," + location.getBlockY() + "," + z + ".water";
|
||||
currentWater = plugin.getSprinklerManager().data.getInt(path);
|
||||
currentWater += ConfigReader.Config.sprinklerRefill;
|
||||
if (currentWater > maxWater){
|
||||
currentWater = maxWater;
|
||||
}
|
||||
plugin.getSprinklerManager().data.set(path, currentWater);
|
||||
}
|
||||
else {
|
||||
if (ConfigReader.Config.canAddWater && itemStack.getType() != Material.AIR){
|
||||
NBTItem nbtItem = new NBTItem(itemStack);
|
||||
int water = nbtItem.getInteger("WaterAmount");
|
||||
if (water > 0){
|
||||
NBTCompound nbtCompound = nbtItem.getCompound("itemsadder");
|
||||
if (nbtCompound != null) {
|
||||
String id = nbtCompound.getString("id");
|
||||
Optional<WateringCan> can = Optional.ofNullable(ConfigReader.CANS.get(id));
|
||||
if (can.isPresent()) {
|
||||
WateringCan wateringCan = can.get();
|
||||
water--;
|
||||
nbtItem.setInteger("WaterAmount", water);
|
||||
AdventureManager.playerSound(player, ConfigReader.Sounds.addWaterToSprinklerSource, ConfigReader.Sounds.addWaterToSprinklerKey);
|
||||
if (sprinkler != null){
|
||||
currentWater = sprinkler.getWater();
|
||||
currentWater++;
|
||||
if (currentWater > maxWater){
|
||||
currentWater = maxWater;
|
||||
}
|
||||
sprinkler.setWater(currentWater);
|
||||
}else {
|
||||
String path = world + "." + x / 16 + "," + z / 16 + "." + x + "," + location.getBlockY() + "," + z + ".water";
|
||||
currentWater = plugin.getSprinklerManager().data.getInt(path);
|
||||
currentWater++;
|
||||
if (currentWater > maxWater){
|
||||
currentWater = maxWater;
|
||||
}
|
||||
plugin.getSprinklerManager().data.set(path, currentWater);
|
||||
AdventureManager.playerSound(player, ConfigReader.Sounds.addWaterToSprinklerSource, ConfigReader.Sounds.addWaterToSprinklerKey);
|
||||
}
|
||||
else {
|
||||
if (ConfigReader.Config.canAddWater && itemStack.getType() != Material.AIR){
|
||||
NBTItem nbtItem = new NBTItem(itemStack);
|
||||
int water = nbtItem.getInteger("WaterAmount");
|
||||
if (water > 0){
|
||||
NBTCompound nbtCompound = nbtItem.getCompound("itemsadder");
|
||||
if (nbtCompound != null) {
|
||||
String id = nbtCompound.getString("id");
|
||||
Optional<WateringCan> can = Optional.ofNullable(ConfigReader.CANS.get(id));
|
||||
if (can.isPresent()) {
|
||||
WateringCan wateringCan = can.get();
|
||||
water--;
|
||||
nbtItem.setInteger("WaterAmount", water);
|
||||
AdventureManager.playerSound(player, ConfigReader.Sounds.addWaterToSprinklerSource, ConfigReader.Sounds.addWaterToSprinklerKey);
|
||||
if (sprinkler != null){
|
||||
currentWater = sprinkler.getWater();
|
||||
currentWater++;
|
||||
if (currentWater > maxWater){
|
||||
currentWater = maxWater;
|
||||
}
|
||||
if (ConfigReader.Message.hasWaterInfo){
|
||||
String string = ConfigReader.Message.waterLeft + ConfigReader.Message.waterFull.repeat(water) +
|
||||
ConfigReader.Message.waterEmpty.repeat(wateringCan.getMax() - water) + ConfigReader.Message.waterRight;
|
||||
AdventureManager.playerActionbar(player, string.replace("{max_water}", String.valueOf(wateringCan.getMax())).replace("{water}", String.valueOf(water)));
|
||||
sprinkler.setWater(currentWater);
|
||||
}else {
|
||||
String path = world + "." + x / 16 + "," + z / 16 + "." + x + "," + location.getBlockY() + "," + z + ".water";
|
||||
currentWater = plugin.getSprinklerManager().data.getInt(path);
|
||||
currentWater++;
|
||||
if (currentWater > maxWater){
|
||||
currentWater = maxWater;
|
||||
}
|
||||
if (ConfigReader.Basic.hasWaterLore){
|
||||
String string = (ConfigReader.Basic.waterLeft + ConfigReader.Basic.waterFull.repeat(water) +
|
||||
ConfigReader.Basic.waterEmpty.repeat(wateringCan.getMax() - water) + ConfigReader.Basic.waterRight).replace("{max_water}", String.valueOf(wateringCan.getMax())).replace("{water}", String.valueOf(water));
|
||||
List<String> lores = nbtItem.getCompound("display").getStringList("Lore");
|
||||
lores.clear();
|
||||
ConfigReader.Basic.waterLore.forEach(lore -> lores.add(GsonComponentSerializer.gson().serialize(MiniMessage.miniMessage().deserialize(lore.replace("{water_info}", string)))));
|
||||
}
|
||||
itemStack.setItemMeta(nbtItem.getItem().getItemMeta());
|
||||
plugin.getSprinklerManager().data.set(path, currentWater);
|
||||
}
|
||||
if (ConfigReader.Message.hasWaterInfo){
|
||||
String string = ConfigReader.Message.waterLeft + ConfigReader.Message.waterFull.repeat(water) +
|
||||
ConfigReader.Message.waterEmpty.repeat(wateringCan.getMax() - water) + ConfigReader.Message.waterRight;
|
||||
AdventureManager.playerActionbar(player, string.replace("{max_water}", String.valueOf(wateringCan.getMax())).replace("{water}", String.valueOf(water)));
|
||||
}
|
||||
if (ConfigReader.Basic.hasWaterLore){
|
||||
String string = (ConfigReader.Basic.waterLeft + ConfigReader.Basic.waterFull.repeat(water) +
|
||||
ConfigReader.Basic.waterEmpty.repeat(wateringCan.getMax() - water) + ConfigReader.Basic.waterRight).replace("{max_water}", String.valueOf(wateringCan.getMax())).replace("{water}", String.valueOf(water));
|
||||
List<String> lores = nbtItem.getCompound("display").getStringList("Lore");
|
||||
lores.clear();
|
||||
ConfigReader.Basic.waterLore.forEach(lore -> lores.add(GsonComponentSerializer.gson().serialize(MiniMessage.miniMessage().deserialize(lore.replace("{water_info}", string)))));
|
||||
}
|
||||
itemStack.setItemMeta(nbtItem.getItem().getItemMeta());
|
||||
}
|
||||
}else {
|
||||
currentWater = getCurrentWater(location, world, x, z, sprinkler);
|
||||
}
|
||||
}
|
||||
else {
|
||||
}else {
|
||||
currentWater = getCurrentWater(location, world, x, z, sprinkler);
|
||||
}
|
||||
}
|
||||
if (ConfigReader.Message.hasSprinklerInfo){
|
||||
String string = ConfigReader.Message.sprinklerLeft + ConfigReader.Message.sprinklerFull.repeat(currentWater) +
|
||||
ConfigReader.Message.sprinklerEmpty.repeat(maxWater - currentWater) + ConfigReader.Message.sprinklerRight;
|
||||
if(HoloUtil.cache.get(location.add(0, ConfigReader.Message.sprinklerOffset,0)) == null) {
|
||||
HoloUtil.showHolo(string.replace("{max_water}", String.valueOf(maxWater)).replace("{water}", String.valueOf(currentWater)), player, location, ConfigReader.Message.sprinklerTime);
|
||||
}
|
||||
else {
|
||||
currentWater = getCurrentWater(location, world, x, z, sprinkler);
|
||||
}
|
||||
}
|
||||
if (ConfigReader.Message.hasSprinklerInfo){
|
||||
String string = ConfigReader.Message.sprinklerLeft + ConfigReader.Message.sprinklerFull.repeat(currentWater) +
|
||||
ConfigReader.Message.sprinklerEmpty.repeat(maxWater - currentWater) + ConfigReader.Message.sprinklerRight;
|
||||
if(HoloUtil.cache.get(location.add(0, ConfigReader.Message.sprinklerOffset,0)) == null) {
|
||||
HoloUtil.showHolo(string.replace("{max_water}", String.valueOf(maxWater)).replace("{water}", String.valueOf(currentWater)), player, location, ConfigReader.Message.sprinklerTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
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);
|
||||
AdventureManager.playerSound(player, ConfigReader.Sounds.plantSeedSource, ConfigReader.Sounds.plantSeedKey);
|
||||
return;
|
||||
@@ -279,8 +279,11 @@ public class RightClick implements Listener {
|
||||
return;
|
||||
}
|
||||
Sprinkler sprinklerData = new Sprinkler(sprinkler.getRange(), 0);
|
||||
sprinklerData.setPlayer(player.getName());
|
||||
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);
|
||||
AdventureManager.playerSound(player, ConfigReader.Sounds.placeSprinklerSource, ConfigReader.Sounds.placeSprinklerKey);
|
||||
return;
|
||||
@@ -420,7 +423,7 @@ public class RightClick implements Listener {
|
||||
AdventureManager.playerSound(player, ConfigReader.Sounds.harvestSource, ConfigReader.Sounds.harvestKey);
|
||||
if(cropInstance.getReturnStage() != null){
|
||||
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);
|
||||
}else {
|
||||
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, ()->{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ public class IAFurniture {
|
||||
|
||||
/**
|
||||
* 判断指定位置的盔甲架是不是洒水器
|
||||
* 仅限加载中的区块
|
||||
* @param location 位置
|
||||
* @param world 世界
|
||||
* @return 是/否
|
||||
|
||||
@@ -21,6 +21,7 @@ public class Sprinkler {
|
||||
|
||||
private int water;
|
||||
private int range;
|
||||
private String player;
|
||||
private String namespacedID_1;
|
||||
private String namespacedID_2;
|
||||
|
||||
@@ -33,9 +34,11 @@ public class Sprinkler {
|
||||
public String getNamespacedID_1() {return namespacedID_1;}
|
||||
public String getNamespacedID_2() {return namespacedID_2;}
|
||||
public int getRange() {return range;}
|
||||
public String getPlayer() {return player;}
|
||||
|
||||
public void setRange(int range) {this.range = range;}
|
||||
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 setWater(int water) {this.water = water;}
|
||||
public void setPlayer(String player) {this.player = player;}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#=============================================================#
|
||||
#ItemsAdder items namespacedID
|
||||
basic:
|
||||
pot: customcrops:pot
|
||||
@@ -5,7 +6,7 @@ basic:
|
||||
greenhouse-glass: customcrops:greenhouse_glass
|
||||
dead-crop: customcrops:crop_stage_death
|
||||
soil-detector: customcrops:soil_detector
|
||||
|
||||
#=============================================================#
|
||||
water-can:
|
||||
watering_can_1:
|
||||
item: customcrops:watering_can_1
|
||||
@@ -29,7 +30,7 @@ water-can:
|
||||
max: 6
|
||||
width: 3
|
||||
length: 5
|
||||
|
||||
#=============================================================#
|
||||
lore:
|
||||
#Should lore be changed when using watering-can
|
||||
watering-can:
|
||||
@@ -45,7 +46,7 @@ lore:
|
||||
full: '뀁뀃'
|
||||
empty: '뀁뀄'
|
||||
right: '뀁뀅</font>'
|
||||
|
||||
#=============================================================#
|
||||
sprinkler:
|
||||
sprinkler_1:
|
||||
range: 1
|
||||
@@ -58,3 +59,4 @@ sprinkler:
|
||||
max-water: 7
|
||||
3Ditem: customcrops:sprinkler_2
|
||||
2Ditem: customcrops:sprinkler_2_item
|
||||
#=============================================================#
|
||||
@@ -1,7 +1,8 @@
|
||||
config:
|
||||
#=============================================================#
|
||||
#english spanish chinese
|
||||
lang: english
|
||||
|
||||
#=============================================================#
|
||||
integration:
|
||||
#integration to prevent other players' grief
|
||||
Residence: false
|
||||
@@ -16,31 +17,46 @@ config:
|
||||
AureliumSkills: false
|
||||
mcMMO: 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)
|
||||
#1000ticks is 7am in game. (0-23999)
|
||||
#Sprinklers will work after all crops finish growing
|
||||
grow-time:
|
||||
- 1000
|
||||
|
||||
#Time in random a single crop need to grow(seconds)
|
||||
#This prevents a large amount of crops grow at the same time
|
||||
#Large amount of block replacement would cause lag.
|
||||
time-to-grow: 60
|
||||
#Similar to "time-to-grow", this prevent all sprinklers work at the same time
|
||||
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:
|
||||
#If disabled, you need to configurate the loot in ItemsAdder config
|
||||
enable: true
|
||||
#Default ratio
|
||||
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
|
||||
sprinkler-refill: 2
|
||||
#Water Amount to refill with a sigle click to water block
|
||||
@@ -49,11 +65,13 @@ config:
|
||||
water-can-add-water-to-sprinkler: true
|
||||
#Should particles be displayed when using watering can?
|
||||
water-particles: true
|
||||
|
||||
#Worlds where crops would grow
|
||||
whitelist-worlds:
|
||||
- world
|
||||
|
||||
#=============================================================#
|
||||
#Will bone meal accelerate the growth of crop
|
||||
bone-meal:
|
||||
enable: true
|
||||
chance: 0.5
|
||||
success-particle: VILLAGER_HAPPY
|
||||
#=============================================================#
|
||||
#Should we limit the max amount of crops and sprinkler in one chunk
|
||||
#Recommended to enable because ItemsAdder might throw StackOverFlow
|
||||
#when there are too many custom blocks in one chunk
|
||||
@@ -61,38 +79,15 @@ config:
|
||||
enable: true
|
||||
crop: 64
|
||||
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?
|
||||
#if set "false" crops can't be harvested repeatedly
|
||||
right-click-harvest: true
|
||||
|
||||
#If "right-click-harvest" is true
|
||||
#Should player be allowed to harvest with items in hand
|
||||
harvest-with-empty-hand: true
|
||||
|
||||
#Should player be prevented from planting if wrong season
|
||||
prevent-plant-if-wrong-season: true
|
||||
#Should notify player of the wrong season?
|
||||
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
|
||||
item: customcrops:speed_3
|
||||
before-plant: true
|
||||
|
||||
#=============================================================#
|
||||
#Pot have a small chance to retain its water after crops grow
|
||||
retaining:
|
||||
retaining_1:
|
||||
@@ -50,7 +50,7 @@ retaining:
|
||||
times: 28
|
||||
item: customcrops:retaining_3
|
||||
before-plant: false
|
||||
|
||||
#=============================================================#
|
||||
#When haveresting, players have a higher chance to get high quality crops.
|
||||
quality:
|
||||
quality_1:
|
||||
@@ -72,4 +72,5 @@ quality:
|
||||
times: 28
|
||||
chance: 2/2/1
|
||||
item: customcrops:quality_3
|
||||
before-plant: true
|
||||
before-plant: true
|
||||
#=============================================================#
|
||||
@@ -1,5 +1,6 @@
|
||||
season:
|
||||
|
||||
#require a restart to apply
|
||||
enable: true
|
||||
|
||||
auto-season-change:
|
||||
|
||||
@@ -61,15 +61,16 @@ config:
|
||||
#记录生长判断和洒水所需的时间(测试性能用)
|
||||
log-time-consume: false
|
||||
|
||||
#是否只有加载中的区块农作物才会生长
|
||||
#如果你不使用季节、可重复收获特性
|
||||
#插件data只会记录正在生长中某个阶段的农作物数据
|
||||
#生长到最后一阶段农作物生长数据就会清除
|
||||
#那么可以尝试设置此值为false来让数据内全部农作物生长
|
||||
#如果你使用上述特性中的任意一个,请不要设置为false
|
||||
#否则农作物生长到最后一阶段不会从数据中清除,过大的数据量
|
||||
#可能会导致服务器严重卡顿
|
||||
only-grow-in-loaded-chunks: true
|
||||
#Mode 1:
|
||||
# 加载中区块的农作物生长
|
||||
#Mode 2:
|
||||
# 在线玩家的农作物生长
|
||||
#Mode 3:
|
||||
# Mode 1 + Mode 2
|
||||
#Mode 4:
|
||||
# 所有农作物生长
|
||||
# 可能会造成卡顿!不建议使用此模式
|
||||
grow-mode: 3
|
||||
|
||||
#是否所有加载中的世界都要进行生长判断
|
||||
#本选项适用于使用玩家独立世界的服务器
|
||||
|
||||
Reference in New Issue
Block a user