9
0
mirror of https://github.com/Xiao-MoMi/Custom-Crops.git synced 2025-12-23 08:59:28 +00:00

3.2.5.0-beta

This commit is contained in:
XiaoMoMi
2023-06-17 18:45:18 +08:00
parent 7d7e87a05e
commit 420960b1ff
10 changed files with 144 additions and 39 deletions

View File

@@ -4,7 +4,7 @@ plugins {
} }
group = 'net.momirealms' group = 'net.momirealms'
version = '3.2.4.0' version = '3.2.5.0-beta'
repositories { repositories {
mavenCentral() mavenCentral()

View File

@@ -45,11 +45,14 @@ import net.momirealms.customcrops.api.object.sprinkler.SprinklerConfig;
import net.momirealms.customcrops.api.object.wateringcan.WateringCanConfig; import net.momirealms.customcrops.api.object.wateringcan.WateringCanConfig;
import net.momirealms.customcrops.api.object.world.SimpleLocation; import net.momirealms.customcrops.api.object.world.SimpleLocation;
import net.momirealms.customcrops.api.util.AdventureUtils; import net.momirealms.customcrops.api.util.AdventureUtils;
import net.momirealms.customcrops.api.util.RotationUtils;
import net.momirealms.protectionlib.ProtectionLib; import net.momirealms.protectionlib.ProtectionLib;
import org.bukkit.*; import org.bukkit.*;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.ItemDisplay;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable; import org.bukkit.event.Cancellable;
import org.bukkit.event.Event; import org.bukkit.event.Event;
@@ -745,7 +748,18 @@ public class PlatformManager extends Function {
if (player.getGameMode() != GameMode.CREATIVE) item_in_hand.setAmount(item_in_hand.getAmount() - 1); if (player.getGameMode() != GameMode.CREATIVE) item_in_hand.setAmount(item_in_hand.getAmount() - 1);
player.swingMainHand(); player.swingMainHand();
CustomCrops.getInstance().getPlatformInterface().placeCustomItem(crop_loc, cropPlantEvent.getCropModel(), cropConfig.getCropMode()); switch (cropConfig.getCropMode()) {
case ITEM_DISPLAY -> {
ItemDisplay itemDisplay = CustomCrops.getInstance().getPlatformInterface().placeItemDisplay(crop_loc, cropPlantEvent.getCropModel());
if (itemDisplay != null && cropConfig.isRotationEnabled()) itemDisplay.setRotation(RotationUtils.getRandomFloatRotation(), 0);
}
case ITEM_FRAME -> {
ItemFrame itemFrame = CustomCrops.getInstance().getPlatformInterface().placeItemFrame(crop_loc, cropPlantEvent.getCropModel());
if (itemFrame != null && cropConfig.isRotationEnabled()) itemFrame.setRotation(RotationUtils.getRandomRotation());
}
case TRIPWIRE -> CustomCrops.getInstance().getPlatformInterface().placeTripWire(crop_loc, cropPlantEvent.getCropModel());
}
plugin.getWorldDataManager().addCropData(SimpleLocation.getByBukkitLocation(crop_loc), new GrowingCrop(cropConfig.getKey(), cropPlantEvent.getPoint()), true); plugin.getWorldDataManager().addCropData(SimpleLocation.getByBukkitLocation(crop_loc), new GrowingCrop(cropConfig.getKey(), cropPlantEvent.getPoint()), true);
return true; return true;
} }

View File

@@ -0,0 +1,33 @@
package net.momirealms.customcrops.api.event;
import net.momirealms.customcrops.api.object.season.CCSeason;
import org.bukkit.World;
import org.bukkit.event.HandlerList;
import org.bukkit.event.world.WorldEvent;
import org.jetbrains.annotations.NotNull;
public class SeasonChangeEvent extends WorldEvent {
private static final HandlerList handlers = new HandlerList();
private final CCSeason ccSeason;
public SeasonChangeEvent(@NotNull World world, CCSeason ccSeason) {
super(world);
this.ccSeason = ccSeason;
}
@NotNull
public static HandlerList getHandlerList() {
return handlers;
}
@NotNull
@Override
public HandlerList getHandlers() {
return getHandlerList();
}
public CCSeason getCcSeason() {
return ccSeason;
}
}

View File

@@ -41,6 +41,7 @@ public class CropConfig {
private final Condition[] growConditions; private final Condition[] growConditions;
private final BoneMeal[] boneMeals; private final BoneMeal[] boneMeals;
private final Action[] plantActions; private final Action[] plantActions;
private final boolean rotation;
public CropConfig(String key, public CropConfig(String key,
ItemMode itemMode, ItemMode itemMode,
@@ -52,7 +53,8 @@ public class CropConfig {
Condition[] growConditions, Condition[] growConditions,
HashMap<Integer, StageConfig> stageMap, HashMap<Integer, StageConfig> stageMap,
BoneMeal[] boneMeals, BoneMeal[] boneMeals,
Action[] plantActions Action[] plantActions,
boolean rotation
) { ) {
this.key = key; this.key = key;
this.itemMode = itemMode; this.itemMode = itemMode;
@@ -65,6 +67,7 @@ public class CropConfig {
this.growConditions = growConditions; this.growConditions = growConditions;
this.boneMeals = boneMeals; this.boneMeals = boneMeals;
this.plantActions = plantActions; this.plantActions = plantActions;
this.rotation = rotation;
} }
public String getKey() { public String getKey() {
@@ -119,4 +122,8 @@ public class CropConfig {
public Action[] getPlantActions() { public Action[] getPlantActions() {
return plantActions; return plantActions;
} }
public boolean isRotationEnabled() {
return rotation;
}
} }

View File

@@ -155,7 +155,8 @@ public class CropManager extends Function implements Listener {
growConditions, growConditions,
stageMap, stageMap,
ConfigUtils.getBoneMeals(cropSec.getConfigurationSection("custom-bone-meal")), ConfigUtils.getBoneMeals(cropSec.getConfigurationSection("custom-bone-meal")),
ConfigUtils.getActions(cropSec.getConfigurationSection("plant-actions"), null) ConfigUtils.getActions(cropSec.getConfigurationSection("plant-actions"), null),
cropSec.getBoolean("random-rotation", false)
); );
cropConfigMap.put(key, cropConfig); cropConfigMap.put(key, cropConfig);
if (seed != null) seedToCropConfig.put(seed, cropConfig); if (seed != null) seedToCropConfig.put(seed, cropConfig);

View File

@@ -17,7 +17,12 @@
package net.momirealms.customcrops.api.object.season; package net.momirealms.customcrops.api.object.season;
import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.api.event.SeasonChangeEvent;
import net.momirealms.customcrops.api.object.basic.ConfigManager; import net.momirealms.customcrops.api.object.basic.ConfigManager;
import org.bukkit.Bukkit;
import java.util.Objects;
public class SeasonData { public class SeasonData {
@@ -50,6 +55,7 @@ public class SeasonData {
if (date > ConfigManager.seasonInterval) { if (date > ConfigManager.seasonInterval) {
this.date = 1; this.date = 1;
this.ccSeason = getNextSeason(ccSeason); this.ccSeason = getNextSeason(ccSeason);
CustomCrops.getInstance().getScheduler().runTask(this::callEvent);
} }
} }
@@ -64,7 +70,10 @@ public class SeasonData {
} }
public void changeSeason(CCSeason ccSeason) { public void changeSeason(CCSeason ccSeason) {
this.ccSeason = ccSeason; if (ccSeason != this.ccSeason) {
this.ccSeason = ccSeason;
callEvent();
}
} }
public String getWorld() { public String getWorld() {
@@ -74,4 +83,9 @@ public class SeasonData {
public void setDate(int date) { public void setDate(int date) {
this.date = date; this.date = date;
} }
private void callEvent() {
SeasonChangeEvent seasonChangeEvent = new SeasonChangeEvent(Objects.requireNonNull(Bukkit.getWorld(world)), ccSeason);
Bukkit.getPluginManager().callEvent(seasonChangeEvent);
}
} }

View File

@@ -42,11 +42,14 @@ import net.momirealms.customcrops.api.object.sprinkler.SprinklerConfig;
import net.momirealms.customcrops.api.util.AdventureUtils; import net.momirealms.customcrops.api.util.AdventureUtils;
import net.momirealms.customcrops.api.util.ConfigUtils; import net.momirealms.customcrops.api.util.ConfigUtils;
import net.momirealms.customcrops.api.util.FakeEntityUtils; import net.momirealms.customcrops.api.util.FakeEntityUtils;
import net.momirealms.customcrops.api.util.RotationUtils;
import net.momirealms.customcrops.helper.Log; import net.momirealms.customcrops.helper.Log;
import org.bukkit.*; import org.bukkit.*;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.data.type.Farmland; import org.bukkit.block.data.type.Farmland;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.ItemDisplay;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -54,10 +57,7 @@ import org.jetbrains.annotations.Nullable;
import java.io.*; import java.io.*;
import java.lang.ref.Reference; import java.lang.ref.Reference;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.*;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*; import java.util.concurrent.*;
public class CCWorld extends Function { public class CCWorld extends Function {
@@ -72,7 +72,8 @@ public class CCWorld extends Function {
private int cacheTimer; private int cacheTimer;
private int workCounter; private int workCounter;
private int consumeCounter; private int consumeCounter;
private final HashSet<SimpleLocation> plantInPoint; private final Set<SimpleLocation> plantInPoint;
private Set<ChunkCoordinate> loadInPoint;
private final ConcurrentHashMap<SimpleLocation, String> corruptedPot; private final ConcurrentHashMap<SimpleLocation, String> corruptedPot;
private final File chunksFolder; private final File chunksFolder;
private final File dateFile; private final File dateFile;
@@ -91,12 +92,14 @@ public class CCWorld extends Function {
this.schedule.setMaximumPoolSize(ConfigManager.maxPoolSize); this.schedule.setMaximumPoolSize(ConfigManager.maxPoolSize);
this.schedule.setKeepAliveTime(ConfigManager.keepAliveTime, TimeUnit.SECONDS); this.schedule.setKeepAliveTime(ConfigManager.keepAliveTime, TimeUnit.SECONDS);
this.schedule.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy()); this.schedule.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
this.plantInPoint = new HashSet<>(128); this.plantInPoint = Collections.synchronizedSet(new HashSet<>(128));
this.loadInPoint = Collections.synchronizedSet(new HashSet<>(32));
this.corruptedPot = new ConcurrentHashMap<>(128); this.corruptedPot = new ConcurrentHashMap<>(128);
this.cacheTimer = ConfigManager.cacheSaveInterval; this.cacheTimer = ConfigManager.cacheSaveInterval;
} }
@Override @Override
@SuppressWarnings("ResultOfMethodCallIgnored")
public void init() { public void init() {
loadDateData(); loadDateData();
loadCorruptedPots(); loadCorruptedPots();
@@ -241,8 +244,7 @@ public class CCWorld extends Function {
long time = current.getTime(); long time = current.getTime();
this.tryDayCycleTask(time, day); this.tryDayCycleTask(time, day);
this.timerTask(); this.timerTask();
} } else {
else {
AdventureUtils.consoleMessage("<red>[CustomCrops] World: " + worldName + " unloaded unexpectedly. Shutdown the schedule."); AdventureUtils.consoleMessage("<red>[CustomCrops] World: " + worldName + " unloaded unexpectedly. Shutdown the schedule.");
this.schedule.shutdown(); this.schedule.shutdown();
} }
@@ -278,31 +280,28 @@ public class CCWorld extends Function {
} }
public void onReachPoint() { public void onReachPoint() {
if (ConfigManager.debugScheduler) Log.info("== Grow point ==");
if (ConfigManager.enableScheduleSystem) { if (ConfigManager.enableScheduleSystem) {
if (ConfigManager.debugScheduler) Log.info("== Grow point =="); // clear the locations where crops are planted in a point interval
plantInPoint.clear(); plantInPoint.clear();
int size = schedule.getQueue().size(); // clear the chunk coordinates that has grown in a point interval
if (size != 0) { loadInPoint = Collections.synchronizedSet(new HashSet<>(chunkMap.keySet()));
schedule.getQueue().clear(); // clear the queue if there exists unhandled tasks
if (ConfigManager.debugScheduler) Log.info("== Clear queue =="); schedule.getQueue().clear();
} // arrange crop grow check task
for (CCChunk chunk : chunkMap.values()) { for (CCChunk chunk : chunkMap.values()) {
chunk.scheduleGrowTask(this, -1); chunk.scheduleGrowTask(this, -1);
} }
if (workCounter > 0) { workCounter--;
workCounter--; consumeCounter--;
}
if (consumeCounter > 0) {
consumeCounter--;
}
if (consumeCounter == 0) { if (consumeCounter == 0) {
consumeCounter = ConfigManager.intervalConsume;
if (ConfigManager.debugScheduler) Log.info("== Consume time =="); if (ConfigManager.debugScheduler) Log.info("== Consume time ==");
consumeCounter = ConfigManager.intervalConsume;
scheduleConsumeTask(-1); scheduleConsumeTask(-1);
} }
if (workCounter == 0) { if (workCounter == 0) {
workCounter = ConfigManager.intervalWork;
if (ConfigManager.debugScheduler) Log.info("== Work time =="); if (ConfigManager.debugScheduler) Log.info("== Work time ==");
workCounter = ConfigManager.intervalWork;
scheduleSprinklerWork(-1); scheduleSprinklerWork(-1);
} }
} }
@@ -342,6 +341,9 @@ public class CCWorld extends Function {
delete = true; delete = true;
} else { } else {
chunkMap.put(chunkCoordinate, chunk); chunkMap.put(chunkCoordinate, chunk);
if (!loadInPoint.contains(chunkCoordinate)) {
chunk.scheduleGrowTask(this, -1);
}
} }
} catch (IOException | ClassNotFoundException e) { } catch (IOException | ClassNotFoundException e) {
e.printStackTrace(); e.printStackTrace();
@@ -561,7 +563,6 @@ public class CCWorld extends Function {
addWaterToPot(simpleLocation, amount, potKey); addWaterToPot(simpleLocation, amount, potKey);
} }
} else if (ConfigManager.enableCorruptionFixer && blockID.equals("NOTE_BLOCK")) { } else if (ConfigManager.enableCorruptionFixer && blockID.equals("NOTE_BLOCK")) {
// Only ItemsAdder can go to this step
Pot pot = getPotData(simpleLocation); Pot pot = getPotData(simpleLocation);
if (pot != null) { if (pot != null) {
// mark it as corrupted // mark it as corrupted
@@ -577,11 +578,11 @@ public class CCWorld extends Function {
} }
} }
corruptedPot.put(simpleLocation, potKey); corruptedPot.put(simpleLocation, potKey);
if (ConfigManager.debugCorruption) AdventureUtils.consoleMessage("[CustomCrops] Trying to fix corrupted pot found at: " + simpleLocation); if (ConfigManager.debugCorruption) AdventureUtils.consoleMessage("[CustomCrops] Corrupted pot found at: " + simpleLocation);
// only custom blocks would corrupt // only custom blocks would corrupt
// so it's not necessary to check if the pot is a vanilla block // so it's not necessary to check if the pot is a vanilla block
String replacer = pot.isWet() ? pot.getConfig().getWetPot(pot.getFertilizer()) : pot.getConfig().getDryPot(pot.getFertilizer()); // String replacer = pot.isWet() ? pot.getConfig().getWetPot(pot.getFertilizer()) : pot.getConfig().getDryPot(pot.getFertilizer());
plugin.getPlatformInterface().placeNoteBlock(location, replacer); // plugin.getPlatformInterface().placeNoteBlock(location, replacer);
} }
} }
} }
@@ -684,7 +685,7 @@ public class CCWorld extends Function {
if (finalNextModel == null || location == null) return; if (finalNextModel == null || location == null) return;
CompletableFuture<Chunk> asyncGetChunk = location.getWorld().getChunkAtAsync(location.getBlockX() >> 4, location.getBlockZ() >> 4); CompletableFuture<Chunk> asyncGetChunk = location.getWorld().getChunkAtAsync(location.getBlockX() >> 4, location.getBlockZ() >> 4);
if (itemMode == ItemMode.ITEM_FRAME || itemMode == ItemMode.ITEM_DISPLAY) { if (itemMode == ItemMode.ITEM_FRAME) {
CompletableFuture<Boolean> loadEntities = asyncGetChunk.thenApply((chunk) -> { CompletableFuture<Boolean> loadEntities = asyncGetChunk.thenApply((chunk) -> {
chunk.getEntities(); chunk.getEntities();
return chunk.isEntitiesLoaded(); return chunk.isEntitiesLoaded();
@@ -692,17 +693,31 @@ public class CCWorld extends Function {
loadEntities.whenComplete((result, throwable) -> loadEntities.whenComplete((result, throwable) ->
plugin.getScheduler().runTask(() -> { plugin.getScheduler().runTask(() -> {
if (plugin.getPlatformInterface().removeCustomItem(location, itemMode)) { if (plugin.getPlatformInterface().removeCustomItem(location, itemMode)) {
plugin.getPlatformInterface().placeCustomItem(location, finalNextModel, itemMode); ItemFrame itemFrame = plugin.getPlatformInterface().placeItemFrame(location, finalNextModel);
if (itemFrame != null && cropConfig.isRotationEnabled()) itemFrame.setRotation(RotationUtils.getRandomRotation());
} else { } else {
removeCropData(simpleLocation); removeCropData(simpleLocation);
} }
})); }));
} } else if (itemMode == ItemMode.ITEM_DISPLAY) {
else { CompletableFuture<Boolean> loadEntities = asyncGetChunk.thenApply((chunk) -> {
chunk.getEntities();
return chunk.isEntitiesLoaded();
});
loadEntities.whenComplete((result, throwable) ->
plugin.getScheduler().runTask(() -> {
if (plugin.getPlatformInterface().removeCustomItem(location, itemMode)) {
ItemDisplay itemDisplay = plugin.getPlatformInterface().placeItemDisplay(location, finalNextModel);
if (itemDisplay != null && cropConfig.isRotationEnabled()) itemDisplay.setRotation(RotationUtils.getRandomFloatRotation(), 0);
} else {
removeCropData(simpleLocation);
}
}));
} else {
asyncGetChunk.whenComplete((result, throwable) -> asyncGetChunk.whenComplete((result, throwable) ->
plugin.getScheduler().runTask(() -> { plugin.getScheduler().runTask(() -> {
if (plugin.getPlatformInterface().removeCustomItem(location, itemMode)) { if (plugin.getPlatformInterface().removeCustomItem(location, itemMode)) {
plugin.getPlatformInterface().placeCustomItem(location, finalNextModel, itemMode); plugin.getPlatformInterface().placeTripWire(location, finalNextModel);
} else { } else {
removeCropData(simpleLocation); removeCropData(simpleLocation);
} }

View File

@@ -1,3 +1,20 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customcrops.api.object.world; package net.momirealms.customcrops.api.object.world;
import com.infernalsuite.aswm.api.events.LoadSlimeWorldEvent; import com.infernalsuite.aswm.api.events.LoadSlimeWorldEvent;

View File

@@ -232,8 +232,7 @@ public class WorldDataManager extends Function {
Sprinkler sprinkler = getSprinklerData(simpleLocation); Sprinkler sprinkler = getSprinklerData(simpleLocation);
if (sprinkler != null) { if (sprinkler != null) {
sprinkler.setWater(Math.min(add + sprinkler.getWater(), sprinklerConfig.getStorage())); sprinkler.setWater(Math.min(add + sprinkler.getWater(), sprinklerConfig.getStorage()));
} } else {
else {
Sprinkler newSprinkler = new Sprinkler(sprinklerConfig.getKey(), Math.min(add, sprinklerConfig.getStorage())); Sprinkler newSprinkler = new Sprinkler(sprinklerConfig.getKey(), Math.min(add, sprinklerConfig.getStorage()));
addSprinklerData(simpleLocation, newSprinkler); addSprinklerData(simpleLocation, newSprinkler);
} }

View File

@@ -24,8 +24,13 @@ import java.util.Random;
public class RotationUtils { public class RotationUtils {
private static final Rotation[] rotations4 = {Rotation.NONE, Rotation.FLIPPED, Rotation.CLOCKWISE, Rotation.COUNTER_CLOCKWISE}; private static final Rotation[] rotations4 = {Rotation.NONE, Rotation.FLIPPED, Rotation.CLOCKWISE, Rotation.COUNTER_CLOCKWISE};
private static final float[] rotationsF = {0f, 90f, 180f, -90f};
public static Rotation getRandomRotation() { public static Rotation getRandomRotation() {
return rotations4[new Random().nextInt(rotations4.length-1)]; return rotations4[new Random().nextInt(4)];
}
public static float getRandomFloatRotation() {
return rotationsF[new Random().nextInt(4)];
} }
} }