Added a visual effect to entities spawned by the necromancy spell

This commit is contained in:
Sollace 2021-12-30 22:44:46 +02:00
parent 26fb68d50f
commit 117bbd797a
4 changed files with 154 additions and 18 deletions

View file

@ -0,0 +1,120 @@
package com.minelittlepony.unicopia.client.render;
import net.minecraft.client.render.VertexConsumer;
public class PassThroughVertexConsumer implements VertexConsumer {
private static final ColorFix COLOR = VertexConsumer::color;
private static final FUvFix TEXTURE = VertexConsumer::texture;
private static final IUvFix OVERLAY = VertexConsumer::overlay;
private static final IUvFix LIGHT = VertexConsumer::light;
private final VertexConsumer parent;
private final ColorFix colorFix;
private final FUvFix textureFix;
private final IUvFix overlayFix;
private final IUvFix lightFix;
public static VertexConsumer of(VertexConsumer parent, Parameters parameters) {
return new PassThroughVertexConsumer(parent, parameters);
}
PassThroughVertexConsumer(VertexConsumer parent, Parameters parameters) {
this.parent = parent;
colorFix = parameters.colorFix;
textureFix = parameters.textureFix;
overlayFix = parameters.overlayFix;
lightFix = parameters.lightFix;
}
@Override
public VertexConsumer vertex(double x, double y, double z) {
parent.vertex(x, y, z);
return this;
}
@Override
public VertexConsumer color(int r, int g, int b, int a) {
colorFix.apply(parent, r, g, b, a);
return this;
}
@Override
public VertexConsumer texture(float u, float v) {
textureFix.apply(parent, u, v);
return this;
}
@Override
public VertexConsumer overlay(int u, int v) {
overlayFix.apply(parent, u, v);
return this;
}
@Override
public VertexConsumer light(int u, int v) {
lightFix.apply(parent, u, v);
return this;
}
@Override
public VertexConsumer normal(float x, float y, float z) {
parent.normal(x, y, z);
return this;
}
@Override
public void next() {
parent.next();
}
@Override
public void fixedColor(int r, int g, int b, int a) {
parent.fixedColor(r, g, b, a);
}
@Override
public void unfixColor() {
parent.unfixColor();
}
public static class Parameters {
private ColorFix colorFix = COLOR;
private FUvFix textureFix = TEXTURE;
private IUvFix overlayFix = OVERLAY;
private IUvFix lightFix = LIGHT;
public Parameters color(ColorFix fix) {
colorFix = fix;
return this;
}
public Parameters texture(FUvFix fix) {
textureFix = fix;
return this;
}
public Parameters overlay(IUvFix fix) {
overlayFix = fix;
return this;
}
public Parameters light(IUvFix fix) {
lightFix = fix;
return this;
}
}
public interface PosFix {
void apply(VertexConsumer consumer, float x, float y, float z);
}
public interface ColorFix {
void apply(VertexConsumer consumer, int r, int g, int b, int a);
}
public interface FUvFix {
void apply(VertexConsumer consumer, float u, float v);
}
public interface IUvFix {
void apply(VertexConsumer consumer, int u, int v);
}
}

View file

