diff --git a/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/MagicMirrorMod.java b/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/MagicMirrorMod.java index 8097bafd..88f40e7a 100644 --- a/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/MagicMirrorMod.java +++ b/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/MagicMirrorMod.java @@ -5,6 +5,7 @@ import com.tomboshoven.minecraft.magicmirror.blocks.modifiers.ArmorMagicMirrorModifier; import com.tomboshoven.minecraft.magicmirror.blocks.modifiers.BannerMagicMirrorModifier; import com.tomboshoven.minecraft.magicmirror.blocks.modifiers.CreatureMagicMirrorModifier; +import com.tomboshoven.minecraft.magicmirror.blocks.modifiers.DyeMagicMirrorModifier; import com.tomboshoven.minecraft.magicmirror.blocks.modifiers.MagicMirrorModifier; import com.tomboshoven.minecraft.magicmirror.client.ClientEvents; import com.tomboshoven.minecraft.magicmirror.commands.Commands; @@ -40,6 +41,7 @@ public MagicMirrorMod(IEventBus modEventBus) { MagicMirrorModifier.register(new ArmorMagicMirrorModifier()); MagicMirrorModifier.register(new BannerMagicMirrorModifier()); MagicMirrorModifier.register(new CreatureMagicMirrorModifier()); + MagicMirrorModifier.register(new DyeMagicMirrorModifier()); if (FMLEnvironment.dist == Dist.CLIENT) { ClientEvents.init(modEventBus); diff --git a/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/blocks/entities/modifiers/DyeMagicMirrorBlockEntityModifier.java b/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/blocks/entities/modifiers/DyeMagicMirrorBlockEntityModifier.java new file mode 100644 index 00000000..c3ac87c9 --- /dev/null +++ b/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/blocks/entities/modifiers/DyeMagicMirrorBlockEntityModifier.java @@ -0,0 +1,42 @@ +package com.tomboshoven.minecraft.magicmirror.blocks.entities.modifiers; + +import com.tomboshoven.minecraft.magicmirror.blocks.entities.MagicMirrorCoreBlockEntity; +import com.tomboshoven.minecraft.magicmirror.blocks.modifiers.MagicMirrorModifier; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.DyeItem; +import net.minecraft.world.item.ItemStack; + +public class DyeMagicMirrorBlockEntityModifier extends ItemBasedMagicMirrorBlockEntityModifier { + /** + * @param modifier The modifier that applied this object to the block entity. + */ + public DyeMagicMirrorBlockEntityModifier(MagicMirrorModifier modifier, ItemStack item) { + super(modifier, item); + } + + public DyeMagicMirrorBlockEntityModifier(MagicMirrorModifier modifier, CompoundTag nbt) { + super(modifier, nbt); + } + + @Override + public boolean tryPlayerActivate(MagicMirrorCoreBlockEntity blockEntity, Player playerIn, InteractionHand hand) { + // No behavior right now. + return false; + } + + /** + * @return the color of the dye that was used. + */ + public float[] getColor() { + float[] color; + if (item.getItem() instanceof DyeItem dyeItem) { + float[] textureDiffuseColors = dyeItem.getDyeColor().getTextureDiffuseColors(); + color = new float[]{textureDiffuseColors[0], textureDiffuseColors[1], textureDiffuseColors[2], 1f}; + } else { + color = new float[]{1f, 1f, 1f, 1f}; + } + return color; + } +} diff --git a/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/blocks/modifiers/DyeMagicMirrorModifier.java b/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/blocks/modifiers/DyeMagicMirrorModifier.java new file mode 100644 index 00000000..95dfacb9 --- /dev/null +++ b/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/blocks/modifiers/DyeMagicMirrorModifier.java @@ -0,0 +1,45 @@ +package com.tomboshoven.minecraft.magicmirror.blocks.modifiers; + +import com.tomboshoven.minecraft.magicmirror.blocks.entities.MagicMirrorCoreBlockEntity; +import com.tomboshoven.minecraft.magicmirror.blocks.entities.modifiers.DyeMagicMirrorBlockEntityModifier; +import com.tomboshoven.minecraft.magicmirror.blocks.entities.modifiers.MagicMirrorBlockEntityModifier; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.item.DyeItem; +import net.minecraft.world.item.ItemStack; + +/** + * A magic mirror modifier that dyes the reflected entity. + */ +public class DyeMagicMirrorModifier extends MagicMirrorModifier { + /** + * The name of the modifier. + * This should be stable as it gets written with save data. + */ + public static final String NAME = "dye"; + + @Override + public String getName() { + return NAME; + } + + @Override + public boolean canModify(ItemStack heldItem, MagicMirrorCoreBlockEntity blockEntity) { + // Must be activated using a dye item. + if (!(heldItem.getItem() instanceof DyeItem)) { + return false; + } + + // Must not have a dye modifier yet. + return !hasModifierOfType(blockEntity); + } + + @Override + MagicMirrorBlockEntityModifier createBlockEntityModifier(CompoundTag nbt) { + return new DyeMagicMirrorBlockEntityModifier(this, nbt); + } + + @Override + MagicMirrorBlockEntityModifier createBlockEntityModifier(ItemStack usedItem) { + return new DyeMagicMirrorBlockEntityModifier(this, usedItem.split(1)); + } +} diff --git a/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/modifiers/DyeReflectionModifier.java b/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/modifiers/DyeReflectionModifier.java new file mode 100644 index 00000000..f47fafb5 --- /dev/null +++ b/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/modifiers/DyeReflectionModifier.java @@ -0,0 +1,25 @@ +package com.tomboshoven.minecraft.magicmirror.client.reflection.modifiers; + +import com.tomboshoven.minecraft.magicmirror.blocks.entities.modifiers.DyeMagicMirrorBlockEntityModifier; +import com.tomboshoven.minecraft.magicmirror.blocks.entities.modifiers.MagicMirrorBlockEntityModifier; +import com.tomboshoven.minecraft.magicmirror.client.reflection.renderers.ReflectionRendererBase; +import com.tomboshoven.minecraft.magicmirror.client.reflection.renderers.modifiers.DyeReflectionRendererModifier; + +import java.util.stream.IntStream; + +/** + * A reflection modifier that changes the color of the rendered model. + */ +public class DyeReflectionModifier extends ReflectionModifier { + @Override + public ReflectionRendererBase apply(MagicMirrorBlockEntityModifier modifier, ReflectionRendererBase reflectionRenderer) { + if (modifier instanceof DyeMagicMirrorBlockEntityModifier dyeModifier) { + float[] color = dyeModifier.getColor(); + // Since this is essentially a color filter, we tend to get very dim colors. + // We can simply make them brighter for a nicer effect. + IntStream.range(0, 3).forEach(i -> color[i] *= 2); + return new DyeReflectionRendererModifier(reflectionRenderer, color); + } + return reflectionRenderer; + } +} diff --git a/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/modifiers/ReflectionModifiers.java b/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/modifiers/ReflectionModifiers.java index b9e7bf7f..38590e2e 100644 --- a/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/modifiers/ReflectionModifiers.java +++ b/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/modifiers/ReflectionModifiers.java @@ -3,6 +3,7 @@ import com.tomboshoven.minecraft.magicmirror.blocks.modifiers.ArmorMagicMirrorModifier; import com.tomboshoven.minecraft.magicmirror.blocks.modifiers.BannerMagicMirrorModifier; import com.tomboshoven.minecraft.magicmirror.blocks.modifiers.CreatureMagicMirrorModifier; +import com.tomboshoven.minecraft.magicmirror.blocks.modifiers.DyeMagicMirrorModifier; import java.util.HashMap; import java.util.Map; @@ -20,5 +21,6 @@ public class ReflectionModifiers { MODIFIERS.put(ArmorMagicMirrorModifier.NAME, new ArmorReflectionModifier()); MODIFIERS.put(BannerMagicMirrorModifier.NAME, new BannerReflectionModifier()); MODIFIERS.put(CreatureMagicMirrorModifier.NAME, new CreatureReflectionModifier()); + MODIFIERS.put(DyeMagicMirrorModifier.NAME, new DyeReflectionModifier()); } } diff --git a/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/renderers/ReflectionRenderer.java b/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/renderers/ReflectionRenderer.java index a4dbaa3d..3cbbb75c 100644 --- a/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/renderers/ReflectionRenderer.java +++ b/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/renderers/ReflectionRenderer.java @@ -1,5 +1,6 @@ package com.tomboshoven.minecraft.magicmirror.client.reflection.renderers; +import com.mojang.blaze3d.platform.Lighting; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexSorting; @@ -10,6 +11,8 @@ import net.minecraft.world.entity.Entity; import org.joml.Matrix4f; +import javax.annotation.Nullable; + /** * Renderer for reflections in the mirror. */ @@ -53,6 +56,8 @@ public void setUp() { RenderSystem.backupProjectionMatrix(); // Aspect is .5 to compensate for the rectangular mirror RenderSystem.setProjectionMatrix(new Matrix4f().setPerspective((float)(Math.PI / 2), .5f, .05f, 50f), VertexSorting.DISTANCE_TO_ORIGIN); + + Lighting.setupForEntityInInventory(); } @Override @@ -62,7 +67,7 @@ public void tearDown() { } @Override - public void render(float facing, float partialTicks, MultiBufferSource renderTypeBuffer) { + public void render(float facing, float partialTicks, MultiBufferSource.BufferSource renderTypeBuffer, @Nullable float[] colorize) { if (entityRenderer == null) { return; } @@ -70,12 +75,39 @@ public void render(float facing, float partialTicks, MultiBufferSource renderTyp PoseStack reflectionMatrixStack = new PoseStack(); // Head's up - reflectionMatrixStack.mulPose(Axis.XP.rotationDegrees(180)); + reflectionMatrixStack.mulPose(Axis.XP.rotation((float) Math.PI)); // Position within the frame reflectionMatrixStack.translate(0, -1, 1.5); // Face toward the front of the mirror reflectionMatrixStack.mulPose(Axis.YP.rotationDegrees(facing)); + if (colorize == null) { + // Skip the buffer manipulation + renderEntity(partialTicks, renderTypeBuffer, reflectionMatrixStack); + } else { + // Finish up what we already rendered because we'll change the shader color and want to make sure it only + // applies to the entity. + renderTypeBuffer.endBatch(); + float[] shaderColor = RenderSystem.getShaderColor().clone(); + RenderSystem.setShaderColor(colorize[0], colorize[1], colorize[2], colorize[3]); + renderEntity(partialTicks, renderTypeBuffer, reflectionMatrixStack); + // Now finish up this batch and reset the color + renderTypeBuffer.endBatch(); + RenderSystem.setShaderColor(shaderColor[0], shaderColor[1], shaderColor[2], shaderColor[3]); + } + } + + /** + * Perform the actual entity rendering. + * + * @param partialTicks The partial ticks, for smooth rendering. + * @param renderTypeBuffer The buffer to render to. + * @param reflectionMatrixStack The initialized matrix stack. + */ + private void renderEntity(float partialTicks, MultiBufferSource.BufferSource renderTypeBuffer, PoseStack reflectionMatrixStack) { + if (entityRenderer == null) { + return; + } // The typing of these classes works out a little weird, so instead of complicating things too much, let's go // with the unchecked cast. //noinspection unchecked diff --git a/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/renderers/ReflectionRendererBase.java b/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/renderers/ReflectionRendererBase.java index 9c6f87ef..3b75404f 100644 --- a/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/renderers/ReflectionRendererBase.java +++ b/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/renderers/ReflectionRendererBase.java @@ -4,6 +4,8 @@ import net.minecraft.client.renderer.entity.EntityRenderer; import net.minecraft.world.entity.Entity; +import javax.annotation.Nullable; + /** * Base class for reflection renderers. */ @@ -35,8 +37,21 @@ public abstract class ReflectionRendererBase { /** * Render the reflection. * - * @param facing The rotation (in degrees) for the entity that is being rendered. - * @param partialTicks The partial ticks, for smooth rendering. + * @param facing The rotation (in degrees) for the entity that is being rendered. + * @param partialTicks The partial ticks, for smooth rendering. + * @param renderTypeBuffer The buffer to render to. + * @param colorize If not null, render the entity in a specific color. + */ + public abstract void render(float facing, float partialTicks, MultiBufferSource.BufferSource renderTypeBuffer, @Nullable float[] colorize); + + /** + * Render the reflection. + * + * @param facing The rotation (in degrees) for the entity that is being rendered. + * @param partialTicks The partial ticks, for smooth rendering. + * @param renderTypeBuffer The buffer to render to. */ - public abstract void render(float facing, float partialTicks, MultiBufferSource renderTypeBuffer); + public void render(float facing, float partialTicks, MultiBufferSource.BufferSource renderTypeBuffer) { + render(facing, partialTicks, renderTypeBuffer, null); + } } diff --git a/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/renderers/modifiers/ArmorReflectionRendererModifier.java b/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/renderers/modifiers/ArmorReflectionRendererModifier.java index 1faa73d1..f60d28b8 100644 --- a/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/renderers/modifiers/ArmorReflectionRendererModifier.java +++ b/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/renderers/modifiers/ArmorReflectionRendererModifier.java @@ -8,6 +8,8 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; +import javax.annotation.Nullable; + /** * A modifier for a reflection renderer which replaces the armor that is worn by the reflected entity. */ @@ -27,7 +29,7 @@ public ArmorReflectionRendererModifier(ReflectionRendererBase baseRenderer, Repl } @Override - public void render(float facing, float partialTicks, MultiBufferSource renderTypeBuffer) { + public void render(float facing, float partialTicks, MultiBufferSource.BufferSource renderTypeBuffer, @Nullable float[] colorize) { Entity entity = getEntity(); if (entity instanceof Player) { NonNullList inventoryToSwap = ((Player) entity).getInventory().armor; @@ -35,7 +37,7 @@ public void render(float facing, float partialTicks, MultiBufferSource renderTyp // Simply swap out the armor inventory twice replacementArmor.swap(inventoryToSwap); - super.render(facing, partialTicks, renderTypeBuffer); + super.render(facing, partialTicks, renderTypeBuffer, colorize); replacementArmor.swap(inventoryToSwap); } diff --git a/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/renderers/modifiers/BannerReflectionRendererModifier.java b/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/renderers/modifiers/BannerReflectionRendererModifier.java index 77894df4..b8acc754 100644 --- a/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/renderers/modifiers/BannerReflectionRendererModifier.java +++ b/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/renderers/modifiers/BannerReflectionRendererModifier.java @@ -14,6 +14,7 @@ import net.minecraft.world.level.block.entity.BannerPattern; import org.apache.commons.lang3.tuple.Pair; +import javax.annotation.Nullable; import java.util.Collection; import java.util.Optional; @@ -36,8 +37,8 @@ public BannerReflectionRendererModifier(ReflectionRendererBase baseRenderer, Col } @Override - public void render(float facing, float partialTicks, MultiBufferSource renderTypeBuffer) { - super.render(facing, partialTicks, renderTypeBuffer); + public void render(float facing, float partialTicks, MultiBufferSource.BufferSource renderTypeBuffer, @Nullable float[] colorize) { + super.render(facing, partialTicks, renderTypeBuffer, colorize); for (Pair, DyeColor> patternColor : patternColorList) { float[] rgb = patternColor.getRight().getTextureDiffuseColors(); diff --git a/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/renderers/modifiers/CreatureReflectionRendererModifier.java b/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/renderers/modifiers/CreatureReflectionRendererModifier.java index a4dd7016..bfd8a52c 100644 --- a/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/renderers/modifiers/CreatureReflectionRendererModifier.java +++ b/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/renderers/modifiers/CreatureReflectionRendererModifier.java @@ -7,6 +7,8 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; +import javax.annotation.Nullable; + /** * Reflection renderer modifier that replaces the rendered entity by a different one. *

@@ -24,13 +26,13 @@ public CreatureReflectionRendererModifier(ReflectionRendererBase baseRenderer, E } @Override - public void render(float facing, float partialTicks, MultiBufferSource renderTypeBuffer) { + public void render(float facing, float partialTicks, MultiBufferSource.BufferSource renderTypeBuffer, @Nullable float[] colorize) { EntityRenderer originalRenderer = getRenderer(); EntityRenderer replacementRenderer = OffModelPlayerRenderers.getInstance().get(entityType); if (replacementRenderer != null) { setRenderer(replacementRenderer); } - super.render(facing, partialTicks, renderTypeBuffer); + super.render(facing, partialTicks, renderTypeBuffer, colorize); setRenderer(originalRenderer); } } diff --git a/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/renderers/modifiers/DyeReflectionRendererModifier.java b/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/renderers/modifiers/DyeReflectionRendererModifier.java new file mode 100644 index 00000000..444c7f56 --- /dev/null +++ b/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/renderers/modifiers/DyeReflectionRendererModifier.java @@ -0,0 +1,30 @@ +package com.tomboshoven.minecraft.magicmirror.client.reflection.renderers.modifiers; + +import com.tomboshoven.minecraft.magicmirror.client.reflection.renderers.ReflectionRendererBase; +import net.minecraft.client.renderer.MultiBufferSource; + +import javax.annotation.Nullable; + +/** + * A modifier for a reflection renderer which colorizes the reflected entity. + */ +public class DyeReflectionRendererModifier extends ReflectionRendererModifier { + /** + * The color for the reflection. + */ + protected final float[] color; + + /** + * @param baseRenderer The renderer that is being proxied. + * @param color The color (RGBA) for the reflected entity. + */ + public DyeReflectionRendererModifier(ReflectionRendererBase baseRenderer, float[] color) { + super(baseRenderer); + this.color = color; + } + + @Override + public void render(float facing, float partialTicks, MultiBufferSource.BufferSource renderTypeBuffer, @Nullable float[] colorize) { + super.render(facing, partialTicks, renderTypeBuffer, color); + } +} diff --git a/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/renderers/modifiers/ReflectionRendererModifier.java b/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/renderers/modifiers/ReflectionRendererModifier.java index 8dbcb8dd..9d7e7c56 100644 --- a/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/renderers/modifiers/ReflectionRendererModifier.java +++ b/MagicMirror/src/main/java/com/tomboshoven/minecraft/magicmirror/client/reflection/renderers/modifiers/ReflectionRendererModifier.java @@ -5,6 +5,8 @@ import net.minecraft.client.renderer.entity.EntityRenderer; import net.minecraft.world.entity.Entity; +import javax.annotation.Nullable; + /** * Modifier for how the reflection is rendered. * Contains some basic functionality for overriding part of the rendering behavior. @@ -48,7 +50,7 @@ public void tearDown() { } @Override - public void render(float facing, float partialTicks, MultiBufferSource renderTypeBuffer) { - baseRenderer.render(facing, partialTicks, renderTypeBuffer); + public void render(float facing, float partialTicks, MultiBufferSource.BufferSource renderTypeBuffer, @Nullable float[] colorize) { + baseRenderer.render(facing, partialTicks, renderTypeBuffer, colorize); } }