9
0
mirror of https://github.com/Xiao-MoMi/Custom-Crops.git synced 2025-12-29 11:59:15 +00:00
This commit is contained in:
Xiao-MoMi
2023-05-17 01:06:33 +08:00
parent 2217f0f6ef
commit 5041662a60
21 changed files with 145 additions and 76 deletions

View File

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

Binary file not shown.

View File

@@ -79,7 +79,7 @@ public class OraxenPluginImpl implements PlatformInterface {
return itemFrame;
else {
AdventureUtils.consoleMessage("<red>[CustomCrops] ItemFrame not exists: " + id);
entity.remove();
OraxenFurniture.remove(entity, null);
return null;
}
}
@@ -97,7 +97,7 @@ public class OraxenPluginImpl implements PlatformInterface {
return itemDisplay;
else {
AdventureUtils.consoleMessage("<red>[CustomCrops] ItemDisplay not exists: " + id);
entity.remove();
OraxenFurniture.remove(entity, null);
return null;
}
}

View File

@@ -24,6 +24,6 @@ import org.jetbrains.annotations.Nullable;
public interface Action {
void doOn(@Nullable Player player, @Nullable SimpleLocation crop_loc, ItemMode itemMode);
void doOn(@Nullable Player player, @Nullable SimpleLocation cropLoc, ItemMode itemMode);
}

View File