@ -4,25 +4,22 @@ import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.VertexFormat;
import net.minecraft.client.render.VertexFormat.DrawMode;
import net.minecraft.client.render.VertexFormats;
public final class RenderLayers extends RenderLayer {
private RenderLayers(String name, VertexFormat vertexFormat, DrawMode drawMode, int expectedBufferSize,
boolean hasCrumbling, boolean translucent, Runnable startAction, Runnable endAction) {
super(name, vertexFormat, drawMode, expectedBufferSize, hasCrumbling, translucent, startAction, endAction);
private RenderLayers() {
super(null, null, null, 0, false, false, null, null);
}
private static final RenderLayer MAGIC_GLOW = RenderLayer.of("uni_shield", VertexFormats.POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL,
VertexFormat.DrawMode.QUADS, 256, true, true, RenderLayer.MultiPhaseParameters.builder()
private static final RenderLayer MAGIC_GLOW = of("uni_shield", VertexFormats.POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL,
VertexFormat.DrawMode.QUADS, 256, true, true, MultiPhaseParameters.builder()
.shader(COLOR_SHADER)
.transparency(TRANSLUCENT_TRANSPARENCY)
.target(TRANSLUCENT_TARGET)
.build(false));
private static final RenderLayer FAIRY = RenderLayer.of("fairy", VertexFormats.POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL,
VertexFormat.DrawMode.QUADS, 256, true, true, RenderLayer.MultiPhaseParameters.builder()
private static final RenderLayer FAIRY = of("fairy", VertexFormats.POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL,
VertexFormat.DrawMode.QUADS, 256, true, true, MultiPhaseParameters.builder()
.shader(COLOR_SHADER)
.transparency(TRANSLUCENT_TRANSPARENCY)
.target(TRANSLUCENT_TARGET)
@ -37,7 +34,7 @@ public final class RenderLayers extends RenderLayer {
return FAIRY;
}
public static Texturing solid(float r, float g, float b, float a) {
private static Texturing solid(float r, float g, float b, float a) {
return new Texturing("solid", () -> {
RenderSystem.setShaderColor(r, g, b, a);
}, () -> {

View file

@ -4,13 +4,13 @@ import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
import com.minelittlepony.unicopia.entity.Creature;
import com.minelittlepony.unicopia.entity.Equine;
import com.minelittlepony.unicopia.entity.ItemImpl;
import com.minelittlepony.unicopia.entity.Living;
import com.minelittlepony.unicopia.entity.behaviour.EntityAppearance;
import com.minelittlepony.unicopia.entity.behaviour.FallingBlockBehaviour;
import com.minelittlepony.unicopia.entity.player.Pony;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
@ -36,10 +36,26 @@ import net.minecraft.util.math.Vec3d;
public class WorldRenderDelegate {
public static final WorldRenderDelegate INSTANCE = new WorldRenderDelegate();
private static final PassThroughVertexConsumer.Parameters MINION_OVERLAY = new PassThroughVertexConsumer.Parameters()
.color((parent, r, g, b, a) -> parent.color((float)Math.random(), 0.6F, 1, a / 255F));
private boolean recurse;
public boolean onEntityRender(EntityRenderDispatcher dispatcher, Equine<?> pony,
double x, double y, double z, float yaw,
float tickDelta, MatrixStack matrices, VertexConsumerProvider vertices, int light) {
if (!recurse && pony instanceof Creature && ((Creature)pony).isMinion()) {
recurse = true;
dispatcher.render(((Creature)pony).getEntity(), x, y, z, yaw, tickDelta, matrices, layer -> {
return PassThroughVertexConsumer.of(vertices.getBuffer(layer), MINION_OVERLAY);
}, light);
recurse = false;
return true;
}
if (pony instanceof ItemImpl) {
matrices.push();
@ -64,11 +80,6 @@ public class WorldRenderDelegate {
matrices.push();
Entity owner = pony.getEntity();
Entity master = pony.getMaster();
if (master != owner) {
RenderSystem.setShaderColor(0, 0, 1, 1);
}
boolean negative = pony.getPhysics().isGravityNegative();
@ -95,7 +106,6 @@ public class WorldRenderDelegate {
}
if (pony instanceof Caster<?>) {
int fireTicks = owner.doesRenderOnFire() ? 1 : 0;
return ((Caster<?>)pony).getSpellSlot().get(SpellPredicate.IS_DISGUISE, true).map(effect -> {
@ -122,7 +132,6 @@ public class WorldRenderDelegate {
}
public void afterEntityRender(Equine<?> pony, MatrixStack matrices) {
if (pony instanceof ItemImpl || pony instanceof Living) {
matrices.pop();

View file

@ -36,6 +36,7 @@ import net.minecraft.nbt.NbtElement;
public class Creature extends Living<LivingEntity> {
private static final TrackedData<NbtCompound> EFFECT = DataTracker.registerData(LivingEntity.class, TrackedDataHandlerRegistry.TAG_COMPOUND);
private static final TrackedData<NbtCompound> MASTER = DataTracker.registerData(LivingEntity.class, TrackedDataHandlerRegistry.TAG_COMPOUND);
public static final TrackedData<Float> GRAVITY = DataTracker.registerData(LivingEntity.class, TrackedDataHandlerRegistry.FLOAT);
private static final LevelStore LEVELS = Levelled.fixed(0);
@ -54,18 +55,27 @@ public class Creature extends Living<LivingEntity> {
public Creature(LivingEntity entity) {
super(entity, EFFECT);
physics = new EntityPhysics<>(entity, GRAVITY);
entity.getDataTracker().startTracking(MASTER, master.toNBT());
}
@Override
public void setMaster(LivingEntity owner) {
master.set(owner);
entity.getDataTracker().set(MASTER, master.toNBT());
if (targets != null && owner != null) {
initMinionAi();
}
}
public boolean isMinion() {
Entity master = getMaster();
return master != null && master != getEntity();
}
@Override
public LivingEntity getMaster() {
NbtCompound data = entity.getDataTracker().get(MASTER);
master.fromNBT(data);
return master.getOrEmpty(getWorld()).orElse(entity);
}