Skip to content

Commit 8f4f575

Browse files
authored
Merge pull request #66 from SammyForReal/1.21
Feature: Screen Block and Screen Tablet
2 parents 82f75b6 + ed2ed8e commit 8f4f575

30 files changed

+1855
-39
lines changed

build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ archivesBaseName = project.slug
1111

1212
repositories {
1313
maven { url "https://maven.nucleoid.xyz/" }
14+
maven { url 'https://repo.sleeping.town/' }
1415
}
1516

1617
dependencies {
@@ -25,6 +26,9 @@ dependencies {
2526

2627
include libs.placeholder
2728
modLocalRuntime libs.polydex
29+
30+
implementation libs.kaleidoConfig
31+
include libs.kaleidoConfig
2832
}
2933

3034
processResources {

libs.versions.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
loom = "1.7.+"
33
minotaur = "2.+"
44

5+
kaleidoConfig = "0.3.1+1.3.2"
6+
57
mc = "1.21"
68
fl = "0.15.11"
79
yarn = "1.21+build.9"
@@ -22,3 +24,4 @@ fapi = { group = "net.fabricmc.fabric-api", name = "fabric-api", version.ref = "
2224

2325
placeholder = { group = "eu.pb4", name = "placeholder-api", version.ref = "placeholder" }
2426
polydex = { group = "eu.pb4", name = "polydex", version.ref = "polydex" }
27+
kaleidoConfig = { group = "folk.sisby", name = "kaleido-config", version.ref = "kaleidoConfig" }

src/main/java/dev/hephaestus/glowcase/Glowcase.java

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,47 +2,48 @@
22

33
import com.google.common.base.Supplier;
44
import com.google.common.base.Suppliers;
5-
import dev.hephaestus.glowcase.block.HyperlinkBlock;
6-
import dev.hephaestus.glowcase.block.ItemAcceptorBlock;
7-
import dev.hephaestus.glowcase.block.ItemDisplayBlock;
8-
import dev.hephaestus.glowcase.block.OutlineBlock;
9-
import dev.hephaestus.glowcase.block.ParticleDisplayBlock;
10-
import dev.hephaestus.glowcase.block.PopupBlock;
11-
import dev.hephaestus.glowcase.block.SoundPlayerBlock;
12-
import dev.hephaestus.glowcase.block.SpriteBlock;
13-
import dev.hephaestus.glowcase.block.TextBlock;
14-
import dev.hephaestus.glowcase.block.entity.HyperlinkBlockEntity;
15-
import dev.hephaestus.glowcase.block.entity.ItemAcceptorBlockEntity;
16-
import dev.hephaestus.glowcase.block.entity.ItemDisplayBlockEntity;
17-
import dev.hephaestus.glowcase.block.entity.OutlineBlockEntity;
18-
import dev.hephaestus.glowcase.block.entity.ParticleDisplayBlockEntity;
19-
import dev.hephaestus.glowcase.block.entity.PopupBlockEntity;
20-
import dev.hephaestus.glowcase.block.entity.SoundPlayerBlockEntity;
21-
import dev.hephaestus.glowcase.block.entity.SpriteBlockEntity;
22-
import dev.hephaestus.glowcase.block.entity.TextBlockEntity;
5+
import com.mojang.datafixers.util.Pair;
6+
import com.mojang.serialization.Codec;
7+
import dev.hephaestus.glowcase.block.*;
8+
import dev.hephaestus.glowcase.block.entity.*;
239
import dev.hephaestus.glowcase.compat.PolydexCompatibility;
2410
import dev.hephaestus.glowcase.item.LockItem;
11+
import dev.hephaestus.glowcase.item.TabletItem;
2512
import net.fabricmc.api.ModInitializer;
2613
import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup;
2714
import net.fabricmc.loader.api.FabricLoader;
2815
import net.minecraft.block.Block;
2916
import net.minecraft.block.entity.BlockEntity;
3017
import net.minecraft.block.entity.BlockEntityType;
18+
import net.minecraft.component.ComponentType;
3119
import net.minecraft.item.BlockItem;
3220
import net.minecraft.item.Item;
3321
import net.minecraft.item.ItemGroup;
3422
import net.minecraft.item.ItemStack;
3523
import net.minecraft.item.Items;
24+
import net.minecraft.network.codec.PacketCodecs;
3625
import net.minecraft.registry.Registries;
3726
import net.minecraft.registry.Registry;
3827
import net.minecraft.registry.RegistryKeys;
3928
import net.minecraft.registry.tag.TagKey;
4029
import net.minecraft.text.Text;
4130
import net.minecraft.util.Identifier;
31+
import net.minecraft.util.Util;
32+
import net.minecraft.util.Uuids;
33+
import net.minecraft.util.dynamic.Codecs;
34+
import net.minecraft.util.math.BlockPos;
35+
import org.slf4j.Logger;
36+
import org.slf4j.LoggerFactory;
37+
38+
import java.util.Arrays;
39+
import java.util.List;
40+
import java.util.UUID;
4241

4342
public class Glowcase implements ModInitializer {
4443
public static final String MODID = "glowcase";
44+
public static final Logger LOGGER = LoggerFactory.getLogger(MODID);
4545

46+
public static final GlowcaseConfig CONFIG = GlowcaseConfig.createToml(FabricLoader.getInstance().getConfigDir(), "", MODID, GlowcaseConfig.class);
4647
public static GlowcaseCommonProxy proxy = new GlowcaseCommonProxy(); //Overridden in GlowcaseClient
4748

4849
public static final TagKey<Item> ITEM_TAG = TagKey.of(RegistryKeys.ITEM, id("items"));
@@ -71,6 +72,10 @@ public class Glowcase implements ModInitializer {
7172
public static final Supplier<BlockItem> POPUP_BLOCK_ITEM = registerItem("popup_block", () -> new BlockItem(POPUP_BLOCK.get(), new Item.Settings()));
7273
public static final Supplier<BlockEntityType<PopupBlockEntity>> POPUP_BLOCK_ENTITY = registerBlockEntity("popup_block", () -> BlockEntityType.Builder.create(PopupBlockEntity::new, POPUP_BLOCK.get()).build(null));
7374

75+
public static final Supplier<ScreenBlock> SCREEN_BLOCK = registerBlock("screen_block", ScreenBlock::new);
76+
public static final Supplier<BlockItem> SCREEN_BLOCK_ITEM = registerItem("screen_block", () -> new BlockItem(SCREEN_BLOCK.get(), new Item.Settings()));
77+
public static final Supplier<BlockEntityType<ScreenBlockEntity>> SCREEN_BLOCK_ENTITY = registerBlockEntity("screen_block", () -> BlockEntityType.Builder.create(ScreenBlockEntity::new, SCREEN_BLOCK.get()).build(null));
78+
7479
public static final Supplier<SpriteBlock> SPRITE_BLOCK = registerBlock("sprite_block", SpriteBlock::new);
7580
public static final Supplier<BlockItem> SPRITE_BLOCK_ITEM = registerItem("sprite_block", () -> new BlockItem(SPRITE_BLOCK.get(), new Item.Settings()));
7681
public static final Supplier<BlockEntityType<SpriteBlockEntity>> SPRITE_BLOCK_ENTITY = registerBlockEntity("sprite_block", () -> BlockEntityType.Builder.create(SpriteBlockEntity::new, SPRITE_BLOCK.get()).build(null));
@@ -85,6 +90,24 @@ public class Glowcase implements ModInitializer {
8590

8691
public static final Supplier<Item> LOCK_ITEM = registerItem("lock", () -> new LockItem(new Item.Settings()));
8792

93+
public static final Supplier<Item> TABLET_ITEM = registerItem("tablet", () -> new TabletItem(new Item.Settings().maxCount(1)));
94+
public static final Supplier<ComponentType<Pair<UUID, BlockPos>>> LINKED_SCREEN_COMPONENT = registerComponent("linked_screen", () -> {
95+
Codec<UUID> uuidCodec = Codec.INT_STREAM.comapFlatMap(stream -> Util.decodeFixedLengthArray(stream, 4).map(Uuids::toUuid), uuid -> Arrays.stream(Uuids.toIntArray(uuid)));
96+
Codec<Pair<UUID, BlockPos>> codec = Codec.mapPair(uuidCodec.fieldOf("uuid"), BlockPos.CODEC.fieldOf("pos")).codec();
97+
return ComponentType.<Pair<UUID, BlockPos>>builder()
98+
.codec(codec)
99+
.packetCodec(PacketCodecs.registryCodec(codec))
100+
.build();
101+
});
102+
public static final Supplier<ComponentType<Integer>> CURRENT_SLIDE_COMPONENT = registerComponent("current_slide", () -> ComponentType.<Integer>builder().codec(Codecs.NONNEGATIVE_INT).packetCodec(PacketCodecs.registryCodec(Codecs.NONNEGATIVE_INT)).build());
103+
public static final Supplier<ComponentType<List<Pair<String,String>>>> SLIDESHOW_COMPONENT = registerComponent("slideshow", () -> {
104+
Codec<List<Pair<String, String>>> codec = Codec.mapPair(Codec.STRING.fieldOf("url"), Codec.STRING.fieldOf("alt")).codec().listOf();
105+
return ComponentType.<List<Pair<String,String>>>builder()
106+
.codec(codec)
107+
.packetCodec(PacketCodecs.registryCodec(codec))
108+
.build();
109+
});
110+
88111
public static final Supplier<ItemGroup> ITEM_GROUP = registerItemGroup("items", () -> FabricItemGroup.builder()
89112
.displayName(Text.translatable("itemGroup.glowcase.items"))
90113
.icon(() -> new ItemStack(Items.GLOWSTONE))
@@ -98,7 +121,9 @@ public class Glowcase implements ModInitializer {
98121
entries.add(ITEM_ACCEPTOR_BLOCK_ITEM.get());
99122
entries.add(HYPERLINK_BLOCK_ITEM.get());
100123
entries.add(POPUP_BLOCK_ITEM.get());
124+
entries.add(SCREEN_BLOCK_ITEM.get());
101125
entries.add(LOCK_ITEM.get());
126+
entries.add(TABLET_ITEM.get());
102127
})
103128
.build()
104129
);
@@ -115,6 +140,10 @@ public static <T extends Item> Supplier<T> registerItem(String path, Supplier<T>
115140
return Suppliers.ofInstance(Registry.register(Registries.ITEM, id(path), supplier.get()));
116141
}
117142

143+
public static <T extends ComponentType<U>, U> Supplier<T> registerComponent(String path, Supplier<T> supplier) {
144+
return Suppliers.ofInstance(Registry.register(Registries.DATA_COMPONENT_TYPE, id(path), supplier.get()));
145+
}
146+
118147
public static <T extends ItemGroup> Supplier<T> registerItemGroup(String path, Supplier<T> supplier) {
119148
return Suppliers.ofInstance(Registry.register(Registries.ITEM_GROUP, id(path), supplier.get()));
120149
}

src/main/java/dev/hephaestus/glowcase/GlowcaseCommonProxy.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package dev.hephaestus.glowcase;
22

3+
import net.minecraft.item.ItemStack;
34
import net.minecraft.util.math.BlockPos;
45

56
public class GlowcaseCommonProxy {
@@ -27,6 +28,10 @@ public void openPopupBlockViewScreen(BlockPos pos) {
2728
//No-op
2829
}
2930

31+
public void openScreenBlockEditScreen(BlockPos pos) {
32+
//No-op
33+
}
34+
3035
public void openSpriteBlockEditScreen(BlockPos pos) {
3136
//No-op
3237
}
@@ -46,4 +51,8 @@ public void openSoundBlockEditScreen(BlockPos pos) {
4651
public void openItemAcceptorBlockEditScreen(BlockPos pos) {
4752
//No-op
4853
}
54+
55+
public void openTabletEditScreen(ItemStack stack) {
56+
//No-op
57+
}
4958
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package dev.hephaestus.glowcase;
2+
3+
import folk.sisby.kaleido.api.ReflectiveConfig;
4+
import folk.sisby.kaleido.lib.quiltconfig.api.annotations.Comment;
5+
import folk.sisby.kaleido.lib.quiltconfig.api.annotations.SerializedName;
6+
import folk.sisby.kaleido.lib.quiltconfig.api.values.TrackedValue;
7+
import folk.sisby.kaleido.lib.quiltconfig.api.values.ValueList;
8+
9+
public class GlowcaseConfig extends ReflectiveConfig {
10+
@Comment("Logs what, why and where a screen could not fetch an image, if enabled.")
11+
@SerializedName("log_invalid_screens")
12+
public final TrackedValue<Boolean> logInvalidScreens = value(false);
13+
14+
@Comment("List of specifically allowed domains or wildcards. Overrules the blacklist.")
15+
public final TrackedValue<ValueList<String>> whitelist = list("");
16+
17+
@Comment("List of specifically disallowed domains or wildcards. Overruled by the whitelist.")
18+
public final TrackedValue<ValueList<String>> blacklist = list("",
19+
"localhost"
20+
);
21+
}

src/main/java/dev/hephaestus/glowcase/GlowcaseNetworking.java

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,6 @@
11
package dev.hephaestus.glowcase;
22

3-
import dev.hephaestus.glowcase.packet.C2SEditHyperlinkBlock;
4-
import dev.hephaestus.glowcase.packet.C2SEditItemAcceptorBlock;
5-
import dev.hephaestus.glowcase.packet.C2SEditItemDisplayBlock;
6-
import dev.hephaestus.glowcase.packet.C2SEditOutlineBlock;
7-
import dev.hephaestus.glowcase.packet.C2SEditParticleDisplayBlock;
8-
import dev.hephaestus.glowcase.packet.C2SEditPopupBlock;
9-
import dev.hephaestus.glowcase.packet.C2SEditSoundBlock;
10-
import dev.hephaestus.glowcase.packet.C2SEditSpriteBlock;
11-
import dev.hephaestus.glowcase.packet.C2SEditTextBlock;
3+
import dev.hephaestus.glowcase.packet.*;
124
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
135
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
146

@@ -23,6 +15,8 @@ public static void init() {
2315
PayloadTypeRegistry.playC2S().register(C2SEditParticleDisplayBlock.ID, C2SEditParticleDisplayBlock.PACKET_CODEC);
2416
PayloadTypeRegistry.playC2S().register(C2SEditSoundBlock.ID, C2SEditSoundBlock.PACKET_CODEC);
2517
PayloadTypeRegistry.playC2S().register(C2SEditItemAcceptorBlock.ID, C2SEditItemAcceptorBlock.PACKET_CODEC);
18+
PayloadTypeRegistry.playC2S().register(C2SEditScreenBlock.ID, C2SEditScreenBlock.PACKET_CODEC);
19+
PayloadTypeRegistry.playC2S().register(C2SEditSlideTablet.ID, C2SEditSlideTablet.PACKET_CODEC);
2620

2721
ServerPlayNetworking.registerGlobalReceiver(C2SEditHyperlinkBlock.ID, C2SEditHyperlinkBlock::receive);
2822
ServerPlayNetworking.registerGlobalReceiver(C2SEditItemDisplayBlock.ID, C2SEditItemDisplayBlock::receive);
@@ -33,5 +27,7 @@ public static void init() {
3327
ServerPlayNetworking.registerGlobalReceiver(C2SEditParticleDisplayBlock.ID, C2SEditParticleDisplayBlock::receive);
3428
ServerPlayNetworking.registerGlobalReceiver(C2SEditSoundBlock.ID, C2SEditSoundBlock::receive);
3529
ServerPlayNetworking.registerGlobalReceiver(C2SEditItemAcceptorBlock.ID, C2SEditItemAcceptorBlock::receive);
30+
ServerPlayNetworking.registerGlobalReceiver(C2SEditScreenBlock.ID, C2SEditScreenBlock::receive);
31+
ServerPlayNetworking.registerGlobalReceiver(C2SEditSlideTablet.ID, C2SEditSlideTablet::receive);
3632
}
3733
}

src/main/java/dev/hephaestus/glowcase/block/GlowcaseBlock.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ protected static <E extends BlockEntity, A extends BlockEntity> BlockEntityTicke
4646
return expectedType == givenType ? (BlockEntityTicker<A>) ticker : null;
4747
}
4848

49-
public boolean canEditGlowcase(PlayerEntity player, BlockPos pos) {
49+
public static boolean canEditGlowcase(PlayerEntity player, BlockPos pos) {
5050
return player.isCreative() && player.canModifyAt(player.getWorld(), pos);
5151
}
5252
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package dev.hephaestus.glowcase.block;
2+
3+
import dev.hephaestus.glowcase.Glowcase;
4+
import dev.hephaestus.glowcase.block.entity.ScreenBlockEntity;
5+
import net.minecraft.block.*;
6+
import net.minecraft.block.entity.BlockEntity;
7+
import net.minecraft.component.DataComponentTypes;
8+
import net.minecraft.component.type.NbtComponent;
9+
import net.minecraft.entity.LivingEntity;
10+
import net.minecraft.entity.player.PlayerEntity;
11+
import net.minecraft.item.Item;
12+
import net.minecraft.item.ItemPlacementContext;
13+
import net.minecraft.item.ItemStack;
14+
import net.minecraft.item.tooltip.TooltipType;
15+
import net.minecraft.state.StateManager;
16+
import net.minecraft.state.property.Properties;
17+
import net.minecraft.text.Text;
18+
import net.minecraft.util.Formatting;
19+
import net.minecraft.util.Hand;
20+
import net.minecraft.util.ItemActionResult;
21+
import net.minecraft.util.hit.BlockHitResult;
22+
import net.minecraft.util.math.BlockPos;
23+
import net.minecraft.util.math.MathHelper;
24+
import net.minecraft.util.shape.VoxelShape;
25+
import net.minecraft.util.shape.VoxelShapes;
26+
import net.minecraft.world.BlockView;
27+
import net.minecraft.world.World;
28+
import org.jetbrains.annotations.Nullable;
29+
30+
import java.util.List;
31+
32+
public class ScreenBlock extends GlowcaseBlock implements BlockEntityProvider {
33+
public ScreenBlock() {
34+
super();
35+
this.setDefaultState(this.getDefaultState().with(Properties.ROTATION, 0));
36+
}
37+
38+
@Override
39+
public @Nullable BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
40+
return new ScreenBlockEntity(pos, state);
41+
}
42+
43+
@Override
44+
protected ItemActionResult onUseWithItem(ItemStack stack, BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
45+
if (!(world.getBlockEntity(pos) instanceof ScreenBlockEntity)) return ItemActionResult.CONSUME;
46+
47+
if (world.isClient && player.getStackInHand(hand).isIn(Glowcase.ITEM_TAG) && canEditGlowcase(player, pos)) {
48+
Glowcase.proxy.openScreenBlockEditScreen(pos);
49+
}
50+
51+
return ItemActionResult.SUCCESS;
52+
}
53+
54+
@Override
55+
public void onPlaced(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
56+
if (world.isClient && placer instanceof PlayerEntity player && canEditGlowcase(player, pos)) {
57+
NbtComponent blockEntityTag = stack.get(DataComponentTypes.BLOCK_ENTITY_DATA);
58+
59+
if (blockEntityTag != null && world.getBlockEntity(pos) instanceof ScreenBlockEntity be)
60+
blockEntityTag.applyToBlockEntity(be, world.getRegistryManager());
61+
62+
Glowcase.proxy.openScreenBlockEditScreen(pos);
63+
}
64+
}
65+
66+
@Override
67+
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
68+
super.appendProperties(builder);
69+
builder.add(Properties.ROTATION);
70+
}
71+
72+
@Override
73+
public BlockState getPlacementState(ItemPlacementContext ctx) {
74+
return this.getDefaultState().with(Properties.ROTATION, MathHelper.floor((double) ((180.0F + ctx.getPlayerYaw()) * 16.0F / 360.0F) + 0.5D) & 15);
75+
}
76+
77+
@Override
78+
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
79+
if (context != ShapeContext.absent() && context instanceof EntityShapeContext econtext &&
80+
econtext.getEntity() instanceof LivingEntity living &&
81+
living.getMainHandStack().isOf(Glowcase.TABLET_ITEM.get())
82+
) {
83+
return VoxelShapes.fullCube();
84+
} else
85+
return super.getOutlineShape(state, world, pos, context);
86+
}
87+
88+
@Override
89+
public void appendTooltip(ItemStack itemStack, Item.TooltipContext context, List<Text> tooltip, TooltipType options) {
90+
tooltip.add(Text.translatable("block.glowcase.screen_block.tooltip.0").formatted(Formatting.GRAY));
91+
tooltip.add(Text.translatable("block.glowcase.generic.tooltip").formatted(Formatting.DARK_GRAY));
92+
}
93+
}

0 commit comments

Comments
 (0)