@@ -24,10 +24,14 @@ import net.momirealms.customcrops.api.object.crop.CropConfig;
import net.momirealms.customcrops.api.object.crop.StageConfig;
import net.momirealms.customcrops.api.object.world.SimpleLocation;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.concurrent.CompletableFuture;
public class BreakImpl implements Action {
private final boolean triggerAction;
@@ -39,30 +43,57 @@ public class BreakImpl implements Action {
}
@Override
public void doOn(@Nullable Player player, @Nullable SimpleLocation crop_loc, ItemMode itemMode) {
if (crop_loc == null || stage_id == null || player == null) return;
public void doOn(@Nullable Player player, @Nullable SimpleLocation cropLoc, ItemMode itemMode) {
if (cropLoc == null || stage_id == null) return;
CropConfig cropConfig = CustomCrops.getInstance().getCropManager().getCropConfigByStage(stage_id);
CustomCrops.getInstance().getScheduler().runTask(() -> {
Location bLoc = crop_loc.getBukkitLocation();
if (bLoc == null) return;
Location bLoc = cropLoc.getBukkitLocation();
if (bLoc == null) return;
if (player != null) {
CropBreakEvent cropBreakEvent = new CropBreakEvent(player, cropConfig, stage_id, bLoc);
Bukkit.getPluginManager().callEvent(cropBreakEvent);
if (cropBreakEvent.isCancelled()) {
return;
}
CustomCrops.getInstance().getPlatformInterface().removeAnyThingAt(bLoc);
CustomCrops.getInstance().getWorldDataManager().removeCropData(crop_loc);
if (triggerAction) {
StageConfig stageConfig = CustomCrops.getInstance().getCropManager().getStageConfig(stage_id);
if (stageConfig != null) {
Action[] actions = stageConfig.getBreakActions();
if (actions != null) {
for (Action action : actions) {
action.doOn(player, crop_loc, itemMode);
}
CustomCrops.getInstance().getWorldDataManager().removeCropData(cropLoc);
doTriggerActions(player, cropLoc, itemMode);
} else {
CompletableFuture<Chunk> asyncGetChunk = bLoc.getWorld().getChunkAtAsync(bLoc.getBlockX() >> 4, bLoc.getBlockZ() >> 4);
if (itemMode == ItemMode.ITEM_FRAME || itemMode == ItemMode.ITEM_DISPLAY) {
CompletableFuture<Boolean> loadEntities = asyncGetChunk.thenApply((chunk) -> {
chunk.getEntities();
return chunk.isEntitiesLoaded();
});
loadEntities.whenComplete((result, throwable) ->
CustomCrops.getInstance().getScheduler().runTask(() -> {
CustomCrops.getInstance().getWorldDataManager().removeCropData(cropLoc);
if (CustomCrops.getInstance().getPlatformInterface().removeCustomItem(bLoc, itemMode)) {
doTriggerActions(null, cropLoc, itemMode);
}
}));
} else {
asyncGetChunk.whenComplete((result, throwable) ->
CustomCrops.getInstance().getScheduler().runTask(() -> {
CustomCrops.getInstance().getWorldDataManager().removeCropData(cropLoc);
if (CustomCrops.getInstance().getPlatformInterface().removeCustomItem(bLoc, itemMode)) {
doTriggerActions(null, cropLoc, itemMode);
}
}));
}
}
}
private void doTriggerActions(@Nullable Player player, @NotNull SimpleLocation crop_loc, ItemMode itemMode) {
if (triggerAction) {
StageConfig stageConfig = CustomCrops.getInstance().getCropManager().getStageConfig(stage_id);
if (stageConfig != null) {
Action[] actions = stageConfig.getBreakActions();
if (actions != null) {
for (Action action : actions) {
action.doOn(player, crop_loc, itemMode);
}
}
}
});
}
}
}

View File

@@ -33,10 +33,10 @@ public class ChainImpl implements Action {
}
@Override
public void doOn(@Nullable Player player, @Nullable SimpleLocation crop_loc, ItemMode itemMode) {
public void doOn(@Nullable Player player, @Nullable SimpleLocation cropLoc, ItemMode itemMode) {
if (Math.random() < chance) {
for (Action action : actions) {
action.doOn(player, crop_loc, itemMode);
action.doOn(player, cropLoc, itemMode);
}
}
}

View File

@@ -26,14 +26,14 @@ import org.jetbrains.annotations.Nullable;
public record CommandActionImpl(String[] commands, double chance) implements Action {
@Override
public void doOn(@Nullable Player player, @Nullable SimpleLocation crop_loc, ItemMode itemMode) {
public void doOn(@Nullable Player player, @Nullable SimpleLocation cropLoc, ItemMode itemMode) {
if (player == null || Math.random() > chance) return;
for (String command : commands) {
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(),
command.replace("{player}", player.getName())
.replace("{x}", crop_loc == null ? "" : String.valueOf(crop_loc.getX()))
.replace("{y}", crop_loc == null ? "" : String.valueOf(crop_loc.getY()))
.replace("{z}", crop_loc == null ? "" : String.valueOf(crop_loc.getZ()))
.replace("{x}", cropLoc == null ? "" : String.valueOf(cropLoc.getX()))
.replace("{y}", cropLoc == null ? "" : String.valueOf(cropLoc.getY()))
.replace("{z}", cropLoc == null ? "" : String.valueOf(cropLoc.getZ()))
.replace("{world}", player.getWorld().getName())
);
}

View File

@@ -17,6 +17,7 @@
package net.momirealms.customcrops.api.object.action;
import net.momirealms.customcrops.CustomCrops;
import net.momirealms.customcrops.api.object.ItemMode;
import net.momirealms.customcrops.api.object.loot.Loot;
import net.momirealms.customcrops.api.object.world.SimpleLocation;
@@ -26,10 +27,18 @@ import org.jetbrains.annotations.Nullable;
public record DropItemImpl(Loot[] loots) implements Action {
@Override
public void doOn(@Nullable Player player, @Nullable SimpleLocation crop_loc, ItemMode itemMode) {
if (crop_loc == null) return;
for (Loot loot : loots) {
loot.drop(player, crop_loc.getBukkitLocation());
public void doOn(@Nullable Player player, @Nullable SimpleLocation cropLoc, ItemMode itemMode) {
if (cropLoc == null) return;
if (player != null) {
for (Loot loot : loots) {
loot.drop(player, cropLoc.getBukkitLocation());
}
} else {
CustomCrops.getInstance().getScheduler().runTask(() -> {
for (Loot loot : loots) {
loot.drop(null, cropLoc.getBukkitLocation());
}
});
}
}
}

View File

@@ -10,7 +10,7 @@ import org.jetbrains.annotations.Nullable;
public record GiveMoneyImpl(double money, double chance) implements Action {
@Override
public void doOn(@Nullable Player player, @Nullable SimpleLocation crop_loc, ItemMode itemMode) {
public void doOn(@Nullable Player player, @Nullable SimpleLocation cropLoc, ItemMode itemMode) {
if (player != null && Math.random() < chance) {
VaultHook vaultHook = CustomCrops.getInstance().getIntegrationManager().getVault();
if (vaultHook != null) {

View File

@@ -27,7 +27,7 @@ import org.jetbrains.annotations.Nullable;
public record JobXPImpl(double amount, double chance) implements Action {
@Override
public void doOn(@Nullable Player player, @Nullable SimpleLocation crop_loc, ItemMode itemMode) {
public void doOn(@Nullable Player player, @Nullable SimpleLocation cropLoc, ItemMode itemMode) {
if (player == null || Math.random() > chance) return;
JobInterface jobInterface = CustomCrops.getInstance().getIntegrationManager().getJobInterface();
if (jobInterface == null) return;

View File

@@ -26,15 +26,15 @@ import org.jetbrains.annotations.Nullable;
public record MessageActionImpl(String[] messages, double chance) implements Action {
@Override
public void doOn(@Nullable Player player, @Nullable SimpleLocation crop_loc, ItemMode itemMode) {
public void doOn(@Nullable Player player, @Nullable SimpleLocation cropLoc, ItemMode itemMode) {
if (player == null || Math.random() > chance) return;
for (String message : messages) {
AdventureUtils.playerMessage(player,
message.replace("{player}", player.getName())
.replace("{world}", player.getWorld().getName())
.replace("{x}", crop_loc == null ? "" : String.valueOf(crop_loc.getX()))
.replace("{y}", crop_loc == null ? "" : String.valueOf(crop_loc.getY()))
.replace("{z}", crop_loc == null ? "" : String.valueOf(crop_loc.getZ()))
.replace("{x}", cropLoc == null ? "" : String.valueOf(cropLoc.getX()))
.replace("{y}", cropLoc == null ? "" : String.valueOf(cropLoc.getY()))
.replace("{z}", cropLoc == null ? "" : String.valueOf(cropLoc.getZ()))
);
}
}

View File

@@ -37,9 +37,9 @@ public class ParticleImpl implements Action {
}
@Override
public void doOn(@Nullable Player player, @Nullable SimpleLocation crop_loc, ItemMode itemMode) {
if (crop_loc == null) return;
Location location = crop_loc.getBukkitLocation();
public void doOn(@Nullable Player player, @Nullable SimpleLocation cropLoc, ItemMode itemMode) {
if (cropLoc == null) return;
Location location = cropLoc.getBukkitLocation();
if (location == null) return;
location.getWorld().spawnParticle(particle, location.clone().add(0.5,0.5,0.5), amount, offset, offset, offset);
}

View File

@@ -26,7 +26,7 @@ import org.jetbrains.annotations.Nullable;
public record PotionEffectImpl(PotionEffect potionEffect, double chance) implements Action {
@Override
public void doOn(@Nullable Player player, @Nullable SimpleLocation crop_loc, ItemMode itemMode) {
public void doOn(@Nullable Player player, @Nullable SimpleLocation cropLoc, ItemMode itemMode) {
if (player == null || Math.random() > chance) return;
player.addPotionEffect(potionEffect);
}

View File

@@ -27,10 +27,13 @@ import net.momirealms.customcrops.api.object.crop.GrowingCrop;
import net.momirealms.customcrops.api.object.world.SimpleLocation;
import net.momirealms.customcrops.api.util.AdventureUtils;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
import java.util.concurrent.CompletableFuture;
public class ReplantImpl implements Action {
private final int point;
@@ -44,30 +47,56 @@ public class ReplantImpl implements Action {
}
@Override
public void doOn(@Nullable Player player, @Nullable SimpleLocation crop_loc, ItemMode itemMode) {
if (player == null || crop_loc == null) return;
public void doOn(@Nullable Player player, @Nullable SimpleLocation cropLoc, ItemMode itemMode) {
if (cropLoc == null) return;
CropConfig cropConfig = CustomCrops.getInstance().getCropManager().getCropConfigByID(crop);
if (cropConfig != null) {
Location location = cropLoc.getBukkitLocation();
if (location == null) return;
ItemMode newCMode = cropConfig.getCropMode();
CustomCrops.getInstance().getScheduler().runTask(() -> {
Location location = crop_loc.getBukkitLocation();
if (location == null) return;
if (ConfigManager.enableLimitation && CustomCrops.getInstance().getWorldDataManager().getChunkCropAmount(crop_loc) >= ConfigManager.maxCropPerChunk) {
AdventureUtils.playerMessage(player, MessageManager.prefix + MessageManager.reachChunkLimit);
return;
if (ConfigManager.enableLimitation && CustomCrops.getInstance().getWorldDataManager().getChunkCropAmount(cropLoc) >= ConfigManager.maxCropPerChunk) {
AdventureUtils.playerMessage(player, MessageManager.prefix + MessageManager.reachChunkLimit);
return;
}
if (player != null) {
// Though the task is executed on main thread
// But it still needs slight delay to prevent crop loots from doubled when clicking with both left and right click
// It's still unsure how it happens
CustomCrops.getInstance().getScheduler().runTask(() -> {
CropPlantEvent cropPlantEvent = new CropPlantEvent(player, player.getInventory().getItemInMainHand(), location, crop, point, model);
Bukkit.getPluginManager().callEvent(cropPlantEvent);
if (cropPlantEvent.isCancelled()) {
return;
}
if (!CustomCrops.getInstance().getPlatformInterface().detectAnyThing(location)) {
CustomCrops.getInstance().getPlatformInterface().placeCustomItem(location, model, newCMode);
CustomCrops.getInstance().getWorldDataManager().addCropData(cropLoc, new GrowingCrop(crop, point), true);
}
});
} else {
CompletableFuture<Chunk> asyncGetChunk = location.getWorld().getChunkAtAsync(location.getBlockX() >> 4, location.getBlockZ() >> 4);
if (itemMode == ItemMode.ITEM_FRAME || itemMode == ItemMode.ITEM_DISPLAY) {
CompletableFuture<Boolean> loadEntities = asyncGetChunk.thenApply((chunk) -> {
chunk.getEntities();
return chunk.isEntitiesLoaded();
});
loadEntities.whenComplete((result, throwable) ->
CustomCrops.getInstance().getScheduler().runTask(() -> {
if (!CustomCrops.getInstance().getPlatformInterface().detectAnyThing(location)) {
CustomCrops.getInstance().getPlatformInterface().placeCustomItem(location, model, newCMode);
CustomCrops.getInstance().getWorldDataManager().addCropData(cropLoc, new GrowingCrop(crop, point), true);
}
}));
} else {
asyncGetChunk.whenComplete((result, throwable) ->
CustomCrops.getInstance().getScheduler().runTask(() -> {
if (!CustomCrops.getInstance().getPlatformInterface().detectAnyThing(location)) {
CustomCrops.getInstance().getPlatformInterface().placeCustomItem(location, model, newCMode);
CustomCrops.getInstance().getWorldDataManager().addCropData(cropLoc, new GrowingCrop(crop, point), true);
}
}));
}
CropPlantEvent cropPlantEvent = new CropPlantEvent(player, player.getInventory().getItemInMainHand(), location, crop, point, model);
Bukkit.getPluginManager().callEvent(cropPlantEvent);
if (cropPlantEvent.isCancelled()) {
return;
}
if (!CustomCrops.getInstance().getPlatformInterface().detectAnyThing(location)) {
CustomCrops.getInstance().getPlatformInterface().placeCustomItem(location, model, newCMode);
CustomCrops.getInstance().getWorldDataManager().addCropData(crop_loc, new GrowingCrop(crop, point), true);
}
});
}
}
}
}

View File

@@ -27,7 +27,7 @@ import org.jetbrains.annotations.Nullable;
public record SkillXPImpl(double amount, double chance) implements Action {
@Override
public void doOn(@Nullable Player player, @Nullable SimpleLocation crop_loc, ItemMode itemMode) {
public void doOn(@Nullable Player player, @Nullable SimpleLocation cropLoc, ItemMode itemMode) {
if (player == null || Math.random() > chance) return;
SkillInterface skillInterface = CustomCrops.getInstance().getIntegrationManager().getSkillInterface();
if (skillInterface == null) return;

View File

@@ -28,7 +28,7 @@ import org.jetbrains.annotations.Nullable;
public record SoundActionImpl(String source, String sound, float volume, float pitch) implements Action {
@Override
public void doOn(@Nullable Player player, @Nullable SimpleLocation crop_loc, ItemMode itemMode) {
public void doOn(@Nullable Player player, @Nullable SimpleLocation cropLoc, ItemMode itemMode) {
if (player == null) return;
AdventureUtils.playerSound(player, Sound.Source.valueOf(source.toUpperCase()), Key.key(sound), volume, pitch);
}

View File

@@ -8,7 +8,7 @@ import org.jetbrains.annotations.Nullable;
public class SwingHandImpl implements Action {
@Override
public void doOn(@Nullable Player player, @Nullable SimpleLocation crop_loc, ItemMode itemMode) {
public void doOn(@Nullable Player player, @Nullable SimpleLocation cropLoc, ItemMode itemMode) {
if (player != null) {
player.swingMainHand();
}

View File

@@ -28,7 +28,7 @@ import org.jetbrains.annotations.Nullable;
public record VanillaXPImpl(int amount, boolean mending, double chance) implements Action {
@Override
public void doOn(@Nullable Player player, @Nullable SimpleLocation crop_loc, ItemMode itemMode) {
public void doOn(@Nullable Player player, @Nullable SimpleLocation cropLoc, ItemMode itemMode) {
if (player == null || Math.random() > chance) return;
player.giveExp(amount, mending);
AdventureUtils.playerSound(player, Sound.Source.PLAYER, Key.key("minecraft:entity.experience_orb.pickup"), 1, 1);

View File

@@ -34,16 +34,16 @@ import java.util.concurrent.CompletableFuture;
public record VariationImpl(VariationCrop[] variationCrops) implements Action {
@Override
public void doOn(@Nullable Player player, @Nullable SimpleLocation crop_loc, ItemMode itemMode) {
if (crop_loc == null) return;
public void doOn(@Nullable Player player, @Nullable SimpleLocation cropLoc, ItemMode itemMode) {
if (cropLoc == null) return;
double bonus = 0;
Pot pot = CustomCrops.getInstance().getWorldDataManager().getPotData(crop_loc.add(0,-1,0));
Pot pot = CustomCrops.getInstance().getWorldDataManager().getPotData(cropLoc.add(0,-1,0));
if (pot != null && CustomCrops.getInstance().getFertilizerManager().getConfigByFertilizer(pot.getFertilizer()) instanceof Variation variation) {
bonus = variation.getChance();
}
for (VariationCrop variationCrop : variationCrops) {
if (Math.random() < variationCrop.getChance() + bonus) {
doVariation(crop_loc, itemMode, variationCrop);
doVariation(cropLoc, itemMode, variationCrop);
break;
}
}
@@ -81,8 +81,7 @@ public record VariationImpl(VariationCrop[] variationCrops) implements Action {
}
return null;
}));
}
else {
} else {
asyncGetChunk.whenComplete((result, throwable) ->
CustomCrops.getInstance().getScheduler().callSyncMethod(() -> {
if (CustomCrops.getInstance().getPlatformInterface().removeCustomItem(location, itemMode)) {

View File

@@ -24,6 +24,7 @@ import net.objecthunter.exp4j.Expression;
import net.objecthunter.exp4j.ExpressionBuilder;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
import java.util.concurrent.ThreadLocalRandom;
@@ -37,7 +38,7 @@ public abstract class Loot {
this.max = max;
}
public void drop(Player player, Location location) {
public void drop(@Nullable Player player, Location location) {
//empty
}
@@ -49,7 +50,7 @@ public abstract class Loot {
return max;
}
public int getAmount(Player player) {
public int getAmount(@Nullable Player player) {
int random = ThreadLocalRandom.current().nextInt(getMin(), getMax() + 1);
if (ConfigManager.enableSkillBonus && player != null) {
SkillInterface skillInterface = CustomCrops.getInstance().getIntegrationManager().getSkillInterface();

View File

@@ -25,13 +25,13 @@ schedule-system:
enable: true
# The average interval for a crop to gain one point (measured in seconds)
# 平均每个农作物获得一生长点的时间间隔(秒)
point-gain-interval: 300
# Water amount and fertilizer would reduce every 4 points are gained
point-gain-interval: 400
# Water amount and fertilizer would reduce every 3 points are gained
# set it to -1 if you don't want CustomCrops to control consumption/sprinkler tasks
# 默认每个生长点进行一次水分、肥料消耗/洒水器工作
# 默认每3个生长点进行一次水分、肥料消耗
# 设置为-1以禁用CustomCrops对水分、肥料消耗/洒水器任务的掌管
consume-water-fertilizer-every-x-point: 4
# Sprinkler would work every two points are gained
consume-water-fertilizer-every-x-point: 3
# Sprinkler would work every 2 points are gained
sprinkler-work-every-x-point: 2
# Save cache to file interval (seconds)
# set "-1" to disable