Skip to content

Commit

Permalink
Merge pull request #37 from Chailotl/popup-block
Browse files Browse the repository at this point in the history
Add the popup block
  • Loading branch information
sisby-folk authored Aug 31, 2024
2 parents 07e213b + dff5ca3 commit 0df37fc
Show file tree
Hide file tree
Showing 17 changed files with 809 additions and 5 deletions.
7 changes: 7 additions & 0 deletions src/main/java/dev/hephaestus/glowcase/Glowcase.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
import com.google.common.base.Suppliers;
import dev.hephaestus.glowcase.block.HyperlinkBlock;
import dev.hephaestus.glowcase.block.ItemDisplayBlock;
import dev.hephaestus.glowcase.block.PopupBlock;
import dev.hephaestus.glowcase.block.TextBlock;
import dev.hephaestus.glowcase.block.entity.HyperlinkBlockEntity;
import dev.hephaestus.glowcase.block.entity.ItemDisplayBlockEntity;
import dev.hephaestus.glowcase.block.entity.PopupBlockEntity;
import dev.hephaestus.glowcase.block.entity.TextBlockEntity;
import dev.hephaestus.glowcase.compat.PolydexCompatibility;
import net.fabricmc.api.ModInitializer;
Expand Down Expand Up @@ -46,13 +48,18 @@ public class Glowcase implements ModInitializer {
public static final Supplier<BlockItem> TEXT_BLOCK_ITEM = registerItem("text_block", () -> new BlockItem(TEXT_BLOCK.get(), new Item.Settings()));
public static final Supplier<BlockEntityType<TextBlockEntity>> TEXT_BLOCK_ENTITY = registerBlockEntity("text_block", () -> BlockEntityType.Builder.create(TextBlockEntity::new, TEXT_BLOCK.get()).build(null));

public static final Supplier<PopupBlock> POPUP_BLOCK = registerBlock("popup_block", PopupBlock::new);
public static final Supplier<BlockItem> POPUP_BLOCK_ITEM = registerItem("popup_block", () -> new BlockItem(POPUP_BLOCK.get(), new Item.Settings()));
public static final Supplier<BlockEntityType<PopupBlockEntity>> POPUP_BLOCK_ENTITY = registerBlockEntity("popup_block", () -> BlockEntityType.Builder.create(PopupBlockEntity::new, POPUP_BLOCK.get()).build(null));

public static final Supplier<ItemGroup> ITEM_GROUP = registerItemGroup("items", () -> FabricItemGroup.builder()
.displayName(Text.translatable("itemGroup.glowcase.items"))
.icon(() -> new ItemStack(Items.GLOWSTONE))
.entries((displayContext, entries) -> {
entries.add(HYPERLINK_BLOCK_ITEM.get());
entries.add(ITEM_DISPLAY_BLOCK_ITEM.get());
entries.add(TEXT_BLOCK_ITEM.get());
entries.add(POPUP_BLOCK_ITEM.get());
})
.build()
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,12 @@ public void openItemDisplayBlockEditScreen(BlockPos pos) {
public void openTextBlockEditScreen(BlockPos pos) {
//No-op
}

public void openPopupBlockEditScreen(BlockPos pos) {
//No-op
}

public void openPopupBlockViewScreen(BlockPos pos) {
//No-op
}
}
3 changes: 3 additions & 0 deletions src/main/java/dev/hephaestus/glowcase/GlowcaseNetworking.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import dev.hephaestus.glowcase.packet.C2SEditHyperlinkBlock;
import dev.hephaestus.glowcase.packet.C2SEditItemDisplayBlock;
import dev.hephaestus.glowcase.packet.C2SEditPopupBlock;
import dev.hephaestus.glowcase.packet.C2SEditTextBlock;
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
Expand All @@ -11,9 +12,11 @@ public static void init() {
PayloadTypeRegistry.playC2S().register(C2SEditHyperlinkBlock.ID, C2SEditHyperlinkBlock.PACKET_CODEC);
PayloadTypeRegistry.playC2S().register(C2SEditItemDisplayBlock.ID, C2SEditItemDisplayBlock.PACKET_CODEC);
PayloadTypeRegistry.playC2S().register(C2SEditTextBlock.ID, C2SEditTextBlock.PACKET_CODEC);
PayloadTypeRegistry.playC2S().register(C2SEditPopupBlock.ID, C2SEditPopupBlock.PACKET_CODEC);

ServerPlayNetworking.registerGlobalReceiver(C2SEditHyperlinkBlock.ID, C2SEditHyperlinkBlock::receive);
ServerPlayNetworking.registerGlobalReceiver(C2SEditItemDisplayBlock.ID, C2SEditItemDisplayBlock::receive);
ServerPlayNetworking.registerGlobalReceiver(C2SEditTextBlock.ID, C2SEditTextBlock::receive);
ServerPlayNetworking.registerGlobalReceiver(C2SEditPopupBlock.ID, C2SEditPopupBlock::receive);
}
}
85 changes: 85 additions & 0 deletions src/main/java/dev/hephaestus/glowcase/block/PopupBlock.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package dev.hephaestus.glowcase.block;

import dev.hephaestus.glowcase.Glowcase;
import dev.hephaestus.glowcase.block.entity.PopupBlockEntity;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.NbtComponent;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.tooltip.TooltipType;
import net.minecraft.text.Text;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Formatting;
import net.minecraft.util.Hand;
import net.minecraft.util.ItemActionResult;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;

import java.util.List;

public class PopupBlock extends GlowcaseBlock implements BlockEntityProvider {
private static final VoxelShape OUTLINE = VoxelShapes.cuboid(0.25, 0.25, 0.25, 0.75, 0.75, 0.75);

@Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return OUTLINE;
}

@Nullable
@Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return new PopupBlockEntity(pos, state);
}

