From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: AlphaKR93 Date: Sun, 27 Oct 2024 15:07:43 +0900 Subject: [PATCH] TickControl System Based on snackbag/TT20 Copyright (C) 2024 snackbag, Licensed under AGPL v3.0 This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 1c3bb7cd27d97e54cbe74465bd8a7c5faeafdf4a..fd23107e3777b79ac7d598bdd5ec9b9fb8822dbb 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -1704,6 +1704,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop it.accelerate.randomTick, false); // Plazma - TickControl system boolean flag1 = this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) != 0L && this.level.getLevelData().getGameTime() % this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) == 0L; // CraftBukkit Iterator iterator1 = list.iterator(); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java index 6fbf3a479ee1927b1099d2678db693341491b2b7..e5721ae2d55c614bcee58868acfcd06025d9e3c8 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -832,9 +832,14 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. if (incrementTicks != 12000) { this.preciseTime += 12000 / (double) incrementTicks; this.setDayTime(this.preciseTime); - } else + } // Plazma - TickControl System // Purpur end - this.setDayTime(this.levelData.getDayTime() + 1L); + // Plazma start - TickControl System + else if (org.plazmamc.plazma.configurations.GlobalConfiguration.get().tickControl.accelerate.dayTime) + this.setDayTime(this.levelData.getDayTime() + org.plazmamc.plazma.util.TickControl.missedTicks() + 1L); + else + this.setDayTime(this.levelData.getDayTime() + 1L); + // Plazma end - TickControl System } } diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java index 9ab19aa8d05384bc03c8250f8ea628a9b0a00fa2..794c012ebc2c46a1f31a71eec1753374bb2ea88c 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -545,6 +545,7 @@ public abstract class LivingEntity extends Entity implements Attackable { } this.tickEffects(); + if (org.plazmamc.plazma.configurations.GlobalConfiguration.get().tickControl.delay.potionEffect) for (int i = 0; i < org.plazmamc.plazma.util.TickControl.missedTicks(); i++) this.tickEffects(); // Plazma - TickControl System this.animStepO = this.animStep; this.yBodyRotO = this.yBodyRot; this.yHeadRotO = this.yHeadRot; diff --git a/src/main/java/net/minecraft/world/entity/PortalProcessor.java b/src/main/java/net/minecraft/world/entity/PortalProcessor.java index 45761c113116ae7417e6ae99069bff35dbccdf30..1727d9d7a3787220f09b6574ce6e4c828106d680 100644 --- a/src/main/java/net/minecraft/world/entity/PortalProcessor.java +++ b/src/main/java/net/minecraft/world/entity/PortalProcessor.java @@ -24,7 +24,7 @@ public class PortalProcessor { return false; } else { this.insidePortalThisTick = false; - return canUsePortals && this.portalTime++ >= this.portal.getPortalTransitionTime(world, entity); + return canUsePortals && this.increaseTick() >= this.portal.getPortalTransitionTime(world, entity); // Plazma - TickControl System } } @@ -41,6 +41,14 @@ public class PortalProcessor { this.portalTime = Math.max(this.portalTime - 4, 0); } + // Plazma start - TickControl System + private int increaseTick() { + if (!org.plazmamc.plazma.configurations.GlobalConfiguration.get().tickControl.delay.portalUse) + this.portalTime += org.plazmamc.plazma.util.TickControl.missedTicks(); + return this.portalTime++; + } + // Plazma end - TickControl System + public boolean hasExpired() { return this.portalTime <= 0; } diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java index ffc754aa6ed61f62a0c94e9117f3008d24c0c163..744385f34727729f7ac4222ed140a9c7326147a8 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java @@ -158,6 +158,7 @@ public class ItemEntity extends Entity implements TraceableEntity { if (this.getItem().isEmpty()) { this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause } else { + if (this.pickupDelay > 0 && org.plazmamc.plazma.configurations.GlobalConfiguration.get().tickControl.delay.itemPickup) this.pickupDelay = Math.max(this.pickupDelay - org.plazmamc.plazma.util.TickControl.missedTicks(), 0); // Plazma - TickControl System super.tick(); // Paper start - remove anti tick skipping measures / wall time - revert to vanilla if (this.pickupDelay > 0 && this.pickupDelay != 32767) { diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java index 330b21946564e6a7b463a258c02fee3f91e0f057..f8e09f24e818f960ea24446675996a25ed06d9a9 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java @@ -302,6 +302,11 @@ public abstract class Player extends LivingEntity { if (this.sleepCounter > 100) { this.sleepCounter = 100; } + // Plazma start - TickControl System + else if (this.sleepCounter < 100 && org.plazmamc.plazma.configurations.GlobalConfiguration.get().tickControl.delay.sleep && org.plazmamc.plazma.util.TickControl.missedTicks() > 0) { + this.sleepCounter += org.plazmamc.plazma.util.TickControl.missedTicks(); + } + // Plazma end - TickControl System if (!this.level().isClientSide && this.level().isDay()) { this.stopSleepInBed(false, true); diff --git a/src/main/java/net/minecraft/world/item/Item.java b/src/main/java/net/minecraft/world/item/Item.java index 8fd54bccb7af59da9113d8a289d12d8fad1fb467..e295b6b920dbb678bafe2042e4b82dc193bae4ef 100644 --- a/src/main/java/net/minecraft/world/item/Item.java +++ b/src/main/java/net/minecraft/world/item/Item.java @@ -268,7 +268,7 @@ public class Item implements FeatureElement, ItemLike { public int getUseDuration(ItemStack stack, LivingEntity user) { FoodProperties foodProperties = stack.get(DataComponents.FOOD); - return foodProperties != null ? foodProperties.eatDurationTicks() : 0; + return foodProperties != null ? org.plazmamc.plazma.util.TickControl.calc(foodProperties.eatDurationTicks(), it -> it.delay.itemUse, true) : 0; // Plazma - TickControl System } public void releaseUsing(ItemStack stack, Level world, LivingEntity user, int remainingUseTicks) { diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java index 40f15a30b1a0dd2040e75045f32f33082e70aaeb..0e022da01f4526b589774a7d304d32a5562d8ce4 100644 --- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java +++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java @@ -339,13 +339,14 @@ public abstract class BlockBehaviour implements FeatureElement { protected float getDestroyProgress(BlockState state, Player player, BlockGetter world, BlockPos pos) { float f = state.getDestroySpeed(world, pos); - if (f == -1.0F) { - return 0.0F; - } else { - int i = player.hasCorrectToolForDrops(state) ? 30 : 100; - - return player.getDestroySpeed(state) / f / (float) i; - } + // Plazma start - TickControl system + if (f == -1.0F) return 0.0F; + return org.plazmamc.plazma.util.TickControl.calc( + player.getDestroySpeed(state) / f / (player.hasCorrectToolForDrops(state) ? 30 : 100), + it -> it.delay.blockBreak, + false + ); + // Plazma end - TickControl system } protected void spawnAfterBreak(BlockState state, ServerLevel world, BlockPos pos, ItemStack tool, boolean dropExperience) {} diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java index 9cc1a79dd25c63af6986e721ceff5560cf56b7d1..c45224e142905921305da51139d5fd3f51583cca 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -1036,8 +1036,18 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p this.chunkCoordinateKey = chunkCoordinateKey; // Plazma - Port SparklyPaper patches; Optimize TickingBlockEntity } + // Plazma start - TickControl System + private void tickTicker(BlockState iblockdata) { + this.ticker.tick(LevelChunk.this.level, this.blockEntity.getBlockPos(), iblockdata, this.blockEntity); + + if (!org.plazmamc.plazma.util.TickControl.shouldTickAgain(iblockdata.getBlock())) return; + for (int i = 0; i < org.plazmamc.plazma.util.TickControl.missedTicks(); i++) + this.ticker.tick(LevelChunk.this.level, this.blockEntity.getBlockPos(), iblockdata, this.blockEntity); + } + // Plazma end - TickControl System + @Override - public void tick() { + public final void tick() { // Plazma - TickControl System (make final) if (!this.blockEntity.isRemoved() && this.blockEntity.hasLevel()) { BlockPos blockposition = this.blockEntity.getBlockPos(); @@ -1050,7 +1060,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p BlockState iblockdata = LevelChunk.this.getBlockState(blockposition); if (this.blockEntity.getType().isValid(iblockdata)) { - this.ticker.tick(LevelChunk.this.level, this.blockEntity.getBlockPos(), iblockdata, this.blockEntity); + this.tickTicker(iblockdata); // Plazma - TickControl System this.loggedInvalidBlockState = false; // Paper start - Remove the Block Entity if it's invalid } else { diff --git a/src/main/java/net/minecraft/world/level/material/LavaFluid.java b/src/main/java/net/minecraft/world/level/material/LavaFluid.java index 2d492d849ff73a738dfbcb16507feb89bf19a962..67206b9c754dfe90002e0bcf6995eae60b852acd 100644 --- a/src/main/java/net/minecraft/world/level/material/LavaFluid.java +++ b/src/main/java/net/minecraft/world/level/material/LavaFluid.java @@ -180,7 +180,7 @@ public abstract class LavaFluid extends FlowingFluid { @Override public int getTickDelay(LevelReader world) { - return world.dimensionType().ultraWarm() ? world.getWorldBorder().world.purpurConfig.lavaSpeedNether : world.getWorldBorder().world.purpurConfig.lavaSpeedNotNether; // Purpur + return org.plazmamc.plazma.util.TickControl.calc(world.dimensionType().ultraWarm() ? world.getWorldBorder().world.purpurConfig.lavaSpeedNether : world.getWorldBorder().world.purpurConfig.lavaSpeedNotNether, it -> it.delay.lavaFluid, true); // Purpur // Plazma - TickControl system } @Override diff --git a/src/main/java/net/minecraft/world/level/material/WaterFluid.java b/src/main/java/net/minecraft/world/level/material/WaterFluid.java index 0fc89b33864000a262ec5369708f7aedeaf6dc0b..5055730053d9d9c1da0a5252654c936c75d04fb6 100644 --- a/src/main/java/net/minecraft/world/level/material/WaterFluid.java +++ b/src/main/java/net/minecraft/world/level/material/WaterFluid.java @@ -122,7 +122,7 @@ public abstract class WaterFluid extends FlowingFluid { @Override public int getTickDelay(LevelReader world) { - return world.getWorldBorder().world.plazmaConfig().block.waterFlowingTick; // Plazma - Configurable water flowing speed + return org.plazmamc.plazma.util.TickControl.calc(world.getWorldBorder().world.plazmaConfig().block.waterFlowingTick, it -> it.delay.waterFluid, true); // Plazma - Configurable water flowing speed; TickControl System } @Override diff --git a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java index 49bce6e28e12f3729cab5628cf3e0f508a56d0d7..2a88a25793e6d963a9a08e615a72c6ed1677a18b 100644 --- a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java +++ b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java @@ -146,4 +146,39 @@ public class GlobalConfiguration extends ConfigurationPart { } + public TickControl tickControl; + public class TickControl extends ConfigurationPart { + + public boolean enabled = false; + + public Delay delay; + public class Delay extends ConfigurationPart { + + public boolean sleep = true; + public boolean itemUse = true; + public boolean portalUse = true; + public boolean lavaFluid = true; + public boolean waterFluid = true; + public boolean blockBreak = true; + public boolean itemPickup = true; + public boolean potionEffect = true; + + } + + public Accelerate accelerate; + public class Accelerate extends ConfigurationPart { + + public boolean dayTime = true; + public boolean randomTick = true; + public boolean blockEntity = true; + + } + + @PostProcess + void post() { + org.plazmamc.plazma.util.TickControl.post(this); + } + + } + } diff --git a/src/main/java/org/plazmamc/plazma/util/TickControl.java b/src/main/java/org/plazmamc/plazma/util/TickControl.java new file mode 100644 index 0000000000000000000000000000000000000000..c8db7b9f590a34b38448a970baaa79dd73eab8d8 --- /dev/null +++ b/src/main/java/org/plazmamc/plazma/util/TickControl.java @@ -0,0 +1,57 @@ +package org.plazmamc.plazma.util; + +import net.minecraft.world.level.block.Block; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; +import org.plazmamc.plazma.configurations.GlobalConfiguration; +import java.util.function.Function; + +import static net.minecraft.server.MinecraftServer.getServer; + +public final class TickControl { + + + private static @Nullable TickControl INSTANCE; + private final GlobalConfiguration.TickControl configuration; + private int missedTicks = 0; + + private TickControl(GlobalConfiguration.TickControl configuration) { + this.configuration = configuration; + } + + public static void tick() { + if (INSTANCE == null) return; + INSTANCE.missedTicks -= INSTANCE.missedTicks; + INSTANCE.missedTicks += (int) (getServer().tickTimes5s.getAverage() / 50 - 1); + } + + public static void post(GlobalConfiguration.TickControl configuration) { + if (!configuration.enabled) { + INSTANCE = null; + return; + } + + INSTANCE = new TickControl(configuration); + } + + public static float calc(float original, @NonNull Function isAffected, boolean swap) { + if (INSTANCE == null || !isAffected.apply(INSTANCE.configuration) || original == 0) return original; + if (swap) return (float) Math.max(original * getServer().tps5s.getAverage() / 20, 1); + return (float) (original * 20 / getServer().tps5s.getAverage()); + } + + public static int calc(int original, @NonNull Function isAccelerated, boolean swap) { + return (int) Math.ceil(calc((float) original, isAccelerated, swap)); + } + + public static int missedTicks() { + if (INSTANCE == null) return 0; + return INSTANCE.missedTicks; + } + + public static boolean shouldTickAgain(Block block) { + // TODO: Configurable block masking + return INSTANCE != null && !INSTANCE.configuration.accelerate.blockEntity; + } + +}