2023-07-06 05:57:19 +02:00
|
|
|
package io.github.cottonmc.templates.block;
|
2019-06-19 22:32:58 +02:00
|
|
|
|
2023-06-16 04:50:41 +02:00
|
|
|
import io.github.cottonmc.templates.Templates;
|
2023-07-04 02:39:48 +02:00
|
|
|
import io.github.cottonmc.templates.api.ThemeableBlockEntity;
|
2019-06-19 22:32:58 +02:00
|
|
|
import net.minecraft.block.BlockState;
|
|
|
|
import net.minecraft.block.Blocks;
|
|
|
|
import net.minecraft.block.entity.BlockEntity;
|
|
|
|
import net.minecraft.block.entity.BlockEntityType;
|
2023-06-15 09:08:20 +02:00
|
|
|
import net.minecraft.nbt.NbtCompound;
|
2023-06-15 07:53:04 +02:00
|
|
|
import net.minecraft.nbt.NbtHelper;
|
2023-06-15 10:24:11 +02:00
|
|
|
import net.minecraft.network.listener.ClientPlayPacketListener;
|
|
|
|
import net.minecraft.network.packet.Packet;
|
|
|
|
import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket;
|
2023-06-15 09:08:20 +02:00
|
|
|
import net.minecraft.registry.Registries;
|
2023-06-16 04:50:41 +02:00
|
|
|
import net.minecraft.server.world.ServerWorld;
|
2023-06-15 09:08:20 +02:00
|
|
|
import net.minecraft.util.math.BlockPos;
|
2023-06-15 10:24:11 +02:00
|
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
|
|
|
|
import java.util.Objects;
|
2019-06-19 22:32:58 +02:00
|
|
|
|
2023-07-04 03:55:32 +02:00
|
|
|
public class TemplateEntity extends BlockEntity implements ThemeableBlockEntity {
|
2019-06-19 22:32:58 +02:00
|
|
|
protected BlockState renderedState = Blocks.AIR.getDefaultState();
|
2023-07-03 09:35:07 +02:00
|
|
|
|
|
|
|
//Whether the player has manually spent a redstone/glowstone item to upgrade the template.
|
|
|
|
//It's possible to get templates that, e.g. glow, without manually spending a glowstone on them
|
|
|
|
//(put a froglight in a template!) Same for redstone activation. We need to separately store
|
|
|
|
//whether a redstone/glowstone should be refunded when the player breaks the template, and wasting a
|
|
|
|
//blockstate for it is a little silly, so, here you go.
|
|
|
|
protected boolean spentGlowstoneDust = false;
|
|
|
|
protected boolean spentRedstoneTorch = false;
|
2023-07-06 05:40:12 +02:00
|
|
|
protected boolean spentPoppedChorus = false;
|
2023-06-15 07:59:48 +02:00
|
|
|
|
2023-07-08 08:29:22 +02:00
|
|
|
protected boolean emitsRedstone;
|
|
|
|
protected boolean isSolid = true;
|
|
|
|
|
2023-06-16 04:50:41 +02:00
|
|
|
public TemplateEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
2023-06-15 09:08:20 +02:00
|
|
|
super(type, pos, state);
|
2019-06-19 22:32:58 +02:00
|
|
|
}
|
2023-06-15 07:59:48 +02:00
|
|
|
|
2019-06-19 22:32:58 +02:00
|
|
|
@Override
|
2023-06-15 09:08:20 +02:00
|
|
|
public void readNbt(NbtCompound tag) {
|
|
|
|
super.readNbt(tag);
|
2023-06-16 04:50:41 +02:00
|
|
|
|
|
|
|
BlockState lastRenderedState = renderedState;
|
|
|
|
|
2023-06-15 09:08:20 +02:00
|
|
|
renderedState = NbtHelper.toBlockState(Registries.BLOCK.getReadOnlyWrapper(), tag.getCompound("BlockState"));
|
2023-07-08 08:29:22 +02:00
|
|
|
spentGlowstoneDust = tag.getBoolean("spentglow");
|
|
|
|
spentRedstoneTorch = tag.getBoolean("spentredst");
|
|
|
|
spentPoppedChorus = tag.getBoolean("spentchor");
|
|
|
|
|
|
|
|
emitsRedstone = tag.getBoolean("emitsredst");
|
|
|
|
isSolid = !tag.contains("solid") || tag.getBoolean("solid"); //default to "true" if it's nonexistent
|
2023-06-16 04:50:41 +02:00
|
|
|
|
2023-07-03 09:35:07 +02:00
|
|
|
//Force a chunk remesh on the client if the displayed blockstate has changed
|
2023-07-21 09:49:49 +02:00
|
|
|
//TODO: doors? (need remeshing when the *other* party changes)
|
2023-06-16 04:50:41 +02:00
|
|
|
if(world != null && world.isClient && !Objects.equals(lastRenderedState, renderedState)) {
|
|
|
|
Templates.chunkRerenderProxy.accept(world, pos);
|
2019-06-19 22:32:58 +02:00
|
|
|
}
|
|
|
|
}
|
2023-06-15 07:59:48 +02:00
|
|
|
|
2019-06-19 22:32:58 +02:00
|
|
|
@Override
|
2023-06-15 09:08:20 +02:00
|
|
|
public void writeNbt(NbtCompound tag) {
|
|
|
|
super.writeNbt(tag);
|
2023-06-15 07:53:04 +02:00
|
|
|
tag.put("BlockState", NbtHelper.fromBlockState(renderedState));
|
2023-07-08 08:29:22 +02:00
|
|
|
tag.putBoolean("spentglow", spentGlowstoneDust);
|
|
|
|
tag.putBoolean("spentredst", spentRedstoneTorch);
|
|
|
|
tag.putBoolean("spentchor", spentPoppedChorus);
|
|
|
|
|
|
|
|
tag.putBoolean("emitsredst", emitsRedstone);
|
|
|
|
tag.putBoolean("solid", isSolid);
|
2019-06-19 22:32:58 +02:00
|
|
|
}
|
2023-06-15 07:59:48 +02:00
|
|
|
|
2023-06-15 10:24:11 +02:00
|
|
|
@Nullable
|
2019-06-19 22:32:58 +02:00
|
|
|
@Override
|
2023-06-15 10:24:11 +02:00
|
|
|
public Packet<ClientPlayPacketListener> toUpdatePacket() {
|
|
|
|
return BlockEntityUpdateS2CPacket.create(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public NbtCompound toInitialChunkDataNbt() {
|
2023-07-03 09:35:07 +02:00
|
|
|
//TERRIBLE yarn name, this is "getUpdateTag", it's the nbt that will be sent to clients
|
2023-07-08 08:29:22 +02:00
|
|
|
//and it just calls "writeNbt"
|
2023-06-15 10:24:11 +02:00
|
|
|
return createNbt();
|
2019-06-19 22:32:58 +02:00
|
|
|
}
|
2023-06-15 07:59:48 +02:00
|
|
|
|
2019-06-19 22:32:58 +02:00
|
|
|
@Override
|
|
|
|
public BlockState getRenderAttachmentData() {
|
|
|
|
return renderedState;
|
|
|
|
}
|
2023-06-15 07:59:48 +02:00
|
|
|
|
2023-07-21 09:49:49 +02:00
|
|
|
protected void dispatch() {
|
2023-07-08 08:29:22 +02:00
|
|
|
if(world instanceof ServerWorld sworld) sworld.getChunkManager().markForUpdate(pos);
|
|
|
|
}
|
|
|
|
|
2023-06-15 10:24:11 +02:00
|
|
|
public void setRenderedState(BlockState newState) {
|
2023-07-03 09:35:07 +02:00
|
|
|
if(!Objects.equals(renderedState, newState)) {
|
|
|
|
renderedState = newState;
|
|
|
|
markDirty();
|
2023-07-08 08:29:22 +02:00
|
|
|
dispatch();
|
2023-07-03 09:35:07 +02:00
|
|
|
}
|
2023-06-15 10:24:11 +02:00
|
|
|
}
|
|
|
|
|
2023-07-03 09:35:07 +02:00
|
|
|
public boolean hasSpentGlowstoneDust() {
|
|
|
|
return spentGlowstoneDust;
|
2019-06-19 22:32:58 +02:00
|
|
|
}
|
2023-06-15 07:59:48 +02:00
|
|
|
|
2023-07-03 09:35:07 +02:00
|
|
|
public void spentGlowstoneDust() {
|
|
|
|
spentGlowstoneDust = true;
|
|
|
|
markDirty();
|
2019-06-19 22:32:58 +02:00
|
|
|
}
|
2023-06-15 07:59:48 +02:00
|
|
|
|
2023-07-03 09:35:07 +02:00
|
|
|
public boolean hasSpentRedstoneTorch() {
|
|
|
|
return spentRedstoneTorch;
|
2019-06-19 22:32:58 +02:00
|
|
|
}
|
2023-06-15 07:59:48 +02:00
|
|
|
|
2023-07-03 09:35:07 +02:00
|
|
|
public void spentRedstoneTorch() {
|
|
|
|
spentRedstoneTorch = true;
|
|
|
|
markDirty();
|
2019-06-19 22:32:58 +02:00
|
|
|
}
|
2023-07-06 05:40:12 +02:00
|
|
|
|
|
|
|
public boolean hasSpentPoppedChorus() {
|
|
|
|
return spentPoppedChorus;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void spentPoppedChorus() {
|
|
|
|
spentPoppedChorus = true;
|
|
|
|
markDirty();
|
|
|
|
}
|
2023-07-08 08:29:22 +02:00
|
|
|
|
|
|
|
public boolean emitsRedstone() {
|
|
|
|
return emitsRedstone;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setEmitsRedstone(boolean emitsRedstone) {
|
|
|
|
if(this.emitsRedstone != emitsRedstone) {
|
|
|
|
this.emitsRedstone = emitsRedstone;
|
|
|
|
markDirty();
|
|
|
|
|
|
|
|
if(world != null) world.updateNeighbors(pos, getCachedState().getBlock());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isSolid() {
|
|
|
|
return isSolid;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setSolidity(boolean isSolid) {
|
|
|
|
if(this.isSolid != isSolid) {
|
|
|
|
this.isSolid = isSolid;
|
|
|
|
markDirty();
|
|
|
|
|
|
|
|
//do i need to invalidate any shape caches or something
|
|
|
|
if(world != null) world.setBlockState(pos, getCachedState());
|
|
|
|
|
|
|
|
dispatch();
|
|
|
|
}
|
|
|
|
}
|
2019-06-19 22:32:58 +02:00
|
|
|
}
|