mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-12-03 17:37:59 +01:00
Fix portals and move them to a spell renderer
This commit is contained in:
parent
225c67d558
commit
edb1e024d6
10 changed files with 197 additions and 103 deletions
|
@ -42,8 +42,6 @@ public class PortalSpell extends AbstractSpell implements PlaceableSpell.Placeme
|
|||
|
||||
private boolean publishedPosition;
|
||||
|
||||
private final ParticleHandle particleEffect = new ParticleHandle();
|
||||
|
||||
private float pitch;
|
||||
private float yaw;
|
||||
|
||||
|
@ -53,6 +51,10 @@ public class PortalSpell extends AbstractSpell implements PlaceableSpell.Placeme
|
|||
super(type);
|
||||
}
|
||||
|
||||
public boolean isLinked() {
|
||||
return teleportationTarget.getTarget().isPresent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Caster<?> caster) {
|
||||
setOrientation(caster.asEntity().getPitch(), caster.asEntity().getYaw());
|
||||
|
@ -73,17 +75,9 @@ public class PortalSpell extends AbstractSpell implements PlaceableSpell.Placeme
|
|||
source.spawnParticles(origin, particleArea, 5, pos -> {
|
||||
source.addParticle(effect, pos, Vec3d.ZERO);
|
||||
});
|
||||
|
||||
teleportationTarget.getTarget().ifPresentOrElse(target -> {
|
||||
particleEffect.update(getUuid(), source, spawner -> {
|
||||
spawner.addParticle(new SphereParticleEffect(UParticles.DISK, getType().getColor(), 0.8F, 1.8F, new Vec3d(-pitch + 90, -yaw, 0)), source.getOriginVector(), Vec3d.ZERO);
|
||||
});
|
||||
}, () -> {
|
||||
particleEffect.destroy();
|
||||
});
|
||||
} else {
|
||||
teleportationTarget.getTarget().ifPresent(target -> {
|
||||
if (Ether.get(source.asWorld()).get(getType(), target, targetPortalId) != null) {
|
||||
if (Ether.get(source.asWorld()).get(getType(), target, targetPortalId) == null) {
|
||||
Unicopia.LOGGER.debug("Lost sibling, breaking connection to " + target.uuid());
|
||||
teleportationTarget.set(null);
|
||||
setDirty();
|
||||
|
@ -178,7 +172,6 @@ public class PortalSpell extends AbstractSpell implements PlaceableSpell.Placeme
|
|||
|
||||
@Override
|
||||
protected void onDestroyed(Caster<?> caster) {
|
||||
particleEffect.destroy();
|
||||
Ether ether = Ether.get(caster.asWorld());
|
||||
ether.remove(getType(), caster);
|
||||
getTarget(caster).ifPresent(e -> e.setTaken(false));
|
||||
|
|
|
@ -63,6 +63,7 @@ import net.minecraft.world.BlockRenderView;
|
|||
public interface URenderers {
|
||||
BlockEntity CHEST_RENDER_ENTITY = new CloudChestBlock.TileData(BlockPos.ORIGIN, UBlocks.CLOUD_CHEST.getDefaultState());
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static void bootstrap() {
|
||||
ParticleFactoryRegistry.getInstance().register(UParticles.UNICORN_MAGIC, createFactory(MagicParticle::new));
|
||||
ParticleFactoryRegistry.getInstance().register(UParticles.CHANGELING_MAGIC, createFactory(ChangelingMagicParticle::new));
|
||||
|
|
|
@ -13,9 +13,11 @@ import net.minecraft.client.util.math.MatrixStack;
|
|||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.math.RotationAxis;
|
||||
|
||||
public class BubbleSpellRenderer implements SpellRenderer<BubbleSpell> {
|
||||
public class BubbleSpellRenderer extends SpellRenderer<BubbleSpell> {
|
||||
@Override
|
||||
public void render(MatrixStack matrices, VertexConsumerProvider vertices, BubbleSpell spell, Caster<?> caster, int light, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) {
|
||||
super.render(matrices, vertices, spell, caster, light, limbAngle, limbDistance, tickDelta, animationProgress, headYaw, headPitch);
|
||||
|
||||
matrices.push();
|
||||
double height = caster.asEntity().getEyeY() - caster.getOriginVector().y;
|
||||
matrices.translate(0, height * 0.5F, 0);
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.minelittlepony.unicopia.client.render.spell;
|
|||
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.TimedSpell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.DarkVortexSpell;
|
||||
import com.minelittlepony.unicopia.client.render.RenderLayers;
|
||||
import com.minelittlepony.unicopia.client.render.model.PlaneModel;
|
||||
|
@ -16,7 +17,7 @@ import net.minecraft.util.Identifier;
|
|||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.RotationAxis;
|
||||
|
||||
public class DarkVortexSpellRenderer implements SpellRenderer<DarkVortexSpell> {
|
||||
public class DarkVortexSpellRenderer extends SpellRenderer<DarkVortexSpell> {
|
||||
|
||||
private static final Identifier ACCRETION_DISK_TEXTURE = Unicopia.id("textures/spells/dark_vortex/accretion_disk.png");
|
||||
|
||||
|
@ -29,8 +30,13 @@ public class DarkVortexSpellRenderer implements SpellRenderer<DarkVortexSpell> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack matrices, VertexConsumerProvider vertices, DarkVortexSpell spell, Caster<?> caster, int light, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) {
|
||||
public boolean shouldRenderEffectPass(int pass) {
|
||||
return pass < 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack matrices, VertexConsumerProvider vertices, DarkVortexSpell spell, Caster<?> caster, int light, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) {
|
||||
super.render(matrices, vertices, spell, caster, light, limbAngle, limbDistance, tickDelta, animationProgress, headYaw, headPitch);
|
||||
|
||||
Entity cameraEntity = MinecraftClient.getInstance().getCameraEntity();
|
||||
|
||||
|
@ -43,15 +49,12 @@ public class DarkVortexSpellRenderer implements SpellRenderer<DarkVortexSpell> {
|
|||
SphereModel.SPHERE.render(matrices, vertices.getBuffer(RenderLayers.getSolid()), light, 1, Math.min(radius * 0.6F, absDistance * 0.1F), 0, 0, 0, 1);
|
||||
|
||||
matrices.push();
|
||||
|
||||
|
||||
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(90));
|
||||
matrices.multiply(RotationAxis.NEGATIVE_X.rotationDegrees(90 + cameraEntity.getYaw(tickDelta)));
|
||||
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(-cameraEntity.getPitch(tickDelta)));
|
||||
|
||||
matrices.scale(0.7F, 1, 1);
|
||||
|
||||
|
||||
float distance = 1F / MathHelper.clamp((absDistance / (radius * 4)), 0.0000001F, 1);
|
||||
distance *= distance;
|
||||
if (absDistance < radius * 4) {
|
||||
|
@ -97,4 +100,9 @@ public class DarkVortexSpellRenderer implements SpellRenderer<DarkVortexSpell> {
|
|||
matrices.pop();
|
||||
matrices.pop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderCountdown(MatrixStack matrices, TimedSpell spell, float tickDelta) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import net.minecraft.client.util.math.MatrixStack;
|
|||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.RotationAxis;
|
||||
|
||||
public class PlacedSpellRenderer implements SpellRenderer<PlaceableSpell> {
|
||||
public class PlacedSpellRenderer extends SpellRenderer<PlaceableSpell> {
|
||||
private static final Identifier[] TEXTURES = new Identifier[] {
|
||||
Unicopia.id("textures/particles/runes_0.png"),
|
||||
Unicopia.id("textures/particles/runes_1.png"),
|
||||
|
@ -27,46 +27,65 @@ public class PlacedSpellRenderer implements SpellRenderer<PlaceableSpell> {
|
|||
|
||||
@Override
|
||||
public void render(MatrixStack matrices, VertexConsumerProvider vertices, PlaceableSpell spell, Caster<?> caster, int light, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) {
|
||||
|
||||
if (!(caster.asEntity() instanceof CastSpellEntity)) {
|
||||
if (!(caster.asEntity() instanceof CastSpellEntity castSpell)) {
|
||||
return;
|
||||
}
|
||||
|
||||
matrices.push();
|
||||
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-castSpell.getYaw()));
|
||||
|
||||
for (Spell delegate : spell.getDelegates()) {
|
||||
renderAmbientEffects(matrices, vertices, spell, delegate, caster, light, animationProgress, tickDelta);
|
||||
|
||||
matrices.push();
|
||||
matrices.translate(0, 0.001, 0);
|
||||
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(spell.pitch));
|
||||
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(90 - spell.yaw));
|
||||
float scale = (spell.getAge(tickDelta) / 25F) * 3;
|
||||
matrices.scale(scale, scale, scale);
|
||||
|
||||
float angle = (animationProgress / 9F) % 360;
|
||||
|
||||
int color = delegate.getType().getColor();
|
||||
|
||||
float red = Color.r(color);
|
||||
float green = Color.g(color);
|
||||
float blue = Color.b(color);
|
||||
|
||||
for (int i = 0; i < TEXTURES.length; i++) {
|
||||
VertexConsumer buffer = vertices.getBuffer(RenderLayer.getEntityTranslucent(TEXTURES[i]));
|
||||
|
||||
for (int dim = 0; dim < 3; dim++) {
|
||||
float ringSpeed = (i % 2 == 0 ? i : -1) * i;
|
||||
|
||||
matrices.push();
|
||||
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(angle * ringSpeed));
|
||||
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(angle * ringSpeed * dim));
|
||||
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(angle * ringSpeed * dim));
|
||||
PlaneModel.INSTANCE.render(matrices, buffer, light, 0, 1, red, green, blue, scale / ((float)(dim * 3) + 1));
|
||||
matrices.pop();
|
||||
}
|
||||
}
|
||||
|
||||
matrices.pop();
|
||||
|
||||
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(-spell.pitch));
|
||||
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180 - spell.yaw));
|
||||
SpellEffectsRenderDispatcher.INSTANCE.render(matrices, vertices, delegate, caster, light, limbAngle, limbDistance, tickDelta, animationProgress, headYaw, headPitch);
|
||||
matrices.pop();
|
||||
}
|
||||
|
||||
matrices.pop();
|
||||
}
|
||||
|
||||
protected void renderAmbientEffects(MatrixStack matrices, VertexConsumerProvider vertices, PlaceableSpell spell, Spell delegate, Caster<?> caster, int light, float animationProgress, float tickDelta) {
|
||||
matrices.push();
|
||||
matrices.translate(0, 0.001, 0);
|
||||
|
||||
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(-spell.pitch));
|
||||
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180 - spell.yaw));
|
||||
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(90));
|
||||
|
||||
float scale = (spell.getAge(tickDelta) / 25F) * 3;
|
||||
matrices.scale(scale, scale, scale);
|
||||
|
||||
float angle = (animationProgress / 9F) % 360;
|
||||
|
||||
int color = delegate.getType().getColor();
|
||||
|
||||
float red = Color.r(color);
|
||||
float green = Color.g(color);
|
||||
float blue = Color.b(color);
|
||||
|
||||
SpellRenderer<?> renderer = SpellEffectsRenderDispatcher.INSTANCE.getRenderer(delegate);
|
||||
|
||||
for (int i = 0; i < TEXTURES.length; i++) {
|
||||
if (!renderer.shouldRenderEffectPass(i)) {
|
||||
continue;
|
||||
}
|
||||
VertexConsumer buffer = vertices.getBuffer(RenderLayer.getEntityTranslucent(TEXTURES[i]));
|
||||
|
||||
for (int dim = 0; dim < 3; dim++) {
|
||||
float ringSpeed = (i % 2 == 0 ? i : -1) * i;
|
||||
|
||||
matrices.push();
|
||||
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(angle * ringSpeed));
|
||||
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(angle * ringSpeed * dim));
|
||||
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(angle * ringSpeed * dim));
|
||||
PlaneModel.INSTANCE.render(matrices, buffer, light, 0, 1, red, green, blue, scale / ((float)(dim * 3) + 1));
|
||||
matrices.pop();
|
||||
}
|
||||
}
|
||||
|
||||
matrices.pop();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
package com.minelittlepony.unicopia.client.render.spell;
|
||||
|
||||
import com.minelittlepony.common.util.Color;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.PortalSpell;
|
||||
import com.minelittlepony.unicopia.client.render.RenderLayers;
|
||||
import com.minelittlepony.unicopia.client.render.model.SphereModel;
|
||||
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.util.math.RotationAxis;
|
||||
|
||||
public class PortalSpellRenderer extends SpellRenderer<PortalSpell> {
|
||||
|
||||
@Override
|
||||
public boolean shouldRenderEffectPass(int pass) {
|
||||
return pass == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack matrices, VertexConsumerProvider vertices, PortalSpell spell, Caster<?> caster, int light, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) {
|
||||
super.render(matrices, vertices, spell, caster, light, limbAngle, limbDistance, tickDelta, animationProgress, headYaw, headPitch);
|
||||
|
||||
if (!spell.isLinked()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int color = spell.getType().getColor();
|
||||
|
||||
float red = Color.r(color);
|
||||
float green = Color.g(color);
|
||||
float blue = Color.b(color);
|
||||
|
||||
VertexConsumer buffer = vertices.getBuffer(RenderLayers.getEndGateway());
|
||||
|
||||
double thickness = 0.1;
|
||||
|
||||
matrices.push();
|
||||
matrices.translate(0, thickness, 0);
|
||||
SphereModel.DISK.render(matrices, buffer, light, 0, 2.5F, red, green, blue, 1);
|
||||
matrices.pop();
|
||||
|
||||
matrices.push();
|
||||
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(180));
|
||||
matrices.translate(0, thickness, 0);
|
||||
SphereModel.DISK.render(matrices, buffer, light, 0, 2.5F, red, green, blue, 1);
|
||||
|
||||
matrices.pop();
|
||||
}
|
||||
}
|
|
@ -12,9 +12,11 @@ import net.minecraft.client.render.VertexConsumerProvider;
|
|||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
public class ShieldSpellRenderer implements SpellRenderer<ShieldSpell> {
|
||||
public class ShieldSpellRenderer extends SpellRenderer<ShieldSpell> {
|
||||
@Override
|
||||
public void render(MatrixStack matrices, VertexConsumerProvider vertices, ShieldSpell spell, Caster<?> caster, int light, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) {
|
||||
super.render(matrices, vertices, spell, caster, light, limbAngle, limbDistance, tickDelta, animationProgress, headYaw, headPitch);
|
||||
|
||||
matrices.push();
|
||||
double height = caster.asEntity().getEyeY() - caster.getOriginVector().y;
|
||||
matrices.translate(0, height, 0);
|
||||
|
|
|
@ -8,19 +8,12 @@ import java.util.stream.Stream;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.EquinePredicates;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.SpellContainer.Operation;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.TimedSpell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.client.gui.DrawableUtil;
|
||||
import com.minelittlepony.unicopia.entity.Living;
|
||||
import com.minelittlepony.unicopia.entity.mob.CastSpellEntity;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
import com.minelittlepony.unicopia.util.ColorHelper;
|
||||
|
||||
import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.font.TextRenderer.TextLayerType;
|
||||
|
@ -28,7 +21,6 @@ import net.minecraft.client.render.RenderLayer;
|
|||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.render.WorldRenderer;
|
||||
import net.minecraft.client.render.model.json.ModelTransformationMode;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.resource.ResourceManager;
|
||||
|
@ -38,7 +30,6 @@ import net.minecraft.util.Colors;
|
|||
import net.minecraft.util.Formatting;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.Box;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.RotationAxis;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
|
@ -56,6 +47,7 @@ public class SpellEffectsRenderDispatcher implements SynchronousResourceReloader
|
|||
register(SpellType.SHIELD, ShieldSpellRenderer::new);
|
||||
register(SpellType.DARK_VORTEX, DarkVortexSpellRenderer::new);
|
||||
register(SpellType.BUBBLE, BubbleSpellRenderer::new);
|
||||
register(SpellType.PORTAL, PortalSpellRenderer::new);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -71,20 +63,16 @@ public class SpellEffectsRenderDispatcher implements SynchronousResourceReloader
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <S extends Spell> SpellRenderer<S> getRenderer(S spell) {
|
||||
return (SpellRenderer<S>)renderers.get(spell.getType());
|
||||
return (SpellRenderer<S>)renderers.getOrDefault(spell.getType(), SpellRenderer.DEFAULT);
|
||||
}
|
||||
|
||||
public void render(MatrixStack matrices, VertexConsumerProvider vertices, Spell spell, Caster<?> caster, int light, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) {
|
||||
var renderer = getRenderer(spell);
|
||||
|
||||
if (renderer != null) {
|
||||
if (renderer != SpellRenderer.DEFAULT) {
|
||||
client.getBufferBuilders().getEntityVertexConsumers().draw();
|
||||
|
||||
renderer.render(matrices, vertices, spell, caster, light, limbAngle, limbDistance, tickDelta, animationProgress, headYaw, headPitch);
|
||||
|
||||
if (EquinePredicates.IS_CASTER.test(client.player)) {
|
||||
renderGemstone(matrices, vertices, spell, caster, light, tickDelta, animationProgress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,38 +93,6 @@ public class SpellEffectsRenderDispatcher implements SynchronousResourceReloader
|
|||
renderers = REGISTRY.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().create()));
|
||||
}
|
||||
|
||||
private void renderGemstone(MatrixStack matrices, VertexConsumerProvider vertices, Spell spell, Caster<?> caster, int light, float tickDelta, float animationProgress) {
|
||||
matrices.push();
|
||||
|
||||
if (!(caster.asEntity() instanceof MagicProjectileEntity)) {
|
||||
|
||||
float y = -caster.asEntity().getHeight();
|
||||
if (caster.asEntity() instanceof CastSpellEntity) {
|
||||
y = 1F;
|
||||
}
|
||||
|
||||
matrices.translate(0, y + MathHelper.sin(animationProgress / 3F) * 0.2F, 0);
|
||||
matrices.push();
|
||||
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(animationProgress));
|
||||
|
||||
client.getItemRenderer().renderItem(spell.getType().withTraits(spell.getTraits()).getDefaultStack(), ModelTransformationMode.FIXED, light, 0, matrices, vertices, caster.asWorld(), 0);
|
||||
matrices.pop();
|
||||
|
||||
if (spell instanceof TimedSpell timed && spell.getType() != SpellType.DARK_VORTEX) {
|
||||
matrices.multiply(client.getEntityRenderDispatcher().getRotation().invert());
|
||||
float radius = 0.6F;
|
||||
float timeRemaining = timed.getTimer().getPercentTimeRemaining(tickDelta);
|
||||
|
||||
DrawableUtil.drawArc(matrices, radius, radius + 0.3F, 0, DrawableUtil.TAU * timeRemaining,
|
||||
ColorHelper.lerp(MathHelper.clamp(timeRemaining * 4, 0, 1), 0xFF0000FF, 0xFFFFFFFF),
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
matrices.pop();
|
||||
}
|
||||
|
||||
private void renderSpellDebugInfo(MatrixStack matrices, VertexConsumerProvider vertices, Caster<?> caster, int light) {
|
||||
matrices.push();
|
||||
matrices.multiply(client.getEntityRenderDispatcher().getRotation());
|
||||
|
|
|
@ -1,11 +1,73 @@
|
|||
package com.minelittlepony.unicopia.client.render.spell;
|
||||
|
||||
import com.minelittlepony.unicopia.EquinePredicates;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.TimedSpell;
|
||||
import com.minelittlepony.unicopia.client.gui.DrawableUtil;
|
||||
import com.minelittlepony.unicopia.entity.mob.CastSpellEntity;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
import com.minelittlepony.unicopia.util.ColorHelper;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.render.model.json.ModelTransformationMode;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.RotationAxis;
|
||||
|
||||
public interface SpellRenderer<T extends Spell> {
|
||||
void render(MatrixStack matrices, VertexConsumerProvider vertices, T spell, Caster<?> caster, int light, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch);
|
||||
public class SpellRenderer<T extends Spell> {
|
||||
public static final SpellRenderer<?> DEFAULT = new SpellRenderer<>();
|
||||
|
||||
protected final MinecraftClient client = MinecraftClient.getInstance();
|
||||
|
||||
public boolean shouldRenderEffectPass(int pass) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void render(MatrixStack matrices, VertexConsumerProvider vertices, T spell, Caster<?> caster, int light, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) {
|
||||
if (caster.asEntity() == client.cameraEntity || (caster.asEntity() instanceof MagicProjectileEntity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (EquinePredicates.IS_CASTER.test(client.player)) {
|
||||
renderGemstone(matrices, vertices, spell, caster, light, tickDelta, animationProgress);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderGemstone(MatrixStack matrices, VertexConsumerProvider vertices, T spell, Caster<?> caster, int light, float tickDelta, float animationProgress) {
|
||||
matrices.push();
|
||||
|
||||
transformGemstone(matrices, vertices, spell, caster, animationProgress);
|
||||
matrices.push();
|
||||
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(animationProgress));
|
||||
|
||||
client.getItemRenderer().renderItem(spell.getType().withTraits(spell.getTraits()).getDefaultStack(), ModelTransformationMode.FIXED, light, 0, matrices, vertices, caster.asWorld(), 0);
|
||||
matrices.pop();
|
||||
|
||||
if (spell instanceof TimedSpell timed) {
|
||||
renderCountdown(matrices, timed, tickDelta);
|
||||
}
|
||||
|
||||
matrices.pop();
|
||||
}
|
||||
|
||||
protected void renderCountdown(MatrixStack matrices, TimedSpell spell, float tickDelta) {
|
||||
matrices.multiply(client.getEntityRenderDispatcher().getRotation().invert());
|
||||
float radius = 0.6F;
|
||||
float timeRemaining = spell.getTimer().getPercentTimeRemaining(tickDelta);
|
||||
|
||||
DrawableUtil.drawArc(matrices, radius, radius + 0.3F, 0, DrawableUtil.TAU * timeRemaining,
|
||||
ColorHelper.lerp(MathHelper.clamp(timeRemaining * 4, 0, 1), 0xFF0000FF, 0xFFFFFFFF),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
protected void transformGemstone(MatrixStack matrices, VertexConsumerProvider vertices, T spell, Caster<?> caster, float animationProgress) {
|
||||
float y = -caster.asEntity().getHeight();
|
||||
if (caster.asEntity() instanceof CastSpellEntity) {
|
||||
y = 1F;
|
||||
}
|
||||
matrices.translate(0, y + MathHelper.sin(animationProgress / 3F) * 0.2F, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ public interface UEntities {
|
|||
.dimensions(EntityDimensions.fixed(1, 1)));
|
||||
EntityType<CastSpellEntity> CAST_SPELL = register("cast_spell", FabricEntityTypeBuilder.create(SpawnGroup.MISC, CastSpellEntity::new)
|
||||
.trackRangeBlocks(200)
|
||||
.dimensions(EntityDimensions.fixed(1, 0.4F)));
|
||||
.dimensions(EntityDimensions.fixed(1, 1)));
|
||||
EntityType<FairyEntity> TWITTERMITE = register("twittermite", FabricEntityTypeBuilder.create(SpawnGroup.MISC, FairyEntity::new)
|
||||
.trackRangeBlocks(200)
|
||||
.dimensions(EntityDimensions.fixed(0.1F, 0.1F)));
|
||||
|
|
Loading…
Reference in a new issue