Remesh chunks on the client when changing the blockstate
And slim down the code a bit
This commit is contained in:
parent
871c3ac54e
commit
f2a60f4e8e
@ -14,7 +14,6 @@ Template blocks can be placed in the world, then right-clicked with a full-size
|
||||
|
||||
# quat was here - TODO
|
||||
|
||||
* Schedule chunk rerenders when a player edits a template block :sweat_smile:
|
||||
* Re-generalize the model system (I removed a layer of indirection while rewriting it, so it's just slopes now)
|
||||
* See what I can do about using the vanilla rotation system (`ModelBakeSettings.getRotation`) instead of manually rotating the `Mesh`
|
||||
* A simplification of the mesh system would *definitely* reduce the friction of adding new meshes
|
||||
|
@ -1,27 +1,34 @@
|
||||
package io.github.cottonmc.templates;
|
||||
|
||||
import io.github.cottonmc.templates.block.SlopeBlock;
|
||||
import io.github.cottonmc.templates.block.entity.SlopeEntity;
|
||||
import io.github.cottonmc.templates.block.entity.TemplateEntity;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.entity.BlockEntityType;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class Templates implements ModInitializer {
|
||||
public static final String MODID = "templates";
|
||||
|
||||
public static final Block SLOPE = Registry.register(Registries.BLOCK, id("slope"), new SlopeBlock());
|
||||
public static final BlockEntityType<SlopeEntity> SLOPE_ENTITY = Registry.register(
|
||||
Registries.BLOCK_ENTITY_TYPE,
|
||||
id("slope"),
|
||||
FabricBlockEntityTypeBuilder.create(SlopeEntity::new, SLOPE).build(null)
|
||||
public static final BlockEntityType<TemplateEntity> SLOPE_ENTITY = Registry.register(
|
||||
Registries.BLOCK_ENTITY_TYPE, id("slope"),
|
||||
FabricBlockEntityTypeBuilder.create(Templates::makeSlopeEntity, SLOPE).build(null)
|
||||
);
|
||||
|
||||
//Overridden in TemplatesClient
|
||||
public static BiConsumer<World, BlockPos> chunkRerenderProxy = (world, pos) -> {};
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
Registry.register(Registries.ITEM, id("slope"), (Item) new BlockItem(SLOPE, new Item.Settings()));
|
||||
@ -30,4 +37,9 @@ public class Templates implements ModInitializer {
|
||||
public static Identifier id(String path) {
|
||||
return new Identifier(MODID, path);
|
||||
}
|
||||
|
||||
//simply for breaking the circular reference in the SLOPE_ENTITY constructor call
|
||||
private static TemplateEntity makeSlopeEntity(BlockPos pos, BlockState state) {
|
||||
return new TemplateEntity(SLOPE_ENTITY, pos, state);
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,9 @@ import io.github.cottonmc.templates.model.TemplateModelVariantProvider;
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
|
||||
import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.minecraft.util.math.ChunkSectionPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
|
||||
public class TemplatesClient implements ClientModInitializer {
|
||||
@ -14,6 +16,16 @@ public class TemplatesClient implements ClientModInitializer {
|
||||
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
Templates.chunkRerenderProxy = (world, pos) -> {
|
||||
if(world == MinecraftClient.getInstance().world) {
|
||||
MinecraftClient.getInstance().worldRenderer.scheduleBlockRender(
|
||||
ChunkSectionPos.getSectionCoord(pos.getX()),
|
||||
ChunkSectionPos.getSectionCoord(pos.getY()),
|
||||
ChunkSectionPos.getSectionCoord(pos.getZ())
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
ModelLoadingRegistry.INSTANCE.registerVariantProvider(rm -> provider);
|
||||
provider.registerTemplateModels2(Templates.SLOPE, Templates.SLOPE.getDefaultState().with(SlopeBlock.FACING, Direction.SOUTH), SlopeUnbakedModel::new);
|
||||
|
||||
|
@ -1,11 +0,0 @@
|
||||
package io.github.cottonmc.templates.block.entity;
|
||||
|
||||
import io.github.cottonmc.templates.Templates;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public class SlopeEntity extends TemplateEntity {
|
||||
public SlopeEntity(BlockPos pos, BlockState state) {
|
||||
super(Templates.SLOPE_ENTITY, pos, state, Templates.SLOPE);
|
||||
}
|
||||
}
|
@ -1,46 +1,45 @@
|
||||
package io.github.cottonmc.templates.block.entity;
|
||||
|
||||
import net.fabricmc.fabric.api.networking.v1.PlayerLookup;
|
||||
import io.github.cottonmc.templates.Templates;
|
||||
import net.fabricmc.fabric.api.rendering.data.v1.RenderAttachmentBlockEntity;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.block.entity.BlockEntityType;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.nbt.NbtHelper;
|
||||
import net.minecraft.network.listener.ClientPlayPacketListener;
|
||||
import net.minecraft.network.packet.Packet;
|
||||
import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class TemplateEntity extends BlockEntity implements RenderAttachmentBlockEntity {
|
||||
public class TemplateEntity extends BlockEntity implements RenderAttachmentBlockEntity {
|
||||
protected BlockState renderedState = Blocks.AIR.getDefaultState();
|
||||
protected boolean glowstone = false;
|
||||
protected boolean redstone = false;
|
||||
private final Block baseBlock;
|
||||
|
||||
public TemplateEntity(BlockEntityType<?> type, BlockPos pos, BlockState state, Block baseBlock) {
|
||||
public TemplateEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||
super(type, pos, state);
|
||||
this.baseBlock = baseBlock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readNbt(NbtCompound tag) {
|
||||
super.readNbt(tag);
|
||||
|
||||
BlockState lastRenderedState = renderedState;
|
||||
|
||||
renderedState = NbtHelper.toBlockState(Registries.BLOCK.getReadOnlyWrapper(), tag.getCompound("BlockState"));
|
||||
glowstone = tag.getBoolean("Glowstone");
|
||||
redstone = tag.getBoolean("Redstone");
|
||||
if(world != null && world.isClient) {
|
||||
//TODO probably unsafe, i think the method was removed in 1.14.4 or something though
|
||||
// i cant find any relevant method that takes only 1 blockpos argument
|
||||
((ClientWorld) world).scheduleBlockRenders(pos.getX(), pos.getY(), pos.getZ());
|
||||
//world.scheduleBlockRender(pos);
|
||||
|
||||
//Force a chunk remesh on the client, if the displayed blockstate has changed
|
||||
if(world != null && world.isClient && !Objects.equals(lastRenderedState, renderedState)) {
|
||||
Templates.chunkRerenderProxy.accept(world, pos);
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,13 +69,7 @@ public abstract class TemplateEntity extends BlockEntity implements RenderAttach
|
||||
|
||||
public void change() {
|
||||
markDirty();
|
||||
if(world != null && !world.isClient) {
|
||||
//for(ServerPlayerEntity player : PlayerLookup.tracking(this)) player.networkHandler.sendPacket(this.toUpdatePacket());
|
||||
|
||||
//TODO is this needed
|
||||
//world.updateNeighborsAlways(pos.offset(Direction.UP), baseBlock);
|
||||
world.updateListeners(pos, getCachedState(), getCachedState(), 3);
|
||||
}
|
||||
if(world instanceof ServerWorld sworld) sworld.getChunkManager().markForUpdate(pos); //dispatch to clients
|
||||
}
|
||||
|
||||
public BlockState getRenderedState() {
|
||||
@ -106,6 +99,9 @@ public abstract class TemplateEntity extends BlockEntity implements RenderAttach
|
||||
public void setRedstone(boolean newRedstone) {
|
||||
boolean lastRedstone = redstone;
|
||||
redstone = newRedstone;
|
||||
if(lastRedstone != newRedstone) change();
|
||||
if(lastRedstone != newRedstone) {
|
||||
world.updateNeighbors(pos, getCachedState().getBlock());
|
||||
change();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user