@Override
public void onPlaced(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
if (world.isClient && placer instanceof PlayerEntity player && canEditGlowcase(player, pos)) {
//load any ctrl-picked NBT clientside
NbtComponent blockEntityTag = stack.get(DataComponentTypes.BLOCK_ENTITY_DATA);
if (blockEntityTag != null && world.getBlockEntity(pos) instanceof PopupBlockEntity be) {
blockEntityTag.applyToBlockEntity(be, world.getRegistryManager());
}

Glowcase.proxy.openPopupBlockEditScreen(pos);
}
}

@Override
protected ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit) {
if (!(world.getBlockEntity(pos) instanceof PopupBlockEntity be)) return ActionResult.CONSUME;
if (world.isClient) {
Glowcase.proxy.openPopupBlockViewScreen(pos);
}
return ActionResult.SUCCESS;
}

@Override
protected ItemActionResult onUseWithItem(ItemStack stack, BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
if (!(world.getBlockEntity(pos) instanceof PopupBlockEntity)) return ItemActionResult.CONSUME;
if (player.getStackInHand(hand).isIn(Glowcase.ITEM_TAG) && canEditGlowcase(player, pos)) {
if (world.isClient) {
Glowcase.proxy.openPopupBlockEditScreen(pos);
}
return ItemActionResult.SUCCESS;
}
return ItemActionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION;
}

@Override
public void appendTooltip(ItemStack itemStack, Item.TooltipContext context, List<Text> tooltip, TooltipType options) {
tooltip.add(Text.translatable("block.glowcase.popup_block.tooltip.0").formatted(Formatting.GRAY));
tooltip.add(Text.translatable("block.glowcase.generic.tooltip").formatted(Formatting.DARK_GRAY));
tooltip.add(Text.translatable("block.glowcase.popup_block.tooltip.1").formatted(Formatting.DARK_GRAY));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package dev.hephaestus.glowcase.block.entity;

import dev.hephaestus.glowcase.Glowcase;
import dev.hephaestus.glowcase.client.render.block.entity.BakedBlockEntityRenderer;
import eu.pb4.placeholders.api.ParserContext;
import eu.pb4.placeholders.api.parsers.NodeParser;
import eu.pb4.placeholders.api.parsers.TagParser;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement;
import net.minecraft.nbt.NbtList;
import net.minecraft.nbt.NbtString;
import net.minecraft.network.listener.ClientPlayPacketListener;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.text.Style;
import net.minecraft.text.Text;
import net.minecraft.util.math.BlockPos;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;

public class PopupBlockEntity extends BlockEntity {
public static final NodeParser PARSER = TagParser.DEFAULT;
public String title = "";
public List<Text> lines = new ArrayList<>();
public TextBlockEntity.TextAlignment textAlignment = TextBlockEntity.TextAlignment.CENTER;
public int color = 0xFFFFFF;
public boolean renderDirty = true;

public PopupBlockEntity(BlockPos pos, BlockState state) {
super(Glowcase.POPUP_BLOCK_ENTITY.get(), pos, state);
lines.add(Text.empty());
}

@Override
protected void writeNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) {
super.writeNbt(tag, registryLookup);

tag.putString("title", this.title);
tag.putInt("color", this.color);

tag.putString("text_alignment", this.textAlignment.name());

NbtList lines = tag.getList("lines", 8);
for (var text : this.lines) {
lines.add(NbtString.of(Text.Serialization.toJsonString(text, registryLookup)));
}

tag.put("lines", lines);
}

@Override
protected void readNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) {
super.readNbt(tag, registryLookup);

this.title = tag.getString("title");
this.lines = new ArrayList<>();
this.color = tag.getInt("color");

this.textAlignment = TextBlockEntity.TextAlignment.valueOf(tag.getString("text_alignment"));

NbtList lines = tag.getList("lines", 8);

for (NbtElement line : lines) {
if (line.getType() == NbtElement.END_TYPE) break;
this.lines.add(Text.Serialization.fromJson(line.asString(), registryLookup));
}

this.renderDirty = true;
}

