mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 23:27:59 +01:00
Separate wing and amulet rendering and give the wings of icarus their own texture
This commit is contained in:
parent
0221451543
commit
f8e19cc17a
6 changed files with 145 additions and 98 deletions
|
@ -15,6 +15,7 @@ import com.minelittlepony.unicopia.client.render.AccessoryFeatureRenderer;
|
||||||
import com.minelittlepony.unicopia.client.render.AmuletFeatureRenderer;
|
import com.minelittlepony.unicopia.client.render.AmuletFeatureRenderer;
|
||||||
import com.minelittlepony.unicopia.client.render.BraceletFeatureRenderer;
|
import com.minelittlepony.unicopia.client.render.BraceletFeatureRenderer;
|
||||||
import com.minelittlepony.unicopia.client.render.FloatingArtefactEntityRenderer;
|
import com.minelittlepony.unicopia.client.render.FloatingArtefactEntityRenderer;
|
||||||
|
import com.minelittlepony.unicopia.client.render.WingsFeatureRenderer;
|
||||||
import com.minelittlepony.unicopia.item.ChameleonItem;
|
import com.minelittlepony.unicopia.item.ChameleonItem;
|
||||||
import com.minelittlepony.unicopia.item.UItems;
|
import com.minelittlepony.unicopia.item.UItems;
|
||||||
import com.minelittlepony.unicopia.particle.UParticles;
|
import com.minelittlepony.unicopia.particle.UParticles;
|
||||||
|
@ -51,6 +52,7 @@ public interface URenderers {
|
||||||
|
|
||||||
AccessoryFeatureRenderer.register(BraceletFeatureRenderer::new);
|
AccessoryFeatureRenderer.register(BraceletFeatureRenderer::new);
|
||||||
AccessoryFeatureRenderer.register(AmuletFeatureRenderer::new);
|
AccessoryFeatureRenderer.register(AmuletFeatureRenderer::new);
|
||||||
|
AccessoryFeatureRenderer.register(WingsFeatureRenderer::new);
|
||||||
|
|
||||||
EntityRendererRegistry.INSTANCE.register(UEntities.THROWN_ITEM, (manager, context) -> new FlyingItemEntityRenderer<>(manager, context.getItemRenderer()));
|
EntityRendererRegistry.INSTANCE.register(UEntities.THROWN_ITEM, (manager, context) -> new FlyingItemEntityRenderer<>(manager, context.getItemRenderer()));
|
||||||
EntityRendererRegistry.INSTANCE.register(UEntities.FLOATING_ARTEFACT, FloatingArtefactEntityRenderer::new);
|
EntityRendererRegistry.INSTANCE.register(UEntities.FLOATING_ARTEFACT, FloatingArtefactEntityRenderer::new);
|
||||||
|
|
|
@ -3,10 +3,7 @@ package com.minelittlepony.unicopia.client.render;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
|
||||||
import com.minelittlepony.unicopia.item.AmuletItem;
|
import com.minelittlepony.unicopia.item.AmuletItem;
|
||||||
import com.minelittlepony.unicopia.item.UItems;
|
|
||||||
|
|
||||||
import net.minecraft.client.model.Model;
|
import net.minecraft.client.model.Model;
|
||||||
import net.minecraft.client.model.ModelPart;
|
import net.minecraft.client.model.ModelPart;
|
||||||
import net.minecraft.client.render.OverlayTexture;
|
import net.minecraft.client.render.OverlayTexture;
|
||||||
|
@ -19,15 +16,13 @@ import net.minecraft.client.render.item.ItemRenderer;
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
import net.minecraft.entity.EquipmentSlot;
|
import net.minecraft.entity.EquipmentSlot;
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
|
||||||
import net.minecraft.item.Item;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.util.registry.Registry;
|
||||||
|
|
||||||
public class AmuletFeatureRenderer<E extends LivingEntity> implements AccessoryFeatureRenderer.Feature<E> {
|
public class AmuletFeatureRenderer<E extends LivingEntity> implements AccessoryFeatureRenderer.Feature<E> {
|
||||||
|
|
||||||
private final BraceletModel model = new BraceletModel(0.3F);
|
private final AmuletModel model = new AmuletModel(0.3F);
|
||||||
|
|
||||||
private final Map<Identifier, Identifier> textures = new HashMap<>();
|
private final Map<Identifier, Identifier> textures = new HashMap<>();
|
||||||
|
|
||||||
|
@ -41,121 +36,35 @@ public class AmuletFeatureRenderer<E extends LivingEntity> implements AccessoryF
|
||||||
public void render(MatrixStack matrices, VertexConsumerProvider renderContext, int lightUv, E entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch) {
|
public void render(MatrixStack matrices, VertexConsumerProvider renderContext, int lightUv, E entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch) {
|
||||||
|
|
||||||
ItemStack stack = entity.getEquippedStack(EquipmentSlot.CHEST);
|
ItemStack stack = entity.getEquippedStack(EquipmentSlot.CHEST);
|
||||||
Item item = stack.getItem();
|
|
||||||
|
|
||||||
boolean amulet = item instanceof AmuletItem;
|
if (stack.getItem() instanceof AmuletItem) {
|
||||||
boolean wings =
|
Identifier texture = textures.computeIfAbsent(Registry.ITEM.getId(stack.getItem()), id -> new Identifier(id.getNamespace(), "textures/models/armor/" + id.getPath() + ".png"));
|
||||||
(amulet && ((AmuletItem)item).isApplicable(stack))
|
|
||||||
|| (entity instanceof PlayerEntity && Pony.of((PlayerEntity)entity).getSpecies().canInteractWithClouds());
|
|
||||||
|
|
||||||
if (wings || amulet) {
|
|
||||||
Identifier texture = textures.computeIfAbsent(Registry.ITEM.getId(amulet ? item : UItems.PEGASUS_AMULET), id -> new Identifier(id.getNamespace(), "textures/models/armor/" + id.getPath() + ".png"));
|
|
||||||
|
|
||||||
VertexConsumer consumer = ItemRenderer.getArmorGlintConsumer(renderContext, RenderLayer.getArmorCutoutNoCull(texture), false, false);
|
VertexConsumer consumer = ItemRenderer.getArmorGlintConsumer(renderContext, RenderLayer.getArmorCutoutNoCull(texture), false, false);
|
||||||
|
|
||||||
model.setVisible(amulet, wings);
|
|
||||||
model.setAngles(entity, context.getModel());
|
model.setAngles(entity, context.getModel());
|
||||||
model.render(matrices, consumer, lightUv, OverlayTexture.DEFAULT_UV, 1, 1, 1, 1);
|
model.render(matrices, consumer, lightUv, OverlayTexture.DEFAULT_UV, 1, 1, 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class BraceletModel extends Model {
|
static class AmuletModel extends Model {
|
||||||
|
|
||||||
private final ModelPart torso;
|
private final ModelPart torso;
|
||||||
private final ModelPart amulet;
|
|
||||||
|
|
||||||
private final Wing[] wings;
|
public AmuletModel(float dilate) {
|
||||||
|
|
||||||
public BraceletModel(float dilate) {
|
|
||||||
super(RenderLayer::getEntityTranslucent);
|
super(RenderLayer::getEntityTranslucent);
|
||||||
torso = new ModelPart(this, 0, 0);
|
torso = new ModelPart(this, 0, 0);
|
||||||
amulet = new ModelPart(this, 0, 0);
|
torso.addCuboid(-4, 0, -2, 8, 12, 4, dilate);
|
||||||
amulet.addCuboid(-4, 0, -2, 8, 12, 4, dilate);
|
torso.setPivot(0, 0, 0);
|
||||||
amulet.setPivot(0, 0, 0);
|
|
||||||
torso.addChild(amulet);
|
|
||||||
wings = new Wing[] {
|
|
||||||
new Wing(this, torso, -1),
|
|
||||||
new Wing(this, torso, 1)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVisible(boolean amulet, boolean wings) {
|
|
||||||
this.amulet.visible = amulet;
|
|
||||||
for (Wing wing : this.wings) {
|
|
||||||
wing.base.visible = wings;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAngles(LivingEntity entity, BipedEntityModel<?> biped) {
|
public void setAngles(LivingEntity entity, BipedEntityModel<?> biped) {
|
||||||
torso.copyPositionAndRotation(biped.torso);
|
torso.copyPositionAndRotation(biped.torso);
|
||||||
for (Wing wing : wings) {
|
|
||||||
wing.setAngles(entity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(MatrixStack matrices, VertexConsumer vertexConsumer, int i, int j, float f, float g, float h, float k) {
|
public void render(MatrixStack matrices, VertexConsumer vertexConsumer, int i, int j, float f, float g, float h, float k) {
|
||||||
torso.render(matrices, vertexConsumer, i, j, f, g, h, k);
|
torso.render(matrices, vertexConsumer, i, j, f, g, h, k);
|
||||||
}
|
}
|
||||||
|
|
||||||
static class Wing {
|
|
||||||
ModelPart base;
|
|
||||||
|
|
||||||
ModelPart[] feathers;
|
|
||||||
|
|
||||||
int k;
|
|
||||||
|
|
||||||
Wing(Model model, ModelPart torso, int k) {
|
|
||||||
this.k = k;
|
|
||||||
base = new ModelPart(model, 0, 16);
|
|
||||||
|
|
||||||
base.setPivot(k * 2, 2, 2 + k * 0.5F);
|
|
||||||
base.addCuboid(0, 0, 0, 2, 10, 2);
|
|
||||||
|
|
||||||
feathers = new ModelPart[8];
|
|
||||||
|
|
||||||
for (int i = 0; i < feathers.length; i++) {
|
|
||||||
int texX = (i % 2) * 8;
|
|
||||||
|
|
||||||
ModelPart feather = new ModelPart(model, 24 + texX, 0);
|
|
||||||
feather.setPivot(0, 9, 0);
|
|
||||||
|
|
||||||
int featherLength = 21 - i * 2;
|
|
||||||
|
|
||||||
feather.addCuboid(-k * (i % 2) / 90F, 0, 0, 2, featherLength, 2);
|
|
||||||
|
|
||||||
base.addChild(feather);
|
|
||||||
feathers[i] = feather;
|
|
||||||
}
|
|
||||||
|
|
||||||
torso.addChild(base);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setAngles(LivingEntity entity) {
|
|
||||||
if (entity instanceof PlayerEntity) {
|
|
||||||
Pony pony = Pony.of((PlayerEntity)entity);
|
|
||||||
|
|
||||||
float spreadAmount = pony.getMotion().getWingAngle();
|
|
||||||
|
|
||||||
base.pitch = 1.5F + 0.8F - spreadAmount / 9F;
|
|
||||||
base.yaw = k * (0.8F + spreadAmount / 3F);
|
|
||||||
|
|
||||||
spreadAmount /= 7F;
|
|
||||||
|
|
||||||
final float ratio = 4F;
|
|
||||||
|
|
||||||
for (int i = 0; i < feathers.length; i++) {
|
|
||||||
|
|
||||||
float spread = i/ratio + 1.5F;
|
|
||||||
spread -= spreadAmount * ratio;
|
|
||||||
spread += spreadAmount * i / ratio;
|
|
||||||
|
|
||||||
feathers[i].pitch = -spread;
|
|
||||||
feathers[i].yaw = k * 0.3F;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,136 @@
|
||||||
|
package com.minelittlepony.unicopia.client.render;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
|
import com.minelittlepony.unicopia.item.UItems;
|
||||||
|
|
||||||
|
import net.minecraft.client.model.Model;
|
||||||
|
import net.minecraft.client.model.ModelPart;
|
||||||
|
import net.minecraft.client.render.OverlayTexture;
|
||||||
|
import net.minecraft.client.render.RenderLayer;
|
||||||
|
import net.minecraft.client.render.VertexConsumer;
|
||||||
|
import net.minecraft.client.render.VertexConsumerProvider;
|
||||||
|
import net.minecraft.client.render.entity.feature.FeatureRendererContext;
|
||||||
|
import net.minecraft.client.render.entity.model.BipedEntityModel;
|
||||||
|
import net.minecraft.client.render.item.ItemRenderer;
|
||||||
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
public class WingsFeatureRenderer<E extends LivingEntity> implements AccessoryFeatureRenderer.Feature<E> {
|
||||||
|
|
||||||
|
private static final Identifier ICARUS_WINGS = new Identifier("unicopia", "textures/models/wings/icarus.png");
|
||||||
|
private static final Identifier PEGASUS_WINGS = new Identifier("unicopia", "textures/models/wings/pegasus.png");
|
||||||
|
|
||||||
|
private final WingsModel model = new WingsModel();
|
||||||
|
|
||||||
|
private final FeatureRendererContext<E, ? extends BipedEntityModel<E>> context;
|
||||||
|
|
||||||
|
public WingsFeatureRenderer(FeatureRendererContext<E, ? extends BipedEntityModel<E>> context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(MatrixStack matrices, VertexConsumerProvider renderContext, int lightUv, E entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch) {
|
||||||
|
|
||||||
|
boolean pegasus = (entity instanceof PlayerEntity && Pony.of((PlayerEntity)entity).getSpecies().canInteractWithClouds());
|
||||||
|
boolean icarus = UItems.PEGASUS_AMULET.isApplicable(entity);
|
||||||
|
|
||||||
|
if (icarus || pegasus) {
|
||||||
|
Identifier texture = pegasus ? PEGASUS_WINGS : ICARUS_WINGS;
|
||||||
|
VertexConsumer consumer = ItemRenderer.getArmorGlintConsumer(renderContext, RenderLayer.getEntityTranslucent(texture), false, false);
|
||||||
|
|
||||||
|
model.setAngles(entity, context.getModel());
|
||||||
|
model.render(matrices, consumer, lightUv, OverlayTexture.DEFAULT_UV, 1, 1, 1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class WingsModel extends Model {
|
||||||
|
|
||||||
|
private final ModelPart root;
|
||||||
|
private final Wing[] wings;
|
||||||
|
|
||||||
|
public WingsModel() {
|
||||||
|
super(RenderLayer::getEntityTranslucent);
|
||||||
|
this.textureHeight = 23;
|
||||||
|
this.textureWidth = 24;
|
||||||
|
root = new ModelPart(this, 0, 0);
|
||||||
|
wings = new Wing[] {
|
||||||
|
new Wing(this, root, -1),
|
||||||
|
new Wing(this, root, 1)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAngles(LivingEntity entity, BipedEntityModel<?> biped) {
|
||||||
|
root.copyPositionAndRotation(biped.torso);
|
||||||
|
for (Wing wing : wings) {
|
||||||
|
wing.setAngles(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(MatrixStack matrices, VertexConsumer vertexConsumer, int i, int j, float f, float g, float h, float k) {
|
||||||
|
root.render(matrices, vertexConsumer, i, j, f, g, h, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Wing {
|
||||||
|
ModelPart base;
|
||||||
|
|
||||||
|
ModelPart[] feathers;
|
||||||
|
|
||||||
|
int k;
|
||||||
|
|
||||||
|
Wing(Model model, ModelPart torso, int k) {
|
||||||
|
this.k = k;
|
||||||
|
base = new ModelPart(model, 0, 0);
|
||||||
|
|
||||||
|
base.setPivot(k * 2, 2, 2 + k * 0.5F);
|
||||||
|
base.addCuboid(0, 0, 0, 2, 10, 2);
|
||||||
|
|
||||||
|
feathers = new ModelPart[8];
|
||||||
|
|
||||||
|
for (int i = 0; i < feathers.length; i++) {
|
||||||
|
int texX = (i % 2) * 8;
|
||||||
|
|
||||||
|
ModelPart feather = new ModelPart(model, 8 + texX, 0);
|
||||||
|
feather.setPivot(0, 9, 0);
|
||||||
|
|
||||||
|
int featherLength = 21 - i * 2;
|
||||||
|
|
||||||
|
feather.addCuboid(-k * (i % 2) / 90F, 0, 0, 2, featherLength, 2);
|
||||||
|
|
||||||
|
base.addChild(feather);
|
||||||
|
feathers[i] = feather;
|
||||||
|
}
|
||||||
|
|
||||||
|
torso.addChild(base);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAngles(LivingEntity entity) {
|
||||||
|
if (entity instanceof PlayerEntity) {
|
||||||
|
Pony pony = Pony.of((PlayerEntity)entity);
|
||||||
|
|
||||||
|
float spreadAmount = pony.getMotion().getWingAngle();
|
||||||
|
|
||||||
|
base.pitch = 1.5F + 0.8F - spreadAmount / 9F;
|
||||||
|
base.yaw = k * (0.8F + spreadAmount / 3F);
|
||||||
|
|
||||||
|
spreadAmount /= 7F;
|
||||||
|
|
||||||
|
final float ratio = 4F;
|
||||||
|
|
||||||
|
for (int i = 0; i < feathers.length; i++) {
|
||||||
|
|
||||||
|
float spread = i/ratio + 1.5F;
|
||||||
|
spread -= spreadAmount * ratio;
|
||||||
|
spread += spreadAmount * i / ratio;
|
||||||
|
|
||||||
|
feathers[i].pitch = -spread;
|
||||||
|
feathers[i].yaw = k * 0.3F;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.3 KiB |
Binary file not shown.
After Width: | Height: | Size: 983 B |
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
Loading…
Reference in a new issue