9
0
mirror of https://github.com/Xiao-MoMi/Custom-Crops.git synced 2025-12-28 03:19:15 +00:00

offline ticks

This commit is contained in:
XiaoMoMi
2024-09-04 02:49:18 +08:00
parent 32f01f1aec
commit a1885e1dda
32 changed files with 216 additions and 142 deletions

View File

@@ -21,7 +21,10 @@ import net.momirealms.customcrops.api.BukkitCustomCropsPlugin;
import net.momirealms.customcrops.api.core.ConfigManager;
import net.momirealms.customcrops.api.core.SimpleRegistryAccess;
import net.momirealms.customcrops.api.core.block.*;
import net.momirealms.customcrops.api.core.item.*;
import net.momirealms.customcrops.api.core.item.FertilizerItem;
import net.momirealms.customcrops.api.core.item.SeedItem;
import net.momirealms.customcrops.api.core.item.SprinklerItem;
import net.momirealms.customcrops.api.core.item.WateringCanItem;
import net.momirealms.customcrops.api.core.mechanic.fertilizer.FertilizerType;
import net.momirealms.customcrops.api.core.world.CustomCropsBlockState;
import net.momirealms.customcrops.api.event.CustomCropsReloadEvent;

View File

@@ -472,8 +472,8 @@ public class PlayerActionManager extends AbstractActionManager<Player> {
Optional<CustomCropsWorld<?>> optionalWorld = plugin.getWorldManager().getWorld(location.getWorld());
optionalWorld.ifPresent(world -> world.getChunk(pos3.toChunkPos()).flatMap(chunk -> chunk.getBlockState(pos3)).ifPresent(state -> {
CustomCropsBlock customCropsBlock = state.type();
customCropsBlock.randomTick(state, world, pos3);
customCropsBlock.scheduledTick(state, world, pos3);
customCropsBlock.randomTick(state, world, pos3, false);
customCropsBlock.scheduledTick(state, world, pos3, false);
if (customCropsBlock instanceof SprinklerBlock sprinklerBlock) {
int water = sprinklerBlock.water(state);
SprinklerConfig config = sprinklerBlock.config(state);
@@ -490,8 +490,8 @@ public class PlayerActionManager extends AbstractActionManager<Player> {
Optional<CustomCropsWorld<?>> optionalWorld = plugin.getWorldManager().getWorld(location.getWorld());
optionalWorld.ifPresent(world -> world.getChunk(pos3.toChunkPos()).flatMap(chunk -> chunk.getBlockState(pos3)).ifPresent(state -> {
CustomCropsBlock customCropsBlock = state.type();
customCropsBlock.randomTick(state, world, pos3);
customCropsBlock.scheduledTick(state, world, pos3);
customCropsBlock.randomTick(state, world, pos3, false);
customCropsBlock.scheduledTick(state, world, pos3, false);
}));
}, "tick");
}

View File

@@ -109,11 +109,11 @@ public class ForceTickCommand extends BukkitCommandFeature<CommandSender> {
private enum Mode {
RANDOM_TICK(CustomCropsBlock::randomTick),
SCHEDULED_TICK(CustomCropsBlock::scheduledTick),
RANDOM_TICK((customCropsBlock, state, world, location) -> customCropsBlock.randomTick(state, world, location, false)),
SCHEDULED_TICK((customCropsBlock, state, world, location) -> customCropsBlock.scheduledTick(state, world, location, false)),
ALL((b, s, w, p) -> {
b.randomTick(s, w, p);
b.scheduledTick(s, w, p);
b.randomTick(s, w, p, false);
b.scheduledTick(s, w, p, false);
});
private final QuadConsumer<CustomCropsBlock, CustomCropsBlockState, CustomCropsWorld<?>, Pos3> consumer;

View File

@@ -30,13 +30,13 @@ import dev.dejvokep.boostedyaml.settings.updater.UpdaterSettings;
import dev.dejvokep.boostedyaml.utils.format.NodeRole;
import net.momirealms.customcrops.api.BukkitCustomCropsPlugin;
import net.momirealms.customcrops.api.core.*;
import net.momirealms.customcrops.api.core.mechanic.fertilizer.FertilizerConfig;
import net.momirealms.customcrops.api.core.mechanic.wateringcan.WateringCanConfig;
import net.momirealms.customcrops.api.core.mechanic.crop.DeathCondition;
import net.momirealms.customcrops.api.core.mechanic.pot.PotConfig;
import net.momirealms.customcrops.api.core.mechanic.crop.CropConfig;
import net.momirealms.customcrops.api.core.mechanic.crop.CropStageConfig;
import net.momirealms.customcrops.api.core.mechanic.crop.DeathCondition;
import net.momirealms.customcrops.api.core.mechanic.fertilizer.FertilizerConfig;
import net.momirealms.customcrops.api.core.mechanic.pot.PotConfig;
import net.momirealms.customcrops.api.core.mechanic.sprinkler.SprinklerConfig;
import net.momirealms.customcrops.api.core.mechanic.wateringcan.WateringCanConfig;
import net.momirealms.customcrops.common.helper.AdventureHelper;
import net.momirealms.customcrops.common.locale.TranslationManager;
import net.momirealms.customcrops.common.plugin.CustomCropsProperties;

View File

@@ -27,10 +27,10 @@ import net.momirealms.customcrops.api.core.ExistenceForm;
import net.momirealms.customcrops.api.core.Registries;
import net.momirealms.customcrops.api.core.mechanic.crop.CropConfig;
import net.momirealms.customcrops.api.core.mechanic.crop.CropStageConfig;
import net.momirealms.customcrops.api.core.mechanic.pot.PotConfig;
import net.momirealms.customcrops.api.core.mechanic.sprinkler.SprinklerConfig;
import net.momirealms.customcrops.api.core.mechanic.fertilizer.FertilizerConfig;
import net.momirealms.customcrops.api.core.mechanic.fertilizer.FertilizerType;
import net.momirealms.customcrops.api.core.mechanic.pot.PotConfig;
import net.momirealms.customcrops.api.core.mechanic.sprinkler.SprinklerConfig;
import net.momirealms.customcrops.api.core.mechanic.wateringcan.WateringCanConfig;
import net.momirealms.customcrops.api.core.world.CustomCropsBlockState;
import net.momirealms.customcrops.api.misc.value.TextValue;

View File

@@ -512,7 +512,7 @@ public class BukkitItemManager extends AbstractItemManager {
if (anyFurnitureID != null) {
if (!customCropsBlockState.type().isBlockInstance(anyFurnitureID)) {
world.removeBlockState(pos3);
plugin.debug("[" + location.getWorld().getName() + "] Removed inconsistent block data at " + pos3 + " which used to be " + customCropsBlockState);
plugin.debug(() -> "[" + location.getWorld().getName() + "] Removed inconsistent block data at " + pos3 + " which used to be " + customCropsBlockState);
} else {
event.setCancelled(true);
return;
@@ -521,7 +521,7 @@ public class BukkitItemManager extends AbstractItemManager {
String anyBlockID = blockID(location);
if (!customCropsBlockState.type().isBlockInstance(anyBlockID)) {
world.removeBlockState(pos3);
plugin.debug("[" + location.getWorld().getName() + "] Removed inconsistent block data at " + pos3 + " which used to be " + customCropsBlockState);
plugin.debug(() -> "[" + location.getWorld().getName() + "] Removed inconsistent block data at " + pos3 + " which used to be " + customCropsBlockState);
} else {
event.setCancelled(true);
return;

View File

@@ -194,7 +194,9 @@ public class BukkitWorldManager implements WorldManager, Listener {
adaptedWorld.setTicking(true);
this.worlds.put(world.getName(), adaptedWorld);
for (Chunk chunk : world.getLoadedChunks()) {
loadLoadedChunk(adaptedWorld, ChunkPos.fromBukkitChunk(chunk));
ChunkPos pos = ChunkPos.fromBukkitChunk(chunk);
loadLoadedChunk(adaptedWorld, pos);
notifyOfflineUpdates(adaptedWorld, pos);
}
return adaptedWorld;
}
@@ -204,7 +206,13 @@ public class BukkitWorldManager implements WorldManager, Listener {
if (world.isChunkLoaded(pos)) return;
Optional<CustomCropsChunk> customChunk = world.getChunk(pos);
// don't load bukkit chunk again since it has been loaded
customChunk.ifPresent(customCropsChunk -> customCropsChunk.load(false));
customChunk.ifPresent(customCropsChunk -> {
customCropsChunk.load(false);
});
}
public void notifyOfflineUpdates(CustomCropsWorld<?> world, ChunkPos pos) {
world.getChunk(pos).ifPresent(CustomCropsChunk::notifyOfflineTask);
}
@Override
@@ -251,12 +259,24 @@ public class BukkitWorldManager implements WorldManager, Listener {
public void onChunkLoad(ChunkLoadEvent event) {
final Chunk chunk = event.getChunk();
final World world = event.getWorld();
this.getWorld(world).ifPresent(customWorld -> loadLoadedChunk(customWorld, ChunkPos.fromBukkitChunk(chunk)));
this.getWorld(world).ifPresent(customWorld -> {
ChunkPos pos = ChunkPos.fromBukkitChunk(chunk);
loadLoadedChunk(customWorld, pos);
if (chunk.isEntitiesLoaded() && customWorld.setting().offlineTick()) {
notifyOfflineUpdates(customWorld, pos);
}
});
}
@EventHandler
public void onEntitiesLoad(EntitiesLoadEvent event) {
final Chunk chunk = event.getChunk();
final World world = event.getWorld();
this.getWorld(world).ifPresent(customWorld -> {
if (customWorld.setting().offlineTick()) {
notifyOfflineUpdates(customWorld, ChunkPos.fromBukkitChunk(chunk));
}
});
}
public boolean isMechanicEnabled(World world) {
@@ -329,6 +349,7 @@ public class BukkitWorldManager implements WorldManager, Listener {
section.getInt("sprinkler.tick-interval", 2),
section.getBoolean("offline-tick.enable", false),
section.getInt("offline-tick.max-offline-seconds", 1200),
section.getInt("offline-tick.max-loading-time", 100),
section.getBoolean("season.enable", false),
section.getBoolean("season.auto-alternation", false),
section.getInt("season.duration", 28),

View File

@@ -52,6 +52,11 @@ worlds:
# as it may cause chunks that have been unloaded for a long time
# taking long to load
max-offline-seconds: 1200
# The max time used in loading this chunk
# Sometimes a chunk might contain a lot of data and has not been loaded for a long time,
# thus taking a long time loading and causing unexpected issues
# This setting allows the plugin to forcefully interrupt the tick process if the time consumed has exceeded a certain value
max-loading-time: 100 #ms
# Settings for crops
crop:
# [RANDOM_TICK]