public String getRawLine(int i) {
var line = this.lines.get(i);

if (line.getStyle() == null) {
return line.getString();
}

var insert = line.getStyle().getInsertion();

if (insert == null) {
return line.getString();
}
return insert;
}

public void addRawLine(int i, String string) {
var parsed = PARSER.parseText(string, ParserContext.of());

if (parsed.getString().equals(string)) {
this.lines.add(i, Text.literal(string));
} else {
this.lines.add(i, Text.empty().append(parsed).setStyle(Style.EMPTY.withInsertion(string)));
}
}

public void setRawLine(int i, String string) {
var parsed = PARSER.parseText(string, ParserContext.of());

if (parsed.getString().equals(string)) {
this.lines.set(i, Text.literal(string));
} else {
this.lines.set(i, Text.empty().append(parsed).setStyle(Style.EMPTY.withInsertion(string)));
}
}

@SuppressWarnings({"MethodCallSideOnly", "VariableUseSideOnly"})
@Override
public void markRemoved() {
if (world != null && world.isClient) {
BakedBlockEntityRenderer.Manager.markForRebuild(getPos());
}
super.markRemoved();
}

// standard blockentity boilerplate

public void dispatch() {
if (world instanceof ServerWorld sworld) sworld.getChunkManager().markForUpdate(pos);
}

@Override
public NbtCompound toInitialChunkDataNbt(RegistryWrapper.WrapperLookup registryLookup) {
return createNbt(registryLookup);
}

@Nullable
@Override
public Packet<ClientPlayPacketListener> toUpdatePacket() {
return BlockEntityUpdateS2CPacket.create(this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import dev.hephaestus.glowcase.client.render.block.entity.HyperlinkBlockEntityRenderer;
import dev.hephaestus.glowcase.client.render.block.entity.ItemDisplayBlockEntityRenderer;
import dev.hephaestus.glowcase.client.render.block.entity.TextBlockEntityRenderer;
import dev.hephaestus.glowcase.client.render.block.entity.PopupBlockEntityRenderer;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.rendering.v1.InvalidateRenderStateCallback;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
Expand All @@ -18,6 +19,7 @@ public void onInitializeClient() {
BlockEntityRendererFactories.register(Glowcase.TEXT_BLOCK_ENTITY.get(), TextBlockEntityRenderer::new);
BlockEntityRendererFactories.register(Glowcase.HYPERLINK_BLOCK_ENTITY.get(), HyperlinkBlockEntityRenderer::new);
BlockEntityRendererFactories.register(Glowcase.ITEM_DISPLAY_BLOCK_ENTITY.get(), ItemDisplayBlockEntityRenderer::new);
BlockEntityRendererFactories.register(Glowcase.POPUP_BLOCK_ENTITY.get(), PopupBlockEntityRenderer::new);

WorldRenderEvents.AFTER_TRANSLUCENT.register(BakedBlockEntityRenderer.Manager::render);
InvalidateRenderStateCallback.EVENT.register(BakedBlockEntityRenderer.Manager::reset);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
import dev.hephaestus.glowcase.GlowcaseCommonProxy;
import dev.hephaestus.glowcase.block.entity.HyperlinkBlockEntity;
import dev.hephaestus.glowcase.block.entity.ItemDisplayBlockEntity;
import dev.hephaestus.glowcase.block.entity.PopupBlockEntity;
import dev.hephaestus.glowcase.block.entity.TextBlockEntity;
import dev.hephaestus.glowcase.client.gui.screen.ingame.HyperlinkBlockEditScreen;
import dev.hephaestus.glowcase.client.gui.screen.ingame.ItemDisplayBlockEditScreen;
import dev.hephaestus.glowcase.client.gui.screen.ingame.TextBlockEditScreen;
import dev.hephaestus.glowcase.client.gui.screen.ingame.*;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ConfirmLinkScreen;
import net.minecraft.util.math.BlockPos;
Expand Down Expand Up @@ -40,4 +39,20 @@ public void openTextBlockEditScreen(BlockPos pos) {
MinecraftClient.getInstance().setScreen(new TextBlockEditScreen(be));
}
}

@Override
public void openPopupBlockEditScreen(BlockPos pos) {
MinecraftClient client = MinecraftClient.getInstance();
if (client.world != null && client.world.getBlockEntity(pos) instanceof PopupBlockEntity be) {
MinecraftClient.getInstance().setScreen(new PopupBlockEditScreen(be));
}
}

@Override
public void openPopupBlockViewScreen(BlockPos pos) {
MinecraftClient client = MinecraftClient.getInstance();
if (client.world != null && client.world.getBlockEntity(pos) instanceof PopupBlockEntity be) {
MinecraftClient.getInstance().setScreen(new PopupBlockViewScreen(be));
}
}
}
Loading

0 comments on commit 0df37fc

Please sign in to comment.