limbo decay block change effects
This commit is contained in:
parent
2dd8e2b9a3
commit
7dbc3c715e
10 changed files with 296 additions and 32 deletions
|
@ -0,0 +1,62 @@
|
|||
package org.dimdev.dimdoors.client;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class CustomBreakBlockHandler {
|
||||
private static final Map<BlockPos, BreakBlockInfo> customBreakBlockMap = new HashMap();
|
||||
|
||||
public static Map<BlockPos, BreakBlockInfo> getCustomBreakBlockMap(int ticks) {
|
||||
Set<BlockPos> expired = customBreakBlockMap.entrySet().stream().filter(entry -> ticks - entry.getValue().getLastUpdateTick() > 400).map(entry -> entry.getKey()).collect(Collectors.toSet());
|
||||
expired.forEach(customBreakBlockMap::remove);
|
||||
return customBreakBlockMap;
|
||||
}
|
||||
|
||||
public static void customBreakBlock(BlockPos pos, int stage, int ticks) {
|
||||
if (stage < 0 || stage > 10) {
|
||||
customBreakBlockMap.remove(pos);
|
||||
} else {
|
||||
if (customBreakBlockMap.containsKey(pos)) {
|
||||
|
||||
BreakBlockInfo info = customBreakBlockMap.get(pos);
|
||||
info.setStage(stage);
|
||||
info.setLastUpdateTick(ticks);
|
||||
} else {
|
||||
customBreakBlockMap.put(pos, new BreakBlockInfo(stage, ticks));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class BreakBlockInfo {
|
||||
private int stage;
|
||||
private int lastUpdateTick;
|
||||
|
||||
private BreakBlockInfo(int stage, int lastUpdateTick) {
|
||||
this.stage = stage;
|
||||
this.lastUpdateTick = lastUpdateTick;
|
||||
}
|
||||
|
||||
public void setStage(int stage) {
|
||||
this.stage = stage;
|
||||
}
|
||||
|
||||
public int getStage() {
|
||||
return stage;
|
||||
}
|
||||
|
||||
public void setLastUpdateTick(int lastUpdateTick) {
|
||||
this.lastUpdateTick = lastUpdateTick;
|
||||
}
|
||||
|
||||
public int getLastUpdateTick() {
|
||||
return lastUpdateTick;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package org.dimdev.dimdoors.mixin;
|
||||
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import org.dimdev.dimdoors.world.decay.LimboDecay;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
@Mixin(ServerWorld.class)
|
||||
public abstract class ServerWorldMixin {
|
||||
|
||||
@Inject(method = "tick(Ljava/util/function/BooleanSupplier;)V", at = @At(target = "Lnet/minecraft/server/world/ServerWorld;fluidTickScheduler:Lnet/minecraft/server/world/ServerTickScheduler;", value = "FIELD", ordinal = 0, shift = At.Shift.AFTER))
|
||||
public void afterScheduledTick(BooleanSupplier shouldKeepTicking, CallbackInfo ci) {
|
||||
LimboDecay.tick((ServerWorld) (Object) this);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,11 @@
|
|||
package org.dimdev.dimdoors.mixin.client;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import net.minecraft.client.render.*;
|
||||
import net.minecraft.client.render.model.ModelLoader;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import org.dimdev.dimdoors.client.CustomBreakBlockHandler;
|
||||
import org.dimdev.dimdoors.listener.pocket.PocketListenerUtil;
|
||||
import org.dimdev.dimdoors.world.ModDimensions;
|
||||
import org.dimdev.dimdoors.world.pocket.type.addon.SkyAddon;
|
||||
|
@ -13,19 +18,11 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
|||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.BufferBuilder;
|
||||
import net.minecraft.client.render.BufferRenderer;
|
||||
import net.minecraft.client.render.GameRenderer;
|
||||
import net.minecraft.client.render.Tessellator;
|
||||
import net.minecraft.client.render.VertexFormat;
|
||||
import net.minecraft.client.render.VertexFormats;
|
||||
import net.minecraft.client.render.WorldRenderer;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.Matrix4f;
|
||||
import net.minecraft.util.math.Vec3f;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
|
@ -33,6 +30,7 @@ import net.fabricmc.api.EnvType;
|
|||
import net.fabricmc.api.Environment;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(WorldRenderer.class)
|
||||
@Environment(EnvType.CLIENT)
|
||||
|
@ -48,6 +46,13 @@ public abstract class WorldRendererMixin {
|
|||
@Shadow
|
||||
private MinecraftClient client;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private BufferBuilderStorage bufferBuilders;
|
||||
|
||||
@Shadow
|
||||
private int ticks;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private static Identifier END_SKY;
|
||||
|
@ -207,4 +212,32 @@ public abstract class WorldRendererMixin {
|
|||
RenderSystem.enableTexture();
|
||||
RenderSystem.disableBlend();
|
||||
}
|
||||
|
||||
@Inject(method = "render(Lnet/minecraft/client/util/math/MatrixStack;FJZLnet/minecraft/client/render/Camera;Lnet/minecraft/client/render/GameRenderer;Lnet/minecraft/client/render/LightmapTextureManager;Lnet/minecraft/util/math/Matrix4f;)V",
|
||||
at = @At(value = "FIELD", target = "Lnet/minecraft/client/render/WorldRenderer;blockBreakingProgressions:Lit/unimi/dsi/fastutil/longs/Long2ObjectMap;", ordinal = 1)) // bytecode order is flipped from java code order, notice the ordinal
|
||||
public void renderCustomBreakBlockAnimation(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, CallbackInfo ci) {
|
||||
Vec3d vec3d = camera.getPos();
|
||||
double d = vec3d.getX();
|
||||
double e = vec3d.getY();
|
||||
double f = vec3d.getZ();
|
||||
|
||||
Map<BlockPos, CustomBreakBlockHandler.BreakBlockInfo> breakBlocks = CustomBreakBlockHandler.getCustomBreakBlockMap(this.ticks);
|
||||
|
||||
// stolen from WorldRenderer#render
|
||||
for (Map.Entry<BlockPos, CustomBreakBlockHandler.BreakBlockInfo> entry : breakBlocks.entrySet()) {
|
||||
BlockPos pos = entry.getKey();
|
||||
double h = (double) pos.getX() - d;
|
||||
double x = (double) pos.getY() - e;
|
||||
double y = (double) pos.getZ() - f;
|
||||
if (!(h * h + x * x + y * y > 1024.0D)) {
|
||||
int stage = entry.getValue().getStage();
|
||||
matrices.push();
|
||||
matrices.translate((double) pos.getX() - d, (double) pos.getY() - e, (double) pos.getZ() - f);
|
||||
MatrixStack.Entry entry3 = matrices.peek();
|
||||
VertexConsumer vertexConsumer2 = new OverlayVertexConsumer(this.bufferBuilders.getEffectVertexConsumers().getBuffer((RenderLayer) ModelLoader.BLOCK_DESTRUCTION_RENDER_LAYERS.get(stage)), entry3.getModel(), entry3.getNormal());
|
||||
this.client.getBlockRenderManager().renderDamage(this.world.getBlockState(pos), pos, this.world, matrices, vertexConsumer2);
|
||||
matrices.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package org.dimdev.dimdoors.mixin.client.accessor;
|
||||
|
||||
import net.minecraft.client.render.WorldRenderer;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(WorldRenderer.class)
|
||||
public interface WorldRendererAccessor {
|
||||
@Accessor
|
||||
int getTicks();
|
||||
}
|
|
@ -1,8 +1,13 @@
|
|||
package org.dimdev.dimdoors.network;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.network.ServerPlayNetworkHandler;
|
||||
|
||||
public interface ExtendedServerPlayNetworkHandler {
|
||||
static ExtendedServerPlayNetworkHandler get(ServerPlayNetworkHandler networkHandler) {
|
||||
return (ExtendedServerPlayNetworkHandler) networkHandler;
|
||||
}
|
||||
|
||||
ServerPacketHandler getDimDoorsPacketHandler();
|
||||
|
||||
MinecraftServer dimdoorsGetServer();
|
||||
|
|
|
@ -7,21 +7,20 @@ import java.util.List;
|
|||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import net.minecraft.client.render.WorldRenderer;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.client.CustomBreakBlockHandler;
|
||||
import org.dimdev.dimdoors.entity.MonolithEntity;
|
||||
import org.dimdev.dimdoors.mixin.client.accessor.WorldRendererAccessor;
|
||||
import org.dimdev.dimdoors.network.SimplePacket;
|
||||
import org.dimdev.dimdoors.network.packet.c2s.NetworkHandlerInitializedC2SPacket;
|
||||
import org.dimdev.dimdoors.network.packet.s2c.MonolithAggroParticlesPacket;
|
||||
import org.dimdev.dimdoors.network.packet.s2c.MonolithTeleportParticlesPacket;
|
||||
import org.dimdev.dimdoors.network.packet.s2c.PlayerInventorySlotUpdateS2CPacket;
|
||||
import org.dimdev.dimdoors.network.packet.s2c.SyncPocketAddonsS2CPacket;
|
||||
import org.dimdev.dimdoors.network.packet.s2c.*;
|
||||
import org.dimdev.dimdoors.particle.client.MonolithParticle;
|
||||
import org.dimdev.dimdoors.world.pocket.type.addon.AutoSyncedAddon;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.world.World;
|
||||
|
@ -30,7 +29,6 @@ import net.fabricmc.api.EnvType;
|
|||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketSender;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class ClientPacketHandler implements ClientPacketListener {
|
||||
|
@ -54,6 +52,7 @@ public class ClientPacketHandler implements ClientPacketListener {
|
|||
registerReceiver(SyncPocketAddonsS2CPacket.ID, SyncPocketAddonsS2CPacket::new);
|
||||
registerReceiver(MonolithAggroParticlesPacket.ID, MonolithAggroParticlesPacket::new);
|
||||
registerReceiver(MonolithTeleportParticlesPacket.ID, MonolithTeleportParticlesPacket::new);
|
||||
registerReceiver(RenderBreakBlockS2CPacket.ID, RenderBreakBlockS2CPacket::new);
|
||||
|
||||
sendPacket(new NetworkHandlerInitializedC2SPacket());
|
||||
}
|
||||
|
@ -141,4 +140,11 @@ public class ClientPacketHandler implements ClientPacketListener {
|
|||
//noinspection ConstantConditions
|
||||
client.execute(() -> client.particleManager.addParticle(new MonolithParticle(client.world, client.player.getX(), client.player.getY(), client.player.getZ())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRenderBreakBlock(RenderBreakBlockS2CPacket packet) {
|
||||
MinecraftClient.getInstance().executeTask(() -> {
|
||||
CustomBreakBlockHandler.customBreakBlock(packet.getPos(), packet.getStage(), ((WorldRendererAccessor) MinecraftClient.getInstance().worldRenderer).getTicks());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
package org.dimdev.dimdoors.network.client;
|
||||
|
||||
import org.dimdev.dimdoors.network.packet.s2c.MonolithAggroParticlesPacket;
|
||||
import org.dimdev.dimdoors.network.packet.s2c.MonolithTeleportParticlesPacket;
|
||||
import org.dimdev.dimdoors.network.packet.s2c.PlayerInventorySlotUpdateS2CPacket;
|
||||
import org.dimdev.dimdoors.network.packet.s2c.SyncPocketAddonsS2CPacket;
|
||||
import org.dimdev.dimdoors.network.packet.s2c.*;
|
||||
|
||||
public interface ClientPacketListener {
|
||||
void onPlayerInventorySlotUpdate(PlayerInventorySlotUpdateS2CPacket packet);
|
||||
|
@ -13,4 +10,6 @@ public interface ClientPacketListener {
|
|||
void onMonolithAggroParticles(MonolithAggroParticlesPacket packet);
|
||||
|
||||
void onMonolithTeleportParticles(MonolithTeleportParticlesPacket packet);
|
||||
|
||||
void onRenderBreakBlock(RenderBreakBlockS2CPacket packet);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
package org.dimdev.dimdoors.network.packet.s2c;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import org.dimdev.dimdoors.network.SimplePacket;
|
||||
import org.dimdev.dimdoors.network.client.ClientPacketListener;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class RenderBreakBlockS2CPacket implements SimplePacket<ClientPacketListener> {
|
||||
public static final Identifier ID = new Identifier("dimdoors:render_break_block");
|
||||
|
||||
private BlockPos pos;
|
||||
private int stage;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public RenderBreakBlockS2CPacket() {
|
||||
|
||||
}
|
||||
|
||||
public RenderBreakBlockS2CPacket(BlockPos pos, int stage) {
|
||||
this.pos = pos;
|
||||
this.stage = stage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimplePacket<ClientPacketListener> read(PacketByteBuf buf) throws IOException {
|
||||
pos = buf.readBlockPos();
|
||||
stage = buf.readInt();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketByteBuf write(PacketByteBuf buf) throws IOException {
|
||||
buf.writeBlockPos(pos);
|
||||
buf.writeInt(stage);
|
||||
return buf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(ClientPacketListener listener) {
|
||||
listener.onRenderBreakBlock(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier channelId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public BlockPos getPos() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
public int getStage() {
|
||||
return stage;
|
||||
}
|
||||
}
|
|
@ -1,21 +1,30 @@
|
|||
package org.dimdev.dimdoors.world.decay;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.nbt.NbtElement;
|
||||
import net.minecraft.network.packet.s2c.play.BlockBreakingProgressS2CPacket;
|
||||
import net.minecraft.predicate.entity.EntityPredicates;
|
||||
import net.minecraft.resource.ResourceManager;
|
||||
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.DimensionalDoorsInitializer;
|
||||
import org.dimdev.dimdoors.network.ExtendedServerPlayNetworkHandler;
|
||||
import org.dimdev.dimdoors.network.packet.s2c.RenderBreakBlockS2CPacket;
|
||||
import org.dimdev.dimdoors.sound.ModSoundEvents;
|
||||
import org.dimdev.dimdoors.util.ResourceUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
@ -29,6 +38,9 @@ import net.minecraft.world.World;
|
|||
*/
|
||||
public final class LimboDecay {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
private static final Map<RegistryKey<World>, Set<DecayTask>> DECAY_QUEUE = new HashMap<>();
|
||||
// TODO: config
|
||||
private static final int DECAY_DELAY = 40;
|
||||
|
||||
private static final Random RANDOM = new Random();
|
||||
|
||||
|
@ -36,33 +48,58 @@ public final class LimboDecay {
|
|||
* Checks the blocks orthogonally around a given location (presumably the location of an Unraveled Fabric block)
|
||||
* and applies Limbo decay to them. This gives the impression that decay spreads outward from Unraveled Fabric.
|
||||
*/
|
||||
public static void applySpreadDecay(World world, BlockPos pos) {
|
||||
public static void applySpreadDecay(ServerWorld world, BlockPos pos) {
|
||||
//Check if we randomly apply decay spread or not. This can be used to moderate the frequency of
|
||||
//full spread decay checks, which can also shift its performance impact on the game.
|
||||
if (RANDOM.nextDouble() < DimensionalDoorsInitializer.getConfig().getLimboConfig().decaySpreadChance) {
|
||||
BlockState origin = world.getBlockState(pos);
|
||||
|
||||
//Apply decay to the blocks above, below, and on all four sides.
|
||||
decayBlock(world, pos.up(), origin);
|
||||
decayBlock(world, pos.down(), origin);
|
||||
decayBlock(world, pos.north(), origin);
|
||||
decayBlock(world, pos.south(), origin);
|
||||
decayBlock(world, pos.west(), origin);
|
||||
decayBlock(world, pos.east(), origin);
|
||||
// TODO: make max amount configurable
|
||||
int decayAmount = RANDOM.nextInt(5) + 1;
|
||||
List<Direction> directions = new ArrayList<>(Arrays.asList(Direction.values()));
|
||||
for (int i = 0; i < decayAmount; i++) {
|
||||
decayBlock(world, pos.offset(directions.remove(RANDOM.nextInt(5 - i))), origin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a block can be decayed and, if so, changes it to the next block ID along the decay sequence.
|
||||
*/
|
||||
private static void decayBlock(World world, BlockPos pos, BlockState origin) {
|
||||
private static void decayBlock(ServerWorld world, BlockPos pos, BlockState origin) {
|
||||
@NotNull Collection<DecayPattern> patterns = DecayLoader.getInstance().getPatterns();
|
||||
|
||||
if(patterns.isEmpty()) return;
|
||||
|
||||
BlockState target = world.getBlockState(pos);
|
||||
|
||||
patterns.stream().filter(decayPattern -> decayPattern.test(world, pos, origin, target)).findAny().ifPresent(pattern -> pattern.process(world, pos, origin, target));
|
||||
patterns.stream().filter(decayPattern -> decayPattern.test(world, pos, origin, target)).findAny().ifPresent(pattern -> {
|
||||
world.getPlayers(EntityPredicates.maxDistance(pos.getX(), pos.getY(), pos.getZ(), 100)).forEach(player -> {
|
||||
ExtendedServerPlayNetworkHandler.get(player.networkHandler).getDimDoorsPacketHandler().sendPacket(new RenderBreakBlockS2CPacket(pos, 5));
|
||||
});
|
||||
world.playSound(null, pos.getX(), pos.getY(), pos.getZ(), ModSoundEvents.TEARING, SoundCategory.BLOCKS, 0.5f, 1f);
|
||||
queueDecay(world, pos, origin, pattern, DECAY_DELAY);
|
||||
});
|
||||
}
|
||||
|
||||
public static void queueDecay(ServerWorld world, BlockPos pos, BlockState origin, DecayPattern pattern, int delay) {
|
||||
DecayTask task = new DecayTask(pos, origin, pattern, delay);
|
||||
if (delay <= 0) {
|
||||
task.process(world);
|
||||
} else {
|
||||
DECAY_QUEUE.computeIfAbsent(world.getRegistryKey(), k -> new HashSet<>()).add(task);
|
||||
}
|
||||
}
|
||||
|
||||
public static void tick(ServerWorld world) {
|
||||
RegistryKey<World> key = world.getRegistryKey();
|
||||
if (DECAY_QUEUE.containsKey(key)) {
|
||||
Set<DecayTask> tasks = DECAY_QUEUE.get(key);
|
||||
Set<DecayTask> tasksToRun = tasks.stream().filter(DecayTask::reduceDelayIsDone).collect(Collectors.toSet());
|
||||
tasks.removeAll(tasksToRun);
|
||||
tasksToRun.forEach(task -> task.process(world));
|
||||
}
|
||||
}
|
||||
|
||||
public static class DecayLoader implements SimpleSynchronousResourceReloadListener {
|
||||
|
@ -97,4 +134,34 @@ public final class LimboDecay {
|
|||
return new Identifier("dimdoors", "decay_pattern");
|
||||
}
|
||||
}
|
||||
|
||||
private static class DecayTask {
|
||||
private final BlockPos pos;
|
||||
private final BlockState origin;
|
||||
private final DecayPattern processor;
|
||||
private int delay;
|
||||
|
||||
|
||||
public DecayTask(BlockPos pos, BlockState origin, DecayPattern processor, int delay) {
|
||||
this.pos = pos;
|
||||
this.origin = origin;
|
||||
this.processor = processor;
|
||||
this.delay = delay;
|
||||
}
|
||||
|
||||
public boolean reduceDelayIsDone() {
|
||||
return --delay <= 0;
|
||||
}
|
||||
|
||||
public void process(ServerWorld world) {
|
||||
BlockState target = world.getBlockState(pos);
|
||||
if (world.isChunkLoaded(pos) && processor.test(world, pos, origin, target)) {
|
||||
world.getPlayers(EntityPredicates.maxDistance(pos.getX(), pos.getY(), pos.getZ(), 100)).forEach(player -> {
|
||||
ExtendedServerPlayNetworkHandler.get(player.networkHandler).getDimDoorsPacketHandler().sendPacket(new RenderBreakBlockS2CPacket(pos, -1));
|
||||
});
|
||||
world.playSound(null, pos.getX(), pos.getY(), pos.getZ(), target.getSoundGroup().getBreakSound(), SoundCategory.BLOCKS, 0.5f, 1f);
|
||||
processor.process(world, pos, origin, world.getBlockState(pos));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
"ServerPlayerEntityMixin",
|
||||
"ServerPlayerInteractionManagerMixin",
|
||||
"ServerPlayNetworkHandlerMixin",
|
||||
"ServerWorldMixin",
|
||||
"StructurePoolMixin",
|
||||
"WorldMixin",
|
||||
"accessor.BuiltinBiomesAccessor",
|
||||
|
@ -26,7 +27,8 @@
|
|||
"accessor.ListTagAccessor",
|
||||
"accessor.RecipesProviderAccessor",
|
||||
"accessor.RedstoneWireBlockAccessor",
|
||||
"accessor.StatsAccessor"
|
||||
"accessor.StatsAccessor",
|
||||
"client.accessor.WorldRendererAccessor"
|
||||
],
|
||||
"client": [
|
||||
"client.ClientPlayerInteractionManagerMixin",
|
||||
|
|
Loading…
Reference in a new issue