mirror of
https://github.com/Xiao-MoMi/Custom-Crops.git
synced 2025-12-26 10:29:10 +00:00
untested offline growth
This commit is contained in:
@@ -38,7 +38,7 @@ import net.momirealms.customcrops.mechanic.misc.migrator.Migration;
|
||||
import net.momirealms.customcrops.mechanic.requirement.RequirementManagerImpl;
|
||||
import net.momirealms.customcrops.mechanic.world.WorldManagerImpl;
|
||||
import net.momirealms.customcrops.scheduler.SchedulerImpl;
|
||||
import net.momirealms.customcrops.utils.EventUtils;
|
||||
import net.momirealms.customcrops.util.EventUtils;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ public class CommandManager implements Initable {
|
||||
for (CustomCropsSection section : chunk.getSections()) {
|
||||
for (CustomCropsBlock block : section.getBlocks()) {
|
||||
if (block.getType() == itemType) {
|
||||
block.tick(1);
|
||||
block.tick(1, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ import dev.dejvokep.boostedyaml.settings.updater.UpdaterSettings;
|
||||
import net.momirealms.customcrops.api.CustomCropsPlugin;
|
||||
import net.momirealms.customcrops.api.manager.ConfigManager;
|
||||
import net.momirealms.customcrops.api.util.LogUtils;
|
||||
import net.momirealms.customcrops.utils.ConfigUtils;
|
||||
import net.momirealms.customcrops.util.ConfigUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
@@ -23,7 +23,7 @@ import net.momirealms.customcrops.api.common.Reloadable;
|
||||
import net.momirealms.customcrops.api.common.Tuple;
|
||||
import net.momirealms.customcrops.api.manager.VersionManager;
|
||||
import net.momirealms.customcrops.api.scheduler.CancellableTask;
|
||||
import net.momirealms.customcrops.utils.FakeEntityUtils;
|
||||
import net.momirealms.customcrops.util.FakeEntityUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
@@ -22,7 +22,7 @@ import net.momirealms.customcrops.api.common.Reloadable;
|
||||
import net.momirealms.customcrops.api.manager.ConfigManager;
|
||||
import net.momirealms.customcrops.api.manager.MessageManager;
|
||||
import net.momirealms.customcrops.api.mechanic.world.season.Season;
|
||||
import net.momirealms.customcrops.utils.ConfigUtils;
|
||||
import net.momirealms.customcrops.util.ConfigUtils;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import net.momirealms.customcrops.api.CustomCropsPlugin;
|
||||
import net.momirealms.customcrops.api.manager.PlaceholderManager;
|
||||
import net.momirealms.customcrops.compatibility.papi.CCPapi;
|
||||
import net.momirealms.customcrops.compatibility.papi.ParseUtils;
|
||||
import net.momirealms.customcrops.utils.ConfigUtils;
|
||||
import net.momirealms.customcrops.util.ConfigUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
@@ -56,10 +56,10 @@ import net.momirealms.customcrops.manager.PacketManager;
|
||||
import net.momirealms.customcrops.mechanic.item.impl.VariationCrop;
|
||||
import net.momirealms.customcrops.mechanic.misc.TempFakeItem;
|
||||
import net.momirealms.customcrops.mechanic.world.block.MemoryCrop;
|
||||
import net.momirealms.customcrops.utils.ClassUtils;
|
||||
import net.momirealms.customcrops.utils.ConfigUtils;
|
||||
import net.momirealms.customcrops.utils.EventUtils;
|
||||
import net.momirealms.customcrops.utils.ItemUtils;
|
||||
import net.momirealms.customcrops.util.ClassUtils;
|
||||
import net.momirealms.customcrops.util.ConfigUtils;
|
||||
import net.momirealms.customcrops.util.EventUtils;
|
||||
import net.momirealms.customcrops.util.ItemUtils;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
@@ -220,6 +220,7 @@ public class ActionManagerImpl implements ActionManager {
|
||||
boolean onlyShowToOne = !section.getBoolean("visible-to-all", false);
|
||||
return condition -> {
|
||||
if (Math.random() > chance) return;
|
||||
if (condition.getArg("{offline}") != null) return;
|
||||
Location location = condition.getLocation().clone().add(x,y,z);
|
||||
SimpleLocation simpleLocation = SimpleLocation.of(location);
|
||||
if (applyCorrection) {
|
||||
@@ -269,6 +270,7 @@ public class ActionManagerImpl implements ActionManager {
|
||||
boolean onlyShowToOne = !section.getBoolean("visible-to-all", true);
|
||||
return condition -> {
|
||||
if (Math.random() > chance) return;
|
||||
if (condition.getArg("{offline}") != null) return;
|
||||
if (item.equals("")) return;
|
||||
Location location = condition.getLocation().clone().add(x,y,z);
|
||||
new TempFakeItem(location, item, duration, onlyShowToOne ? condition.getPlayer() : null).start();
|
||||
@@ -446,7 +448,7 @@ public class ActionManagerImpl implements ActionManager {
|
||||
.flatMap(world -> world.getLoadedChunkAt(ChunkPos.getByBukkitChunk(location.getChunk())))
|
||||
.flatMap(chunk -> chunk.getBlockAt(SimpleLocation.of(location)))
|
||||
.ifPresent(block -> {
|
||||
block.tick(1);
|
||||
block.tick(1, false);
|
||||
if (block instanceof WorldSprinkler sprinkler) {
|
||||
Sprinkler config = sprinkler.getConfig();
|
||||
state.setArg("{current}", String.valueOf(sprinkler.getWater()));
|
||||
|
||||
@@ -33,8 +33,9 @@ import net.momirealms.customcrops.api.mechanic.world.season.Season;
|
||||
import net.momirealms.customcrops.api.util.LogUtils;
|
||||
import net.momirealms.customcrops.compatibility.papi.ParseUtils;
|
||||
import net.momirealms.customcrops.mechanic.misc.CrowAttackAnimation;
|
||||
import net.momirealms.customcrops.utils.ClassUtils;
|
||||
import net.momirealms.customcrops.utils.ConfigUtils;
|
||||
import net.momirealms.customcrops.mechanic.world.block.MemoryCrop;
|
||||
import net.momirealms.customcrops.util.ClassUtils;
|
||||
import net.momirealms.customcrops.util.ConfigUtils;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.type.Farmland;
|
||||
@@ -95,6 +96,7 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
this.registerCrowAttackCondition();
|
||||
this.registerPotCondition();
|
||||
this.registerLightCondition();
|
||||
this.registerPointCondition();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -167,7 +169,7 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
String flyModel = section.getString("fly-model");
|
||||
String standModel = section.getString("stand-model");
|
||||
double chance = section.getDouble("chance");
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
if (Math.random() > chance) return false;
|
||||
SimpleLocation location = block.getLocation();
|
||||
if (ConfigManager.enableScarecrow()) {
|
||||
@@ -185,7 +187,8 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
new CrowAttackAnimation(location, flyModel, standModel).start();
|
||||
if (!offline)
|
||||
new CrowAttackAnimation(location, flyModel, standModel).start();
|
||||
return true;
|
||||
};
|
||||
} else {
|
||||
@@ -198,14 +201,14 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
private void registerBiomeRequirement() {
|
||||
registerCondition("biome", (args) -> {
|
||||
HashSet<String> biomes = new HashSet<>(ConfigUtils.stringListArgs(args));
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
String currentBiome = BiomeAPI.getBiomeAt(block.getLocation().getBukkitLocation());
|
||||
return biomes.contains(currentBiome);
|
||||
};
|
||||
});
|
||||
registerCondition("!biome", (args) -> {
|
||||
HashSet<String> biomes = new HashSet<>(ConfigUtils.stringListArgs(args));
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
String currentBiome = BiomeAPI.getBiomeAt(block.getLocation().getBukkitLocation());
|
||||
return !biomes.contains(currentBiome);
|
||||
};
|
||||
@@ -215,21 +218,21 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
private void registerRandomCondition() {
|
||||
registerCondition("random", (args -> {
|
||||
double value = ConfigUtils.getDoubleValue(args);
|
||||
return block -> Math.random() < value;
|
||||
return (block, offline) -> Math.random() < value;
|
||||
}));
|
||||
}
|
||||
|
||||
private void registerPotCondition() {
|
||||
registerCondition("pot", (args -> {
|
||||
HashSet<String> pots = new HashSet<>(ConfigUtils.stringListArgs(args));
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
Optional<WorldPot> worldPot = plugin.getWorldManager().getPotAt(block.getLocation().copy().add(0,-1,0));
|
||||
return worldPot.filter(pot -> pots.contains(pot.getKey())).isPresent();
|
||||
};
|
||||
}));
|
||||
registerCondition("!pot", (args -> {
|
||||
HashSet<String> pots = new HashSet<>(ConfigUtils.stringListArgs(args));
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
Optional<WorldPot> worldPot = plugin.getWorldManager().getPotAt(block.getLocation().copy().add(0,-1,0));
|
||||
return worldPot.filter(pot -> !pots.contains(pot.getKey())).isPresent();
|
||||
};
|
||||
@@ -239,7 +242,7 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
private void registerFertilizerCondition() {
|
||||
registerCondition("fertilizer", (args -> {
|
||||
HashSet<String> fertilizer = new HashSet<>(ConfigUtils.stringListArgs(args));
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
Optional<WorldPot> worldPot = plugin.getWorldManager().getPotAt(block.getLocation().copy().add(0,-1,0));
|
||||
return worldPot.filter(pot -> {
|
||||
Fertilizer fertilizerInstance = pot.getFertilizer();
|
||||
@@ -250,7 +253,7 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
}));
|
||||
registerCondition("fertilizer_type", (args -> {
|
||||
HashSet<String> fertilizer = new HashSet<>(ConfigUtils.stringListArgs(args).stream().map(str -> str.toUpperCase(Locale.ENGLISH)).toList());
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
Optional<WorldPot> worldPot = plugin.getWorldManager().getPotAt(block.getLocation().copy().add(0,-1,0));
|
||||
return worldPot.filter(pot -> {
|
||||
Fertilizer fertilizerInstance = pot.getFertilizer();
|
||||
@@ -265,7 +268,7 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
registerCondition("&&", (args -> {
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
Condition[] conditions = getConditions(section);
|
||||
return block -> ConditionManager.isConditionMet(block, conditions);
|
||||
return (block, offline) -> ConditionManager.isConditionMet(block, offline, conditions);
|
||||
} else {
|
||||
LogUtils.warn("Wrong value format found at && condition.");
|
||||
return EmptyCondition.instance;
|
||||
@@ -277,9 +280,9 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
registerCondition("||", (args -> {
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
Condition[] conditions = getConditions(section);
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
for (Condition condition : conditions) {
|
||||
if (condition.isConditionMet(block)) {
|
||||
if (condition.isConditionMet(block, offline)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -295,7 +298,7 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
private void registerTemperatureCondition() {
|
||||
registerCondition("temperature", (args) -> {
|
||||
List<Pair<Integer, Integer>> tempPairs = ConfigUtils.stringListArgs(args).stream().map(it -> ConfigUtils.splitStringIntegerArgs(it, "~")).toList();
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
SimpleLocation location = block.getLocation();
|
||||
World world = location.getBukkitWorld();
|
||||
if (world == null) return false;
|
||||
@@ -316,7 +319,7 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
String v1 = section.getString("value1", "");
|
||||
String v2 = section.getString("value2", "");
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
String p1 = v1.startsWith("%") ? ParseUtils.setPlaceholders(null, v1) : v1;
|
||||
String p2 = v2.startsWith("%") ? ParseUtils.setPlaceholders(null, v2) : v2;
|
||||
return Double.parseDouble(p1) >= Double.parseDouble(p2);
|
||||
@@ -330,7 +333,7 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
String v1 = section.getString("value1", "");
|
||||
String v2 = section.getString("value2", "");
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
String p1 = v1.startsWith("%") ? ParseUtils.setPlaceholders(null, v1) : v1;
|
||||
String p2 = v2.startsWith("%") ? ParseUtils.setPlaceholders(null, v2) : v2;
|
||||
return Double.parseDouble(p1) > Double.parseDouble(p2);
|
||||
@@ -347,7 +350,7 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
String v1 = section.getString("papi", "");
|
||||
String v2 = section.getString("regex", "");
|
||||
return block -> ParseUtils.setPlaceholders(null, v1).matches(v2);
|
||||
return (block, offline) -> ParseUtils.setPlaceholders(null, v1).matches(v2);
|
||||
} else {
|
||||
LogUtils.warn("Wrong value format found at regex requirement.");
|
||||
return EmptyCondition.instance;
|
||||
@@ -360,7 +363,7 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
String v1 = section.getString("value1", "");
|
||||
String v2 = section.getString("value2", "");
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
String p1 = v1.startsWith("%") ? ParseUtils.setPlaceholders(null, v1) : v1;
|
||||
String p2 = v2.startsWith("%") ? ParseUtils.setPlaceholders(null, v2) : v2;
|
||||
return Double.parseDouble(p1) == Double.parseDouble(p2);
|
||||
@@ -374,7 +377,7 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
String v1 = section.getString("value1", "");
|
||||
String v2 = section.getString("value2", "");
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
String p1 = v1.startsWith("%") ? ParseUtils.setPlaceholders(null, v1) : v1;
|
||||
String p2 = v2.startsWith("%") ? ParseUtils.setPlaceholders(null, v2) : v2;
|
||||
return Double.parseDouble(p1) != Double.parseDouble(p2);
|
||||
@@ -392,7 +395,7 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
String v1 = section.getString("value1", "");
|
||||
String v2 = section.getString("value2", "");
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
String p1 = v1.startsWith("%") ? ParseUtils.setPlaceholders(null, v1) : v1;
|
||||
String p2 = v2.startsWith("%") ? ParseUtils.setPlaceholders(null, v2) : v2;
|
||||
return Double.parseDouble(p1) < Double.parseDouble(p2);
|
||||
@@ -406,7 +409,7 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
String v1 = section.getString("value1", "");
|
||||
String v2 = section.getString("value2", "");
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
String p1 = v1.startsWith("%") ? ParseUtils.setPlaceholders(null, v1) : v1;
|
||||
String p2 = v2.startsWith("%") ? ParseUtils.setPlaceholders(null, v2) : v2;
|
||||
return Double.parseDouble(p1) <= Double.parseDouble(p2);
|
||||
@@ -423,7 +426,7 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
String v1 = section.getString("value1", "");
|
||||
String v2 = section.getString("value2", "");
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
String p1 = v1.startsWith("%") ? ParseUtils.setPlaceholders(null, v1) : v1;
|
||||
String p2 = v2.startsWith("%") ? ParseUtils.setPlaceholders(null, v2) : v2;
|
||||
return p1.startsWith(p2);
|
||||
@@ -437,7 +440,7 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
String v1 = section.getString("value1", "");
|
||||
String v2 = section.getString("value2", "");
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
String p1 = v1.startsWith("%") ? ParseUtils.setPlaceholders(null, v1) : v1;
|
||||
String p2 = v2.startsWith("%") ? ParseUtils.setPlaceholders(null, v2) : v2;
|
||||
return !p1.startsWith(p2);
|
||||
@@ -454,7 +457,7 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
String v1 = section.getString("value1", "");
|
||||
String v2 = section.getString("value2", "");
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
String p1 = v1.startsWith("%") ? ParseUtils.setPlaceholders(null, v1) : v1;
|
||||
String p2 = v2.startsWith("%") ? ParseUtils.setPlaceholders(null, v2) : v2;
|
||||
return p1.endsWith(p2);
|
||||
@@ -468,7 +471,7 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
String v1 = section.getString("value1", "");
|
||||
String v2 = section.getString("value2", "");
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
String p1 = v1.startsWith("%") ? ParseUtils.setPlaceholders(null, v1) : v1;
|
||||
String p2 = v2.startsWith("%") ? ParseUtils.setPlaceholders(null, v2) : v2;
|
||||
return !p1.endsWith(p2);
|
||||
@@ -485,7 +488,7 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
String v1 = section.getString("value1", "");
|
||||
String v2 = section.getString("value2", "");
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
String p1 = v1.startsWith("%") ? ParseUtils.setPlaceholders(null, v1) : v1;
|
||||
String p2 = v2.startsWith("%") ? ParseUtils.setPlaceholders(null, v2) : v2;
|
||||
return p1.contains(p2);
|
||||
@@ -499,7 +502,7 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
String v1 = section.getString("value1", "");
|
||||
String v2 = section.getString("value2", "");
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
String p1 = v1.startsWith("%") ? ParseUtils.setPlaceholders(null, v1) : v1;
|
||||
String p2 = v2.startsWith("%") ? ParseUtils.setPlaceholders(null, v2) : v2;
|
||||
return !p1.contains(p2);
|
||||
@@ -516,7 +519,7 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
String papi = section.getString("papi", "");
|
||||
HashSet<String> values = new HashSet<>(ConfigUtils.stringListArgs(section.get("values")));
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
String p1 = papi.startsWith("%") ? ParseUtils.setPlaceholders(null, papi) : papi;
|
||||
return values.contains(p1);
|
||||
};
|
||||
@@ -529,7 +532,7 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
String papi = section.getString("papi", "");
|
||||
HashSet<String> values = new HashSet<>(ConfigUtils.stringListArgs(section.get("values")));
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
String p1 = papi.startsWith("%") ? ParseUtils.setPlaceholders(null, papi) : papi;
|
||||
return !values.contains(p1);
|
||||
};
|
||||
@@ -545,7 +548,7 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
String v1 = section.getString("value1", "");
|
||||
String v2 = section.getString("value2", "");
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
String p1 = v1.startsWith("%") ? ParseUtils.setPlaceholders(null, v1) : v1;
|
||||
String p2 = v2.startsWith("%") ? ParseUtils.setPlaceholders(null, v2) : v2;
|
||||
return p1.equals(p2);
|
||||
@@ -559,7 +562,7 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
String v1 = section.getString("value1", "");
|
||||
String v2 = section.getString("value2", "");
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
String p1 = v1.startsWith("%") ? ParseUtils.setPlaceholders(null, v1) : v1;
|
||||
String p2 = v2.startsWith("%") ? ParseUtils.setPlaceholders(null, v2) : v2;
|
||||
return !p1.equals(p2);
|
||||
@@ -574,7 +577,7 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
private void registerSeasonCondition() {
|
||||
registerCondition("suitable_season", (args) -> {
|
||||
HashSet<String> seasons = new HashSet<>(ConfigUtils.stringListArgs(args).stream().map(it -> it.toUpperCase(Locale.ENGLISH)).toList());
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
Season season = plugin.getIntegrationManager().getSeason(block.getLocation().getBukkitWorld());
|
||||
if (season == null) {
|
||||
return true;
|
||||
@@ -598,7 +601,7 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
});
|
||||
registerCondition("unsuitable_season", (args) -> {
|
||||
HashSet<String> seasons = new HashSet<>(ConfigUtils.stringListArgs(args).stream().map(it -> it.toUpperCase(Locale.ENGLISH)).toList());
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
Season season = plugin.getIntegrationManager().getSeason(block.getLocation().getBukkitWorld());
|
||||
if (season == null) {
|
||||
return false;
|
||||
@@ -625,52 +628,73 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
private void registerLightCondition() {
|
||||
registerCondition("skylight_more_than", (args) -> {
|
||||
int value = (int) args;
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
int light = block.getLocation().getBukkitLocation().getBlock().getLightFromSky();
|
||||
return value > light;
|
||||
};
|
||||
});
|
||||
registerCondition("skylight_less_than", (args) -> {
|
||||
int value = (int) args;
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
int light = block.getLocation().getBukkitLocation().getBlock().getLightFromSky();
|
||||
return value < light;
|
||||
};
|
||||
});
|
||||
registerCondition("light_more_than", (args) -> {
|
||||
int value = (int) args;
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
int light = block.getLocation().getBukkitLocation().getBlock().getLightLevel();
|
||||
return value > light;
|
||||
};
|
||||
});
|
||||
registerCondition("light_less_than", (args) -> {
|
||||
int value = (int) args;
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
int light = block.getLocation().getBukkitLocation().getBlock().getLightLevel();
|
||||
return value < light;
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
private void registerPointCondition() {
|
||||
registerCondition("point_more_than", (args) -> {
|
||||
int value = (int) args;
|
||||
return (block, offline) -> {
|
||||
if (block instanceof MemoryCrop crop) {
|
||||
return crop.getPoint() > value;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
});
|
||||
registerCondition("point_less_than", (args) -> {
|
||||
int value = (int) args;
|
||||
return (block, offline) -> {
|
||||
if (block instanceof MemoryCrop crop) {
|
||||
return crop.getPoint() < value;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
private void registerWaterCondition() {
|
||||
registerCondition("water_more_than", (args) -> {
|
||||
int value = (int) args;
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
Optional<WorldPot> worldPot = plugin.getWorldManager().getPotAt(block.getLocation().copy().add(0,-1,0));
|
||||
return worldPot.filter(pot -> pot.getWater() > value).isPresent();
|
||||
};
|
||||
});
|
||||
registerCondition("water_less_than", (args) -> {
|
||||
int value = (int) args;
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
Optional<WorldPot> worldPot = plugin.getWorldManager().getPotAt(block.getLocation().copy().add(0,-1,0));
|
||||
return worldPot.filter(pot -> pot.getWater() < value).isPresent();
|
||||
};
|
||||
});
|
||||
registerCondition("moisture_more_than", (args) -> {
|
||||
int value = (int) args;
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
Block underBlock = block.getLocation().copy().add(0,-1,0).getBukkitLocation().getBlock();
|
||||
if (underBlock.getBlockData() instanceof Farmland farmland) {
|
||||
return farmland.getMoisture() > value;
|
||||
@@ -680,7 +704,7 @@ public class ConditionManagerImpl implements ConditionManager {
|
||||
});
|
||||
registerCondition("moisture_less_than", (args) -> {
|
||||
int value = (int) args;
|
||||
return block -> {
|
||||
return (block, offline) -> {
|
||||
Block underBlock = block.getLocation().copy().add(0,-1,0).getBukkitLocation().getBlock();
|
||||
if (underBlock.getBlockData() instanceof Farmland farmland) {
|
||||
return farmland.getMoisture() < value;
|
||||
|
||||
@@ -25,7 +25,7 @@ public class EmptyCondition implements Condition {
|
||||
public static EmptyCondition instance = new EmptyCondition();
|
||||
|
||||
@Override
|
||||
public boolean isConditionMet(CustomCropsBlock block) {
|
||||
public boolean isConditionMet(CustomCropsBlock block, boolean offline) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,9 +20,9 @@ package net.momirealms.customcrops.mechanic.item;
|
||||
import net.momirealms.customcrops.api.manager.VersionManager;
|
||||
import net.momirealms.customcrops.api.mechanic.misc.CRotation;
|
||||
import net.momirealms.customcrops.api.util.LocationUtils;
|
||||
import net.momirealms.customcrops.utils.ConfigUtils;
|
||||
import net.momirealms.customcrops.utils.DisplayEntityUtils;
|
||||
import net.momirealms.customcrops.utils.RotationUtils;
|
||||
import net.momirealms.customcrops.util.ConfigUtils;
|
||||
import net.momirealms.customcrops.util.DisplayEntityUtils;
|
||||
import net.momirealms.customcrops.util.RotationUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
@@ -57,10 +57,10 @@ import net.momirealms.customcrops.mechanic.item.impl.SprinklerConfig;
|
||||
import net.momirealms.customcrops.mechanic.item.impl.WateringCanConfig;
|
||||
import net.momirealms.customcrops.mechanic.item.impl.fertilizer.*;
|
||||
import net.momirealms.customcrops.mechanic.world.block.*;
|
||||
import net.momirealms.customcrops.utils.ConfigUtils;
|
||||
import net.momirealms.customcrops.utils.EventUtils;
|
||||
import net.momirealms.customcrops.utils.ItemUtils;
|
||||
import net.momirealms.customcrops.utils.RotationUtils;
|
||||
import net.momirealms.customcrops.util.ConfigUtils;
|
||||
import net.momirealms.customcrops.util.EventUtils;
|
||||
import net.momirealms.customcrops.util.ItemUtils;
|
||||
import net.momirealms.customcrops.util.RotationUtils;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
@@ -213,7 +213,7 @@ public class ItemManagerImpl implements ItemManager {
|
||||
|
||||
@Override
|
||||
public String getItemID(ItemStack itemStack) {
|
||||
if (itemStack == null)
|
||||
if (itemStack == null || itemStack.getType() == Material.AIR || itemStack.getAmount() == 0)
|
||||
return "AIR";
|
||||
String id;
|
||||
id = customProvider.getItemID(itemStack);
|
||||
|
||||
@@ -27,7 +27,7 @@ import net.momirealms.customcrops.api.mechanic.requirement.State;
|
||||
import net.momirealms.customcrops.api.mechanic.world.SimpleLocation;
|
||||
import net.momirealms.customcrops.api.mechanic.world.level.WorldCrop;
|
||||
import net.momirealms.customcrops.mechanic.item.ItemManagerImpl;
|
||||
import net.momirealms.customcrops.utils.EventUtils;
|
||||
import net.momirealms.customcrops.util.EventUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
@@ -20,7 +20,6 @@ package net.momirealms.customcrops.mechanic.item.custom.itemsadder;
|
||||
import dev.lone.itemsadder.api.CustomBlock;
|
||||
import dev.lone.itemsadder.api.CustomFurniture;
|
||||
import dev.lone.itemsadder.api.CustomStack;
|
||||
import net.momirealms.customcrops.api.util.LocationUtils;
|
||||
import net.momirealms.customcrops.api.util.LogUtils;
|
||||
import net.momirealms.customcrops.mechanic.item.CustomProvider;
|
||||
import org.bukkit.Location;
|
||||
|
||||
@@ -41,9 +41,7 @@ public class OraxenProvider implements CustomProvider {
|
||||
if (block.getType() == Material.AIR) {
|
||||
return false;
|
||||
}
|
||||
if (!OraxenBlocks.remove(location, null, false)) {
|
||||
block.setType(Material.AIR);
|
||||
}
|
||||
block.setType(Material.AIR);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ import net.momirealms.customcrops.api.mechanic.item.water.PassiveFillMethod;
|
||||
import net.momirealms.customcrops.api.mechanic.misc.image.WaterBar;
|
||||
import net.momirealms.customcrops.api.mechanic.requirement.Requirement;
|
||||
import net.momirealms.customcrops.mechanic.item.AbstractEventItem;
|
||||
import net.momirealms.customcrops.utils.ConfigUtils;
|
||||
import net.momirealms.customcrops.util.ConfigUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
@@ -22,7 +22,7 @@ import net.momirealms.customcrops.api.CustomCropsPlugin;
|
||||
import net.momirealms.customcrops.api.mechanic.world.SimpleLocation;
|
||||
import net.momirealms.customcrops.api.scheduler.CancellableTask;
|
||||
import net.momirealms.customcrops.manager.PacketManager;
|
||||
import net.momirealms.customcrops.utils.FakeEntityUtils;
|
||||
import net.momirealms.customcrops.util.FakeEntityUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
@@ -21,7 +21,7 @@ import com.comphenix.protocol.events.PacketContainer;
|
||||
import net.momirealms.customcrops.api.CustomCropsPlugin;
|
||||
import net.momirealms.customcrops.api.mechanic.world.SimpleLocation;
|
||||
import net.momirealms.customcrops.manager.PacketManager;
|
||||
import net.momirealms.customcrops.utils.FakeEntityUtils;
|
||||
import net.momirealms.customcrops.util.FakeEntityUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
@@ -11,7 +11,7 @@ import net.momirealms.customcrops.api.mechanic.world.level.WorldSetting;
|
||||
import net.momirealms.customcrops.api.util.LogUtils;
|
||||
import net.momirealms.customcrops.mechanic.world.CWorld;
|
||||
import net.momirealms.customcrops.mechanic.world.adaptor.BukkitWorldAdaptor;
|
||||
import net.momirealms.customcrops.utils.ConfigUtils;
|
||||
import net.momirealms.customcrops.util.ConfigUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
@@ -47,7 +47,7 @@ public class Migration {
|
||||
if (CustomCropsPlugin.get().getWorldManager().getWorldAdaptor() instanceof BukkitWorldAdaptor adaptor) {
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
CWorld temp = new CWorld(CustomCropsPlugin.getInstance().getWorldManager(), world);
|
||||
temp.setWorldSetting(WorldSetting.of(false,300,true, 1,true,2,true,2,false,false,false,28,-1,-1,-1, 0));
|
||||
temp.setWorldSetting(WorldSetting.of(false,300,true, 1,true,2,true,2,false,1200, false,false,28,-1,-1,-1, 0));
|
||||
adaptor.convertWorldFromV342toV343(temp, world);
|
||||
}
|
||||
}
|
||||
@@ -102,7 +102,7 @@ public class Migration {
|
||||
if (CustomCropsPlugin.get().getWorldManager().getWorldAdaptor() instanceof BukkitWorldAdaptor adaptor) {
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
CWorld temp = new CWorld(CustomCropsPlugin.getInstance().getWorldManager(), world);
|
||||
temp.setWorldSetting(WorldSetting.of(false,300,true, 1,true,2,true,2,false,false,false,28,-1,-1,-1, 0));
|
||||
temp.setWorldSetting(WorldSetting.of(false,300,true, 1,true,2,true,2,false, 1200, false,false,28,-1,-1,-1, 0));
|
||||
adaptor.convertWorldFromV33toV34(temp, world);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
package net.momirealms.customcrops.mechanic.misc.value;
|
||||
|
||||
import net.momirealms.customcrops.api.mechanic.misc.Value;
|
||||
import net.momirealms.customcrops.utils.ConfigUtils;
|
||||
import net.momirealms.customcrops.util.ConfigUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
@@ -37,8 +37,8 @@ import net.momirealms.customcrops.api.mechanic.world.season.Season;
|
||||
import net.momirealms.customcrops.api.util.LogUtils;
|
||||
import net.momirealms.customcrops.compatibility.VaultHook;
|
||||
import net.momirealms.customcrops.compatibility.papi.ParseUtils;
|
||||
import net.momirealms.customcrops.utils.ClassUtils;
|
||||
import net.momirealms.customcrops.utils.ConfigUtils;
|
||||
import net.momirealms.customcrops.util.ClassUtils;
|
||||
import net.momirealms.customcrops.util.ConfigUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
|
||||
@@ -88,7 +88,26 @@ public class CChunk implements CustomCropsChunk {
|
||||
|
||||
@Override
|
||||
public void notifyOfflineUpdates() {
|
||||
this.lastLoadedTime = System.currentTimeMillis();
|
||||
long current = System.currentTimeMillis();
|
||||
int offlineTimeInSeconds = (int) (this.lastLoadedTime - current) / 1000;
|
||||
offlineTimeInSeconds = Math.min(offlineTimeInSeconds, cWorld.getWorldSetting().getMaxOfflineTime());
|
||||
this.lastLoadedTime = current;
|
||||
var setting = cWorld.getWorldSetting();
|
||||
int minTickUnit = setting.getMinTickUnit();
|
||||
|
||||
for (int i = 0; i < offlineTimeInSeconds; i++) {
|
||||
this.loadedSeconds++;
|
||||
if (this.loadedSeconds >= minTickUnit) {
|
||||
this.loadedSeconds = 0;
|
||||
this.tickedBlocks.clear();
|
||||
this.queue.clear();
|
||||
if (setting.isScheduledTick()) {
|
||||
this.arrangeTasks(minTickUnit);
|
||||
}
|
||||
}
|
||||
scheduledTick(setting, true);
|
||||
randomTick(setting, true);
|
||||
}
|
||||
}
|
||||
|
||||
public void setWorld(CWorld cWorld) {
|
||||
@@ -121,10 +140,15 @@ public class CChunk implements CustomCropsChunk {
|
||||
this.tickedBlocks.clear();
|
||||
this.queue.clear();
|
||||
if (setting.isScheduledTick()) {
|
||||
this.arrangeTasks(setting.getMinTickUnit());
|
||||
this.arrangeTasks(interval);
|
||||
}
|
||||
}
|
||||
|
||||
scheduledTick(setting, false);
|
||||
randomTick(setting, false);
|
||||
}
|
||||
|
||||
private void scheduledTick(WorldSetting setting, boolean offline) {
|
||||
// scheduled tick
|
||||
while (!queue.isEmpty() && queue.peek().getTime() <= loadedSeconds) {
|
||||
TickTask task = queue.poll();
|
||||
@@ -138,24 +162,26 @@ public class CChunk implements CustomCropsChunk {
|
||||
case SCARECROW, GREENHOUSE -> {}
|
||||
case POT -> {
|
||||
if (!setting.randomTickPot()) {
|
||||
block.tick(setting.getTickPotInterval());
|
||||
block.tick(setting.getTickPotInterval(), offline);
|
||||
}
|
||||
}
|
||||
case CROP -> {
|
||||
if (!setting.randomTickCrop()) {
|
||||
block.tick(setting.getTickCropInterval());
|
||||
block.tick(setting.getTickCropInterval(), offline);
|
||||
}
|
||||
}
|
||||
case SPRINKLER -> {
|
||||
if (!setting.randomTickSprinkler()) {
|
||||
block.tick(setting.getTickSprinklerInterval());
|
||||
block.tick(setting.getTickSprinklerInterval(), offline);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void randomTick(WorldSetting setting, boolean offline) {
|
||||
// random tick
|
||||
ThreadLocalRandom random = ThreadLocalRandom.current();
|
||||
int randomTicks = setting.getRandomTickSpeed();
|
||||
@@ -171,18 +197,18 @@ public class CChunk implements CustomCropsChunk {
|
||||
switch (block.getType()) {
|
||||
case CROP -> {
|
||||
if (setting.randomTickCrop()) {
|
||||
block.tick(setting.getTickCropInterval());
|
||||
block.tick(setting.getTickCropInterval(), offline);
|
||||
}
|
||||
}
|
||||
case SPRINKLER -> {
|
||||
if (setting.randomTickSprinkler()) {
|
||||
block.tick(setting.getTickSprinklerInterval());
|
||||
block.tick(setting.getTickSprinklerInterval(), offline);
|
||||
}
|
||||
}
|
||||
case POT -> {
|
||||
((WorldPot) block).tickWater(this);
|
||||
if (setting.randomTickPot()) {
|
||||
block.tick(setting.getTickPotInterval());
|
||||
block.tick(setting.getTickPotInterval(), offline);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ import net.momirealms.customcrops.api.mechanic.world.season.Season;
|
||||
import net.momirealms.customcrops.api.scheduler.CancellableTask;
|
||||
import net.momirealms.customcrops.api.scheduler.Scheduler;
|
||||
import net.momirealms.customcrops.api.util.LogUtils;
|
||||
import net.momirealms.customcrops.utils.EventUtils;
|
||||
import net.momirealms.customcrops.util.EventUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -122,13 +122,19 @@ public class CWorld implements CustomCropsWorld {
|
||||
this.updateSeasonAndDate();
|
||||
}
|
||||
if (setting.isSchedulerEnabled()) {
|
||||
Scheduler scheduler = CustomCropsPlugin.get().getScheduler();
|
||||
if (VersionManager.folia()) {
|
||||
Scheduler scheduler = CustomCropsPlugin.get().getScheduler();
|
||||
for (CChunk chunk : loadedChunks.values()) {
|
||||
if (unloadIfNotLoaded(chunk.getChunkPos())) {
|
||||
continue;
|
||||
}
|
||||
scheduler.runTaskSync(chunk::secondTimer, getWorld(), chunk.getChunkPos().x(), chunk.getChunkPos().z());
|
||||
}
|
||||
} else {
|
||||
for (CChunk chunk : loadedChunks.values()) {
|
||||
if (unloadIfNotLoaded(chunk.getChunkPos())) {
|
||||
continue;
|
||||
}
|
||||
chunk.secondTimer();
|
||||
}
|
||||
}
|
||||
@@ -302,49 +308,49 @@ public class CWorld implements CustomCropsWorld {
|
||||
|
||||
@Override
|
||||
public Optional<WorldSprinkler> getSprinklerAt(SimpleLocation location) {
|
||||
CChunk chunk = loadedChunks.get(location.getChunkCoordinate());
|
||||
CChunk chunk = loadedChunks.get(location.getChunkPos());
|
||||
if (chunk == null) return Optional.empty();
|
||||
return chunk.getSprinklerAt(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<WorldPot> getPotAt(SimpleLocation location) {
|
||||
CChunk chunk = loadedChunks.get(location.getChunkCoordinate());
|
||||
CChunk chunk = loadedChunks.get(location.getChunkPos());
|
||||
if (chunk == null) return Optional.empty();
|
||||
return chunk.getPotAt(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<WorldCrop> getCropAt(SimpleLocation location) {
|
||||
CChunk chunk = loadedChunks.get(location.getChunkCoordinate());
|
||||
CChunk chunk = loadedChunks.get(location.getChunkPos());
|
||||
if (chunk == null) return Optional.empty();
|
||||
return chunk.getCropAt(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<WorldGlass> getGlassAt(SimpleLocation location) {
|
||||
CChunk chunk = loadedChunks.get(location.getChunkCoordinate());
|
||||
CChunk chunk = loadedChunks.get(location.getChunkPos());
|
||||
if (chunk == null) return Optional.empty();
|
||||
return chunk.getGlassAt(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<WorldScarecrow> getScarecrowAt(SimpleLocation location) {
|
||||
CChunk chunk = loadedChunks.get(location.getChunkCoordinate());
|
||||
CChunk chunk = loadedChunks.get(location.getChunkPos());
|
||||
if (chunk == null) return Optional.empty();
|
||||
return chunk.getScarecrowAt(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<CustomCropsBlock> getBlockAt(SimpleLocation location) {
|
||||
CChunk chunk = loadedChunks.get(location.getChunkCoordinate());
|
||||
CChunk chunk = loadedChunks.get(location.getChunkPos());
|
||||
if (chunk == null) return Optional.empty();
|
||||
return chunk.getBlockAt(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addWaterToSprinkler(Sprinkler sprinkler, SimpleLocation location, int amount) {
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkCoordinate());
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkPos());
|
||||
if (chunk.isPresent()) {
|
||||
chunk.get().addWaterToSprinkler(sprinkler, location, amount);
|
||||
} else {
|
||||
@@ -354,7 +360,7 @@ public class CWorld implements CustomCropsWorld {
|
||||
|
||||
@Override
|
||||
public void addFertilizerToPot(Pot pot, Fertilizer fertilizer, SimpleLocation location) {
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkCoordinate());
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkPos());
|
||||
if (chunk.isPresent()) {
|
||||
chunk.get().addFertilizerToPot(pot, fertilizer, location);
|
||||
} else {
|
||||
@@ -364,7 +370,7 @@ public class CWorld implements CustomCropsWorld {
|
||||
|
||||
@Override
|
||||
public void addWaterToPot(Pot pot, SimpleLocation location, int amount) {
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkCoordinate());
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkPos());
|
||||
if (chunk.isPresent()) {
|
||||
chunk.get().addWaterToPot(pot, location, amount);
|
||||
} else {
|
||||
@@ -374,7 +380,7 @@ public class CWorld implements CustomCropsWorld {
|
||||
|
||||
@Override
|
||||
public void addPotAt(WorldPot pot, SimpleLocation location) {
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkCoordinate());
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkPos());
|
||||
if (chunk.isPresent()) {
|
||||
chunk.get().addPotAt(pot, location);
|
||||
} else {
|
||||
@@ -384,7 +390,7 @@ public class CWorld implements CustomCropsWorld {
|
||||
|
||||
@Override
|
||||
public void addSprinklerAt(WorldSprinkler sprinkler, SimpleLocation location) {
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkCoordinate());
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkPos());
|
||||
if (chunk.isPresent()) {
|
||||
chunk.get().addSprinklerAt(sprinkler, location);
|
||||
} else {
|
||||
@@ -394,7 +400,7 @@ public class CWorld implements CustomCropsWorld {
|
||||
|
||||
@Override
|
||||
public void addCropAt(WorldCrop crop, SimpleLocation location) {
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkCoordinate());
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkPos());
|
||||
if (chunk.isPresent()) {
|
||||
chunk.get().addCropAt(crop, location);
|
||||
} else {
|
||||
@@ -404,7 +410,7 @@ public class CWorld implements CustomCropsWorld {
|
||||
|
||||
@Override
|
||||
public void addPointToCrop(Crop crop, SimpleLocation location, int points) {
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkCoordinate());
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkPos());
|
||||
if (chunk.isPresent()) {
|
||||
chunk.get().addPointToCrop(crop, location, points);
|
||||
} else {
|
||||
@@ -414,7 +420,7 @@ public class CWorld implements CustomCropsWorld {
|
||||
|
||||
@Override
|
||||
public void addGlassAt(WorldGlass glass, SimpleLocation location) {
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkCoordinate());
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkPos());
|
||||
if (chunk.isPresent()) {
|
||||
chunk.get().addGlassAt(glass, location);
|
||||
} else {
|
||||
@@ -424,7 +430,7 @@ public class CWorld implements CustomCropsWorld {
|
||||
|
||||
@Override
|
||||
public void addScarecrowAt(WorldScarecrow scarecrow, SimpleLocation location) {
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkCoordinate());
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkPos());
|
||||
if (chunk.isPresent()) {
|
||||
chunk.get().addScarecrowAt(scarecrow, location);
|
||||
} else {
|
||||
@@ -434,7 +440,7 @@ public class CWorld implements CustomCropsWorld {
|
||||
|
||||
@Override
|
||||
public void removeSprinklerAt(SimpleLocation location) {
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkCoordinate());
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkPos());
|
||||
if (chunk.isPresent()) {
|
||||
chunk.get().removeSprinklerAt(location);
|
||||
} else {
|
||||
@@ -444,7 +450,7 @@ public class CWorld implements CustomCropsWorld {
|
||||
|
||||
@Override
|
||||
public void removePotAt(SimpleLocation location) {
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkCoordinate());
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkPos());
|
||||
if (chunk.isPresent()) {
|
||||
chunk.get().removePotAt(location);
|
||||
} else {
|
||||
@@ -454,7 +460,7 @@ public class CWorld implements CustomCropsWorld {
|
||||
|
||||
@Override
|
||||
public void removeCropAt(SimpleLocation location) {
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkCoordinate());
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkPos());
|
||||
if (chunk.isPresent()) {
|
||||
chunk.get().removeCropAt(location);
|
||||
} else {
|
||||
@@ -464,7 +470,7 @@ public class CWorld implements CustomCropsWorld {
|
||||
|
||||
@Override
|
||||
public void removeGlassAt(SimpleLocation location) {
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkCoordinate());
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkPos());
|
||||
if (chunk.isPresent()) {
|
||||
chunk.get().removeGlassAt(location);
|
||||
} else {
|
||||
@@ -474,7 +480,7 @@ public class CWorld implements CustomCropsWorld {
|
||||
|
||||
@Override
|
||||
public void removeScarecrowAt(SimpleLocation location) {
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkCoordinate());
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkPos());
|
||||
if (chunk.isPresent()) {
|
||||
chunk.get().removeScarecrowAt(location);
|
||||
} else {
|
||||
@@ -484,7 +490,7 @@ public class CWorld implements CustomCropsWorld {
|
||||
|
||||
@Override
|
||||
public CustomCropsBlock removeAnythingAt(SimpleLocation location) {
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkCoordinate());
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkPos());
|
||||
if (chunk.isPresent()) {
|
||||
return chunk.get().removeBlockAt(location);
|
||||
} else {
|
||||
@@ -514,7 +520,7 @@ public class CWorld implements CustomCropsWorld {
|
||||
|
||||
@Override
|
||||
public boolean isPotReachLimit(SimpleLocation location) {
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkCoordinate());
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkPos());
|
||||
if (chunk.isEmpty()) {
|
||||
LogUtils.warn("Invalid operation: Querying pot amount from a not generated chunk");
|
||||
return true;
|
||||
@@ -525,7 +531,7 @@ public class CWorld implements CustomCropsWorld {
|
||||
|
||||
@Override
|
||||
public boolean isCropReachLimit(SimpleLocation location) {
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkCoordinate());
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkPos());
|
||||
if (chunk.isEmpty()) {
|
||||
LogUtils.warn("Invalid operation: Querying crop amount from a not generated chunk");
|
||||
return true;
|
||||
@@ -536,7 +542,7 @@ public class CWorld implements CustomCropsWorld {
|
||||
|
||||
@Override
|
||||
public boolean isSprinklerReachLimit(SimpleLocation location) {
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkCoordinate());
|
||||
Optional<CustomCropsChunk> chunk = getLoadedChunkAt(location.getChunkPos());
|
||||
if (chunk.isEmpty()) {
|
||||
LogUtils.warn("Invalid operation: Querying sprinkler amount from a not generated chunk");
|
||||
return true;
|
||||
@@ -559,4 +565,12 @@ public class CWorld implements CustomCropsWorld {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean unloadIfNotLoaded(ChunkPos pos) {
|
||||
if (!world.get().isChunkLoaded(pos.x(), pos.z())) {
|
||||
unloadChunk(pos);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import net.momirealms.customcrops.api.mechanic.world.level.*;
|
||||
import net.momirealms.customcrops.api.util.LogUtils;
|
||||
import net.momirealms.customcrops.mechanic.world.adaptor.BukkitWorldAdaptor;
|
||||
import net.momirealms.customcrops.mechanic.world.adaptor.SlimeWorldAdaptor;
|
||||
import net.momirealms.customcrops.utils.ConfigUtils;
|
||||
import net.momirealms.customcrops.util.ConfigUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
@@ -490,6 +490,7 @@ public class WorldManagerImpl implements WorldManager, Listener {
|
||||
}
|
||||
|
||||
CustomCropsChunk chunk = optionalChunk.get();
|
||||
// load the entities if not loaded
|
||||
bukkitChunk.getEntities();
|
||||
chunk.notifyOfflineUpdates();
|
||||
}
|
||||
|
||||
@@ -101,13 +101,13 @@ public class MemoryCrop extends AbstractCustomCropsBlock implements WorldCrop {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(int interval) {
|
||||
public void tick(int interval, boolean offline) {
|
||||
if (canTick(interval)) {
|
||||
tick();
|
||||
tick(offline);
|
||||
}
|
||||
}
|
||||
|
||||
private void tick() {
|
||||
private void tick(boolean offline) {
|
||||
Crop crop = getConfig();
|
||||
if (crop == null) {
|
||||
LogUtils.warn("Found a crop without config at " + getLocation() + ". Try removing the data.");
|
||||
@@ -124,14 +124,14 @@ public class MemoryCrop extends AbstractCustomCropsBlock implements WorldCrop {
|
||||
// check death conditions
|
||||
for (DeathConditions deathConditions : crop.getDeathConditions()) {
|
||||
for (Condition condition : deathConditions.getConditions()) {
|
||||
if (condition.isConditionMet(this)) {
|
||||
if (condition.isConditionMet(this, offline)) {
|
||||
CustomCropsPlugin.get().getScheduler().runTaskSyncLater(() -> {
|
||||
CustomCropsPlugin.get().getWorldManager().removeCropAt(location);
|
||||
CustomCropsPlugin.get().getItemManager().removeAnythingAt(bukkitLocation);
|
||||
if (deathConditions.getDeathItem() != null) {
|
||||
CustomCropsPlugin.get().getItemManager().placeItem(bukkitLocation, deathConditions.getItemCarrier(), deathConditions.getDeathItem());
|
||||
}
|
||||
}, bukkitLocation, deathConditions.getDeathDelay());
|
||||
}, bukkitLocation, offline ? 0 : deathConditions.getDeathDelay());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -144,7 +144,7 @@ public class MemoryCrop extends AbstractCustomCropsBlock implements WorldCrop {
|
||||
|
||||
// check grow conditions
|
||||
for (Condition condition : crop.getGrowConditions().getConditions()) {
|
||||
if (!condition.isConditionMet(this)) {
|
||||
if (!condition.isConditionMet(this, offline)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ public class MemoryGlass extends AbstractCustomCropsBlock implements WorldGlass
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(int interval) {
|
||||
public void tick(int interval, boolean offline) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,12 +189,13 @@ public class MemoryPot extends AbstractCustomCropsBlock implements WorldPot {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(int interval) {
|
||||
public void tick(int interval, boolean offline) {
|
||||
if (canTick(interval)) {
|
||||
tick();
|
||||
}
|
||||
}
|
||||
|
||||
// if the tick is triggered by offline growth
|
||||
private void tick() {
|
||||
Pot pot = getConfig();
|
||||
if (pot == null) {
|
||||
|
||||
@@ -54,7 +54,7 @@ public class MemoryScarecrow extends AbstractCustomCropsBlock implements WorldSc
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(int interval) {
|
||||
public void tick(int interval, boolean offline) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import net.momirealms.customcrops.api.mechanic.item.ItemType;
|
||||
import net.momirealms.customcrops.api.mechanic.item.Pot;
|
||||
import net.momirealms.customcrops.api.mechanic.item.Sprinkler;
|
||||
import net.momirealms.customcrops.api.mechanic.requirement.State;
|
||||
import net.momirealms.customcrops.api.mechanic.world.ChunkPos;
|
||||
import net.momirealms.customcrops.api.mechanic.world.SimpleLocation;
|
||||
import net.momirealms.customcrops.api.mechanic.world.level.AbstractCustomCropsBlock;
|
||||
import net.momirealms.customcrops.api.mechanic.world.level.CustomCropsWorld;
|
||||
@@ -34,10 +35,10 @@ import net.momirealms.customcrops.api.mechanic.world.level.WorldSprinkler;
|
||||
import net.momirealms.customcrops.api.util.LogUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
|
||||
public class MemorySprinkler extends AbstractCustomCropsBlock implements WorldSprinkler {
|
||||
|
||||
@@ -97,13 +98,14 @@ public class MemorySprinkler extends AbstractCustomCropsBlock implements WorldSp
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(int interval) {
|
||||
public void tick(int interval, boolean offline) {
|
||||
if (canTick(interval)) {
|
||||
tick();
|
||||
tick(offline);
|
||||
}
|
||||
}
|
||||
|
||||
private void tick() {
|
||||
// if the tick is triggered by offline growth
|
||||
private void tick(boolean offline) {
|
||||
Sprinkler sprinkler = getConfig();
|
||||
if (sprinkler == null) {
|
||||
LogUtils.warn("Found a sprinkler without config at " + getLocation() + ". Try removing the data.");
|
||||
@@ -127,7 +129,9 @@ public class MemorySprinkler extends AbstractCustomCropsBlock implements WorldSp
|
||||
Location bukkitLocation = location.getBukkitLocation();
|
||||
if (bukkitLocation == null) return;
|
||||
CustomCropsPlugin.get().getScheduler().runTaskSync(() -> {
|
||||
sprinkler.trigger(ActionTrigger.WORK, new State(null, new ItemStack(Material.AIR), bukkitLocation));
|
||||
State state = new State(null, new ItemStack(Material.AIR), bukkitLocation);
|
||||
if (offline) state.setArg("{offline}", "true");
|
||||
sprinkler.trigger(ActionTrigger.WORK, state);
|
||||
if (updateState && sprinkler.get3DItemWithWater() != null) {
|
||||
CustomCropsPlugin.get().getItemManager().removeAnythingAt(bukkitLocation);
|
||||
CustomCropsPlugin.get().getItemManager().placeItem(bukkitLocation, sprinkler.getItemCarrier(), sprinkler.get3DItemID());
|
||||
@@ -135,11 +139,26 @@ public class MemorySprinkler extends AbstractCustomCropsBlock implements WorldSp
|
||||
}, bukkitLocation);
|
||||
|
||||
int range = sprinkler.getRange();
|
||||
CustomCropsWorld world = CustomCropsPlugin.get().getWorldManager().getCustomCropsWorld(location.getWorldName()).get();
|
||||
HashMap<ChunkPos, ArrayList<SimpleLocation>> map = new HashMap<>();
|
||||
for (int i = -range; i <= range; i++) {
|
||||
for (int j = -range; j <= range; j++) {
|
||||
for (int k : new int[]{-1,0}) {
|
||||
SimpleLocation potLocation = location.copy().add(i,k,j);
|
||||
var cPos = potLocation.getChunkPos();
|
||||
var list = map.computeIfAbsent(cPos, key -> new ArrayList<>());
|
||||
list.add(potLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CustomCropsWorld world = CustomCropsPlugin.get().getWorldManager().getCustomCropsWorld(location.getWorldName()).get();
|
||||
World bkWorld = world.getWorld();
|
||||
for (Map.Entry<ChunkPos, ArrayList<SimpleLocation>> entry : map.entrySet()) {
|
||||
var chunkPos = entry.getKey();
|
||||
CustomCropsPlugin.get().getScheduler().runTaskSync(() -> {
|
||||
// load the chunk firstly to load CustomCrops data
|
||||
bkWorld.getChunkAt(chunkPos.x(), chunkPos.z());
|
||||
for (SimpleLocation potLocation : entry.getValue()) {
|
||||
Optional<WorldPot> pot = world.getPotAt(potLocation);
|
||||
if (pot.isPresent()) {
|
||||
WorldPot worldPot = pot.get();
|
||||
@@ -152,13 +171,13 @@ public class MemorySprinkler extends AbstractCustomCropsBlock implements WorldSp
|
||||
}
|
||||
worldPot.setWater(current + sprinkler.getWater());
|
||||
if (current == 0) {
|
||||
CustomCropsPlugin.get().getScheduler().runTaskSync(() -> CustomCropsPlugin.get().getItemManager().updatePotState(potLocation.getBukkitLocation(), potConfig, true, worldPot.getFertilizer()), potLocation.getBukkitLocation());
|
||||
CustomCropsPlugin.get().getItemManager().updatePotState(potLocation.getBukkitLocation(), potConfig, true, worldPot.getFertilizer());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, bkWorld, chunkPos.x(), chunkPos.z());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.utils;
|
||||
package net.momirealms.customcrops.util;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -15,7 +15,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.utils;
|
||||
package net.momirealms.customcrops.util;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import net.momirealms.customcrops.api.CustomCropsPlugin;
|
||||
@@ -70,7 +70,8 @@ public class ConfigUtils {
|
||||
section.getInt("pot.tick-interval", 2),
|
||||
getRandomTickModeByString(section.getString("sprinkler.mode")),
|
||||
section.getInt("sprinkler.tick-interval", 2),
|
||||
section.getBoolean("offline-grow", false),
|
||||
section.getBoolean("offline-growth.enable", false),
|
||||
section.getInt("offline-growth.max-offline-seconds", 1200),
|
||||
section.getBoolean("season.enable", false),
|
||||
section.getBoolean("season.auto-alternation", false),
|
||||
section.getInt("season.duration", 28),
|
||||
@@ -1,4 +1,4 @@
|
||||
package net.momirealms.customcrops.utils;
|
||||
package net.momirealms.customcrops.util;
|
||||
|
||||
import net.momirealms.customcrops.api.mechanic.misc.CRotation;
|
||||
import org.bukkit.entity.Entity;
|
||||
@@ -15,7 +15,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.utils;
|
||||
package net.momirealms.customcrops.util;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.Cancellable;
|
||||
@@ -15,7 +15,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.utils;
|
||||
package net.momirealms.customcrops.util;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
@@ -15,7 +15,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.utils;
|
||||
package net.momirealms.customcrops.util;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTItem;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -15,7 +15,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.utils;
|
||||
package net.momirealms.customcrops.util;
|
||||
|
||||
import net.momirealms.customcrops.api.mechanic.misc.CRotation;
|
||||
import org.bukkit.Rotation;
|
||||
@@ -46,6 +46,16 @@ worlds:
|
||||
# For crops, under the same conditions, the growth rate of crops is basically the same
|
||||
# For sprinklers and pots, they would work periodically.
|
||||
min-tick-unit: 300
|
||||
# Offline growth settings
|
||||
# This option allows crops to grow even if the world is unloaded or the server is closed
|
||||
# This may lead to some issues caused by timeliness conditions for instance seasons
|
||||
offline-growth:
|
||||
enable: false
|
||||
# Maximum offline time recorded in seconds
|
||||
# Please do not set this option to a value that is too large,
|
||||
# as it may cause chunks that have been unloaded for a long time
|
||||
# taking long to load
|
||||
max-offline-seconds: 1200
|
||||
# Settings for crops
|
||||
crop:
|
||||
# [RANDOM_TICK]
|
||||
|
||||
Reference in New Issue
Block a user