diff --git a/build.gradle b/build.gradle index 7350b82..d7fe43f 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } group = 'net.momirealms' -version = '2.0-r3' +version = '2.0-r4' repositories { mavenCentral() diff --git a/src/main/java/net/momirealms/customcrops/CustomCrops.java b/src/main/java/net/momirealms/customcrops/CustomCrops.java index 1768be6..3cea6f4 100644 --- a/src/main/java/net/momirealms/customcrops/CustomCrops.java +++ b/src/main/java/net/momirealms/customcrops/CustomCrops.java @@ -43,6 +43,26 @@ public final class CustomCrops extends JavaPlugin { private CropManager cropManager; private PluginCommand pluginCommand; +// _ooOoo_ +// o8888888o +// 88" . "88 +// (| -_- |) +// O\ = /O +// ____/`---'\____ +// .' \\| |// `. +// / \\||| : |||// \ +// / _||||| -:- |||||_ \ +// | | \\\ - /'| | | +// | \_| `\`---'// |_/ | +// \ .-\__ `-. -'__/-. / +// ___`. .' /--.--\ `. .'___ +// ."" '< `.___\_<|>_/___.' _> \"". +// | | : `- \`. ;`. _/; .'/ / .' ; | +// \ \ `-. \_\_`. _.'_/_/ -' _.' / +// ================-.`___`-.__\ \___ /__.-'_.'_.-'================ +// `=--=-' +// 佛祖保佑 永无BUG 永不卡服 + @Override public void onLoad(){ plugin = this; diff --git a/src/main/java/net/momirealms/customcrops/config/MainConfig.java b/src/main/java/net/momirealms/customcrops/config/MainConfig.java index 4ca52e4..993a2ff 100644 --- a/src/main/java/net/momirealms/customcrops/config/MainConfig.java +++ b/src/main/java/net/momirealms/customcrops/config/MainConfig.java @@ -98,6 +98,11 @@ public class MainConfig { public static String waterBarEmpty; public static String waterBarRight; public static boolean topOrBottom; + public static boolean enableSeasonBroadcast; + public static String[] springMsg; + public static String[] summerMsg; + public static String[] autumnMsg; + public static String[] winterMsg; public static void load() { ConfigUtil.update("config.yml"); @@ -154,6 +159,12 @@ public class MainConfig { enableParticles = !config.getBoolean("optimization.disable-water-particles", false); enableAnimations = !config.getBoolean("optimization.disable-sprinkler-animation", false); + enableSeasonBroadcast = config.getBoolean("season-broadcast.enable", true); + springMsg = config.getStringList("season-broadcast.spring").toArray(new String[0]); + summerMsg = config.getStringList("season-broadcast.summer").toArray(new String[0]); + autumnMsg = config.getStringList("season-broadcast.autumn").toArray(new String[0]); + winterMsg = config.getStringList("season-broadcast.winter").toArray(new String[0]); + try { boneMealSuccess = Particle.valueOf(config.getString("mechanics.bone-meal.success-particle", "VILLAGER_HAPPY")); } diff --git a/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderFrameCropImpl.java b/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderFrameCropImpl.java index 406d485..b39f7a4 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderFrameCropImpl.java +++ b/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderFrameCropImpl.java @@ -22,6 +22,7 @@ import net.momirealms.customcrops.api.crop.Crop; import net.momirealms.customcrops.config.BasicItemConfig; import net.momirealms.customcrops.config.CropConfig; import net.momirealms.customcrops.config.MainConfig; +import net.momirealms.customcrops.helper.Log; import net.momirealms.customcrops.integrations.customplugin.CustomInterface; import net.momirealms.customcrops.managers.CropManager; import net.momirealms.customcrops.managers.CropModeInterface; @@ -56,6 +57,7 @@ public class ItemsAdderFrameCropImpl implements CropModeInterface { Location cropLoc = location.clone().add(0.5,0.5,0.5); ItemFrame itemFrame = FurnitureUtil.getItemFrame(cropLoc); if (itemFrame == null) return true; + String id = customInterface.getItemID(itemFrame.getItem()); if (id == null) return true; if (id.equals(BasicItemConfig.deadCrop)) return true; @@ -64,7 +66,6 @@ public class ItemsAdderFrameCropImpl implements CropModeInterface { String cropKey = StringUtils.split(cropNameList[0], ":")[1]; Crop crop = CropConfig.CROPS.get(cropKey); if (crop == null) return true; - if (MainConfig.needSkyLight && location.getBlock().getLightFromSky() < MainConfig.skyLightLevel) { itemFrame.setItem(customInterface.getItemStack(BasicItemConfig.deadCrop), false); return true; @@ -74,21 +75,18 @@ public class ItemsAdderFrameCropImpl implements CropModeInterface { itemFrame.setItem(customInterface.getItemStack(BasicItemConfig.deadCrop), false); return true; } - Location potLoc = location.clone().subtract(0,1,0); String potID = customInterface.getBlockID(potLoc); if (potID == null) return true; - Fertilizer fertilizer = cropManager.getFertilizer(potLoc); boolean certainGrow = potID.equals(BasicItemConfig.wetPot); - int nextStage = Integer.parseInt(cropNameList[2]) + 1; String temp = StringUtils.chop(id); if (customInterface.doesExist(temp + nextStage)) { if (MainConfig.enableCrow && cropManager.crowJudge(location, itemFrame)) return true; if (fertilizer instanceof SpeedGrow speedGrow && Math.random() < speedGrow.getChance()) { if (customInterface.doesExist(temp + (nextStage+1))) { - addStage(itemFrame, temp + (nextStage+1)); + addStage(itemFrame, temp + (nextStage + 1)); } } else if (certainGrow || Math.random() < MainConfig.dryGrowChance) { diff --git a/src/main/java/net/momirealms/customcrops/integrations/season/InternalSeason.java b/src/main/java/net/momirealms/customcrops/integrations/season/InternalSeason.java index 49e7229..beceeef 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/season/InternalSeason.java +++ b/src/main/java/net/momirealms/customcrops/integrations/season/InternalSeason.java @@ -21,12 +21,16 @@ import net.momirealms.customcrops.CustomCrops; import net.momirealms.customcrops.Function; import net.momirealms.customcrops.config.MainConfig; import net.momirealms.customcrops.config.SeasonConfig; +import net.momirealms.customcrops.utils.AdventureUtil; +import org.bukkit.Bukkit; import org.bukkit.World; +import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitTask; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collection; import java.util.concurrent.ConcurrentHashMap; public class InternalSeason extends Function implements SeasonInterface { @@ -87,7 +91,42 @@ public class InternalSeason extends Function implements SeasonInterface { setSeason(countSeason(world), world); } else { - seasonHashMap.put(world, season); + if (MainConfig.syncSeason && world != MainConfig.syncWorld) { + seasonHashMap.put(world, getSeason(MainConfig.syncWorld)); + return; + } + CCSeason oldSeason = seasonHashMap.put(world, season); + if (!MainConfig.enableSeasonBroadcast) return; + if (oldSeason == null) return; + // season changed + if (oldSeason != season) { + Collection players; + if (MainConfig.syncSeason) players = Bukkit.getOnlinePlayers(); + else players = world.getPlayers(); + + switch (season) { + case SPRING -> players.forEach(player -> { + for (String msg : MainConfig.springMsg) { + AdventureUtil.playerMessage(player, msg); + } + }); + case SUMMER -> players.forEach(player -> { + for (String msg : MainConfig.summerMsg) { + AdventureUtil.playerMessage(player, msg); + } + }); + case AUTUMN -> players.forEach(player -> { + for (String msg : MainConfig.autumnMsg) { + AdventureUtil.playerMessage(player, msg); + } + }); + case WINTER -> players.forEach(player -> { + for (String msg : MainConfig.winterMsg) { + AdventureUtil.playerMessage(player, msg); + } + }); + } + } } } diff --git a/src/main/java/net/momirealms/customcrops/managers/CustomWorld.java b/src/main/java/net/momirealms/customcrops/managers/CustomWorld.java index 7a23467..7e8a818 100644 --- a/src/main/java/net/momirealms/customcrops/managers/CustomWorld.java +++ b/src/main/java/net/momirealms/customcrops/managers/CustomWorld.java @@ -22,6 +22,7 @@ import net.momirealms.customcrops.CustomCrops; import net.momirealms.customcrops.api.event.CustomWorldEvent; import net.momirealms.customcrops.api.utils.SeasonUtils; import net.momirealms.customcrops.config.*; +import net.momirealms.customcrops.helper.Log; import net.momirealms.customcrops.integrations.season.CCSeason; import net.momirealms.customcrops.objects.SimpleLocation; import net.momirealms.customcrops.objects.Sprinkler; @@ -59,6 +60,8 @@ public class CustomWorld { private final CropManager cropManager; private final HashSet tasksCache; private final BukkitScheduler bukkitScheduler; + private final HashSet plantedToday; + private final CropModeInterface cropMode; public CustomWorld(World world, CropManager cropManager) { this.world = world; @@ -72,6 +75,8 @@ public class CustomWorld { this.watered = Collections.synchronizedSet(new HashSet<>()); this.playerWatered = new HashSet<>(); this.tempWatered = new HashSet<>(); + this.plantedToday = new HashSet<>(); + this.cropMode = cropManager.getCropMode(); Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.plugin, () -> { loadData(); Bukkit.getScheduler().runTask(CustomCrops.plugin, () -> { @@ -195,10 +200,11 @@ public class CustomWorld { String season = jsonPrimitive.getAsString(); if (MainConfig.realisticSeasonHook) return; SeasonUtils.setSeason(world, CCSeason.valueOf(season)); - return; } } - SeasonUtils.setSeason(world, CCSeason.UNKNOWN); + else { + SeasonUtils.setSeason(world, CCSeason.UNKNOWN); + } } catch (FileNotFoundException e) { //bypass @@ -358,20 +364,22 @@ public class CustomWorld { potDryJudge(sprinklerTime + randomGenerator.nextInt(dryTime)); } - CropModeInterface cropMode = cropManager.getCropMode(); - for (SimpleLocation location : cropCache.keySet()) { - BukkitTask task = bukkitScheduler.runTaskLaterAsynchronously(CustomCrops.plugin, () -> { - Location seedLoc = MiscUtils.getLocation(location); - if (seedLoc == null) return; - if (cropMode.growJudge(seedLoc)) { - cropCache.remove(location); - } - }, sprinklerTime + dryTime + randomGenerator.nextInt(cropTime)); - tasksCache.add(task); + growSingleWire(location, sprinklerTime + dryTime + randomGenerator.nextInt(cropTime)); } } + private void growSingleWire(SimpleLocation location, long delay) { + BukkitTask task = bukkitScheduler.runTaskLaterAsynchronously(CustomCrops.plugin, () -> { + Location seedLoc = MiscUtils.getLocation(location); + if (seedLoc == null) return; + if (cropMode.growJudge(seedLoc)) { + cropCache.remove(location); + } + }, delay); + tasksCache.add(task); + } + public void growFrame(int cropTime, int sprinklerTime, int dryTime, boolean compensation) { Random randomGenerator = new Random(); @@ -381,27 +389,29 @@ public class CustomWorld { potDryJudge(sprinklerTime + randomGenerator.nextInt(dryTime)); } - CropModeInterface cropMode = cropManager.getCropMode(); - for (SimpleLocation location : cropCache.keySet()) { long random = randomGenerator.nextInt(cropTime); - BukkitTask task1 = bukkitScheduler.runTaskLater(CustomCrops.plugin, () -> { - Location seedLoc = MiscUtils.getLocation(location); - if (seedLoc == null) return; - cropMode.loadChunk(seedLoc); - }, random + dryTime + random); - BukkitTask task2 = bukkitScheduler.runTaskLater(CustomCrops.plugin, () -> { - Location seedLoc = MiscUtils.getLocation(location); - if (seedLoc == null) return; - if (cropMode.growJudge(seedLoc)) { - cropCache.remove(location); - } - }, sprinklerTime + dryTime + random + 5); - tasksCache.add(task1); - tasksCache.add(task2); + growSingleFrame(location, sprinklerTime + dryTime + random); } } + private void growSingleFrame(SimpleLocation location, long delay) { + BukkitTask task1 = bukkitScheduler.runTaskLater(CustomCrops.plugin, () -> { + Location seedLoc = MiscUtils.getLocation(location); + if (seedLoc == null) return; + cropMode.loadChunk(seedLoc); + }, delay); + BukkitTask task2 = bukkitScheduler.runTaskLater(CustomCrops.plugin, () -> { + Location seedLoc = MiscUtils.getLocation(location); + if (seedLoc == null) return; + if (cropMode.growJudge(seedLoc)) { + cropCache.remove(location); + } + }, delay + 5); + tasksCache.add(task1); + tasksCache.add(task2); + } + private void route(int sprinklerTime) { for (BukkitTask task : tasksCache) { @@ -413,6 +423,7 @@ public class CustomWorld { watered.clear(); watered.addAll(playerWatered); playerWatered.clear(); + plantedToday.clear();; Random randomGenerator = new Random(); for (Map.Entry sprinklerEntry : sprinklerCache.entrySet()) { @@ -509,7 +520,18 @@ public class CustomWorld { } public void addCrop(Location cropLoc, String crop) { - cropCache.put(MiscUtils.getSimpleLocation(cropLoc), crop); + SimpleLocation simpleLocation = MiscUtils.getSimpleLocation(cropLoc); + cropCache.put(simpleLocation, crop); + if (MainConfig.enableCompensation && !plantedToday.contains(simpleLocation) && world.getTime() < 23000) { + long random = new Random().nextInt(MainConfig.timeToGrow); + plantedToday.add(simpleLocation); + if (MainConfig.cropMode) { + growSingleWire(simpleLocation, random); + } + else { + growSingleFrame(simpleLocation, random); + } + } } public void removeSprinkler(Location location) { diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index be61ad6..ab0459d 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,5 +1,5 @@ #Don't change -config-version: '11' +config-version: '12' # lang: english / spanish / chinese lang: english @@ -197,6 +197,19 @@ actionbar: +season-broadcast: + enable: true + spring: + - '<#3CB371>Spring is coming!' + summer: + - '<#FFFFE0>Summer is coming!' + autumn: + - '<#FF8C00>Autumn is coming!' + winter: + - '<#87CEFA>Winter is coming!' + + + watering-can-lore: # Should watering-can has dynamic lore according to the water amount enable: true