9
0
mirror of https://github.com/Xiao-MoMi/Custom-Crops.git synced 2025-12-21 16:09:21 +00:00
This commit is contained in:
Xiao-MoMi
2022-10-04 02:51:03 +08:00
parent e185bff763
commit a21ae65ea0
19 changed files with 346 additions and 76 deletions

View File

@@ -17,6 +17,8 @@
package net.momirealms.customcrops;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.momirealms.customcrops.commands.PluginCommand;
import net.momirealms.customcrops.config.ConfigUtil;
@@ -34,6 +36,7 @@ public final class CustomCrops extends JavaPlugin {
public static BukkitAudiences adventure;
public static CustomCrops plugin;
public static ProtocolManager protocolManager;
private PlaceholderManager placeholderManager;
private CropManager cropManager;
@@ -50,6 +53,7 @@ public final class CustomCrops extends JavaPlugin {
public void onEnable() {
adventure = BukkitAudiences.create(plugin);
protocolManager = ProtocolLibrary.getProtocolManager();
AdventureUtil.consoleMessage("[CustomCrops] Running on <white>" + Bukkit.getVersion());
if (Bukkit.getPluginManager().getPlugin("ItemsAdder") != null) {

View File

@@ -48,7 +48,7 @@ public class SimulateCommand extends AbstractSubCommand {
return true;
}
Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.plugin, () -> {
CustomCrops.plugin.getCropManager().grow(world, growTime, sprinklerTime, dryTime);
CustomCrops.plugin.getCropManager().grow(world, growTime, sprinklerTime, dryTime, false);
});
AdventureUtil.sendMessage(sender, MessageConfig.prefix + MessageConfig.growSimulation);
}

View File

@@ -26,7 +26,8 @@ public class BasicItemConfig {
public static String deadCrop;
public static String soilSurveyor;
public static String greenHouseGlass;
public static String crow;
public static String crowLand;
public static String crowFly;
public static String scarecrow;
public static String waterEffect;
@@ -37,7 +38,8 @@ public class BasicItemConfig {
greenHouseGlass = config.getString("greenhouse-glass");
soilSurveyor = config.getString("soil-surveyor");
deadCrop = config.getString("dead-crop");
crow = config.getString("crow");
crowLand = config.getString("crow-land");
crowFly = config.getString("crow-fly");
scarecrow = config.getString("scarecrow");
waterEffect = config.getString("water-effect");
}

View File

@@ -84,6 +84,8 @@ public class MainConfig {
public static boolean enableAnimations;
public static boolean autoGrow;
public static boolean enableCompensation;
public static boolean requireLight;
public static byte lightLevel;
public static void load() {
ConfigUtil.update("config.yml");

View File

@@ -48,7 +48,7 @@ import net.momirealms.customcrops.objects.fertilizer.Fertilizer;
import net.momirealms.customcrops.objects.fertilizer.QualityCrop;
import net.momirealms.customcrops.objects.fertilizer.RetainingSoil;
import net.momirealms.customcrops.objects.fertilizer.YieldIncreasing;
import net.momirealms.customcrops.utils.AdventureUtil;
import net.momirealms.customcrops.utils.ArmorStandUtil;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
@@ -71,6 +71,7 @@ public class CropManager extends Function {
private CropModeInterface cropMode;
private SeasonInterface seasonInterface;
private CustomInterface customInterface;
private ArmorStandUtil armorStandUtil;
private HandlerP handler;
public CropManager() {
@@ -84,6 +85,7 @@ public class CropManager extends Function {
this.itemSpawnListener = new ItemSpawnListener(this);
this.worldListener = new WorldListener(this);
this.armorStandUtil = new ArmorStandUtil(this);
//Custom Plugin
if (MainConfig.customPlugin.equals("itemsadder")) {
@@ -145,7 +147,7 @@ public class CropManager extends Function {
customWorlds.put(world, customWorld);
if (MainConfig.autoGrow && MainConfig.enableCompensation) {
if (world.getTime() < 24000 - MainConfig.timeToWork - MainConfig.timeToDry - 1200 && world.getTime() > 1500) {
Bukkit.getScheduler().runTaskLaterAsynchronously(CustomCrops.plugin, () -> grow(world, MainConfig.timeToGrow, MainConfig.timeToWork, MainConfig.timeToDry), 100);
Bukkit.getScheduler().runTaskLaterAsynchronously(CustomCrops.plugin, () -> grow(world, MainConfig.timeToGrow, MainConfig.timeToWork, MainConfig.timeToDry, true), 100);
}
}
}
@@ -159,11 +161,11 @@ public class CropManager extends Function {
seasonInterface.unloadWorld(world);
}
public void grow(World world, int cropTime, int sprinklerTime, int dryTime) {
public void grow(World world, int cropTime, int sprinklerTime, int dryTime, boolean compensation) {
CustomWorld customWorld = customWorlds.get(world);
if (customWorld == null) return;
if (MainConfig.cropMode) customWorld.growWire(cropTime, sprinklerTime, dryTime);
else customWorld.growFrame(cropTime, sprinklerTime, dryTime);
if (MainConfig.cropMode) customWorld.growWire(cropTime, sprinklerTime, dryTime, compensation);
else customWorld.growFrame(cropTime, sprinklerTime, dryTime, compensation);
}
public CropModeInterface getCropMode() {
@@ -309,4 +311,8 @@ public class CropManager extends Function {
}
}
}
public ArmorStandUtil getArmorStandUtil() {
return armorStandUtil;
}
}

View File

@@ -24,10 +24,7 @@ import com.google.gson.JsonParser;
import com.google.gson.stream.JsonReader;
import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.api.event.CustomWorldEvent;
import net.momirealms.customcrops.config.ConfigUtil;
import net.momirealms.customcrops.config.CropConfig;
import net.momirealms.customcrops.config.FertilizerConfig;
import net.momirealms.customcrops.config.SprinklerConfig;
import net.momirealms.customcrops.config.*;
import net.momirealms.customcrops.objects.SimpleLocation;
import net.momirealms.customcrops.objects.Sprinkler;
import net.momirealms.customcrops.objects.WorldState;
@@ -39,6 +36,7 @@ import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.scheduler.BukkitTask;
@@ -240,21 +238,17 @@ public class CustomWorld {
}
}
public void growWire(int cropTime, int sprinklerTime, int dryTime) {
public void growWire(int cropTime, int sprinklerTime, int dryTime, boolean compensation) {
route(sprinklerTime);
Random randomGenerator = new Random();
CropModeInterface cropMode = cropManager.getCropMode();
tempWatered.removeAll(watered);
for (SimpleLocation simpleLocation : tempWatered) {
bukkitScheduler.runTaskLater(CustomCrops.plugin, () -> {
Location dryLoc = MiscUtils.getLocation(simpleLocation);
if (dryLoc == null) return;
cropManager.potDryJudge(dryLoc);
}, sprinklerTime + randomGenerator.nextInt(dryTime));
if (!compensation) {
route(sprinklerTime);
potDryJudge(sprinklerTime + randomGenerator.nextInt(dryTime));
}
CropModeInterface cropMode = cropManager.getCropMode();
for (SimpleLocation location : cropCache.keySet()) {
BukkitTask task = bukkitScheduler.runTaskLaterAsynchronously(CustomCrops.plugin, () -> {
Location seedLoc = MiscUtils.getLocation(location);
@@ -267,21 +261,17 @@ public class CustomWorld {
}
}
public void growFrame(int cropTime, int sprinklerTime, int dryTime) {
public void growFrame(int cropTime, int sprinklerTime, int dryTime, boolean compensation) {
route(sprinklerTime);
Random randomGenerator = new Random();
CropModeInterface cropMode = cropManager.getCropMode();
tempWatered.removeAll(watered);
for (SimpleLocation simpleLocation : tempWatered) {
bukkitScheduler.runTaskLaterAsynchronously(CustomCrops.plugin, () -> {
Location dryLoc = MiscUtils.getLocation(simpleLocation);
if (dryLoc == null) return;
cropManager.potDryJudge(dryLoc);
}, sprinklerTime + randomGenerator.nextInt(dryTime));
if (!compensation) {
route(sprinklerTime);
potDryJudge(sprinklerTime + randomGenerator.nextInt(dryTime));
}
CropModeInterface cropMode = cropManager.getCropMode();
for (SimpleLocation location : cropCache.keySet()) {
long random = randomGenerator.nextInt(cropTime);
BukkitTask task1 = bukkitScheduler.runTaskLater(CustomCrops.plugin, () -> {
@@ -346,17 +336,37 @@ public class CustomWorld {
if (sprinkler.getWater() <= 0) return;
Location sprinklerLoc = MiscUtils.getLocation(location);
if (sprinklerLoc == null) return;
if (MainConfig.enableAnimations) {
Bukkit.getScheduler().runTask(CustomCrops.plugin, () -> {
for (Player player : sprinklerLoc.getNearbyPlayers(48)) {
cropManager.getArmorStandUtil().playWaterAnimation(player, sprinklerLoc.clone().add(0.5, 0.3, 0.5));
}
});
}
sprinkler.setWater(sprinkler.getWater() - 1);
int range = sprinkler.getRange();
for(int i = -range; i <= range; i++){
for (int j = -range; j <= range; j++){
Location wetLoc = sprinklerLoc.clone().add(i,-1,j);
cropManager.makePotWet(wetLoc);
watered.add(MiscUtils.getSimpleLocation(wetLoc));
setPotWet(wetLoc);
}
}
}
private void potDryJudge(int time) {
bukkitScheduler.runTaskLater(CustomCrops.plugin, () -> {
tempWatered.removeAll(watered);
for (SimpleLocation simpleLocation : tempWatered) {
Location dryLoc = MiscUtils.getLocation(simpleLocation);
if (dryLoc == null) return;
cropManager.potDryJudge(dryLoc);
}
}, time);
}
@Nullable
public Fertilizer getFertilizer(Location potLoc) {
return fertilizerCache.get(MiscUtils.getSimpleLocation(potLoc));

View File

@@ -26,7 +26,6 @@ import net.momirealms.customcrops.integrations.customplugin.CustomInterface;
import net.momirealms.customcrops.objects.GiganticCrop;
import net.momirealms.customcrops.objects.fertilizer.Fertilizer;
import net.momirealms.customcrops.objects.fertilizer.Gigantic;
import net.momirealms.customcrops.objects.fertilizer.RetainingSoil;
import net.momirealms.customcrops.objects.fertilizer.SpeedGrow;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;

View File

@@ -36,7 +36,7 @@ public class TimerTask extends BukkitRunnable {
for (World world : MainConfig.getWorldsList()) {
long time = world.getTime();
if (time > 950 && time < 1051) {
cropManager.grow(world, MainConfig.timeToGrow, MainConfig.timeToWork, MainConfig.timeToDry);
cropManager.grow(world, MainConfig.timeToGrow, MainConfig.timeToWork, MainConfig.timeToDry, false);
}
}
}

View File

@@ -0,0 +1,35 @@
package net.momirealms.customcrops.objects;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
public class CrowTask extends BukkitRunnable {
private int timer;
private Player player;
private Location location;
private Vector vector_1;
private Vector vector_2;
private float yaw;
public CrowTask(Player player, Vector vector_1, Vector vector_2, Location location, float yaw) {
this.player = player;
this.timer = 0;
this.vector_1 = vector_1;
this.vector_2 = vector_2;
this.location = location;
this.yaw = yaw;
}
@Override
public void run() {
while (this.timer < 40) {
timer++;
location.add(vector_1).subtract(0,0.2,0);
}
}
}

View File

@@ -0,0 +1,128 @@
package net.momirealms.customcrops.utils;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.wrappers.EnumWrappers;
import com.comphenix.protocol.wrappers.Pair;
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.config.BasicItemConfig;
import net.momirealms.customcrops.config.MainConfig;
import net.momirealms.customcrops.managers.CropManager;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
public class ArmorStandUtil {
private final CropManager cropManager;
private static final Vector[] vectors =
{new Vector(10,10,10), new Vector(0,10,-15)
, new Vector(10,10,-10), new Vector(15,10,0)
, new Vector(-15,10,0), new Vector(-10,10,10)
, new Vector(0,10,15), new Vector(-10,10,-10)};
private static final float[] yaws = {135f, 180f, -135f, -90f, -45f, 0f, 45f, 90f};
public ArmorStandUtil(CropManager cropManager) {
this.cropManager = cropManager;
}
public void playWaterAnimation(Player player, Location location) {
int id = new Random().nextInt(1000000000);
try {
CustomCrops.protocolManager.sendServerPacket(player, getSpawnPacket(id, location));
CustomCrops.protocolManager.sendServerPacket(player, getMetaPacket(id));
CustomCrops.protocolManager.sendServerPacket(player, getEquipPacket(id, cropManager.getCustomInterface().getItemStack(BasicItemConfig.waterEffect)));
} catch (InvocationTargetException e) {
e.printStackTrace();
}
Bukkit.getScheduler().runTaskLaterAsynchronously(CustomCrops.plugin, () -> {
try {
CustomCrops.protocolManager.sendServerPacket(player, getDestroyPacket(id));
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}, MainConfig.timeToWork/2);
}
public void playCrowAnimation(Player player, Location location) {
int id = new Random().nextInt(1000000000);
Location startLoc = location.clone().add(vectors[new Random().nextInt(vectors.length - 1)]);
try {
CustomCrops.protocolManager.sendServerPacket(player, getSpawnPacket(id, startLoc));
CustomCrops.protocolManager.sendServerPacket(player, getMetaPacket(id));
CustomCrops.protocolManager.sendServerPacket(player, getEquipPacket(id, cropManager.getCustomInterface().getItemStack(BasicItemConfig.crowLand)));
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
private WrappedDataWatcher createDataWatcher() {
WrappedDataWatcher wrappedDataWatcher = new WrappedDataWatcher();
WrappedDataWatcher.Serializer serializer1 = WrappedDataWatcher.Registry.get(Boolean.class);
WrappedDataWatcher.Serializer serializer2 = WrappedDataWatcher.Registry.get(Byte.class);
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(3, serializer1), false);
byte flag = 0x20;
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, serializer2), flag);
return wrappedDataWatcher;
}
private PacketContainer getDestroyPacket(int id) {
PacketContainer destroyPacket = new PacketContainer(PacketType.Play.Server.ENTITY_DESTROY);
destroyPacket.getIntLists().write(0, List.of(id));
return destroyPacket;
}
private PacketContainer getSpawnPacket(int id, Location location) {
PacketContainer entityPacket = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY);
entityPacket.getModifier().write(0, id);
entityPacket.getModifier().write(1, UUID.randomUUID());
entityPacket.getEntityTypeModifier().write(0, EntityType.ARMOR_STAND);
entityPacket.getDoubles().write(0, location.getX());
entityPacket.getDoubles().write(1, location.getY());
entityPacket.getDoubles().write(2, location.getZ());
return entityPacket;
}
private PacketContainer getMetaPacket(int id) {
PacketContainer metaPacket = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
metaPacket.getIntegers().write(0, id);
metaPacket.getWatchableCollectionModifier().write(0, createDataWatcher().getWatchableObjects());
return metaPacket;
}
private PacketContainer getEquipPacket(int id, ItemStack itemStack) {
PacketContainer equipPacket = new PacketContainer(PacketType.Play.Server.ENTITY_EQUIPMENT);
equipPacket.getIntegers().write(0, id);
List<Pair<EnumWrappers.ItemSlot, ItemStack>> pairs = new ArrayList<>();
pairs.add(new Pair<>(EnumWrappers.ItemSlot.HEAD, itemStack));
equipPacket.getSlotStackPairLists().write(0, pairs);
return equipPacket;
}
private PacketContainer getTeleportPacket(int id, Location location) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_TELEPORT);
packet.getIntegers().write(0, id);
packet.getDoubles().write(0, location.getX());
packet.getDoubles().write(1, location.getY());
packet.getDoubles().write(2, location.getZ());
return packet;
}
private PacketContainer getRotationPacket(int id, float yaw) {
PacketContainer rotationPacket = new PacketContainer(PacketType.Play.Server.ENTITY_HEAD_ROTATION);
rotationPacket.getIntegers().write(0, id);
rotationPacket.getBytes().write(0, (byte) yaw);
return rotationPacket;
}
}

View File

@@ -67,8 +67,8 @@ public class HologramUtil {
metaPacket.getModifier().write(0,id);
metaPacket.getWatchableCollectionModifier().write(0, wrappedDataWatcher.getWatchableObjects());
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(player, spawnPacket);
ProtocolLibrary.getProtocolManager().sendServerPacket(player, metaPacket);
CustomCrops.protocolManager.sendServerPacket(player, spawnPacket);
CustomCrops.protocolManager.sendServerPacket(player, metaPacket);
}
catch (Exception e) {
AdventureUtil.consoleMessage("<red>[CustomCrops] Failed to display hologram for " + player.getName() + " !</red>");
@@ -84,7 +84,7 @@ public class HologramUtil {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_DESTROY);
packet.getIntLists().write(0, List.of(entityId));
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet);
CustomCrops.protocolManager.sendServerPacket(player, packet);
}
catch (Exception e) {
AdventureUtil.consoleMessage("<red>[CustomCrops] Failed to remove hologram for " + player.getName() + " !</red>");

View File

@@ -3,6 +3,7 @@ wet-pot: customcrops:watered_pot
greenhouse-glass: customcrops:greenhouse_glass
dead-crop: customcrops:crop_stage_death
soil-surveyor: customcrops:soil_surveyor
crow: customcrops:crow
crow-fly: customcrops:crow_fly
crow-land: customcrops:crow_land
scarecow: customcrops:scarecow
water-effect: customcrops:water_effect

View File

@@ -3,6 +3,7 @@ wet-pot: watered_pot
greenhouse-glass: greenhouse_glass
dead-crop: crop_stage_death
soil-surveyor: soil_surveyor
crow: crow
crow-fly: crow_fly
crow-land: crow_land
scarecow: scarecow
water-effect: water_effect

View File

@@ -29,20 +29,12 @@ integration:
# Season
RealisticSeasons: false
worlds:
# Mode: whitelist/blacklist
mode: whitelist
list:
- world
optimization:
# Recommend enabling this to prevent large quantities of crops/itemframes lagging the server
limitation:
@@ -55,7 +47,6 @@ optimization:
# Disable the animation when sprinkler works
disable-sprinkler-animation: false
mechanics:
# Mode: tripwire/item_frame
@@ -90,7 +81,7 @@ mechanics:
prevent-plant-if-wrong-season: true
# Should player be notified of the wrong season?
should-notify-if-wrong-season: true
#
fill:
watering-can-to-sprinkler: 1
water-bucket-to-sprinkler: 3

View File

@@ -1,5 +1,7 @@
# Crop Name
# Your seeds should end with "_seeds" and stage model should end with "_stage_x"
tomato:
# If you don't need quality-loots just delete them
quality-loots:
amount: 1~4
quality:
@@ -21,32 +23,110 @@ tomato:
gigantic-crop:
block: customcrops:gigantic_tomato
#furniture: customcrops:gigantic_tomato(If you want gigantic crop to be a furniture)
# furniture: customcrops:gigantic_tomato (If you want gigantic crop to be a furniture)
chance: 0.01
harvest-actions:
messages:
- 'Test Message'
- 'Hello, {player}! <u><click:open_url:xxx.xxx>Click here to read the CustomCrops wiki'
- '<u>This plugin uses MiniMessage Format, check it here</u><click:open_url:https://docs.adventure.kyori.net/minimessage/format.html> <gold>[Click Me]'
commands:
- 'say {player} harvested a tomato! lol'
xp: 10
#skill-xp: 100
# When you harvest with a single right click, the crop would return to a certain stage
return: customcrops:tomato_stage_1
#optional
season:
- summer
- autumn
- Spring
requirements:
condition_1:
# available types:
# permission/biome/time/weather/world/yPos
# Condition System:
type: permission
# Mode: && / ||
mode: '&&'
value:
- crops.plant.tomato
# The message to be shown when player doesn't fit the requirement
message: 'You don''t have permission to plant this seed!'
message: 'You don''t have permission to plant this seed!'
grape:
quality-loots:
amount: 3~4
quality:
1: customcrops:grape
2: customcrops:grape_silver_star
3: customcrops:grape_golden_star
return: customcrops:grape_stage_4
season:
- Spring
- Summer
- Autumn
garlic:
quality-loots:
amount: 1~4
quality:
1: customcrops:garlic
2: customcrops:garlic_silver_star
3: customcrops:garlic_golden_star
season:
- Autumn
- Winter
redpacket:
other-loots:
loot_1:
item: customcrops:redpacket
min_amount: 1
max_amount: 2
chance: 1
loot_2:
item: customcrops:redpacket
min_amount: 1
max_amount: 4
chance: 0.8
loot_3:
item: customcrops:redpacket
min_amount: 1
max_amount: 2
chance: 0.4
cabbage:
quality-loots:
amount: 1~1
quality:
1: customcrops:cabbage
2: customcrops:cabbage_silver_star
3: customcrops:cabbage_golden_star
season:
- Spring
- Summer
gigantic-crop:
block: customcrops:gigantic_cabbage
chance: 0.02
pepper:
quality-loots:
amount: 3~6
quality:
1: customcrops:pepper
2: customcrops:pepper_silver_star
3: customcrops:pepper_golden_star
return: customcrops:pepper_stage_4
season:
- Spring
- Autumn
corn:
quality-loots:
amount: 1~3
quality:
1: customcrops:corn
2: customcrops:corn_silver_star
3: customcrops:corn_golden_star
season:
- Summer
- Autumn

View File

@@ -86,7 +86,7 @@ quality:
#When haveresting, players have a higher chance to get more crops.
quantity:
quantity_1:
name: ''
name: ''
times: 14
chance: 0.5
bonus: 1
@@ -114,23 +114,24 @@ quantity:
#Crops have a higher chance to be gigantic
gigantic:
gigantic_1:
name: ''
name: ''
times: 14
chance: 0.5
# If a crop's default gigantic chance is 0.01, now it's 0.03
chance: 0.02
item: customcrops:gigantic_1
before-plant: true
particle: SPELL_MOB
particle: SOUL
gigantic_2:
name: ''
name: ''
times: 14
chance: 0.5
chance: 0.04
item: customcrops:gigantic_2
before-plant: true
particle: SPELL_MOB
particle: SOUL
gigantic_3:
name: ''
name: ''
times: 14
chance: 0.8
chance: 0.08
item: customcrops:gigantic_3
before-plant: true
particle: SPELL_MOB
particle: SOUL

View File

@@ -120,18 +120,18 @@ gigantic:
chance: 0.02
item: gigantic_1
before-plant: true
particle: SPELL_MOB
particle: SOUL
gigantic_2:
name: '뀐'
times: 14
chance: 0.04
item: gigantic_2
before-plant: true
particle: SPELL_MOB
particle: SOUL
gigantic_3:
name: '뀑'
times: 14
chance: 0.08
item: gigantic_3
before-plant: true
particle: SPELL_MOB
particle: SOUL

View File

@@ -5,6 +5,11 @@ sprinkler_1:
2Ditem: customcrops:sprinkler_1_item
sprinkler_2:
range: 2
max-water-storage: 7
max-water-storage: 6
3Ditem: customcrops:sprinkler_2
2Ditem: customcrops:sprinkler_2_item
2Ditem: customcrops:sprinkler_2_item
sprinkler_3:
range: 3
max-water-storage: 7
3Ditem: customcrops:sprinkler_3
2Ditem: customcrops:sprinkler_3_item

View File

@@ -5,6 +5,11 @@ sprinkler_1:
2Ditem: sprinkler_1_item
sprinkler_2:
range: 2
max-water-storage: 7
max-water-storage: 6
3Ditem: sprinkler_2
2Ditem: sprinkler_2_item
2Ditem: sprinkler_2_item
sprinkler_3:
range: 3
max-water-storage: 7
3Ditem: sprinkler_3
2Ditem: sprinkler_3_item