First person magic (#56)

* Unicorns now levitate their items in first person

* Move the levitating item renderer out of being a singleton and add handling for bows and other special actions
This commit is contained in:
Sollace 2018-05-26 23:37:50 +02:00 committed by Matthew Messinger
parent a0648d3526
commit 1e73c5d2bf
6 changed files with 189 additions and 53 deletions

View file

@ -7,6 +7,7 @@ import com.minelittlepony.mixin.MixinRenderManager;
import com.minelittlepony.hdskins.gui.EntityPonyModel;
import com.minelittlepony.hdskins.gui.RenderPonyModel;
import com.minelittlepony.model.player.PlayerModels;
import com.minelittlepony.render.LevitatingItemRenderer;
import com.minelittlepony.render.player.RenderPonyPlayer;
import com.minelittlepony.render.ponies.RenderPonyIllager;
import com.minelittlepony.render.ponies.RenderPonyPigman;
@ -42,6 +43,9 @@ import net.minecraft.entity.passive.EntityVillager;
*/
public class PonyRenderManager {
private LevitatingItemRenderer magicRenderer = new LevitatingItemRenderer();
private final Map<Class<? extends Entity>, Render<?>> renderMap = Maps.newHashMap();
/**
@ -149,4 +153,8 @@ public class PonyRenderManager {
ModUtilities.addRenderer(type, (Render<T>)renderMap.get(type));
}
}
public LevitatingItemRenderer getMagicRenderer() {
return magicRenderer;
}
}

View file

@ -0,0 +1,32 @@
package com.minelittlepony.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import com.minelittlepony.MineLittlePony;
import net.minecraft.client.entity.AbstractClientPlayer;
import net.minecraft.client.renderer.ItemRenderer;
import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.ItemStack;
@Mixin(ItemRenderer.class)
public class MixinItemRenderer {
private static final String AbstractClientPlayer = "Lnet/minecraft/client/entity/AbstractClientPlayer;";
private static final String ItemStack = "Lnet/minecraft/item/ItemStack;";
private static final String EnumHand = "Lnet/minecraft/util/EnumHand;";
private static final String EntityLivingBase = "Lnet/minecraft/entity/EntityLivingBase;";
private static final String TransformType = "Lnet/minecraft/client/renderer/block/model/ItemCameraTransforms$TransformType;";
//public void renderItemInFirstPerson(AbstractClientPlayer player, float p_187457_2_, float p_187457_3_, EnumHand hand, float p_187457_5_, ItemStack stack, float p_187457_7_)
//public void renderItemSide(EntityLivingBase entitylivingbaseIn, ItemStack heldStack, ItemCameraTransforms.TransformType transform, boolean leftHanded)
@Redirect(method = "renderItemInFirstPerson(" + AbstractClientPlayer + "FF" + EnumHand + "F" + ItemStack + "F)V",
at = @At(value = "INVOKE",
target = "Lnet/minecraft/client/renderer/ItemRenderer;renderItemSide(" + EntityLivingBase + ItemStack + TransformType + ")V"))
private void redirectRenderItemSide(ItemRenderer self, EntityLivingBase entity, ItemStack stack, TransformType transform, boolean left) {
MineLittlePony.getInstance().getRenderManager().getMagicRenderer().renderItemInFirstPerson(self, (AbstractClientPlayer)entity, stack, transform, left);
}
}

View file

@ -0,0 +1,142 @@
package com.minelittlepony.render;
import org.lwjgl.opengl.GL14;
import com.minelittlepony.MineLittlePony;
import com.minelittlepony.ducks.IRenderItem;
import com.minelittlepony.pony.data.Pony;
import com.minelittlepony.util.coordinates.Color;
import com.mumfrey.liteloader.client.overlays.IMinecraft;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.AbstractClientPlayer;
import net.minecraft.client.renderer.ItemRenderer;
import net.minecraft.client.renderer.RenderItem;
import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.EnumAction;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHandSide;
import static net.minecraft.client.renderer.GlStateManager.*;
public class LevitatingItemRenderer {
/**
* Renders a magical overlay over an item in third person.
*/
public void renderItemGlow(EntityLivingBase entity, ItemStack drop, TransformType transform, EnumHandSide hand, int glowColor) {
// enchantments mess up the rendering
drop = stackWithoutEnchantment(drop);
pushMatrix();
disableLighting();
setColor(glowColor);
RenderItem renderItem = Minecraft.getMinecraft().getRenderItem();
((IRenderItem) renderItem).useTransparency(true);
scale(1.1, 1.1, 1.1);
translate(0, 0.01F, 0.01F);
renderItem.renderItem(drop, entity, transform, hand == EnumHandSide.LEFT);
translate(0.01F, -0.01F, -0.02F);
renderItem.renderItem(drop, entity, transform, hand == EnumHandSide.LEFT);
((IRenderItem) renderItem).useTransparency(false);
unsetColor();
enableLighting();
popMatrix();
// I hate rendering
}
private void setColor(int glowColor) {
GL14.glBlendColor(Color.r(glowColor), Color.g(glowColor), Color.b(glowColor), 0.2F);
}
private void unsetColor() {
GL14.glBlendColor(255, 255, 255, 1);
}
/**
* Renders an item in first person optionally with a magical overlay.
*/
public void renderItemInFirstPerson(ItemRenderer renderer, AbstractClientPlayer entity, ItemStack stack, TransformType transform, boolean left) {
Pony pony = MineLittlePony.getInstance().getManager().getPony(entity);
pushMatrix();
boolean doMagic = pony.getMetadata().hasMagic();
if (doMagic) {
setupPerspective(entity, stack, left);
}
renderer.renderItemSide(entity, stack, transform, left);
if (doMagic) {
disableLighting();
IRenderItem renderItem = (IRenderItem)Minecraft.getMinecraft().getRenderItem();
renderItem.useTransparency(true);
setColor(pony.getMetadata().getGlowColor());
scale(1.1, 1.1, 1.1);
translate(0, 0.01F, 0.01F);
renderer.renderItemSide(entity, stack, transform, left);
translate(0.01F, -0.01F, -0.02F);
renderer.renderItemSide(entity, stack, transform, left);
renderItem.useTransparency(false);
unsetColor();
enableLighting();
}
popMatrix();
// I hate rendering
}
/**
* Moves held items to look like they're floating in the player's field.
*/
private void setupPerspective(EntityLivingBase entity, ItemStack stack, boolean left) {
EnumAction action = stack.getItemUseAction();
boolean doNormal = entity.getItemInUseCount() <= 0 || action == EnumAction.NONE;
boolean doBow = doNormal && stack.getItemUseAction() == EnumAction.BOW;
if (doNormal) { // eating, blocking, and drinking are not transformed. Only held items.
float ticks = ((IMinecraft)Minecraft.getMinecraft()).getTimer().elapsedPartialTicks - entity.ticksExisted;
float floatAmount = (float)Math.sin(ticks / 9) / 40;
float driftAmount = (float)Math.cos(ticks / 10) / 40;
translate(driftAmount - floatAmount / 4, floatAmount, doBow ? -0.3F : -0.6F);
if (!doBow) { // bows have to point forwards
if (left) {
rotate(-60, 0, 1, 0);
rotate(30, 0, 0, 1);
} else {
rotate(60, 0, 1, 0);
rotate(-30, 0, 0, 1);
}
}
}
}
private ItemStack stackWithoutEnchantment(ItemStack original) {
if (original.isItemEnchanted()) {
original = original.copy();
original.getTagCompound().removeTag("ench");
}
return original;
}
}

View file

@ -1,7 +1,8 @@
package com.minelittlepony.render.layer;
import com.minelittlepony.model.AbstractPonyModel;
import com.minelittlepony.model.BodyPart;
import com.minelittlepony.model.capabilities.IModel;
import net.minecraft.client.Minecraft;
import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelBiped;
@ -34,8 +35,8 @@ public class LayerHeldPonyItem<T extends EntityLivingBase> extends AbstractPonyL
ModelBase model = getRenderer().getMainModel();
pushMatrix();
if (model instanceof AbstractPonyModel) {
((AbstractPonyModel) model).transform(BodyPart.LEGS);
if (model instanceof IModel) {
((IModel) model).transform(BodyPart.LEGS);
}
if (model.isChild) {

View file

@ -1,21 +1,8 @@
package com.minelittlepony.render.layer;
import static net.minecraft.client.renderer.GlStateManager.disableLighting;
import static net.minecraft.client.renderer.GlStateManager.enableLighting;
import static net.minecraft.client.renderer.GlStateManager.popMatrix;
import static net.minecraft.client.renderer.GlStateManager.pushMatrix;
import static net.minecraft.client.renderer.GlStateManager.scale;
import static net.minecraft.client.renderer.GlStateManager.translate;
import org.lwjgl.opengl.GL14;
import com.minelittlepony.ducks.IRenderItem;
import com.minelittlepony.MineLittlePony;
import com.minelittlepony.model.capabilities.IModelUnicorn;
import com.minelittlepony.util.coordinates.Color;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.RenderItem;
import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType;
import net.minecraft.client.renderer.entity.RenderLivingBase;
import net.minecraft.entity.EntityLivingBase;
@ -44,7 +31,7 @@ public class LayerHeldPonyItemMagical<T extends EntityLivingBase> extends LayerH
@Override
protected void postItemRender(T entity, ItemStack drop, TransformType transform, EnumHandSide hand) {
if (isUnicorn()) {
renderItemGlow(entity, drop, transform, hand, this.<IModelUnicorn>getPonyModel().getMagicColor());
MineLittlePony.getInstance().getRenderManager().getMagicRenderer().renderItemGlow(entity, drop, transform, hand, this.<IModelUnicorn>getPonyModel().getMagicColor());
}
}
@ -56,39 +43,4 @@ public class LayerHeldPonyItemMagical<T extends EntityLivingBase> extends LayerH
super.renderArm(side);
}
}
public void renderItemGlow(T entity, ItemStack drop, TransformType transform, EnumHandSide hand, int glowColor) {
// enchantments mess up the rendering
drop = stackWithoutEnchantment(drop);
pushMatrix();
disableLighting();
GL14.glBlendColor(Color.r(glowColor), Color.g(glowColor), Color.b(glowColor), 0.2F);
RenderItem renderItem = Minecraft.getMinecraft().getRenderItem();
((IRenderItem) renderItem).useTransparency(true);
scale(1.1, 1.1, 1.1);
translate(0, 0.01F, 0.01F);
renderItem.renderItem(drop, entity, transform, hand == EnumHandSide.LEFT);
translate(0.01F, -0.01F, -0.02F);
renderItem.renderItem(drop, entity, transform, hand == EnumHandSide.LEFT);
((IRenderItem) renderItem).useTransparency(false);
enableLighting();
popMatrix();
// I hate rendering
}
private ItemStack stackWithoutEnchantment(ItemStack original) {
if (original.isItemEnchanted()) {
original = original.copy();
original.getTagCompound().removeTag("ench");
}
return original;
}
}

View file

@ -8,6 +8,7 @@
"MixinThreadDownloadImageData",
"MixinNetworkPlayerInfo",
"MixinRenderItem",
"MixinItemRenderer",
"MixinRenderManager"
]
}