mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-08 06:26:43 +01:00
Move shield effect over to a spell renderer
This commit is contained in:
parent
b3a7d338d2
commit
7fb9543dbe
7 changed files with 107 additions and 38 deletions
|
@ -13,6 +13,7 @@ import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||||
import com.minelittlepony.unicopia.entity.damage.UDamageTypes;
|
import com.minelittlepony.unicopia.entity.damage.UDamageTypes;
|
||||||
import com.minelittlepony.unicopia.particle.ParticleHandle.Attachment;
|
import com.minelittlepony.unicopia.particle.ParticleHandle.Attachment;
|
||||||
import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect;
|
import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect;
|
||||||
|
import com.minelittlepony.unicopia.particle.ParticleHandle;
|
||||||
import com.minelittlepony.unicopia.particle.ParticleUtils;
|
import com.minelittlepony.unicopia.particle.ParticleUtils;
|
||||||
import com.minelittlepony.unicopia.particle.SphereParticleEffect;
|
import com.minelittlepony.unicopia.particle.SphereParticleEffect;
|
||||||
import com.minelittlepony.unicopia.particle.UParticles;
|
import com.minelittlepony.unicopia.particle.UParticles;
|
||||||
|
@ -51,6 +52,9 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileDelega
|
||||||
private int age = 0;
|
private int age = 0;
|
||||||
private float accumulatedMass = 0;
|
private float accumulatedMass = 0;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
protected final ParticleHandle particlEffect = new ParticleHandle();
|
||||||
|
|
||||||
protected DarkVortexSpell(CustomisedSpellType<?> type) {
|
protected DarkVortexSpell(CustomisedSpellType<?> type) {
|
||||||
super(type);
|
super(type);
|
||||||
}
|
}
|
||||||
|
@ -109,6 +113,11 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileDelega
|
||||||
return EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR.test(entity) && getAttractiveForce(source, entity) > 0;
|
return EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR.test(entity) && getAttractiveForce(source, entity) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroyed(Caster<?> caster) {
|
||||||
|
particlEffect.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generateParticles(Caster<?> source) {
|
public void generateParticles(Caster<?> source) {
|
||||||
super.generateParticles(source);
|
super.generateParticles(source);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.Affinity;
|
import com.minelittlepony.unicopia.Affinity;
|
||||||
import com.minelittlepony.unicopia.USounds;
|
import com.minelittlepony.unicopia.USounds;
|
||||||
import com.minelittlepony.unicopia.Unicopia;
|
import com.minelittlepony.unicopia.Unicopia;
|
||||||
|
@ -10,11 +12,9 @@ import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
|
import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect;
|
||||||
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
||||||
import com.minelittlepony.unicopia.particle.ParticleHandle;
|
import com.minelittlepony.unicopia.particle.ParticleUtils;
|
||||||
import com.minelittlepony.unicopia.particle.SphereParticleEffect;
|
|
||||||
import com.minelittlepony.unicopia.particle.UParticles;
|
|
||||||
import com.minelittlepony.unicopia.particle.ParticleHandle.Attachment;
|
|
||||||
import com.minelittlepony.unicopia.projectile.ProjectileUtil;
|
import com.minelittlepony.unicopia.projectile.ProjectileUtil;
|
||||||
import com.minelittlepony.unicopia.util.shape.Sphere;
|
import com.minelittlepony.unicopia.util.shape.Sphere;
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ import net.minecraft.entity.passive.PassiveEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.entity.vehicle.AbstractMinecartEntity;
|
import net.minecraft.entity.vehicle.AbstractMinecartEntity;
|
||||||
import net.minecraft.entity.vehicle.BoatEntity;
|
import net.minecraft.entity.vehicle.BoatEntity;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
public class ShieldSpell extends AbstractSpell {
|
public class ShieldSpell extends AbstractSpell {
|
||||||
|
@ -40,10 +41,14 @@ public class ShieldSpell extends AbstractSpell {
|
||||||
.with(Trait.AIR, 9)
|
.with(Trait.AIR, 9)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
protected final ParticleHandle particlEffect = new ParticleHandle();
|
|
||||||
|
|
||||||
private final TargetSelecter targetSelecter = new TargetSelecter(this);
|
private final TargetSelecter targetSelecter = new TargetSelecter(this);
|
||||||
|
|
||||||
|
private float prevRadius;
|
||||||
|
private float radius;
|
||||||
|
|
||||||
|
private float rangeMultiplier;
|
||||||
|
private float targetRangeMultiplier;
|
||||||
|
|
||||||
protected ShieldSpell(CustomisedSpellType<?> type) {
|
protected ShieldSpell(CustomisedSpellType<?> type) {
|
||||||
super(type);
|
super(type);
|
||||||
}
|
}
|
||||||
|
@ -53,33 +58,27 @@ public class ShieldSpell extends AbstractSpell {
|
||||||
return method == CastingMethod.STAFF || getTraits().get(Trait.GENEROSITY) > 0 ? toPlaceable() : this;
|
return method == CastingMethod.STAFF || getTraits().get(Trait.GENEROSITY) > 0 ? toPlaceable() : this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroyed(Caster<?> caster) {
|
|
||||||
particlEffect.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Affinity getAffinity() {
|
public Affinity getAffinity() {
|
||||||
return getTraits().get(Trait.DARKNESS) > 0 ? Affinity.BAD : Affinity.GOOD;
|
return getTraits().get(Trait.DARKNESS) > 0 ? Affinity.BAD : Affinity.GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void generateParticles(Caster<?> source) {
|
protected void generateParticles(Caster<?> source) {
|
||||||
float radius = (float)getDrawDropOffRange(source);
|
|
||||||
Vec3d origin = getOrigin(source);
|
Vec3d origin = getOrigin(source);
|
||||||
|
|
||||||
source.spawnParticles(origin, new Sphere(true, radius), (int)(radius * 6), pos -> {
|
source.spawnParticles(origin, new Sphere(true, radius), (int)(radius * 6), pos -> {
|
||||||
source.addParticle(new MagicParticleEffect(getType().getColor()), pos, Vec3d.ZERO);
|
source.addParticle(new MagicParticleEffect(getType().getColor()), pos, Vec3d.ZERO);
|
||||||
});
|
|
||||||
|
|
||||||
particlEffect.update(getUuid(), source, spawner -> {
|
if (source.asWorld().random.nextInt(10) == 0 && source.asWorld().random.nextFloat() < source.getCorruption().getScaled(1)) {
|
||||||
spawner.addParticle(new SphereParticleEffect(UParticles.SPHERE, getType().getColor(), 0.3F, radius), origin, Vec3d.ZERO);
|
ParticleUtils.spawnParticle(source.asWorld(), new LightningBoltParticleEffect(true, 3, 2, 0.1F, Optional.empty()), pos, Vec3d.ZERO);
|
||||||
}).ifPresent(p -> {
|
}
|
||||||
p.setAttribute(Attachment.ATTR_RADIUS, radius);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean tick(Caster<?> source, Situation situation) {
|
public boolean tick(Caster<?> source, Situation situation) {
|
||||||
|
prevRadius = radius;
|
||||||
|
radius = (float)getDrawDropOffRange(source);
|
||||||
|
|
||||||
if (source.isClient()) {
|
if (source.isClient()) {
|
||||||
generateParticles(source);
|
generateParticles(source);
|
||||||
|
@ -108,20 +107,32 @@ public class ShieldSpell extends AbstractSpell {
|
||||||
|
|
||||||
cost *= costMultiplier / ((1 + source.getLevel().get()) * 3F);
|
cost *= costMultiplier / ((1 + source.getLevel().get()) * 3F);
|
||||||
cost /= knowledge;
|
cost /= knowledge;
|
||||||
cost += getDrawDropOffRange(source) / 10F;
|
cost += radius / 10F;
|
||||||
|
|
||||||
if (!source.subtractEnergyCost(cost)) {
|
if (!source.subtractEnergyCost(cost)) {
|
||||||
setDead();
|
setDead();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float getRadius(float tickDelta) {
|
||||||
|
return MathHelper.lerp(tickDelta, prevRadius, radius);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the maximum radius of the shield. aka The area of effect.
|
* Calculates the maximum radius of the shield. aka The area of effect.
|
||||||
*/
|
*/
|
||||||
public double getDrawDropOffRange(Caster<?> source) {
|
public double getDrawDropOffRange(Caster<?> source) {
|
||||||
float multiplier = source instanceof Pony pony && pony.asEntity().isSneaking() ? 1 : 2;
|
targetRangeMultiplier = source instanceof Pony pony && pony.asEntity().isSneaking() ? 1 : 2;
|
||||||
|
if (rangeMultiplier < targetRangeMultiplier - 0.1F) {
|
||||||
|
rangeMultiplier += 0.1F;
|
||||||
|
} else if (rangeMultiplier > targetRangeMultiplier + 0.1) {
|
||||||
|
rangeMultiplier -= 0.1F;
|
||||||
|
} else {
|
||||||
|
rangeMultiplier = targetRangeMultiplier;
|
||||||
|
}
|
||||||
|
|
||||||
float min = (source instanceof Pony ? 4 : 6) + getTraits().get(Trait.POWER);
|
float min = (source instanceof Pony ? 4 : 6) + getTraits().get(Trait.POWER);
|
||||||
double range = (min + (source.getLevel().getScaled(source instanceof Pony ? 4 : 40) * (source instanceof Pony ? 2 : 10))) / multiplier;
|
double range = (min + (source.getLevel().getScaled(source instanceof Pony ? 4 : 40) * (source instanceof Pony ? 2 : 10))) / rangeMultiplier;
|
||||||
|
|
||||||
return range;
|
return range;
|
||||||
}
|
}
|
||||||
|
@ -150,7 +161,7 @@ public class ShieldSpell extends AbstractSpell {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected long applyEntities(Caster<?> source) {
|
protected long applyEntities(Caster<?> source) {
|
||||||
double radius = getDrawDropOffRange(source);
|
double radius = this.radius;
|
||||||
|
|
||||||
Vec3d origin = getOrigin(source);
|
Vec3d origin = getOrigin(source);
|
||||||
|
|
||||||
|
|
|
@ -22,9 +22,9 @@ public class MagicParticle extends SpriteBillboardParticle {
|
||||||
velocityX = vX;
|
velocityX = vX;
|
||||||
velocityY = vY;
|
velocityY = vY;
|
||||||
velocityZ = vZ;
|
velocityZ = vZ;
|
||||||
startX = x + random.nextGaussian()/3;
|
startX = x;// + random.nextGaussian()/3;
|
||||||
startY = y + random.nextGaussian()/3;
|
startY = y;// + random.nextGaussian()/3;
|
||||||
startZ = z + random.nextGaussian()/3;
|
startZ = z;// + random.nextGaussian()/3;
|
||||||
scale = random.nextFloat() * 0.12F;
|
scale = random.nextFloat() * 0.12F;
|
||||||
maxAge = (int)(Math.random() * 10) + 20;
|
maxAge = (int)(Math.random() * 10) + 20;
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,15 @@ public final class RenderLayers extends RenderLayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RenderLayer getMagicNoColor() {
|
public static RenderLayer getMagicNoColor() {
|
||||||
return MAGIC_NO_COLOR;
|
//return MAGIC_NO_COLOR;
|
||||||
|
return of("magic_no_color", VertexFormats.POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL,
|
||||||
|
VertexFormat.DrawMode.QUADS, 256, true, true, MultiPhaseParameters.builder()
|
||||||
|
.program(COLOR_PROGRAM)
|
||||||
|
.transparency(TRANSLUCENT_TRANSPARENCY)
|
||||||
|
.target(TRANSLUCENT_TARGET)
|
||||||
|
.cull(DISABLE_CULLING)
|
||||||
|
.writeMaskState(COLOR_MASK)
|
||||||
|
.build(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RenderLayer getMagicColored() {
|
public static RenderLayer getMagicColored() {
|
||||||
|
|
|
@ -3,38 +3,37 @@ package com.minelittlepony.unicopia.client.render.model;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Vector3f;
|
||||||
import org.joml.Vector4f;
|
import org.joml.Vector4f;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.client.render.RenderUtil;
|
||||||
|
|
||||||
import net.minecraft.client.render.VertexConsumer;
|
import net.minecraft.client.render.VertexConsumer;
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
|
||||||
public class BakedModel {
|
public class BakedModel {
|
||||||
private static final Vector4f drawVert = new Vector4f();
|
protected final List<RenderUtil.Vertex> vertices = new ArrayList<>();
|
||||||
|
|
||||||
protected final List<Vertex> vertices = new ArrayList<>();
|
|
||||||
|
|
||||||
protected void addVertex(Vector4f vertex) {
|
protected void addVertex(Vector4f vertex) {
|
||||||
addVertex(vertex.x, vertex.y, vertex.z, 0, 0);
|
addVertex(vertex.x, vertex.y, vertex.z, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void addVertex(float x, float y, float z, float u, float v) {
|
protected void addVertex(float x, float y, float z, float u, float v) {
|
||||||
vertices.add(new Vertex(x, y, z, u, v));
|
vertices.add(new RenderUtil.Vertex(new Vector3f(x, y, z), u, v));
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void render(MatrixStack matrices, VertexConsumer vertexWriter, int light, int overlay, float scale, float r, float g, float b, float a) {
|
public final void render(MatrixStack matrices, VertexConsumer buffer, int light, int overlay, float scale, float r, float g, float b, float a) {
|
||||||
scale = Math.abs(scale);
|
scale = Math.abs(scale);
|
||||||
if (scale < 0.001F) {
|
if (scale < 0.001F) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix4f model = matrices.peek().getPositionMatrix();
|
matrices.push();
|
||||||
for (Vertex vertex : vertices) {
|
matrices.scale(scale, scale, scale);
|
||||||
drawVert.set(vertex.x() * scale, vertex.y() * scale, vertex.z() * scale, 1);
|
for (RenderUtil.Vertex vertex : vertices) {
|
||||||
drawVert.mul(model);
|
Vector4f pos = vertex.position(matrices);
|
||||||
vertexWriter.vertex(drawVert.x, drawVert.y, drawVert.z, r, g, b, a, vertex.u(), vertex.v(), overlay, light, 0, 0, 0);
|
buffer.vertex(pos.x, pos.y, pos.z, r, g, b, a, vertex.u(), vertex.v(), overlay, light, 0, 0, 0);
|
||||||
|
}
|
||||||
|
matrices.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
record Vertex(float x, float y, float z, float u, float v) {}
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
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.ShieldSpell;
|
||||||
|
import com.minelittlepony.unicopia.client.render.RenderLayers;
|
||||||
|
import com.minelittlepony.unicopia.client.render.model.SphereModel;
|
||||||
|
import com.minelittlepony.unicopia.util.ColorHelper;
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.render.VertexConsumer;
|
||||||
|
import net.minecraft.client.render.VertexConsumerProvider;
|
||||||
|
import net.minecraft.client.render.VertexConsumerProvider.Immediate;
|
||||||
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
|
||||||
|
public class ShieldSpellRenderer implements 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) {
|
||||||
|
matrices.push();
|
||||||
|
double height = caster.asEntity().getEyeY() - caster.getOriginVector().y;
|
||||||
|
matrices.translate(0, height, 0);
|
||||||
|
|
||||||
|
Immediate immediate = MinecraftClient.getInstance().getBufferBuilders().getEntityVertexConsumers();
|
||||||
|
immediate.draw();
|
||||||
|
|
||||||
|
int color = ColorHelper.lerp(caster.getCorruption().getScaled(1) * (tickDelta / (1 + caster.asWorld().random.nextFloat())), spell.getType().getColor(), 0xFF000);
|
||||||
|
float[] colors = ColorHelper.changeSaturation(Color.r(color), Color.g(color), Color.b(color), 4);
|
||||||
|
float radius = 0.35F + spell.getRadius(tickDelta) + MathHelper.sin(animationProgress / 30F) * 0.01F;
|
||||||
|
|
||||||
|
VertexConsumer buffer = vertices.getBuffer(RenderLayers.getMagicNoColor());
|
||||||
|
|
||||||
|
float thickness = 0.02F * MathHelper.sin(animationProgress / 30F);
|
||||||
|
float alpha = 1 - Math.abs(MathHelper.sin(animationProgress / 20F)) * 0.2F;
|
||||||
|
SphereModel.SPHERE.render(matrices, buffer, light, 1, radius + thickness, colors[0], colors[1], colors[2], alpha * 0.08F);
|
||||||
|
SphereModel.SPHERE.render(matrices, buffer, light, 1, radius - thickness, colors[0], colors[1], colors[2], alpha * 0.05F);
|
||||||
|
SphereModel.SPHERE.render(matrices, buffer, light, 1, radius + thickness * 2, colors[0], colors[1], colors[2], alpha * 0.05F);
|
||||||
|
|
||||||
|
matrices.pop();
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,6 +45,7 @@ public class SpellEffectsRenderDispatcher implements SynchronousResourceReloader
|
||||||
|
|
||||||
static {
|
static {
|
||||||
register(SpellType.PLACED_SPELL, PlacedSpellRenderer::new);
|
register(SpellType.PLACED_SPELL, PlacedSpellRenderer::new);
|
||||||
|
register(SpellType.SHIELD, ShieldSpellRenderer::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|
Loading…
Reference in a new issue