mirror of
https://github.com/Xiao-MoMi/Custom-Crops.git
synced 2025-12-26 18:39:17 +00:00
migration system
This commit is contained in:
@@ -34,6 +34,7 @@ import net.momirealms.customcrops.manager.*;
|
||||
import net.momirealms.customcrops.mechanic.action.ActionManagerImpl;
|
||||
import net.momirealms.customcrops.mechanic.condition.ConditionManagerImpl;
|
||||
import net.momirealms.customcrops.mechanic.item.ItemManagerImpl;
|
||||
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;
|
||||
@@ -102,6 +103,7 @@ public class CustomCropsPluginImpl extends CustomCropsPlugin {
|
||||
this.antiGriefLib.init();
|
||||
this.integrationManager.init();
|
||||
this.disableNBTAPILogs();
|
||||
Migration.tryUpdating();
|
||||
this.reload();
|
||||
this.worldManager.init();
|
||||
if (ConfigManager.metrics()) new Metrics(this, 16593);
|
||||
|
||||
@@ -17,6 +17,12 @@
|
||||
|
||||
package net.momirealms.customcrops.manager;
|
||||
|
||||
import dev.dejvokep.boostedyaml.YamlDocument;
|
||||
import dev.dejvokep.boostedyaml.dvs.versioning.BasicVersioning;
|
||||
import dev.dejvokep.boostedyaml.settings.dumper.DumperSettings;
|
||||
import dev.dejvokep.boostedyaml.settings.general.GeneralSettings;
|
||||
import dev.dejvokep.boostedyaml.settings.loader.LoaderSettings;
|
||||
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;
|
||||
@@ -26,12 +32,14 @@ import org.bukkit.World;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ConfigManagerImpl extends ConfigManager {
|
||||
|
||||
private static final String configVersion = "35";
|
||||
public static final String configVersion = "35";
|
||||
private CustomCropsPlugin plugin;
|
||||
private String lang;
|
||||
private int maximumPoolSize;
|
||||
@@ -54,6 +62,7 @@ public class ConfigManagerImpl extends ConfigManager {
|
||||
private int scarecrowRange;
|
||||
private boolean syncSeasons;
|
||||
private WeakReference<World> referenceWorld;
|
||||
private boolean convertWorldOnLoad;
|
||||
|
||||
public ConfigManagerImpl(CustomCropsPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
@@ -61,6 +70,29 @@ public class ConfigManagerImpl extends ConfigManager {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
if (!new File(plugin.getDataFolder(), "config.yml").exists())
|
||||
ConfigUtils.getConfig("config.yml");
|
||||
// update config version
|
||||
try {
|
||||
YamlDocument.create(
|
||||
new File(CustomCropsPlugin.getInstance().getDataFolder(), "config.yml"),
|
||||
Objects.requireNonNull(CustomCropsPlugin.getInstance().getResource("config.yml")),
|
||||
GeneralSettings.DEFAULT,
|
||||
LoaderSettings
|
||||
.builder()
|
||||
.setAutoUpdate(true)
|
||||
.build(),
|
||||
DumperSettings.DEFAULT,
|
||||
UpdaterSettings
|
||||
.builder()
|
||||
.setVersioning(new BasicVersioning("config-version"))
|
||||
.addIgnoredRoute(configVersion, "other-settings.placeholder-register", '.')
|
||||
.build()
|
||||
);
|
||||
} catch (IOException e) {
|
||||
LogUtils.warn(e.getMessage());
|
||||
}
|
||||
|
||||
YamlConfiguration config = ConfigUtils.getConfig("config.yml");
|
||||
|
||||
debug = config.getBoolean("debug");
|
||||
@@ -80,6 +112,7 @@ public class ConfigManagerImpl extends ConfigManager {
|
||||
itemDetectionOrder = otherSettings.getStringList("item-detection-order").toArray(new String[0]);
|
||||
protectLore = otherSettings.getBoolean("protect-original-lore", false);
|
||||
legacyColorSupport = otherSettings.getBoolean("legacy-color-code-support", true);
|
||||
convertWorldOnLoad = otherSettings.getBoolean("convert-on-world-load", false);
|
||||
|
||||
ConfigurationSection mechanics = config.getConfigurationSection("mechanics");
|
||||
if (mechanics == null) {
|
||||
@@ -129,6 +162,11 @@ public class ConfigManagerImpl extends ConfigManager {
|
||||
return keepAliveTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isConvertWorldOnLoad() {
|
||||
return convertWorldOnLoad;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double[] getDefaultQualityRatio() {
|
||||
return defaultQualityRatio;
|
||||
|
||||
@@ -118,6 +118,7 @@ public class ActionManagerImpl implements ActionManager {
|
||||
this.registerVariationAction();
|
||||
this.registerForceTickAction();
|
||||
this.registerHologramAction();
|
||||
this.registerLegacyDropItemsAction();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -536,7 +537,7 @@ public class ActionManagerImpl implements ActionManager {
|
||||
}
|
||||
|
||||
private void registerDropItemsAction() {
|
||||
registerAction("drop-items", (args, chance) -> {
|
||||
registerAction("drop-item", (args, chance) -> {
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
boolean ignoreFertilizer = section.getBoolean("ignore-fertilizer", true);
|
||||
String item = section.getString("item");
|
||||
@@ -574,64 +575,95 @@ public class ActionManagerImpl implements ActionManager {
|
||||
});
|
||||
}
|
||||
|
||||
private void registerPlantAction() {
|
||||
registerAction("plant", (args, chance) -> {
|
||||
private void registerLegacyDropItemsAction() {
|
||||
registerAction("drop-items", (args, chance) -> {
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
int point = section.getInt("point", 0);
|
||||
String key = section.getString("crop");
|
||||
return state -> {
|
||||
if (Math.random() > chance) return;
|
||||
if (key == null) return;
|
||||
Crop crop = plugin.getItemManager().getCropByID(key);
|
||||
if (crop == null) {
|
||||
LogUtils.warn("Crop: " + key + " doesn't exist.");
|
||||
return;
|
||||
}
|
||||
Location location = state.getLocation();
|
||||
Pot pot = plugin.getItemManager().getPotByBlock(location.getBlock().getRelative(BlockFace.DOWN));
|
||||
if (pot == null) {
|
||||
plugin.debug("Crop should be planted on a pot at " + location);
|
||||
return;
|
||||
}
|
||||
// check whitelist
|
||||
if (!crop.getPotWhitelist().contains(pot.getKey())) {
|
||||
crop.trigger(ActionTrigger.WRONG_POT, state);
|
||||
return;
|
||||
}
|
||||
// check plant requirements
|
||||
if (!RequirementManager.isRequirementMet(state, crop.getPlantRequirements())) {
|
||||
return;
|
||||
}
|
||||
// check limitation
|
||||
if (plugin.getWorldManager().isReachLimit(SimpleLocation.of(location), ItemType.CROP)) {
|
||||
crop.trigger(ActionTrigger.REACH_LIMIT, state);
|
||||
return;
|
||||
}
|
||||
// fire event
|
||||
CropPlantEvent plantEvent = new CropPlantEvent(state.getPlayer(), state.getItemInHand(), location, crop, 0);
|
||||
if (EventUtils.fireAndCheckCancel(plantEvent)) {
|
||||
return;
|
||||
}
|
||||
// place the crop
|
||||
switch (crop.getItemCarrier()) {
|
||||
case ITEM_FRAME, ITEM_DISPLAY, TRIPWIRE -> plugin.getItemManager().placeItem(location, crop.getItemCarrier(), crop.getStageItemByPoint(point));
|
||||
default -> {
|
||||
LogUtils.warn("Unsupported type for crop: " + crop.getItemCarrier().name());
|
||||
return;
|
||||
List<Action> actions = new ArrayList<>();
|
||||
ConfigurationSection otherItemSection = section.getConfigurationSection("other-items");
|
||||
if (otherItemSection != null) {
|
||||
for (Map.Entry<String, Object> entry : otherItemSection.getValues(false).entrySet()) {
|
||||
if (entry.getValue() instanceof ConfigurationSection inner) {
|
||||
actions.add(getActionFactory("drop-item").build(inner, inner.getDouble("chance", 1)));
|
||||
}
|
||||
}
|
||||
plugin.getWorldManager().addCropAt(new MemoryCrop(SimpleLocation.of(location), crop.getKey(), point), SimpleLocation.of(location));
|
||||
}
|
||||
ConfigurationSection qualitySection = section.getConfigurationSection("quality-crops");
|
||||
if (qualitySection != null) {
|
||||
actions.add(getActionFactory("quality-crops").build(qualitySection, 1));
|
||||
}
|
||||
return state -> {
|
||||
if (Math.random() > chance) return;
|
||||
for (Action action : actions) {
|
||||
action.trigger(state);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
LogUtils.warn("Illegal value format found at action: plant");
|
||||
LogUtils.warn("Illegal value format found at action: drop-items");
|
||||
return EmptyAction.instance;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void registerPlantAction() {
|
||||
for (String name : List.of("plant", "replant")) {
|
||||
registerAction(name, (args, chance) -> {
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
int point = section.getInt("point", 0);
|
||||
String key = section.getString("crop");
|
||||
return state -> {
|
||||
if (Math.random() > chance) return;
|
||||
if (key == null) return;
|
||||
Crop crop = plugin.getItemManager().getCropByID(key);
|
||||
if (crop == null) {
|
||||
LogUtils.warn("Crop: " + key + " doesn't exist.");
|
||||
return;
|
||||
}
|
||||
Location location = state.getLocation();
|
||||
Pot pot = plugin.getItemManager().getPotByBlock(location.getBlock().getRelative(BlockFace.DOWN));
|
||||
if (pot == null) {
|
||||
plugin.debug("Crop should be planted on a pot at " + location);
|
||||
return;
|
||||
}
|
||||
// check whitelist
|
||||
if (!crop.getPotWhitelist().contains(pot.getKey())) {
|
||||
crop.trigger(ActionTrigger.WRONG_POT, state);
|
||||
return;
|
||||
}
|
||||
// check plant requirements
|
||||
if (!RequirementManager.isRequirementMet(state, crop.getPlantRequirements())) {
|
||||
return;
|
||||
}
|
||||
// check limitation
|
||||
if (plugin.getWorldManager().isReachLimit(SimpleLocation.of(location), ItemType.CROP)) {
|
||||
crop.trigger(ActionTrigger.REACH_LIMIT, state);
|
||||
return;
|
||||
}
|
||||
// fire event
|
||||
CropPlantEvent plantEvent = new CropPlantEvent(state.getPlayer(), state.getItemInHand(), location, crop, 0);
|
||||
if (EventUtils.fireAndCheckCancel(plantEvent)) {
|
||||
return;
|
||||
}
|
||||
// place the crop
|
||||
switch (crop.getItemCarrier()) {
|
||||
case ITEM_FRAME, ITEM_DISPLAY, TRIPWIRE -> plugin.getItemManager().placeItem(location, crop.getItemCarrier(), crop.getStageItemByPoint(point));
|
||||
default -> {
|
||||
LogUtils.warn("Unsupported type for crop: " + crop.getItemCarrier().name());
|
||||
return;
|
||||
}
|
||||
}
|
||||
plugin.getWorldManager().addCropAt(new MemoryCrop(SimpleLocation.of(location), crop.getKey(), point), SimpleLocation.of(location));
|
||||
};
|
||||
} else {
|
||||
LogUtils.warn("Illegal value format found at action: " + name);
|
||||
return EmptyAction.instance;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void registerBreakAction() {
|
||||
registerAction("break", (args, chance) -> {
|
||||
boolean arg = (boolean) args;
|
||||
boolean arg = (boolean) (args == null ? true : args);
|
||||
return state -> {
|
||||
if (Math.random() > chance) return;
|
||||
Optional<CustomCropsBlock> removed = plugin.getWorldManager().getBlockAt(SimpleLocation.of(state.getLocation()));
|
||||
@@ -746,19 +778,13 @@ public class ActionManagerImpl implements ActionManager {
|
||||
|
||||
private void registerItemAmountAction() {
|
||||
registerAction("item-amount", (args, chance) -> {
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
boolean mainOrOff = section.getString("hand", "main").equalsIgnoreCase("main");
|
||||
int amount = section.getInt("amount", 1);
|
||||
return state -> {
|
||||
if (Math.random() > chance) return;
|
||||
Player player = state.getPlayer();
|
||||
ItemStack itemStack = mainOrOff ? player.getInventory().getItemInMainHand() : player.getInventory().getItemInOffHand();
|
||||
itemStack.setAmount(Math.max(0, itemStack.getAmount() + amount));
|
||||
};
|
||||
} else {
|
||||
LogUtils.warn("Illegal value format found at action: item-amount");
|
||||
return EmptyAction.instance;
|
||||
}
|
||||
int amount = (int) args;
|
||||
return state -> {
|
||||
if (Math.random() > chance) return;
|
||||
Player player = state.getPlayer();
|
||||
ItemStack itemStack = player.getInventory().getItemInMainHand();
|
||||
itemStack.setAmount(Math.max(0, itemStack.getAmount() + amount));
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ public interface CustomProvider {
|
||||
}
|
||||
}
|
||||
|
||||
void placeFurniture(Location location, String id);
|
||||
Entity placeFurniture(Location location, String id);
|
||||
|
||||
void removeFurniture(Entity entity);
|
||||
|
||||
|
||||
@@ -56,15 +56,17 @@ 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 org.bukkit.*;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.Waterlogged;
|
||||
import org.bukkit.block.data.type.Farmland;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.ItemDisplay;
|
||||
import org.bukkit.entity.ItemFrame;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
@@ -334,6 +336,25 @@ public class ItemManagerImpl implements ItemManager {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void placeItem(Location location, ItemCarrier carrier, String id, boolean rotate) {
|
||||
switch (carrier) {
|
||||
case ITEM_DISPLAY, ITEM_FRAME -> {
|
||||
Entity entity = customProvider.placeFurniture(location, id);
|
||||
if (rotate) {
|
||||
if (entity instanceof ItemFrame frame) {
|
||||
frame.setRotation(RotationUtils.getRandomRotation());
|
||||
} else if (entity instanceof ItemDisplay display) {
|
||||
display.setRotation(RotationUtils.getRandomFloatRotation(), display.getLocation().getPitch());
|
||||
}
|
||||
}
|
||||
}
|
||||
case TRIPWIRE, NOTE_BLOCK, CHORUS, MUSHROOM -> {
|
||||
customProvider.placeBlock(location, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAnythingAt(Location location) {
|
||||
customProvider.removeAnythingAt(location);
|
||||
|
||||
@@ -46,8 +46,12 @@ public class ItemsAdderProvider implements CustomProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void placeFurniture(Location location, String id) {
|
||||
CustomFurniture.spawnPreciseNonSolid(id, location);
|
||||
public Entity placeFurniture(Location location, String id) {
|
||||
Location center = location.toCenterLocation();
|
||||
center.setY(center.getBlockY());
|
||||
CustomFurniture furniture = CustomFurniture.spawnPreciseNonSolid(id, location);
|
||||
if (furniture == null) return null;
|
||||
return furniture.getEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -52,8 +52,10 @@ public class OraxenProvider implements CustomProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void placeFurniture(Location location, String id) {
|
||||
OraxenFurniture.place(id, location, Rotation.NONE, BlockFace.UP);
|
||||
public Entity placeFurniture(Location location, String id) {
|
||||
Location center = location.toCenterLocation();
|
||||
center.setY(center.getBlockY());
|
||||
return OraxenFurniture.place(id, location, Rotation.NONE, BlockFace.UP);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -134,7 +134,7 @@ public class CropConfig extends AbstractEventItem implements Crop {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRotation() {
|
||||
public boolean hasRotation() {
|
||||
return rotation;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,456 @@
|
||||
package net.momirealms.customcrops.mechanic.misc.migrator;
|
||||
|
||||
import dev.dejvokep.boostedyaml.YamlDocument;
|
||||
import dev.dejvokep.boostedyaml.dvs.versioning.BasicVersioning;
|
||||
import dev.dejvokep.boostedyaml.settings.dumper.DumperSettings;
|
||||
import dev.dejvokep.boostedyaml.settings.general.GeneralSettings;
|
||||
import dev.dejvokep.boostedyaml.settings.loader.LoaderSettings;
|
||||
import dev.dejvokep.boostedyaml.settings.updater.UpdaterSettings;
|
||||
import net.momirealms.customcrops.api.CustomCropsPlugin;
|
||||
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 org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Migration {
|
||||
|
||||
public static void tryUpdating() {
|
||||
File configFile = new File(CustomCropsPlugin.getInstance().getDataFolder(), "config.yml");
|
||||
// If not config file found, do nothing
|
||||
if (!configFile.exists()) return;
|
||||
|
||||
YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
|
||||
String version = config.getString("config-version");
|
||||
if (version == null) return;
|
||||
|
||||
int versionNumber = Integer.parseInt(version);
|
||||
if (!(versionNumber >= 25 && versionNumber <= 34)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// do migration
|
||||
if (config.contains("mechanics.season.sync-season")) {
|
||||
config.set("mechanics.sync-season.enable", config.getBoolean("mechanics.season.sync-season.enable"));
|
||||
config.set("mechanics.sync-season.reference", config.getBoolean("mechanics.season.sync-season.reference"));
|
||||
}
|
||||
if (config.contains("mechanics.season.greenhouse")) {
|
||||
config.set("mechanics.greenhouse.enable", config.getBoolean("mechanics.season.greenhouse.enable"));
|
||||
config.set("mechanics.greenhouse.id", config.getString("mechanics.season.greenhouse.block"));
|
||||
config.set("mechanics.greenhouse.range", config.getInt("mechanics.season.greenhouse.range"));
|
||||
}
|
||||
if (config.contains("mechanics.scarecrow")) {
|
||||
config.set("mechanics.scarecrow.id", config.getString("mechanics.scarecrow"));
|
||||
}
|
||||
|
||||
try {
|
||||
config.save(configFile);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
YamlDocument.create(
|
||||
new File(CustomCropsPlugin.getInstance().getDataFolder(), "config.yml"),
|
||||
Objects.requireNonNull(CustomCropsPlugin.getInstance().getResource("config.yml")),
|
||||
GeneralSettings.DEFAULT,
|
||||
LoaderSettings
|
||||
.builder()
|
||||
.setAutoUpdate(true)
|
||||
.build(),
|
||||
DumperSettings.DEFAULT,
|
||||
UpdaterSettings
|
||||
.builder()
|
||||
.setVersioning(new BasicVersioning("config-version"))
|
||||
.build()
|
||||
);
|
||||
} catch (IOException e) {
|
||||
LogUtils.warn(e.getMessage());
|
||||
}
|
||||
|
||||
updateWateringCans();
|
||||
updatePots();
|
||||
updateFertilizers();
|
||||
updateSprinklers();
|
||||
updateCrops();
|
||||
|
||||
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));
|
||||
adaptor.convertWorld(temp, world);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void updateWateringCans() {
|
||||
var files = ConfigUtils.getFilesRecursively(new File(CustomCropsPlugin.getInstance().getDataFolder(), "contents" + File.separator + "watering-cans"));
|
||||
for (File file : files) {
|
||||
YamlConfiguration yaml = YamlConfiguration.loadConfiguration(file);
|
||||
for (Map.Entry<String, Object> sections : yaml.getValues(false).entrySet()) {
|
||||
if (sections.getValue() instanceof ConfigurationSection section) {
|
||||
ConfigurationSection fillSection = section.getConfigurationSection("fill-method");
|
||||
if (fillSection != null) {
|
||||
for (String key : fillSection.getKeys(false)) {
|
||||
fillSection.set(key + ".particle", null);
|
||||
fillSection.set(key + ".sound", null);
|
||||
}
|
||||
}
|
||||
if (section.contains("sound")) {
|
||||
section.set("events.consume_water.sound_action.type", "sound");
|
||||
section.set("events.consume_water.sound_action.value.key", section.getString("sound"));
|
||||
section.set("events.consume_water.sound_action.value.source", "player");
|
||||
section.set("events.consume_water.sound_action.value.volume", 1);
|
||||
section.set("events.consume_water.sound_action.value.pitch", 1);
|
||||
section.set("sound", null);
|
||||
}
|
||||
if (section.contains("particle")) {
|
||||
section.set("events.add_water.particle_action.type", "particle");
|
||||
section.set("events.add_water.particle_action.value.particle", section.getString("particle"));
|
||||
section.set("events.add_water.particle_action.value.x", 0.5);
|
||||
section.set("events.add_water.particle_action.value.z", 0.5);
|
||||
section.set("events.add_water.particle_action.value.y", 1.3);
|
||||
section.set("events.add_water.particle_action.value.count", 5);
|
||||
section.set("particle", null);
|
||||
}
|
||||
if (section.contains("actionbar")) {
|
||||
if (section.getBoolean("actionbar.enable")) {
|
||||
section.set("events.consume_water.actionbar_action.type", "actionbar");
|
||||
section.set("events.consume_water.actionbar_action.value", section.getString("actionbar.content"));
|
||||
section.set("events.add_water.actionbar_action.type", "actionbar");
|
||||
section.set("events.add_water.actionbar_action.value", section.getString("actionbar.content"));
|
||||
}
|
||||
section.set("actionbar", null);
|
||||
}
|
||||
section.set("events.add_water.sound_action.type", "sound");
|
||||
section.set("events.add_water.sound_action.value.key", "minecraft:item.bucket.empty");
|
||||
section.set("events.add_water.sound_action.value.source", "player");
|
||||
section.set("events.add_water.sound_action.value.volume", 1);
|
||||
section.set("events.add_water.sound_action.value.pitch", 1);
|
||||
}
|
||||
}
|
||||
try {
|
||||
yaml.save(file);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void updatePots() {
|
||||
var files = ConfigUtils.getFilesRecursively(new File(CustomCropsPlugin.getInstance().getDataFolder(), "contents" + File.separator + "pots"));
|
||||
for (File file : files) {
|
||||
YamlConfiguration yaml = YamlConfiguration.loadConfiguration(file);
|
||||
for (Map.Entry<String, Object> sections : yaml.getValues(false).entrySet()) {
|
||||
if (sections.getValue() instanceof ConfigurationSection section) {
|
||||
section.set("absorb-rainwater", true);
|
||||
section.set("absorb-nearby-water", false);
|
||||
ConfigurationSection fillSection = section.getConfigurationSection("fill-method");
|
||||
if (fillSection != null) {
|
||||
for (String key : fillSection.getKeys(false)) {
|
||||
fillSection.set(key + ".particle", null);
|
||||
fillSection.set(key + ".sound", null);
|
||||
}
|
||||
}
|
||||
if (section.contains("hologram.water.water-bar")) {
|
||||
section.set("water-bar.left", section.getString("hologram.water.water-bar.left"));
|
||||
section.set("water-bar.right", section.getString("hologram.water.water-bar.right"));
|
||||
section.set("water-bar.empty", section.getString("hologram.water.water-bar.empty"));
|
||||
section.set("water-bar.full", section.getString("hologram.water.water-bar.full"));
|
||||
}
|
||||
section.set("events.add_water.particle_action.type", "particle");
|
||||
section.set("events.add_water.particle_action.value.particle", "WATER_SPLASH");
|
||||
section.set("events.add_water.particle_action.value.x", 0.5);
|
||||
section.set("events.add_water.particle_action.value.z", 0.5);
|
||||
section.set("events.add_water.particle_action.value.y", 1.3);
|
||||
section.set("events.add_water.particle_action.value.count", 5);
|
||||
section.set("events.add_water.particle_action.value.offset-x", 0.3);
|
||||
section.set("events.add_water.particle_action.value.offset-z", 0.3);
|
||||
|
||||
ConfigurationSection holoSection = section.getConfigurationSection("hologram");
|
||||
if (holoSection != null) {
|
||||
int duration = holoSection.getInt("duration") * 20;
|
||||
String requireItem = holoSection.getString("require-item", "*");
|
||||
section.set("events.interact.conditional_action.type", "conditional");
|
||||
section.set("events.interact.conditional_action.value.conditions.requirement_1.type", "item-in-hand");
|
||||
section.set("events.interact.conditional_action.value.conditions.requirement_1.value.amount", 1);
|
||||
section.set("events.interact.conditional_action.value.conditions.requirement_1.value.item", requireItem);
|
||||
if (holoSection.getBoolean("water.enable")) {
|
||||
String waterText = holoSection.getString("water.content");
|
||||
section.set("events.interact.conditional_action.value.actions.water_hologram.type", "hologram");
|
||||
section.set("events.interact.conditional_action.value.actions.water_hologram.value.duration", duration);
|
||||
section.set("events.interact.conditional_action.value.actions.water_hologram.value.text", waterText);
|
||||
section.set("events.interact.conditional_action.value.actions.water_hologram.value.apply-correction", true);
|
||||
section.set("events.interact.conditional_action.value.actions.water_hologram.value.x", 0.5);
|
||||
section.set("events.interact.conditional_action.value.actions.water_hologram.value.y", 0.6);
|
||||
section.set("events.interact.conditional_action.value.actions.water_hologram.value.z", 0.5);
|
||||
}
|
||||
if (holoSection.getBoolean("fertilizer.enable")) {
|
||||
String fertilizerText = holoSection.getString("fertilizer.content");
|
||||
section.set("events.interact.conditional_action.value.actions.conditional_fertilizer_action.type", "conditional");
|
||||
section.set("events.interact.conditional_action.value.actions.conditional_fertilizer_action.value.conditions.requirement_1.type", "fertilizer");
|
||||
section.set("events.interact.conditional_action.value.actions.conditional_fertilizer_action.value.conditions.requirement_1.value.has", true);
|
||||
section.set("events.interact.conditional_action.value.actions.conditional_fertilizer_action.value.actions.fertilizer_hologram.type", "hologram");
|
||||
section.set("events.interact.conditional_action.value.actions.conditional_fertilizer_action.value.actions.fertilizer_hologram.value.text", fertilizerText);
|
||||
section.set("events.interact.conditional_action.value.actions.conditional_fertilizer_action.value.actions.fertilizer_hologram.value.duration", duration);
|
||||
section.set("events.interact.conditional_action.value.actions.conditional_fertilizer_action.value.actions.fertilizer_hologram.value.apply-correction", true);
|
||||
section.set("events.interact.conditional_action.value.actions.conditional_fertilizer_action.value.actions.fertilizer_hologram.value.x", 0.5);
|
||||
section.set("events.interact.conditional_action.value.actions.conditional_fertilizer_action.value.actions.fertilizer_hologram.value.y", 0.83);
|
||||
section.set("events.interact.conditional_action.value.actions.conditional_fertilizer_action.value.actions.fertilizer_hologram.value.z", 0.5);
|
||||
}
|
||||
section.set("hologram", null);
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
yaml.save(file);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void updateFertilizers() {
|
||||
var files = ConfigUtils.getFilesRecursively(new File(CustomCropsPlugin.getInstance().getDataFolder(), "contents" + File.separator + "fertilizers"));
|
||||
for (File file : files) {
|
||||
YamlConfiguration yaml = YamlConfiguration.loadConfiguration(file);
|
||||
for (Map.Entry<String, Object> sections : yaml.getValues(false).entrySet()) {
|
||||
if (sections.getValue() instanceof ConfigurationSection section) {
|
||||
if (section.contains("particle")) {
|
||||
section.set("events.use.particle_action.type", "particle");
|
||||
section.set("events.use.particle_action.value.particle", section.getString("particle"));
|
||||
section.set("events.use.particle_action.value.x", 0.5);
|
||||
section.set("events.use.particle_action.value.y", 1.3);
|
||||
section.set("events.use.particle_action.value.z", 0.5);
|
||||
section.set("events.use.particle_action.value.count", 5);
|
||||
section.set("events.use.particle_action.value.offset-x", 0.3);
|
||||
section.set("events.use.particle_action.value.offset-z", 0.3);
|
||||
section.set("particle", null);
|
||||
}
|
||||
if (section.contains("sound")) {
|
||||
section.set("events.use.sound_action.type", "sound");
|
||||
section.set("events.use.sound_action.value.source", "player");
|
||||
section.set("events.use.sound_action.value.key", section.getString("sound"));
|
||||
section.set("events.use.sound_action.value.volume", 1);
|
||||
section.set("events.use.sound_action.value.pitch", 1);
|
||||
section.set("sound", null);
|
||||
}
|
||||
if (section.contains("pot-whitelist")) {
|
||||
section.set("events.wrong_pot.sound_action.type", "sound");
|
||||
section.set("events.wrong_pot.sound_action.value.source", "player");
|
||||
section.set("events.wrong_pot.sound_action.value.key", "minecraft:item.bundle.insert");
|
||||
section.set("events.wrong_pot.sound_action.value.volume", 1);
|
||||
section.set("events.wrong_pot.sound_action.value.pitch", 1);
|
||||
section.set("events.wrong_pot.actionbar_action.type", "actionbar");
|
||||
section.set("events.wrong_pot.actionbar_action.value", "<red><bold>[X] This fertilizer can only be used in pots.");
|
||||
}
|
||||
if (section.getBoolean("before-plant")) {
|
||||
section.set("events.before_plant.sound_action.type", "sound");
|
||||
section.set("events.before_plant.sound_action.value.source", "player");
|
||||
section.set("events.before_plant.sound_action.value.key", "minecraft:item.bundle.insert");
|
||||
section.set("events.before_plant.sound_action.value.volume", 1);
|
||||
section.set("events.before_plant.sound_action.value.pitch", 1);
|
||||
section.set("events.before_plant.actionbar_action.type", "actionbar");
|
||||
section.set("events.before_plant.actionbar_action.value", "<red><bold>[X] You can only use this fertilizer before planting the crop.");
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
yaml.save(file);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void updateSprinklers() {
|
||||
var files = ConfigUtils.getFilesRecursively(new File(CustomCropsPlugin.getInstance().getDataFolder(), "contents" + File.separator + "sprinklers"));
|
||||
for (File file : files) {
|
||||
YamlConfiguration yaml = YamlConfiguration.loadConfiguration(file);
|
||||
for (Map.Entry<String, Object> sections : yaml.getValues(false).entrySet()) {
|
||||
if (sections.getValue() instanceof ConfigurationSection section) {
|
||||
section.set("infinite", false);
|
||||
ConfigurationSection fillSection = section.getConfigurationSection("fill-method");
|
||||
if (fillSection != null) {
|
||||
for (String key : fillSection.getKeys(false)) {
|
||||
fillSection.set(key + ".particle", null);
|
||||
fillSection.set(key + ".sound", null);
|
||||
}
|
||||
}
|
||||
if (section.contains("place-sound")) {
|
||||
section.set("events.place.sound_action.type", "sound");
|
||||
section.set("events.place.sound_action.value.key", section.getString("place-sound"));
|
||||
section.set("events.place.sound_action.value.source", "player");
|
||||
section.set("events.place.sound_action.value.volume", 1);
|
||||
section.set("events.place.sound_action.value.pitch", 1);
|
||||
section.set("place-sound", null);
|
||||
}
|
||||
section.set("events.interact.force_work_action.type", "conditional");
|
||||
section.set("events.interact.force_work_action.value.conditions.requirement_1.type", "sneak");
|
||||
section.set("events.interact.force_work_action.value.conditions.requirement_1.value", true);
|
||||
section.set("events.interact.force_work_action.value.actions.action_1.type", "force-tick");
|
||||
if (section.contains("hologram")) {
|
||||
if (section.getBoolean("hologram.enable")) {
|
||||
int duration = section.getInt("hologram.duration") * 20;
|
||||
String text = section.getString("hologram.content");
|
||||
if (section.contains("hologram.water-bar")) {
|
||||
section.set("water-bar.left", section.getString("hologram.water-bar.left"));
|
||||
section.set("water-bar.right", section.getString("hologram.water-bar.right"));
|
||||
section.set("water-bar.empty", section.getString("hologram.water-bar.empty"));
|
||||
section.set("water-bar.full", section.getString("hologram.water-bar.full"));
|
||||
}
|
||||
section.set("events.interact.hologram_action.type", "hologram");
|
||||
section.set("events.interact.hologram_action.value.duration", duration);
|
||||
section.set("events.interact.hologram_action.value.text", text);
|
||||
section.set("events.interact.hologram_action.value.x", 0.5);
|
||||
section.set("events.interact.hologram_action.value.y", -0.3);
|
||||
section.set("events.interact.hologram_action.value.z", 0.5);
|
||||
section.set("events.interact.hologram_action.value.visible-to-all", false);
|
||||
}
|
||||
section.set("hologram", null);
|
||||
}
|
||||
if (section.contains("animation")) {
|
||||
if (section.getBoolean("animation.enable")) {
|
||||
String item = section.getString("animation.item");
|
||||
int duration = section.getInt("animation.duration") * 20;
|
||||
section.set("events.work.fake_item_action.type", "fake-item");
|
||||
section.set("events.work.fake_item_action.value.item", item);
|
||||
section.set("events.work.fake_item_action.value.duration", duration);
|
||||
section.set("events.work.fake_item_action.value.x", 0.5);
|
||||
section.set("events.work.fake_item_action.value.y", 0.4);
|
||||
section.set("events.work.fake_item_action.value.z", 0.5);
|
||||
section.set("events.work.fake_item_action.value.visible-to-all", true);
|
||||
}
|
||||
section.set("animation", null);
|
||||
}
|
||||
section.set("events.add_water.particle_action.type", "particle");
|
||||
section.set("events.add_water.particle_action.value.particle", "WATER_SPLASH");
|
||||
section.set("events.add_water.particle_action.value.x", 0.5);
|
||||
section.set("events.add_water.particle_action.value.z", 0.5);
|
||||
section.set("events.add_water.particle_action.value.y", 0.7);
|
||||
section.set("events.add_water.particle_action.value.count", 5);
|
||||
section.set("events.add_water.sound_action.type", "sound");
|
||||
section.set("events.add_water.sound_action.value.key", "minecraft:item.bucket.empty");
|
||||
section.set("events.add_water.sound_action.value.source", "player");
|
||||
section.set("events.add_water.sound_action.value.pitch", 1);
|
||||
section.set("events.add_water.sound_action.value.volume", 1);
|
||||
}
|
||||
}
|
||||
try {
|
||||
yaml.save(file);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void updateCrops() {
|
||||
var files = ConfigUtils.getFilesRecursively(new File(CustomCropsPlugin.getInstance().getDataFolder(), "contents" + File.separator + "crops"));
|
||||
for (File file : files) {
|
||||
YamlConfiguration yaml = YamlConfiguration.loadConfiguration(file);
|
||||
for (Map.Entry<String, Object> sections : yaml.getValues(false).entrySet()) {
|
||||
if (sections.getValue() instanceof ConfigurationSection section) {
|
||||
if (section.contains("plant-actions")) {
|
||||
section.set("events.plant", section.getConfigurationSection("plant-actions"));
|
||||
section.set("plant-actions", null);
|
||||
}
|
||||
ConfigurationSection boneMeal = section.getConfigurationSection("custom-bone-meal");
|
||||
if (boneMeal != null) {
|
||||
for (Map.Entry<String, Object> entry : boneMeal.getValues(false).entrySet()) {
|
||||
if (entry.getValue() instanceof ConfigurationSection inner) {
|
||||
inner.set("actions.swing_action.type", "swing-hand");
|
||||
inner.set("actions.swing_action.value", true);
|
||||
if (inner.contains("particle")) {
|
||||
inner.set("actions.particle_action.type", "particle");
|
||||
inner.set("actions.particle_action.value.particle", inner.getString("particle"));
|
||||
inner.set("actions.particle_action.value.count",5);
|
||||
inner.set("actions.particle_action.value.x", 0.5);
|
||||
inner.set("actions.particle_action.value.y", 0.5);
|
||||
inner.set("actions.particle_action.value.z", 0.5);
|
||||
inner.set("actions.particle_action.value.offset-x", 0.3);
|
||||
inner.set("actions.particle_action.value.offset-y", 0.3);
|
||||
inner.set("actions.particle_action.value.offset-z", 0.3);
|
||||
inner.set("particle", null);
|
||||
}
|
||||
if (inner.contains("sound")) {
|
||||
inner.set("actions.sound_action.type", "sound");
|
||||
inner.set("actions.sound_action.value.key", inner.getString("sound"));
|
||||
inner.set("actions.sound_action.value.source", "player");
|
||||
inner.set("actions.sound_action.value.volume", 1);
|
||||
inner.set("actions.sound_action.value.pitch", 1);
|
||||
inner.set("sound", null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConfigurationSection pointSection = section.getConfigurationSection("points");
|
||||
if (pointSection == null) continue;
|
||||
for (Map.Entry<String, Object> entry1 : pointSection.getValues(false).entrySet()) {
|
||||
if (entry1.getValue() instanceof ConfigurationSection pointS1) {
|
||||
ConfigurationSection eventSection = pointS1.getConfigurationSection("events");
|
||||
if (eventSection != null) {
|
||||
if (eventSection.contains("interact-by-hand")) {
|
||||
eventSection.set("interact.empty_hand_action.type", "conditional");
|
||||
eventSection.set("interact.empty_hand_action.value.conditions", eventSection.getConfigurationSection("interact-by-hand.requirements"));
|
||||
eventSection.set("interact.empty_hand_action.value.conditions.requirement_empty_hand.type", "item-in-hand");
|
||||
eventSection.set("interact.empty_hand_action.value.conditions.requirement_empty_hand.value.item", "AIR");
|
||||
eventSection.set("interact.empty_hand_action.value.actions", eventSection.getConfigurationSection("interact-by-hand"));
|
||||
eventSection.set("interact.empty_hand_action.value.actions.requirements", null);
|
||||
eventSection.set("interact-by-hand", null);
|
||||
}
|
||||
if (eventSection.contains("interact-with-item")) {
|
||||
ConfigurationSection interactWithItem = eventSection.getConfigurationSection("interact-with-item");
|
||||
if (interactWithItem != null) {
|
||||
int amount = 0;
|
||||
for (Map.Entry<String, Object> entry : interactWithItem.getValues(false).entrySet()) {
|
||||
if (entry.getValue() instanceof ConfigurationSection inner) {
|
||||
amount++;
|
||||
String requiredItem = inner.getString("item");
|
||||
boolean consume = inner.getBoolean("reduce-amount");
|
||||
String returned = inner.getString("return");
|
||||
ConfigurationSection actions = inner.getConfigurationSection("actions");
|
||||
eventSection.set("interact.action_" + amount + ".type", "conditional");
|
||||
eventSection.set("interact.action_" + amount + ".type", "conditional");
|
||||
eventSection.set("interact.action_" + amount + ".value.conditions", inner.getConfigurationSection("requirements"));
|
||||
eventSection.set("interact.action_" + amount + ".value.conditions.requirement_item.type", "item-in-hand");
|
||||
eventSection.set("interact.action_" + amount + ".value.conditions.requirement_item.value.item", requiredItem);
|
||||
eventSection.set("interact.action_" + amount + ".value.actions", actions);
|
||||
if (consume) {
|
||||
eventSection.set("interact.action_" + amount + ".value.actions.consume_item.type", "item-amount");
|
||||
eventSection.set("interact.action_" + amount + ".value.actions.consume_item.value", -1);
|
||||
}
|
||||
if (returned != null) {
|
||||
eventSection.set("interact.action_" + amount + ".value.actions.return_item.type", "give-item");
|
||||
eventSection.set("interact.action_" + amount + ".value.actions.return_item.value.id", returned);
|
||||
eventSection.set("interact.action_" + amount + ".value.actions.return_item.value.amount", 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
eventSection.set("interact-with-item", null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
try {
|
||||
yaml.save(file);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -163,6 +163,10 @@ public class RequirementManagerImpl implements RequirementManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (section.contains("message")) {
|
||||
List<String> messages = ConfigUtils.stringListArgs(section.get("message"));
|
||||
actionList.add(plugin.getActionManager().getActionFactory("message").build(messages, 1));
|
||||
}
|
||||
if (actionList.size() == 0)
|
||||
actionList = null;
|
||||
}
|
||||
|
||||
@@ -355,7 +355,7 @@ public class CChunk implements CustomCropsChunk {
|
||||
String after = crop.getStageItemByPoint(x);
|
||||
if (pre.equals(after)) return;
|
||||
CustomCropsPlugin.get().getItemManager().removeAnythingAt(bkLoc);
|
||||
CustomCropsPlugin.get().getItemManager().placeItem(bkLoc, crop.getItemCarrier(), after);
|
||||
CustomCropsPlugin.get().getItemManager().placeItem(bkLoc, crop.getItemCarrier(), after, crop.hasRotation());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -81,7 +81,7 @@ public class CWorld implements CustomCropsWorld {
|
||||
for (Map.Entry<ChunkCoordinate, CChunk> lazyEntry : lazyChunks.entrySet()) {
|
||||
CChunk chunk = lazyEntry.getValue();
|
||||
int sec = chunk.getUnloadedSeconds() + 1;
|
||||
if (sec >= 10) {
|
||||
if (sec >= 30) {
|
||||
chunksToSave.add(Pair.of(lazyEntry.getKey(), chunk));
|
||||
} else {
|
||||
chunk.setUnloadedSeconds(sec);
|
||||
|
||||
@@ -20,12 +20,12 @@ package net.momirealms.customcrops.mechanic.world;
|
||||
import net.momirealms.customcrops.api.CustomCropsPlugin;
|
||||
import net.momirealms.customcrops.api.manager.WorldManager;
|
||||
import net.momirealms.customcrops.api.mechanic.item.*;
|
||||
import net.momirealms.customcrops.api.mechanic.world.AbstractWorldAdaptor;
|
||||
import net.momirealms.customcrops.api.mechanic.world.ChunkCoordinate;
|
||||
import net.momirealms.customcrops.api.mechanic.world.CustomCropsBlock;
|
||||
import net.momirealms.customcrops.api.mechanic.world.SimpleLocation;
|
||||
import net.momirealms.customcrops.api.mechanic.world.level.*;
|
||||
import net.momirealms.customcrops.api.util.LogUtils;
|
||||
import net.momirealms.customcrops.mechanic.world.adaptor.AbstractWorldAdaptor;
|
||||
import net.momirealms.customcrops.mechanic.world.adaptor.BukkitWorldAdaptor;
|
||||
import net.momirealms.customcrops.mechanic.world.adaptor.SlimeWorldAdaptor;
|
||||
import net.momirealms.customcrops.utils.ConfigUtils;
|
||||
@@ -502,4 +502,9 @@ public class WorldManagerImpl implements WorldManager, Listener {
|
||||
public void saveChunkToFile(CustomCropsChunk chunk) {
|
||||
this.worldAdaptor.saveDynamicData(chunk.getCustomCropsWorld(), chunk);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractWorldAdaptor getWorldAdaptor() {
|
||||
return worldAdaptor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* 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.mechanic.world.adaptor;
|
||||
|
||||
import net.momirealms.customcrops.api.manager.WorldManager;
|
||||
import net.momirealms.customcrops.api.mechanic.world.ChunkCoordinate;
|
||||
import net.momirealms.customcrops.api.mechanic.world.level.CustomCropsChunk;
|
||||
import net.momirealms.customcrops.api.mechanic.world.level.CustomCropsWorld;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
public abstract class AbstractWorldAdaptor implements Listener {
|
||||
|
||||
public static final int version = 1;
|
||||
protected WorldManager worldManager;
|
||||
|
||||
public AbstractWorldAdaptor(WorldManager worldManager) {
|
||||
this.worldManager = worldManager;
|
||||
}
|
||||
|
||||
public abstract void unload(CustomCropsWorld customCropsWorld);
|
||||
|
||||
public abstract void init(CustomCropsWorld customCropsWorld);
|
||||
|
||||
public abstract void loadDynamicData(CustomCropsWorld customCropsWorld, ChunkCoordinate chunkCoordinate);
|
||||
|
||||
public abstract void unloadDynamicData(CustomCropsWorld customCropsWorld, ChunkCoordinate chunkCoordinate);
|
||||
|
||||
public abstract void saveDynamicData(CustomCropsWorld ccWorld, CustomCropsChunk chunk);
|
||||
}
|
||||
@@ -26,23 +26,30 @@ import com.flowpowered.nbt.stream.NBTOutputStream;
|
||||
import com.github.luben.zstd.Zstd;
|
||||
import com.google.gson.Gson;
|
||||
import net.momirealms.customcrops.api.CustomCropsPlugin;
|
||||
import net.momirealms.customcrops.api.manager.ConfigManager;
|
||||
import net.momirealms.customcrops.api.manager.WorldManager;
|
||||
import net.momirealms.customcrops.api.mechanic.world.ChunkCoordinate;
|
||||
import net.momirealms.customcrops.api.mechanic.world.ChunkPos;
|
||||
import net.momirealms.customcrops.api.mechanic.world.CustomCropsBlock;
|
||||
import net.momirealms.customcrops.api.mechanic.world.*;
|
||||
import net.momirealms.customcrops.api.mechanic.world.level.CustomCropsChunk;
|
||||
import net.momirealms.customcrops.api.mechanic.world.level.CustomCropsWorld;
|
||||
import net.momirealms.customcrops.api.mechanic.world.level.WorldInfoData;
|
||||
import net.momirealms.customcrops.api.mechanic.world.season.Season;
|
||||
import net.momirealms.customcrops.api.object.crop.GrowingCrop;
|
||||
import net.momirealms.customcrops.api.object.fertilizer.Fertilizer;
|
||||
import net.momirealms.customcrops.api.object.pot.Pot;
|
||||
import net.momirealms.customcrops.api.object.sprinkler.Sprinkler;
|
||||
import net.momirealms.customcrops.api.object.world.CCChunk;
|
||||
import net.momirealms.customcrops.api.util.LogUtils;
|
||||
import net.momirealms.customcrops.mechanic.world.*;
|
||||
import net.momirealms.customcrops.mechanic.world.block.*;
|
||||
import net.momirealms.customcrops.scheduler.task.TickTask;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.world.WorldLoadEvent;
|
||||
import org.bukkit.event.world.WorldUnloadEvent;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.ByteOrder;
|
||||
@@ -58,6 +65,7 @@ public class BukkitWorldAdaptor extends AbstractWorldAdaptor {
|
||||
public BukkitWorldAdaptor(WorldManager worldManager) {
|
||||
super(worldManager);
|
||||
this.gson = new Gson();
|
||||
this.worldFolder = "";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -89,12 +97,19 @@ public class BukkitWorldAdaptor extends AbstractWorldAdaptor {
|
||||
return;
|
||||
}
|
||||
|
||||
// create directory
|
||||
new File(world.getWorldFolder(), "customcrops").mkdir();
|
||||
|
||||
// try converting legacy worlds
|
||||
if (ConfigManager.convertWorldOnLoad()) {
|
||||
convertWorld(cWorld, world);
|
||||
return;
|
||||
}
|
||||
|
||||
// init world basic info
|
||||
String json = world.getPersistentDataContainer().get(key, PersistentDataType.STRING);
|
||||
WorldInfoData data = (json == null || json.equals("null")) ? WorldInfoData.empty() : gson.fromJson(json, WorldInfoData.class);
|
||||
cWorld.setInfoData(data);
|
||||
|
||||
new File(world.getWorldFolder(), "customcrops").mkdir();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -435,4 +450,75 @@ public class BukkitWorldAdaptor extends AbstractWorldAdaptor {
|
||||
outStream.writeTag(tag);
|
||||
return outByteStream.toByteArray();
|
||||
}
|
||||
|
||||
public void convertWorld(@Nullable CWorld cWorld, World world) {
|
||||
// handle legacy files
|
||||
File leagcyFile = new File(world.getWorldFolder(), "customcrops" + File.separator + "data.yml");
|
||||
if (leagcyFile.exists()) {
|
||||
// read date and season
|
||||
YamlConfiguration data = YamlConfiguration.loadConfiguration(leagcyFile);
|
||||
try {
|
||||
Season season = Season.valueOf(data.getString("season"));
|
||||
if (cWorld != null)
|
||||
cWorld.setInfoData(new WorldInfoData(season, data.getInt("date", 1)));
|
||||
world.getPersistentDataContainer().set(key, PersistentDataType.STRING,
|
||||
gson.toJson(new WorldInfoData(season, data.getInt("date", 1))));
|
||||
} catch (IllegalArgumentException e) {
|
||||
if (cWorld != null)
|
||||
cWorld.setInfoData(WorldInfoData.empty());
|
||||
}
|
||||
// delete the file
|
||||
leagcyFile.delete();
|
||||
new File(world.getWorldFolder(), "customcrops" + File.separator + "corrupted.yml").delete();
|
||||
|
||||
// read chunks
|
||||
File folder = new File(world.getWorldFolder(), "customcrops" + File.separator + "chunks");
|
||||
if (!folder.exists()) return;
|
||||
LogUtils.warn("Converting chunks for world " + world.getName() + " from 3.3 to 3.4... This might take some time.");
|
||||
File[] data_files = folder.listFiles();
|
||||
if (data_files == null) return;
|
||||
for (File file : data_files) {
|
||||
ChunkCoordinate chunkCoordinate = ChunkCoordinate.getByString(file.getName().substring(0, file.getName().length() - 7));
|
||||
try (FileInputStream fis = new FileInputStream(file); ObjectInputStream ois = new ObjectInputStream(fis)) {
|
||||
CCChunk chunk = (CCChunk) ois.readObject();
|
||||
CChunk cChunk = new CChunk(cWorld, chunkCoordinate);
|
||||
for (net.momirealms.customcrops.api.object.world.SimpleLocation legacyLocation : chunk.getGreenhouseSet()) {
|
||||
SimpleLocation simpleLocation = new SimpleLocation(legacyLocation.getWorldName(), legacyLocation.getX(), legacyLocation.getY(), legacyLocation.getZ());
|
||||
cChunk.addGlassAt(new MemoryGlass(simpleLocation), simpleLocation);
|
||||
}
|
||||
for (net.momirealms.customcrops.api.object.world.SimpleLocation legacyLocation : chunk.getScarecrowSet()) {
|
||||
SimpleLocation simpleLocation = new SimpleLocation(legacyLocation.getWorldName(), legacyLocation.getX(), legacyLocation.getY(), legacyLocation.getZ());
|
||||
cChunk.addScarecrowAt(new MemoryScarecrow(simpleLocation), simpleLocation);
|
||||
}
|
||||
for (Map.Entry<net.momirealms.customcrops.api.object.world.SimpleLocation, GrowingCrop> entry : chunk.getGrowingCropMap().entrySet()) {
|
||||
net.momirealms.customcrops.api.object.world.SimpleLocation legacyLocation = entry.getKey();
|
||||
SimpleLocation simpleLocation = new SimpleLocation(legacyLocation.getWorldName(), legacyLocation.getX(), legacyLocation.getY(), legacyLocation.getZ());
|
||||
cChunk.addCropAt(new MemoryCrop(simpleLocation, entry.getValue().getKey(), entry.getValue().getPoints()), simpleLocation);
|
||||
}
|
||||
for (Map.Entry<net.momirealms.customcrops.api.object.world.SimpleLocation, Sprinkler> entry : chunk.getSprinklerMap().entrySet()) {
|
||||
net.momirealms.customcrops.api.object.world.SimpleLocation legacyLocation = entry.getKey();
|
||||
SimpleLocation simpleLocation = new SimpleLocation(legacyLocation.getWorldName(), legacyLocation.getX(), legacyLocation.getY(), legacyLocation.getZ());
|
||||
cChunk.addSprinklerAt(new MemorySprinkler(simpleLocation, entry.getValue().getKey(), entry.getValue().getWater()), simpleLocation);
|
||||
}
|
||||
for (Map.Entry<net.momirealms.customcrops.api.object.world.SimpleLocation, Pot> entry : chunk.getPotMap().entrySet()) {
|
||||
net.momirealms.customcrops.api.object.world.SimpleLocation legacyLocation = entry.getKey();
|
||||
SimpleLocation simpleLocation = new SimpleLocation(legacyLocation.getWorldName(), legacyLocation.getX(), legacyLocation.getY(), legacyLocation.getZ());
|
||||
Fertilizer fertilizer = entry.getValue().getFertilizer();
|
||||
cChunk.addPotAt(new MemoryPot(simpleLocation, entry.getValue().getKey(), entry.getValue().getWater(), fertilizer == null ? "" : fertilizer.getKey(), fertilizer == null ? 0 : fertilizer.getTimes()), simpleLocation);
|
||||
}
|
||||
try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(getChunkDataFilePath(world, cChunk.getChunkCoordinate())))) {
|
||||
bos.write(serialize(cChunk));
|
||||
} catch (IOException e) {
|
||||
LogUtils.severe("Failed to save CustomCrops data.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
LogUtils.info("Error at " + file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
LogUtils.info("Successfully converted chunks for world: " + world);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ package net.momirealms.customcrops.mechanic.world.adaptor;
|
||||
import com.infernalsuite.aswm.api.SlimePlugin;
|
||||
import com.infernalsuite.aswm.api.events.LoadSlimeWorldEvent;
|
||||
import net.momirealms.customcrops.api.manager.WorldManager;
|
||||
import net.momirealms.customcrops.api.mechanic.world.AbstractWorldAdaptor;
|
||||
import net.momirealms.customcrops.api.mechanic.world.ChunkCoordinate;
|
||||
import net.momirealms.customcrops.api.mechanic.world.level.CustomCropsChunk;
|
||||
import net.momirealms.customcrops.api.mechanic.world.level.CustomCropsWorld;
|
||||
|
||||
@@ -111,6 +111,7 @@ public class MemoryCrop extends AbstractCustomCropsBlock implements WorldCrop {
|
||||
|
||||
SimpleLocation location = getLocation();
|
||||
Location bukkitLocation = location.getBukkitLocation();
|
||||
if (bukkitLocation == null) return;
|
||||
|
||||
int previous = getPoint();
|
||||
|
||||
@@ -168,7 +169,7 @@ public class MemoryCrop extends AbstractCustomCropsBlock implements WorldCrop {
|
||||
}
|
||||
if (pre.equals(after)) return;
|
||||
CustomCropsPlugin.get().getItemManager().removeAnythingAt(bukkitLocation);
|
||||
CustomCropsPlugin.get().getItemManager().placeItem(bukkitLocation, crop.getItemCarrier(), after);
|
||||
CustomCropsPlugin.get().getItemManager().placeItem(bukkitLocation, crop.getItemCarrier(), after, crop.hasRotation());
|
||||
}, bukkitLocation);
|
||||
}
|
||||
}
|
||||
@@ -52,6 +52,14 @@ public class MemoryPot extends AbstractCustomCropsBlock implements WorldPot {
|
||||
setData("fertilizer-times", new IntTag("fertilizer-times", 0));
|
||||
}
|
||||
|
||||
public MemoryPot(SimpleLocation location, String key, int water, String fertilizer, int fertilizerTimes) {
|
||||
super(location, new CompoundMap());
|
||||
setData("key", new StringTag("key", key));
|
||||
setData("water", new IntTag("water", water));
|
||||
setData("fertilizer", new StringTag("fertilizer", fertilizer));
|
||||
setData("fertilizer-times", new IntTag("fertilizer-times", fertilizerTimes));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return getData("key").getAsStringTag()
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.utils;
|
||||
|
||||
import org.bukkit.Rotation;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class RotationUtils {
|
||||
|
||||
private static final Rotation[] rotationsI = {Rotation.NONE, Rotation.FLIPPED, Rotation.CLOCKWISE, Rotation.COUNTER_CLOCKWISE};
|
||||
private static final float[] rotationsF = {0f, 90f, 180f, -90f};
|
||||
|
||||
public static Rotation getRandomRotation() {
|
||||
return rotationsI[new Random().nextInt(4)];
|
||||
}
|
||||
|
||||
public static float getRandomFloatRotation() {
|
||||
return rotationsF[new Random().nextInt(4)];
|
||||
}
|
||||
}
|
||||
@@ -102,13 +102,13 @@ mechanics:
|
||||
# Scarecrow prevents crops from being attacked by crows
|
||||
scarecrow:
|
||||
enable: true
|
||||
id: {0}scarecrow
|
||||
id: '{0}scarecrow'
|
||||
range: 7
|
||||
|
||||
# Greenhouse glass prevents crops from withering from season changing
|
||||
greenhouse:
|
||||
enable: true
|
||||
id: {0}greenhouse_glass
|
||||
id: '{0}greenhouse_glass'
|
||||
range: 5
|
||||
|
||||
# Sync seasons
|
||||
@@ -145,4 +145,7 @@ other-settings:
|
||||
# Whether to protect the original lore of the item
|
||||
# This uses the scoreboard component to identify the plugin's lore,
|
||||
# which may conflict with some plugins that still use SpigotAPI#ItemMeta.
|
||||
protect-original-lore: false
|
||||
protect-original-lore: false
|
||||
|
||||
# Should the plugin try to convert worlds from 3.3 to 3.4 when WorldLoadEvent is triggered
|
||||
convert-on-world-load: false
|
||||
@@ -60,7 +60,7 @@ tomato:
|
||||
break:
|
||||
# 30% chance of dropping crop seeds
|
||||
action_1:
|
||||
type: drop-items
|
||||
type: drop-item
|
||||
value:
|
||||
ignore-fertilizer: true
|
||||
item: {0}tomato_seeds
|
||||
@@ -73,7 +73,7 @@ tomato:
|
||||
events:
|
||||
break:
|
||||
action_1:
|
||||
type: drop-items
|
||||
type: drop-item
|
||||
value:
|
||||
ignore-fertilizer: true
|
||||
item: {0}tomato_seeds
|
||||
@@ -86,7 +86,7 @@ tomato:
|
||||
events:
|
||||
break:
|
||||
action_1:
|
||||
type: drop-items
|
||||
type: drop-item
|
||||
value:
|
||||
ignore-fertilizer: true
|
||||
item: {0}tomato_seeds
|
||||
@@ -128,7 +128,7 @@ tomato:
|
||||
chance: 0.01
|
||||
break:
|
||||
action_1:
|
||||
type: drop-items
|
||||
type: drop-item
|
||||
value:
|
||||
ignore-fertilizer: true
|
||||
item: {0}tomato_seeds
|
||||
@@ -173,7 +173,7 @@ tomato:
|
||||
events:
|
||||
break:
|
||||
action_1:
|
||||
type: drop-items
|
||||
type: drop-item
|
||||
value:
|
||||
ignore-fertilizer: true
|
||||
item: {0}tomato_seeds
|
||||
@@ -181,7 +181,7 @@ tomato:
|
||||
max: 2
|
||||
chance: 1
|
||||
action_2:
|
||||
type: drop-items
|
||||
type: drop-item
|
||||
value:
|
||||
ignore-fertilizer: false
|
||||
item: {0}golden_tomato
|
||||
@@ -259,6 +259,9 @@ tomato:
|
||||
custom-bone-meal:
|
||||
bone_meal_1:
|
||||
item: BONE_MEAL
|
||||
chance:
|
||||
2: 0.2
|
||||
1: 0.6
|
||||
actions:
|
||||
swing_action:
|
||||
type: swing-hand
|
||||
@@ -280,7 +283,4 @@ tomato:
|
||||
source: player
|
||||
key: minecraft:item.bone_meal.use
|
||||
volume: 1
|
||||
pitch: 1
|
||||
chance:
|
||||
2: 0.2
|
||||
1: 0.6
|
||||
pitch: 1
|
||||
@@ -93,7 +93,6 @@ default:
|
||||
requirement_1:
|
||||
type: item-in-hand
|
||||
value:
|
||||
hand: main
|
||||
amount: 1
|
||||
item: {0}soil_surveyor
|
||||
actions:
|
||||
@@ -116,6 +115,7 @@ default:
|
||||
x: 0.5
|
||||
y: 0.83
|
||||
z: 0.5
|
||||
visible-to-all: false
|
||||
# Display the amount of water in pot
|
||||
water_hologram:
|
||||
type: hologram
|
||||
@@ -126,3 +126,4 @@ default:
|
||||
x: 0.5
|
||||
y: 0.6
|
||||
z: 0.5
|
||||
visible-to-all: false
|
||||
Reference in New Issue
Block a user