Skip to content

Commit

Permalink
Add slide items and divide the features into blocks and items
Browse files Browse the repository at this point in the history
  • Loading branch information
ustc-zzzz committed Aug 15, 2024
1 parent 3857669 commit f7f34b8
Show file tree
Hide file tree
Showing 52 changed files with 2,451 additions and 1,058 deletions.
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,19 @@

… is a Minecraft mod that adds a "Slide Show Projector" block. This block can project any online image into the world.

![Preview](./docs/preview.png)
![Preview](./docs/img5.png)

Simply right-click the block to open its GUI, and paste the URL to the image, and then it will work!
Simply right-click the block to open its GUI, take the slide item out,
open it and paste the URL to the image, then put it back into the block, and it will work!
There are also several options to adjust; hover your mouse to these icons to get familiar with these options.

![GUI](./docs/gui.png)
![GUI](./docs/img1.png)

![GUI](./docs/img2.png)

![GUI](./docs/img3.png)

![GUI](./docs/img4.png)

By now, only PNG/JPG/GIF format images are verified as supported (including animations);
other image formats may or may not be supported, and further testing are still needed.
Expand Down
2 changes: 0 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,9 @@ configurations {
dependencies {
// Modified by TeaCon
jarJar implementation('org.teacon:urlpattern:1.0.1')
jarJar implementation('net.objecthunter:exp4j:0.4.8')
jarJar implementation('org.apache.httpcomponents:httpclient-cache:4.5.13')
// Modified by TeaCon
additionalRuntimeClasspath 'org.teacon:urlpattern:1.0.1'
additionalRuntimeClasspath 'net.objecthunter:exp4j:0.4.8'
additionalRuntimeClasspath 'org.apache.httpcomponents:httpclient-cache:4.5.13'
}

Expand Down
Binary file removed docs/gui.png
Binary file not shown.
Binary file added docs/img1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed docs/preview.png
Binary file not shown.
18 changes: 15 additions & 3 deletions src/main/java/org/teacon/slides/ModClientRegistries.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@

import net.minecraft.FieldsAreNonnullByDefault;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.client.renderer.item.ItemProperties;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
import net.neoforged.neoforge.client.event.EntityRenderersEvent;
import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent;
import org.teacon.slides.item.SlideItem;
import org.teacon.slides.renderer.ProjectorRenderer;
import org.teacon.slides.renderer.SlideState;
import org.teacon.slides.screen.ProjectorScreen;
import org.teacon.slides.screen.SlideItemScreen;

import javax.annotation.ParametersAreNonnullByDefault;

Expand All @@ -33,25 +36,34 @@ private static boolean isOptifineLoaded() {
@SubscribeEvent
public static void onRegisterMenuScreen(final RegisterMenuScreensEvent event) {
SlideShow.LOGGER.info("OptiFine loaded: {}", IS_OPTIFINE_LOADED);
event.register(ModRegistries.MENU.get(), ProjectorScreen::new);
event.register(ModRegistries.PROJECTOR_MENU.get(), ProjectorScreen::new);
event.register(ModRegistries.SLIDE_ITEM_MENU.get(), SlideItemScreen::new);
}

@SubscribeEvent
public static void onClientSetup(final FMLClientSetupEvent event) {
SlideShow.setRequestUrlPrefetch(SlideState::prefetch);
SlideShow.setApplyPrefetch(SlideState::applyPrefetch);
event.enqueueWork(() -> {
var slideItem = ModRegistries.SLIDE_ITEM.get();
ItemProperties.register(slideItem, SlideShow.id("url_status"), (stack, level, entity, seed) -> {
var uuid = stack.getOrDefault(ModRegistries.SLIDE_ENTRY, SlideItem.ENTRY_DEF).id();
var status = SlideShow.checkBlock(uuid);
return status.ordinal() / 2F;
});
});
}

@SubscribeEvent
public static void registerRenders(EntityRenderersEvent.RegisterRenderers event) {
event.registerBlockEntityRenderer(ModRegistries.BLOCK_ENTITY.get(), ProjectorRenderer::new);
event.registerBlockEntityRenderer(ModRegistries.PROJECTOR_BLOCK_ENTITY.get(), ProjectorRenderer::new);
}

/*@SubscribeEvent
public static void registerShaders(RegisterShadersEvent event) {
try {
event.registerShader(new ShaderInstance(event.getResourceProvider(),
ResourceLocation.fromNamespaceAndPath(SlideShow.ID, "rendertype_palette_slide"),
SlideShow.identifier("rendertype_palette_slide"),
DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP), SlideRenderType::setPaletteSlideShader);
} catch (IOException e) {
throw new RuntimeException(e);
Expand Down
75 changes: 51 additions & 24 deletions src/main/java/org/teacon/slides/ModRegistries.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,35 @@

import net.minecraft.FieldsAreNonnullByDefault;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.core.Direction;
import net.minecraft.core.component.DataComponentType;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.ItemTags;
import net.minecraft.tags.TagKey;
import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.item.CreativeModeTabs;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.capabilities.BlockCapability;
import net.neoforged.neoforge.capabilities.Capabilities;
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent;
import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent;
import net.neoforged.neoforge.items.IItemHandler;
import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent;
import net.neoforged.neoforge.registries.DeferredHolder;
import net.neoforged.neoforge.registries.RegisterEvent;
import org.teacon.slides.network.SlideURLPrefetchPacket;
import org.teacon.slides.network.SlideURLRequestPacket;
import org.teacon.slides.network.SlideURLSummaryPacket;
import org.teacon.slides.network.SlideUpdatePacket;
import org.teacon.slides.projector.ProjectorBlock;
import org.teacon.slides.projector.ProjectorBlockEntity;
import org.teacon.slides.projector.ProjectorContainerMenu;
import org.teacon.slides.projector.ProjectorItem;
import org.jetbrains.annotations.Nullable;
import org.teacon.slides.block.ProjectorBlock;
import org.teacon.slides.block.ProjectorBlockEntity;
import org.teacon.slides.inventory.ProjectorContainerMenu;
import org.teacon.slides.inventory.SlideItemContainerMenu;
import org.teacon.slides.item.ProjectorItem;
import org.teacon.slides.item.SlideItem;
import org.teacon.slides.network.*;
import org.teacon.slides.url.ProjectorURLArgument;
import org.teacon.slides.url.ProjectorURLPatternArgument;

Expand All @@ -43,49 +52,67 @@ public final class ModRegistries {
// Last Update: Mon, 29 Jul 2024 21:00:00 +0800 (3 => 4)
public static final String NETWORK_VERSION = "4";

public static final ResourceLocation PROJECTOR_URL_PATTERN_ID = ResourceLocation.fromNamespaceAndPath(SlideShow.ID, "projector_url_pattern");
public static final ResourceLocation PROJECTOR_URL_PATTERN_ID = SlideShow.id("projector_url_pattern");
public static final ResourceLocation PROJECTOR_URL_ID = SlideShow.id("projector_url");
public static final ResourceLocation PROJECTOR_ID = SlideShow.id("projector");
public static final ResourceLocation SLIDE_ITEM_ID = SlideShow.id("slide_item");
public static final ResourceLocation SLIDE_ENTRY_ID = SlideShow.id("slide_entry");

public static final ResourceLocation PROJECTOR_URL_ID = ResourceLocation.fromNamespaceAndPath(SlideShow.ID, "projector_url");
public static final TagKey<Item> SLIDE_ITEMS = ItemTags.create(SlideShow.id("slide_items"));

public static final ResourceLocation PROJECTOR_ID = ResourceLocation.fromNamespaceAndPath(SlideShow.ID, "projector");

public static final DeferredHolder<Block, ProjectorBlock> PROJECTOR;

public static final DeferredHolder<BlockEntityType<?>, BlockEntityType<ProjectorBlockEntity>> BLOCK_ENTITY;

public static final DeferredHolder<MenuType<?>, MenuType<ProjectorContainerMenu>> MENU;
public static final DeferredHolder<Block, ProjectorBlock> PROJECTOR_BLOCK;
public static final DeferredHolder<Item, SlideItem> SLIDE_ITEM;
public static final DeferredHolder<DataComponentType<?>, DataComponentType<SlideItem.Entry>> SLIDE_ENTRY;
public static final DeferredHolder<BlockEntityType<?>, BlockEntityType<ProjectorBlockEntity>> PROJECTOR_BLOCK_ENTITY;
public static final DeferredHolder<MenuType<?>, MenuType<ProjectorContainerMenu>> PROJECTOR_MENU;
public static final DeferredHolder<MenuType<?>, MenuType<SlideItemContainerMenu>> SLIDE_ITEM_MENU;

static {
PROJECTOR = DeferredHolder.create(BuiltInRegistries.BLOCK.key(), PROJECTOR_ID);
BLOCK_ENTITY = DeferredHolder.create(BuiltInRegistries.BLOCK_ENTITY_TYPE.key(), PROJECTOR_ID);
MENU = DeferredHolder.create(BuiltInRegistries.MENU.key(), PROJECTOR_ID);
PROJECTOR_BLOCK = DeferredHolder.create(BuiltInRegistries.BLOCK.key(), PROJECTOR_ID);
SLIDE_ITEM = DeferredHolder.create(BuiltInRegistries.ITEM.key(), SLIDE_ITEM_ID);
SLIDE_ENTRY = DeferredHolder.create(BuiltInRegistries.DATA_COMPONENT_TYPE.key(), SLIDE_ENTRY_ID);
PROJECTOR_BLOCK_ENTITY = DeferredHolder.create(BuiltInRegistries.BLOCK_ENTITY_TYPE.key(), PROJECTOR_ID);
PROJECTOR_MENU = DeferredHolder.create(BuiltInRegistries.MENU.key(), PROJECTOR_ID);
SLIDE_ITEM_MENU = DeferredHolder.create(BuiltInRegistries.MENU.key(), SLIDE_ITEM_ID);
}

@SubscribeEvent
public static void register(final RegisterEvent event) {
event.register(BuiltInRegistries.BLOCK.key(), PROJECTOR_ID, ProjectorBlock::new);
event.register(BuiltInRegistries.ITEM.key(), PROJECTOR_ID, ProjectorItem::new);
event.register(BuiltInRegistries.ITEM.key(), SLIDE_ITEM_ID, SlideItem::new);
event.register(BuiltInRegistries.DATA_COMPONENT_TYPE.key(), SLIDE_ENTRY_ID, SlideItem.Entry::createComponentType);
event.register(BuiltInRegistries.BLOCK_ENTITY_TYPE.key(), PROJECTOR_ID, ProjectorBlockEntity::create);
event.register(BuiltInRegistries.MENU.key(), PROJECTOR_ID, ProjectorContainerMenu::create);
event.register(BuiltInRegistries.MENU.key(), SLIDE_ITEM_ID, SlideItemContainerMenu::create);
event.register(BuiltInRegistries.COMMAND_ARGUMENT_TYPE.key(), PROJECTOR_URL_ID, ProjectorURLArgument::create);
event.register(BuiltInRegistries.COMMAND_ARGUMENT_TYPE.key(), PROJECTOR_URL_PATTERN_ID, ProjectorURLPatternArgument::create);
}

@SubscribeEvent
public static void onPayloadRegister(final RegisterPayloadHandlersEvent event) {
var pr = event.registrar(NETWORK_VERSION);
pr.playToServer(SlideUpdatePacket.TYPE, SlideUpdatePacket.CODEC, SlideUpdatePacket::handle);
pr.playToServer(ProjectorUpdatePacket.TYPE, ProjectorUpdatePacket.CODEC, ProjectorUpdatePacket::handle);
pr.playToServer(SlideItemUpdatePacket.TYPE, SlideItemUpdatePacket.CODEC, SlideItemUpdatePacket::handle);
pr.playToClient(SlideURLPrefetchPacket.TYPE, SlideURLPrefetchPacket.CODEC, SlideURLPrefetchPacket::handle);
pr.playToServer(SlideURLRequestPacket.TYPE, SlideURLRequestPacket.CODEC, SlideURLRequestPacket::handle);
pr.commonToClient(SlideURLSummaryPacket.TYPE, SlideURLSummaryPacket.CODEC, SlideURLSummaryPacket::handle);
pr.commonToClient(SlideSummaryPacket.TYPE, SlideSummaryPacket.CODEC, SlideSummaryPacket::handle);
SlideShow.LOGGER.info("Registered related network packages (version {})", NETWORK_VERSION);
}

@SubscribeEvent
public static void onBuildContents(BuildCreativeModeTabContentsEvent event) {
public static void onRegisterCapabilities(final RegisterCapabilitiesEvent event) {
var blockItemHandler = Capabilities.ItemHandler.BLOCK;
event.registerBlockEntity(blockItemHandler,PROJECTOR_BLOCK_ENTITY.get(), ProjectorBlockEntity::getCapability);
}

@SubscribeEvent
public static void onBuildContents(final BuildCreativeModeTabContentsEvent event) {
var tabKey = BuiltInRegistries.CREATIVE_MODE_TAB.getResourceKey(event.getTab());
if (tabKey.isPresent() && CreativeModeTabs.TOOLS_AND_UTILITIES.equals(tabKey.get())) {
event.accept(PROJECTOR.get());
event.accept(SLIDE_ITEM.get());
event.accept(PROJECTOR_BLOCK.get());
}
}

}
18 changes: 14 additions & 4 deletions src/main/java/org/teacon/slides/SlideShow.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package org.teacon.slides;

import com.mojang.datafixers.util.Either;
import net.minecraft.FieldsAreNonnullByDefault;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.resources.ResourceLocation;
import net.neoforged.fml.common.Mod;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.teacon.slides.projector.ProjectorBlockEntity;
import org.teacon.slides.block.ProjectorBlockEntity;
import org.teacon.slides.url.ProjectorURL;

import javax.annotation.ParametersAreNonnullByDefault;
Expand All @@ -27,7 +29,7 @@ public final class SlideShow {

private static volatile Consumer<ProjectorBlockEntity> requestUrlPrefetch = Objects::hash;
private static volatile BiConsumer<Set<UUID>, Map<UUID, ProjectorURL>> applyPrefetch = Objects::hash;
private static volatile Function<ProjectorURL, ProjectorURL.Status> checkBlock = url -> ProjectorURL.Status.UNKNOWN;
private static volatile Function<Either<UUID, ProjectorURL>, ProjectorURL.Status> checkBlock = url -> ProjectorURL.Status.UNKNOWN;

public static void setRequestUrlPrefetch(Consumer<ProjectorBlockEntity> requestUrlPrefetch) {
SlideShow.requestUrlPrefetch = requestUrlPrefetch;
Expand All @@ -45,11 +47,19 @@ public static void applyPrefetch(Set<UUID> nonExistent, Map<UUID, ProjectorURL>
applyPrefetch.accept(nonExistent, existent);
}

public static void setCheckBlock(Function<ProjectorURL, ProjectorURL.Status> checkBlock) {
public static void setCheckBlock(Function<Either<UUID, ProjectorURL>, ProjectorURL.Status> checkBlock) {
SlideShow.checkBlock = checkBlock;
}

public static ProjectorURL.Status checkBlock(UUID uuid) {
return checkBlock.apply(Either.left(uuid));
}

public static ProjectorURL.Status checkBlock(ProjectorURL url) {
return checkBlock.apply(url);
return checkBlock.apply(Either.right(url));
}

public static ResourceLocation id(String path) {
return ResourceLocation.fromNamespaceAndPath(SlideShow.ID, path);
}
}
Loading

0 comments on commit f7f34b8

Please sign in to comment.