9
0
mirror of https://github.com/Xiao-MoMi/Custom-Crops.git synced 2025-12-24 01:19:28 +00:00
This commit is contained in:
Xiao-MoMi
2022-10-05 14:53:54 +08:00
parent 984fbff8e8
commit 7bb18a4925
19 changed files with 283 additions and 657 deletions

View File

@@ -244,8 +244,9 @@ public abstract class HandlerP extends Function {
Sprinkler config = SprinklerConfig.SPRINKLERS_2D.get(id);
if (config != null) {
Location sprinklerLoc = location.clone().add(0.5, 1.5, 0.5);
Location sprinklerLoc;
if (MainConfig.OraxenHook) sprinklerLoc = location.clone().add(0.5, 1.03125, 0.5);
else sprinklerLoc = location.clone().add(0.5, 1.5, 0.5);
if (FurnitureUtil.hasFurniture(sprinklerLoc)) return false;
Sprinkler sprinkler = new Sprinkler(config.getKey(), config.getRange(), 0);
@@ -286,6 +287,11 @@ public abstract class HandlerP extends Function {
return customInterface.doesExist(StringUtils.chop(id) + nextStage);
}
public String getNextStage(String id) {
int nextStage = Integer.parseInt(id.substring(id.length()-1)) + 1;
return StringUtils.chop(id) + nextStage;
}
public boolean fillWaterCan(String id, NBTItem nbtItem, ItemStack itemStack, Player player) {
WaterCan config = WaterCanConfig.CANS.get(id);
if (config != null) {
@@ -348,8 +354,9 @@ public abstract class HandlerP extends Function {
if (customWorld == null) return false;
if (fertilizer.isBefore()) {
Location above = potLoc.clone().add(0.5,1.5,0.5);
if (MainConfig.OraxenHook) above.subtract(0, 0.46875, 0);
Location above;
if (MainConfig.OraxenHook) above = potLoc.clone().add(0.5,1.03125,0.5);
else above = potLoc.clone().add(0.5,1.5,0.5);
if (FurnitureUtil.hasFurniture(above)) {
AdventureUtil.playerMessage(player, MessageConfig.prefix + MessageConfig.beforePlant);

View File

@@ -21,7 +21,6 @@ import dev.lone.itemsadder.api.CustomBlock;
import dev.lone.itemsadder.api.CustomFurniture;
import dev.lone.itemsadder.api.CustomStack;
import dev.lone.itemsadder.api.Events.CustomBlockBreakEvent;
import dev.lone.itemsadder.api.Events.CustomBlockInteractEvent;
import dev.lone.itemsadder.api.Events.FurnitureBreakEvent;
import dev.lone.itemsadder.api.Events.FurnitureInteractEvent;
import net.momirealms.customcrops.api.crop.Crop;
@@ -38,7 +37,10 @@ import net.momirealms.customcrops.objects.requirements.RequirementInterface;
import net.momirealms.customcrops.utils.AdventureUtil;
import net.momirealms.customcrops.utils.FurnitureUtil;
import net.momirealms.customcrops.utils.LimitationUtil;
import org.bukkit.*;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Entity;
@@ -63,27 +65,41 @@ public class ItemsAdderFrameHandler extends ItemsAdderHandler {
final Player player = event.getPlayer();
final Entity entity = event.getBukkitEntity();
final Location location = entity.getLocation();;
Sprinkler sprinkler = SprinklerConfig.SPRINKLERS_3D.get(namespacedID);
if (sprinkler != null) {
if (!AntiGrief.testPlace(player, entity.getLocation())) return;
super.onInteractSprinkler(entity.getLocation(), player, player.getInventory().getItemInMainHand(), sprinkler);
return;
}
if (namespacedID.contains("_stage_")) {
if (!namespacedID.equals(BasicItemConfig.deadCrop) && !hasNextStage(namespacedID) && MainConfig.canRightClickHarvest) {
if (!(MainConfig.emptyHand && player.getInventory().getItemInMainHand().getType() != Material.AIR)) {
if (!namespacedID.equals(BasicItemConfig.deadCrop)) {
ItemStack itemInHand = player.getInventory().getItemInMainHand();
if (!hasNextStage(namespacedID)) {
if (MainConfig.canRightClickHarvest && !(MainConfig.emptyHand && itemInHand.getType() != Material.AIR)) {
if (!AntiGrief.testBreak(player, entity.getLocation())) return;
CustomFurniture.remove(entity, false);
this.onInteractRipeCrop(entity.getLocation(), namespacedID, player);
this.onInteractRipeCrop(location, namespacedID, player);
return;
}
}
//has next stage
else if (MainConfig.enableBoneMeal && itemInHand.getType() == Material.BONE_MEAL) {
if (!AntiGrief.testPlace(player, location)) return;
if (player.getGameMode() != GameMode.CREATIVE) itemInHand.setAmount(itemInHand.getAmount() - 1);
if (Math.random() < MainConfig.boneMealChance) {
entity.getWorld().spawnParticle(MainConfig.boneMealSuccess, location.clone().add(0,0.5, 0),3,0.2,0.2,0.2);
CustomFurniture.remove(entity, false);
CustomFurniture.spawn(getNextStage(namespacedID), location.getBlock());
}
return;
}
}
if (!AntiGrief.testPlace(player, entity.getLocation())) return;
Location potLoc = entity.getLocation().clone().subtract(0, 1, 0).getBlock().getLocation();
if (!AntiGrief.testPlace(player, location)) return;
Location potLoc = location.clone().subtract(0, 1, 0).getBlock().getLocation();
super.tryMisc(player, player.getInventory().getItemInMainHand(), potLoc);
}
}
@@ -182,7 +198,7 @@ public class ItemsAdderFrameHandler extends ItemsAdderHandler {
}
if (MainConfig.limitation && LimitationUtil.reachFrameLimit(potLoc)) {
AdventureUtil.playerMessage(player, MessageConfig.prefix + MessageConfig.limitWire.replace("{max}", String.valueOf(MainConfig.wireAmount)));
AdventureUtil.playerMessage(player, MessageConfig.prefix + MessageConfig.limitFrame.replace("{max}", String.valueOf(MainConfig.frameAmount)));
return;
}

View File

@@ -106,39 +106,45 @@ public class ItemsAdderWireHandler extends ItemsAdderHandler {
if (block == null) return;
CustomBlock cb = CustomBlock.byAlreadyPlaced(block);
if (cb == null) return;
Location seedLoc = block.getLocation().clone().add(0,1,0);
Location location = block.getLocation();
final String blockID = cb.getNamespacedID();
//interact crop
if (blockID.contains("_stage_")) {
//ripe crops
if (!blockID.equals(BasicItemConfig.deadCrop) && !hasNextStage(blockID) && MainConfig.canRightClickHarvest) {
if (!(MainConfig.emptyHand && event.hasItem())) {
if (!AntiGrief.testBreak(player, seedLoc)) return;
CustomBlock.remove(seedLoc);
this.onInteractRipeCrop(seedLoc, blockID, player);
ItemStack itemInHand = event.getItem();
if (!blockID.equals(BasicItemConfig.deadCrop)) {
if (!hasNextStage(blockID)) {
if (MainConfig.canRightClickHarvest && !(MainConfig.emptyHand && itemInHand != null && itemInHand.getType() != Material.AIR)) {
if (!AntiGrief.testBreak(player, location)) return;
CustomBlock.remove(location);
this.onInteractRipeCrop(location, blockID, player);
return;
}
}
if (!AntiGrief.testPlace(player, seedLoc)) return;
Location potLoc = block.getLocation().clone().subtract(0,1,0);
super.tryMisc(player, event.getItem(), potLoc);
//has next stage
else if (MainConfig.enableBoneMeal && itemInHand != null && itemInHand.getType() == Material.BONE_MEAL) {
if (!AntiGrief.testPlace(player, location)) return;
if (player.getGameMode() != GameMode.CREATIVE) itemInHand.setAmount(itemInHand.getAmount() - 1);
if (Math.random() < MainConfig.boneMealChance) {
location.getWorld().spawnParticle(MainConfig.boneMealSuccess, location.clone().add(0.5,0.5, 0.5),3,0.2,0.2,0.2);
CustomBlock.remove(location);
CustomBlock.place(getNextStage(blockID), location);
}
return;
}
}
if (!AntiGrief.testPlace(player, location)) return;
Location potLoc = location.clone().subtract(0,1,0);
super.tryMisc(player, itemInHand, potLoc);
}
//interact pot (must have an item)
else if (blockID.equals(BasicItemConfig.wetPot) || blockID.equals(BasicItemConfig.dryPot)) {
if (!AntiGrief.testPlace(player, seedLoc)) return;
if (!AntiGrief.testPlace(player, location)) return;
ItemStack itemInHand = event.getItem();
Location potLoc = block.getLocation();
if (super.tryMisc(player, itemInHand, potLoc)) return;
if (super.tryMisc(player, itemInHand, location)) return;
if (event.getBlockFace() != BlockFace.UP) return;
@@ -150,6 +156,7 @@ public class ItemsAdderWireHandler extends ItemsAdderHandler {
Crop crop = CropConfig.CROPS.get(cropName);
if (crop == null) return;
Location seedLoc = location.clone().add(0,1,0);
CustomWorld customWorld = cropManager.getCustomWorld(seedLoc.getWorld());
if (customWorld == null) return;
@@ -166,7 +173,7 @@ public class ItemsAdderWireHandler extends ItemsAdderHandler {
}
}
if (MainConfig.limitation && LimitationUtil.reachWireLimit(potLoc)) {
if (MainConfig.limitation && LimitationUtil.reachWireLimit(location)) {
AdventureUtil.playerMessage(player, MessageConfig.prefix + MessageConfig.limitWire.replace("{max}", String.valueOf(MainConfig.wireAmount)));
return;
}

View File

@@ -19,18 +19,12 @@ package net.momirealms.customcrops.integrations.customplugin.oraxen;
import de.tr7zw.changeme.nbtapi.NBTCompound;
import de.tr7zw.changeme.nbtapi.NBTItem;
import dev.lone.itemsadder.api.CustomFurniture;
import io.th0rgal.oraxen.OraxenPlugin;
import io.th0rgal.oraxen.events.OraxenFurnitureBreakEvent;
import io.th0rgal.oraxen.events.OraxenFurnitureInteractEvent;
import io.th0rgal.oraxen.events.OraxenNoteBlockBreakEvent;
import io.th0rgal.oraxen.events.OraxenNoteBlockInteractEvent;
import io.th0rgal.oraxen.items.OraxenItems;
import io.th0rgal.oraxen.mechanics.MechanicFactory;
import io.th0rgal.oraxen.mechanics.MechanicsManager;
import io.th0rgal.oraxen.mechanics.provided.gameplay.furniture.FurnitureFactory;
import io.th0rgal.oraxen.mechanics.provided.gameplay.furniture.FurnitureMechanic;
import io.th0rgal.oraxen.mechanics.provided.gameplay.stringblock.StringBlockMechanic;
import io.th0rgal.oraxen.utils.drops.Drop;
import net.momirealms.customcrops.api.crop.Crop;
import net.momirealms.customcrops.api.event.SeedPlantEvent;
@@ -169,7 +163,7 @@ public class OraxenFrameHandler extends OraxenHandler {
}
}
if (MainConfig.limitation && LimitationUtil.reachFrameLimit(potLoc)) {
AdventureUtil.playerMessage(player, MessageConfig.prefix + MessageConfig.limitWire.replace("{max}", String.valueOf(MainConfig.wireAmount)));
AdventureUtil.playerMessage(player, MessageConfig.prefix + MessageConfig.limitFrame.replace("{max}", String.valueOf(MainConfig.frameAmount)));
return;
}
CCSeason[] seasons = crop.getSeasons();
@@ -213,24 +207,42 @@ public class OraxenFrameHandler extends OraxenHandler {
final Player player = event.getPlayer();
final ItemFrame itemFrame = event.getItemFrame();
final Location location = itemFrame.getLocation();
Sprinkler sprinkler = SprinklerConfig.SPRINKLERS_3D.get(id);
if (sprinkler != null) {
if (!AntiGrief.testPlace(player, itemFrame.getLocation())) return;
super.onInteractSprinkler(itemFrame.getLocation(), player, player.getInventory().getItemInMainHand(), sprinkler);
super.onInteractSprinkler(location, player, player.getInventory().getItemInMainHand(), sprinkler);
return;
}
if (id.contains("_stage_")) {
if (!id.equals(BasicItemConfig.deadCrop) && !hasNextStage(id) && MainConfig.canRightClickHarvest) {
if (!(MainConfig.emptyHand && player.getInventory().getItemInMainHand().getType() != Material.AIR)) {
if (!AntiGrief.testBreak(player, itemFrame.getLocation())) return;
if (!id.equals(BasicItemConfig.deadCrop)) {
ItemStack itemInHand = player.getInventory().getItemInMainHand();
if (!hasNextStage(id)) {
if (MainConfig.canRightClickHarvest && !(MainConfig.emptyHand && itemInHand.getType() != Material.AIR)) {
if (!AntiGrief.testBreak(player, location)) return;
itemFrame.remove();
this.onInteractRipeCrop(itemFrame.getLocation(), id, player);
this.onInteractRipeCrop(location, id, player);
return;
}
}
if (!AntiGrief.testPlace(player, itemFrame.getLocation())) return;
Location potLoc = itemFrame.getLocation().clone().subtract(0,1,0).getBlock().getLocation();
//has next stage
else if (MainConfig.enableBoneMeal && itemInHand.getType() == Material.BONE_MEAL) {
if (!AntiGrief.testPlace(player, location)) return;
if (player.getGameMode() != GameMode.CREATIVE) itemInHand.setAmount(itemInHand.getAmount() - 1);
if (Math.random() < MainConfig.boneMealChance) {
itemFrame.getWorld().spawnParticle(MainConfig.boneMealSuccess, location.clone().add(0,0.5, 0),3,0.2,0.2,0.2);
String nextStage = getNextStage(id);
itemFrame.setItem(customInterface.getItemStack(nextStage));
itemFrame.getPersistentDataContainer().set(OraxenHook.FURNITURE, PersistentDataType.STRING, nextStage);
}
return;
}
}
if (!AntiGrief.testPlace(player, location)) return;
Location potLoc = location.clone().subtract(0,1,0).getBlock().getLocation();
super.tryMisc(player, player.getInventory().getItemInMainHand(), potLoc);
}
}

View File

@@ -30,7 +30,6 @@ import net.momirealms.customcrops.integrations.customplugin.CustomInterface;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.Rotation;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Entity;
@@ -40,8 +39,6 @@ import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.Nullable;
import java.util.Random;
import static io.th0rgal.oraxen.mechanics.provided.gameplay.furniture.FurnitureMechanic.FURNITURE_KEY;
public class OraxenHook implements CustomInterface {

View File

@@ -22,7 +22,6 @@ import io.th0rgal.oraxen.items.OraxenItems;
import io.th0rgal.oraxen.mechanics.provided.gameplay.furniture.FurnitureMechanic;
import io.th0rgal.oraxen.mechanics.provided.gameplay.stringblock.StringBlockMechanic;
import io.th0rgal.oraxen.mechanics.provided.gameplay.stringblock.StringBlockMechanicFactory;
import io.th0rgal.oraxen.mechanics.provided.gameplay.stringblock.StringBlockMechanicListener;
import io.th0rgal.oraxen.utils.drops.Drop;
import net.momirealms.customcrops.api.crop.Crop;
import net.momirealms.customcrops.api.event.SeedPlantEvent;
@@ -58,39 +57,41 @@ public class OraxenWireHandler extends OraxenHandler{
public void onBreakNoteBlock(OraxenNoteBlockBreakEvent event) {
if (event.isCancelled()) return;
String id = event.getNoteBlockMechanic().getItemID();
if (id.equals(BasicItemConfig.dryPot) || id.equals(BasicItemConfig.wetPot)) {
// not necessary because string break event would be triggered too
Location location = event.getBlock().getLocation();
Player player = event.getPlayer();
// String id = event.getNoteBlockMechanic().getItemID();
// if (id.equals(BasicItemConfig.dryPot) || id.equals(BasicItemConfig.wetPot)) {
//
// Location location = event.getBlock().getLocation();
// Player player = event.getPlayer();
//
// if (!AntiGrief.testBreak(player, location)) {
// event.setCancelled(true);
// return;
// }
// super.onBreakPot(location);
//
// Location seedLocation = location.clone().add(0,1,0);
// StringBlockMechanic mechanic = StringBlockMechanicListener.getStringMechanic(seedLocation.getBlock());
// if (mechanic == null) return;
// String seedID = mechanic.getItemID();
//
// if (seedID.contains("_stage_")) {
if (!AntiGrief.testBreak(player, location)) {
event.setCancelled(true);
return;
}
super.onBreakPot(location);
Location seedLocation = location.clone().add(0,1,0);
StringBlockMechanic mechanic = StringBlockMechanicListener.getStringMechanic(seedLocation.getBlock());
if (mechanic == null) return;
String seedID = mechanic.getItemID();
if (seedID.contains("_stage_")) {
seedLocation.getBlock().setType(Material.AIR);
if (seedID.equals(BasicItemConfig.deadCrop)) return;
// seedLocation.getBlock().setType(Material.AIR);
// if (seedID.equals(BasicItemConfig.deadCrop)) return;
//ripe or not
if (hasNextStage(seedID)) {
Drop drop = mechanic.getDrop();
if (drop != null && player.getGameMode() != GameMode.CREATIVE) {
drop.spawns(location, new ItemStack(Material.AIR));
}
super.onBreakUnripeCrop(location);
return;
}
super.onBreakRipeCrop(seedLocation, seedID, player, false, false);
}
}
// if (hasNextStage(seedID)) {
// Drop drop = mechanic.getDrop();
// if (drop != null && player.getGameMode() != GameMode.CREATIVE) {
// drop.spawns(location, new ItemStack(Material.AIR));
// }
// super.onBreakUnripeCrop(location);
// return;
// }
// super.onBreakRipeCrop(seedLocation, seedID, player, false, false);
// }
// }
}
@Override
@@ -152,18 +153,16 @@ public class OraxenWireHandler extends OraxenHandler{
if (event.isCancelled()) return;
final Player player = event.getPlayer();
final Location blockLoc = event.getItemFrame().getLocation();
//TODO Check if air is block
final Block block = event.getBlock();
if (!AntiGrief.testPlace(player, block.getLocation())) return;
if (!AntiGrief.testPlace(player, blockLoc)) return;
FurnitureMechanic mechanic = event.getFurnitureMechanic();
if (mechanic == null) return;
String id = mechanic.getItemID();
Sprinkler sprinkler = SprinklerConfig.SPRINKLERS_3D.get(id);
if (sprinkler != null) {
super.onInteractSprinkler(block.getLocation(), player, player.getInventory().getItemInMainHand(), sprinkler);
super.onInteractSprinkler(blockLoc, player, player.getInventory().getItemInMainHand(), sprinkler);
}
}
@@ -180,6 +179,7 @@ public class OraxenWireHandler extends OraxenHandler{
if (event.getBlockFace() != BlockFace.UP) return;
String id = OraxenItems.getIdByItem(itemInHand);
if (id == null) return;
if (id.endsWith("_seeds")) {
String cropName = id.substring(0, id.length() - 6);
Crop crop = CropConfig.CROPS.get(cropName);
@@ -189,7 +189,7 @@ public class OraxenWireHandler extends OraxenHandler{
CustomWorld customWorld = cropManager.getCustomWorld(seedLoc.getWorld());
if (customWorld == null) return;
if (FurnitureUtil.hasFurniture(seedLoc.clone().add(0.5,0.5,0.5))) return;
if (FurnitureUtil.hasFurniture(seedLoc.clone().add(0.5,0.03125,0.5))) return;
if (seedLoc.getBlock().getType() != Material.AIR) return;
PlantingCondition plantingCondition = new PlantingCondition(seedLoc, player);
@@ -240,18 +240,26 @@ public class OraxenWireHandler extends OraxenHandler{
public void onInteractStringBlock(OraxenStringBlockInteractEvent event) {
if (event.isCancelled()) return;
final String id = event.getStringBlockMechanic().getItemID();
final Player player = event.getPlayer();
long time = System.currentTimeMillis();
if (time - (coolDown.getOrDefault(player, time - 50)) < 50) return;
coolDown.put(player, time);
final Block block = event.getBlock();
final String id = event.getStringBlockMechanic().getItemID();
if (id.contains("_stage_")) {
Location seedLoc = block.getLocation();
ItemStack itemInHand = event.getItemInHand();
//ripe crops
if (!id.equals(BasicItemConfig.deadCrop) && !hasNextStage(id) && MainConfig.canRightClickHarvest) {
if (!(MainConfig.emptyHand && (event.getItemInHand() != null && event.getItemInHand().getType() != Material.AIR))) {
if (!id.equals(BasicItemConfig.deadCrop)) {
if (!hasNextStage(id)) {
if (MainConfig.canRightClickHarvest && !(MainConfig.emptyHand && itemInHand != null && itemInHand.getType() != Material.AIR)) {
if (!AntiGrief.testBreak(player, seedLoc)) return;
block.setType(Material.AIR);
@@ -259,6 +267,17 @@ public class OraxenWireHandler extends OraxenHandler{
return;
}
}
//has next stage
else if (MainConfig.enableBoneMeal && itemInHand != null && itemInHand.getType() == Material.BONE_MEAL) {
if (!AntiGrief.testPlace(player, seedLoc)) return;
if (player.getGameMode() != GameMode.CREATIVE) itemInHand.setAmount(itemInHand.getAmount() - 1);
if (Math.random() < MainConfig.boneMealChance) {
seedLoc.getWorld().spawnParticle(MainConfig.boneMealSuccess, seedLoc.clone().add(0.5,0.5, 0.5),3,0.2,0.2,0.2);
StringBlockMechanicFactory.setBlockModel(block, getNextStage(id));
}
return;
}
}
if (!AntiGrief.testPlace(player, seedLoc)) return;

View File

@@ -59,8 +59,9 @@ public class FrameCropImpl implements CropModeInterface {
if (chunk.isEntitiesLoaded()) {
Location cropLoc = location.clone().add(0.5,0.5,0.5);
if (MainConfig.OraxenHook) cropLoc.subtract(0, 0.46875, 0);
Location cropLoc;
if (MainConfig.OraxenHook) cropLoc = location.clone().add(0.5,0.03125,0.5);
else cropLoc = location.clone().add(0.5,0.5,0.5);
ItemFrame itemFrame = FurnitureUtil.getItemFrame(cropLoc);
if (itemFrame == null) return true;
@@ -105,7 +106,6 @@ public class FrameCropImpl implements CropModeInterface {
if (fertilizer instanceof Gigantic gigantic) {
chance += gigantic.getChance();
}
System.out.println(chance);
if (Math.random() < chance) {
Bukkit.getScheduler().runTask(CustomCrops.plugin, () -> {
customInterface.removeFurniture(itemFrame);

View File

@@ -70,11 +70,10 @@ public class WireCropImpl implements CropModeInterface{
if (potID == null) return true;
Fertilizer fertilizer = cropManager.getFertilizer(potLoc);
boolean certainGrow = potID.equals(BasicItemConfig.wetPot);
int nextStage = Integer.parseInt(cropNameList[2]) + 1;
String temp = StringUtils.chop(blockID);
if (customInterface.doesExist(temp + nextStage)) {
if (fertilizer instanceof SpeedGrow speedGrow && Math.random() < speedGrow.getChance()) {
if (customInterface.doesExist(temp + (nextStage+1))) {
@@ -111,7 +110,7 @@ public class WireCropImpl implements CropModeInterface{
private void addStage(Location seedLoc, String stage) {
Bukkit.getScheduler().runTask(CustomCrops.plugin, () -> {
customInterface.removeBlock(seedLoc);
if (!MainConfig.OraxenHook) customInterface.removeBlock(seedLoc);
customInterface.placeWire(seedLoc, stage);
});
}

View File

@@ -49,7 +49,9 @@ public class LimitationUtil {
int n = 0;
for (int i = 0; i < 16; ++i) {
for (int j = 0; j < 16; ++j) {
Location square = chunkLocation.clone().add(i + 0.5, 0.5, j + 0.5);
Location square;
if (MainConfig.OraxenHook) square = chunkLocation.clone().add(i + 0.5, 0.03125, j + 0.5);
else square = chunkLocation.clone().add(i + 0.5, 0.5, j + 0.5);
for (int k = minHeight; k <= maxHeight; ++k) {
square.add(0.0, 1.0, 0.0);
if (FurnitureUtil.hasFurniture(square) && ++n > MainConfig.frameAmount) {

View File

@@ -1,13 +1,9 @@
#Don't change
config-version: '9'
# lang: english / spanish / chinese
lang: chinese
integration:
# AntiGrief
Residence: false
@@ -50,7 +46,7 @@ optimization:
auto-back-up: true
mechanics:
# Requires a restart tp change mode
# Mode: tripwire/item_frame
crops-mode: tripwire
@@ -99,7 +95,6 @@ mechanics:
# Season would not affect ripe crops(for better performance and friendly player's experience)
season:
enable: true
# If you want all the worlds share the same season
sync-seasons:
enable: false

View File

@@ -51,3 +51,82 @@ tomato:
- 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!'
grape:
quality-loots:
amount: 3~4
quality:
1: grape
2: grape_silver_star
3: grape_golden_star
return: grape_stage_4
season:
- Spring
- Summer
- Autumn
garlic:
quality-loots:
amount: 1~4
quality:
1: garlic
2: garlic_silver_star
3: garlic_golden_star
season:
- Autumn
- Winter
redpacket:
other-loots:
loot_1:
item: redpacket
min_amount: 1
max_amount: 2
chance: 1
loot_2:
item: redpacket
min_amount: 1
max_amount: 4
chance: 0.8
loot_3:
item: redpacket
min_amount: 1
max_amount: 2
chance: 0.4
cabbage:
quality-loots:
amount: 1~1
quality:
1: cabbage
2: cabbage_silver_star
3: cabbage_golden_star
season:
- Spring
- Summer
gigantic-crop:
block: gigantic_cabbage
chance: 0.02
pepper:
quality-loots:
amount: 3~6
quality:
1: pepper
2: pepper_silver_star
3: pepper_golden_star
return: pepper_stage_3
season:
- Spring
- Autumn
corn:
quality-loots:
amount: 1~3
quality:
1: corn
2: corn_silver_star
3: corn_golden_star
season:
- Summer
- Autumn

View File

@@ -2,23 +2,25 @@
#https://docs.adventure.kyori.net/minimessage/format.html
messages:
prefix: '<gradient:#ff206c:#fdee55>[CustomCrops] </gradient>'
reload: '<white>重载成功! 耗时 <green>{time}ms'
no-perm: '<red>权限不足!'
lack-args: '<white>参数不足!'
wrong-args: '<white>参数错误!'
spring: '春'
summer: '夏'
autumn: ''
winter: ''
limitation-tripwire: '<white>此区块的拌线数量已到达上限 {max}'
limitation-itemframe: '<white>此区块的展示框数量已到达上限 {max}'
grow-simulation: '<white>已开始模拟生长'
back-up: '<white>已完成数据备份!'
set-season: '<white>成功切换世界 {world} 的季节为 {season}!'
before-plant: '<white>这种肥料必须在种植前使用!'
reload: '<white>Reloaded! Took <green>{time}ms'
no-perm: '<red>No Permission!'
lack-args: '<white>Arguments are insufficient!'
wrong-args: '<white>Wrong arguments!'
none-args: '<white>None arguments!'
invalid-args: '<white>Invalid arguments!'
spring: 'Spring'
summer: 'Summer'
autumn: 'Autumn'
winter: 'Winter'
limitation-tripwire: '<white>Tripwires in this chunk have reached limitation {max}'
limitation-itemframe: '<white>Item frames in this chunk have reached limitation {max}'
grow-simulation: '<white>Growing simulation has started'
set-season: '<white>Successfully set {world}''s season to {season}!'
before-plant: '<white>This fertilizer must be used before planting!'
wrong-season: '<white>Current season is not suitable for planting this seed'
no-season: '此世界没有季节'
season-disabled: '季节系统已被禁用'
auto-season-disabled: '自动季节切换已被禁用,无法计算此变量'
world-not-exist: '世界 {world} 不存在'
season-not-exist: '季节 {season} 不存在'
no-season: 'No season'
season-disabled: 'Season is disabled'
auto-season-disabled: 'Failed to count'
world-not-exist: 'World {world} does not exist'
season-not-exist: 'Season {season} does not exist'

View File

@@ -3,26 +3,24 @@
messages:
prefix: '<gradient:#ff206c:#fdee55>[CustomCrops] </gradient>'
reload: '<white>¡Recargado! Tomó <green>{time}ms'
no-perm: '<red>¡No hay permisos!'
lack-args: '<white>Los argumentos son insuficientes.'
wrong-args: '<white>Argumentos equivocados!'
no-perm: '<red>No tienes permisos!'
lack-args: '<white>Los argumentos son insuficientes'
wrong-args: '<white>Argumentos equivocados'
none-args: '<white>¡Ningún argumento!'
invalid-args: '<white>Argumentos no válidos'
spring: 'Primavera'
summer: 'Verano'
autumn: 'Otoño'
winter: 'Invierno'
sprinkler-limit: '<white>Los aspersores han llegado al límite de su capacidad {max}'
crop-limit: '<white>Los cultivos han llegado al límite de su tamaño {max}'
not-configed: '<white>Esta semilla no está configurada en la configuración.'
bad-Y: '<white>Esta altura no es adecuada para plantar.'
bad-biome: '<white>Este bioma no es apto para ser plantado.'
bad-perm: '<white>¡No tienes permiso para plantar este cultivo!'
bad-world: '<white>Este mundo no es adecuado para plantar'
bad-season: '<white>La temporada actual no es adecuada para la plantación'
force-grow: '<white>¡Forzó a los cultivos de {world} a empezar a crecer!'
force-water: '<white>¡Forzó a los aspersores del {world} a empezar a crecer!'
force-save: '<white>¡Guardado con éxito la caché en un archivo!'
force-all: '<white>Forced {world}''s crops to start growing and sprinklers to start working!'
back-up: '<white>Backed up!'
set-season: '<white>¡Cambió la estación de {world} a {season}!'
before-plant: '<white>Este abono debe utilizarse antes de la siembra.'
no-season: 'Temporada Desactivada'
limitation-tripwire: '<white>Los Tripwires en este trozo han alcanzado la limitación {max}'
limitation-itemframe: '<white>Los ItemFrames de este trozo han alcanzado el límite {max}'
grow-simulation: '<white>La simulación de crecimiento ha comenzado'
set-season: '<white>Fijado con éxito {world}''s temporada a {season}!'
before-plant: '<white>Este abono debe utilizarse antes de la siembra'
wrong-season: '<white>La temporada actual no es adecuada para plantar esta semilla'
no-season: 'Sin temporada'
season-disabled: 'La temporada está desactivada'
auto-season-disabled: 'No se ha podido contar'
world-not-exist: 'World {world} no existe'
season-not-exist: 'Temporada {season} no existe'

View File

@@ -1,70 +0,0 @@
#填写IA物品的命名空间与物品ID
basic:
#植物的种植盆方块
pot: customcrops:pot
#植物的浇过水的种植盆方块
watered-pot: customcrops:watered_pot
#温室玻璃方块
greenhouse-glass: customcrops:greenhouse_glass
#农作物枯萎后变成的方块,物品ID中请保留stage以保持其下方方块被破坏时枯萎作物也被破坏的特性
dead-crop: customcrops:crop_stage_death
#土质探测器,用于查看使用的肥料种类和残余量
soil-detector: customcrops:soil_detector
#如果你想要水壶有自定义耐久度
#请在ia里将它设置为耐久度的物品例如木剑
#IA的自定义耐久度对本插件生效
water-can:
watering_can_1:
item: customcrops:watering_can_1
#水壶最大容量
max: 3
#水壶工作的范围
width: 1
length: 1
#水壶的最大耐久度,不填写则无限耐久
durability: 100
watering_can_2:
item: customcrops:watering_can_2
max: 4
width: 1
length: 3
watering_can_3:
item: customcrops:watering_can_3
max: 5
width: 3
length: 3
watering_can_4:
item: customcrops:watering_can_4
max: 6
width: 3
length: 5
lore:
#是否修改水壶物品的Lore
watering-can:
enable: true
#Lore样式
#可用变量 {water}当前水量 {max_water}最大蓄水量
lore:
- '<italic:false><white>{water_info}'
- '<italic:false><gray>右键水方块为水壶加水'
#水量 {water_info}
left: '<font:customcrops:default>뀂'
full: '뀁뀃'
empty: '뀁뀄'
right: '뀁뀅</font>'
sprinkler:
sprinkler_1:
#洒水器工作范围
range: 1
#洒水器最大水储量
max-water: 5
3Ditem: customcrops:sprinkler_1
2Ditem: customcrops:sprinkler_1_item
sprinkler_2:
range: 2
max-water: 7
3Ditem: customcrops:sprinkler_2
2Ditem: customcrops:sprinkler_2_item

View File

@@ -1,155 +0,0 @@
#请不要修改此值
config-version: '6'
config:
# 语言: english / spanish / chinese
lang: chinese
# 模式: tripwire / item_frame
# 此设置需要重启服务器
# ------------ tripwire ------------
# 优势:
# ● 几乎完全异步
# ● 有原版一样的真实碰撞体积
#
# 劣势:
# ● 拌线数量限制127
# ● 破坏拌线产生的视觉问题
# ● 无法移除破坏拌线的音效
#
# ------------ item_frame ------------
# 优势:
# ● 无限制农作物数量
# ● 支持旋转
#
# 劣势:
# ● 展示框是实体,相对较卡
# ● Spigot优化了实体可见距离
# ● 没有真实的碰撞体积
# ● ItemsAdder的战利品系统无法应用于家具
#
crop-mode: tripwire
# 农作物会有随机的朝向吗?
# 这只在展示框模式中生效
rotation:
enable: false
# 4 / 8
variant: 4
integration:
#领地保护
Residence: false
WorldGuard: false
Kingdoms: false
GriefDefender: false
PlotSquared: false
Towny: false
Lands: false
GriefPrevention: false
CrashClaim: false
BentoBox: false
#增加技能经验
AureliumSkills: false
mcMMO: false
MMOCore: false
EcoSkills: false
JobsReborn: false
#季节同步
RealisticSeasons: false
# Mode 1:
# ● 农作物仅在加载中的区块生长
# Mode 2:
# ● 在线玩家种植的农作物会生长
# Mode 3:
# ● (推荐) Mode 1 + Mode 2
# Mode 4:
# ● 在这个模式下请关闭季节
# ● 所有数据内的农作物都会生长
grow-mode: 3
# 开始生长的时间(ticks)
# 1000ticks 代表游戏时间 7点 (0-23999)
# 洒水器将在所有农作物完成生长后开始工作
grow-time:
- 1000
# 现实时间
#real-time:
# - 06:30
# 农作物将在开始生长的时间点后多少秒内完成生长seconds
# 这是为了避免大量农作物在同一时间点进行判断和方块替换,否则会造成卡顿
# 假如你有100个农作物默认配置代表在游戏时间7点后的现实时间60秒内100个农作物会在这60秒内随机时间点完成生长
time-to-grow: 60
# 和上面的配置类似,只不过这一次是洒水器工作的时间
time-to-work: 30
# 异步时间检测 (需要重启)
# 服务端可能因为某些原因跳tick所以异步模式下可能会错过生长判断
# 异步检测不是很有必要,同步的检测也不会造成性能问题,除非你设置了几百个白名单世界
async-time-check: false
# 哪些世界的农作物能够生长(即白名单世界)
whitelist-worlds:
- world
# 所有世界的农作物都生长吗?
# 此选项适用于单玩家单世界服务器.
# 这种模式下你只能填写一个白名单世界作为时间,季节的判断依据.
all-world-grow: false
# 农作物巨大化是否仅进行一次尝试
# 如果你喜欢星露谷模式,农作物将在成熟后继续吸收水分,每天都有概率巨大化
# 如果你喜欢起源模式,你可以设置巨大化农作物为金农作物,并且仅有一次成为金农作物的机会
gigantic-only-one-try: false
quality:
# 如果禁用品质系统你需要在ItemsAdder的配置文件中单独设置每个农作物的掉落物
enable: true
# 默认品质比例
default-ratio: 17/2/1
# 使用水桶右键洒水器能够补充几格水量
sprinkler-refill: 2
# 使用水壶右键水方块的时候能够为水壶补充多少水量
water-can-refill: 1
# 能否使用水壶为洒水器加水
water-can-add-water-to-sprinkler: true
# 使用水壶的时候发送水花粒子效果吗
water-particles: true
# 是否启用骨粉特性
bone-meal:
enable: true
chance: 0.5
success-particle: VILLAGER_HAPPY
# 区块限制最大农作物和洒水器数量
# 建议开启限制因为一个区块内过多的农作物方块会导致IA插件报错Stack Overflow
limit:
enable: true
crop: 64
sprinkler: 8
# 玩家是否可以使用右键收获农作物
# 如果禁用右键收获,那么重复收获的特性也会被关闭
right-click-harvest: true
# 玩家是否必须要空手才能右键收获
harvest-with-empty-hand: true
# 是否阻止玩家在错误季节的种植
prevent-plant-if-wrong-season: true
# 是否告知玩家这是错误的季节
should-notify-if-wrong-season: true

View File

@@ -1,132 +0,0 @@
#在IA配置文件中
#农作物种子ID请以 _seeds 结尾
#农作物生长阶段请以 _stage_X 结尾
#生长阶段从1开始依次累加
#若无法理解可以参考范例配置文件
crops:
tomato:
#收获时候掉落多少个农产品
amount: 1~4
#品质农作物掉落
quality:
1: customcrops:tomato
2: customcrops:tomato_silver_star
3: customcrops:tomato_golden_star
#当你破坏农作物的时候这个事件会同时被ItemsAdder和CustomCrops处理所以IA配置内的掉落物会被必定掉落
#当你右键收获农作物的时候这个事件仅被CustomCrops处理因此是否掉落IA配置内的掉落物为可选项目
#右键收获的时候是否掉落IA配置内的掉落物
#这对于那些需要农作物掉落额外物品的用户帮助很大,比如掉落种子(但是此设置仅适用于拌线模式因为IA的家具没有掉落物系统)
drop-ia-loots: false
#右键收获的时候是否额外掉落IA物品
#这对于那些需要农作物掉落额外物品的用户帮助很大,比如掉落种子(这是本插件提供的额外掉落物系统独立于IA存在所以拌线和展示框模式都适用)
drop-other-loots:
- customcrops:tomato_seeds
#可选
#农作物在某个生长点的生长概率
#比如你可以设置一天在0点6点12点18点进行生长判断不建议设置太多每次生长概率为0.25,这样即可增大玩家加载到农作物区块的概率
#但是同一时间点种植的农作物,可能会出现一个已经成熟,而另一个还在第一阶段(如果你喜欢这种模式,可以这样设置)
grow-chance: 0.9
#可选
#巨大化农作物
gigantic:
block: customcrops:gigantic_tomato
chance: 0.01
#如果你想要使用展示框/盔甲架作为巨大化农作物的载体
#你需要像这样填写注意IA的API不提供solid屏障方块的放置
#所以家具模式下的巨大化作物无法被屏障包裹
#gigantic:
# furniture: customcrops:gigantic_tomato
# chance: 0.01
#可选
commands:
- 'say {player} harvested a tomato! lol'
#可选
#如果你启用了技能插件的兼容,那么可以设置收获该农作物的经验值
#skill-xp: 100
#可选
#若不填写则农作物四季生长
season:
- summer
- autumn
#可选
#一些农作物种植的其他条件
requirements:
yPos:
- 50~100
- 150~200
biome:
- minecraft:plains
world:
- world
permission: 'customcrops.plant.tomato'
cabbage:
amount: 1~2
quality:
1: customcrops:cabbage
2: customcrops:cabbage_silver_star
3: customcrops:cabbage_golden_star
gigantic:
block: customcrops:gigantic_cabbage
chance: 0.01
season:
- spring
grape:
amount: 2~4
quality:
1: customcrops:grape
2: customcrops:grape_silver_star
3: customcrops:grape_golden_star
#可选
#右键收获的时候农作物返回哪一个阶段
return: customcrops:grape_stage_4
season:
- autumn
corn:
amount: 2~3
quality:
1: customcrops:corn
2: customcrops:corn_silver_star
3: customcrops:corn_golden_star
season:
- autumn
- summer
pepper:
amount: 3~6
quality:
1: customcrops:pepper
2: customcrops:pepper_silver_star
3: customcrops:pepper_golden_star
season:
- spring
- summer
return: customcrops:pepper_stage_3
garlic:
amount: 3~4
quality:
1: customcrops:garlic
2: customcrops:garlic_silver_star
3: customcrops:garlic_golden_star
redpacket:
amount: 3~4
quality:
1: customcrops:redpacket
2: customcrops:redpacket
3: customcrops:redpacket

View File

@@ -1,101 +0,0 @@
#你可以自定义任意数量的肥料
#有概率一次生长两个阶段
speed:
speed_1:
#肥料名,用于悬浮展示
name: '뀌'
#生效的概率
chance: 0.1
#肥料在土壤中存留的生长周期数
times: 14
#命名空间随意物品ID请保持一致
item: customcrops:speed_1
#肥料是否只有在种植前才能使用
before-plant: true
#施肥的粒子效果(可选)
#https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Particle.html
#particle: VILLAGER_HAPPY
speed_2:
name: '뀍'
chance: 0.2
times: 14
item: customcrops:speed_2
before-plant: true
speed_3:
name: '뀎'
chance: 0.3
times: 14
item: customcrops:speed_3
before-plant: true
#土壤在生长点过后有一定概率仍然保持湿润
retaining:
retaining_1:
name: '뀉'
chance: 0.1
times: 28
item: customcrops:retaining_1
before-plant: false
retaining_2:
name: '뀊'
chance: 0.2
times: 28
item: customcrops:retaining_2
before-plant: false
retaining_3:
name: '뀋'
chance: 0.3
times: 28
item: customcrops:retaining_3
before-plant: false
#更改农作物产物三种品质的权重
quality:
quality_1:
name: '뀆'
times: 28
chance: 7/2/1
item: customcrops:quality_1
before-plant: true
quality_2:
name: '뀇'
times: 28
chance: 11/6/3
item: customcrops:quality_2
before-plant: true
quality_3:
name: '뀈'
times: 28
chance: 2/2/1
item: customcrops:quality_3
before-plant: true
#增加农作物的产量
quantity:
quantity_1:
name: '뀏'
times: 14
chance: 0.5
bonus: 1
item: customcrops:quantity_1
before-plant: true
quantity_2:
name: '뀐'
times: 14
chance: 0.5
bonus: 2
item: customcrops:quantity_2
before-plant: true
quantity_3:
name: '뀑'
times: 14
chance: 0.8
bonus: 2
item: customcrops:quantity_3
before-plant: true

View File

@@ -1,17 +0,0 @@
season:
#是否使用季节限制
#非植物季节则无法耕种,过了季节则枯死
enable: true
auto-season-change:
#是否启用内置季节交替
#启用此设置将根据服务器单个世界的游戏天数自动计算当前季节
enable: true
#每个季节的时长(天)
duration: 28
greenhouse:
#温室系统,在温室玻璃正下方的方块可以无视季节种植
enable: true
#温室玻璃有效范围
range: 5

View File

@@ -1,32 +0,0 @@
#使用水壶浇水的音效
water-pot:
sound: minecraft:block.water.ambient
type: player
#使用水壶装水的音效
add-water-to-can:
sound: minecraft:item.bucket.fill
type: player
#将水加入洒水器的音效
add-water-to-sprinkler:
sound: minecraft:item.bucket.fill
type: player
#放置洒水器的音效
place-sprinkler:
sound: minecraft:block.bone_block.place
type: player
#种植种子的音效
plant-seed:
sound: minecraft:item.hoe.till
type: player
#使用肥料的音效
use-fertilizer:
sound: minecraft:item.hoe.till
type: player
#空手收获的音效
harvest:
sound: minecraft:block.crop.break
type: player
#使用骨粉的音效
bonemeal:
sound: minecraft:item.hoe.till
type: player