Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a dye modifier to the magic mirror #289

Open
wants to merge 3 commits into
base: 1.20.2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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));
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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());
}
}
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -10,6 +11,8 @@
import net.minecraft.world.entity.Entity;
import org.joml.Matrix4f;

import javax.annotation.Nullable;

/**
* Renderer for reflections in the mirror.
*/
Expand Down Expand Up @@ -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
Expand All @@ -62,20 +67,47 @@ 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;
}

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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand All @@ -27,15 +29,15 @@ 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<ItemStack> inventoryToSwap = ((Player) entity).getInventory().armor;

// Simply swap out the armor inventory twice
replacementArmor.swap(inventoryToSwap);

super.render(facing, partialTicks, renderTypeBuffer);
super.render(facing, partialTicks, renderTypeBuffer, colorize);

replacementArmor.swap(inventoryToSwap);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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<Holder<BannerPattern>, DyeColor> patternColor : patternColorList) {
float[] rgb = patternColor.getRight().getTextureDiffuseColors();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
* <p>
Expand All @@ -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<? extends Entity> 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);
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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);
}
}