Thrown spells now look like magic beams rather than the old thrown item

This commit is contained in:
Sollace 2022-01-11 18:19:36 +02:00
parent 42cad69410
commit 1a1bc2396f
11 changed files with 154 additions and 30 deletions

View file

@ -32,7 +32,7 @@ public class UnicornProjectileAbility implements Ability<Hit> {
@Override
public int getWarmupTime(Pony player) {
return 1;
return 8;
}
@Override
@ -60,17 +60,39 @@ public class UnicornProjectileAbility implements Ability<Hit> {
return 7;
}
@Override
public boolean onQuickAction(Pony player, ActivationType type) {
if (type == ActivationType.DOUBLE_TAP) {
if (!player.isClient()) {
TypedActionResult<CustomisedSpellType<?>> thrown = player.getCharms().getSpellInHand(Hand.OFF_HAND);
if (thrown.getResult() != ActionResult.FAIL) {
thrown.getValue().create().toThrowable().throwProjectile(player).ifPresent(projectile -> {
player.subtractEnergyCost(getCostEstimate(player));
player.setAnimation(Animation.ARMS_FORWARD, 2);
});
}
}
return true;
}
return false;
}
@Override
public void apply(Pony player, Hit data) {
TypedActionResult<CustomisedSpellType<?>> thrown = player.getCharms().getSpellInHand(Hand.OFF_HAND);
TypedActionResult<CustomisedSpellType<?>> thrown = player.getCharms().getSpellInHand(Hand.MAIN_HAND);
if (thrown.getResult() != ActionResult.FAIL) {
player.subtractEnergyCost(getCostEstimate(player));
Spell spell = thrown.getValue().create();
spell.toThrowable().throwProjectile(player).ifPresent(projectile -> {
player.subtractEnergyCost(getCostEstimate(player));
player.setAnimation(Animation.ARMS_FORWARD);
projectile.setHydrophobic();
if (spell instanceof HomingSpell) {
RayTraceHelper.doTrace(player.getMaster(), 600, 1, EntityPredicates.CAN_COLLIDE).getEntity().filter(((HomingSpell)spell)::setTarget).ifPresent(target -> {
projectile.setHomingTarget(target);

View file

@ -8,6 +8,7 @@ import com.minelittlepony.unicopia.USounds;
import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
import com.minelittlepony.unicopia.entity.UEntities;
import com.minelittlepony.unicopia.item.GemstoneItem;
import com.minelittlepony.unicopia.item.UItems;
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
@ -60,12 +61,12 @@ public final class ThrowableSpell extends AbstractDelegatingSpell {
caster.playSound(USounds.SPELL_CAST_SHOOT, 0.7F, 0.4F / (world.random.nextFloat() * 0.4F + 0.8F));
if (!caster.isClient()) {
MagicProjectileEntity projectile = new MagicProjectileEntity(world, entity);
MagicProjectileEntity projectile = UEntities.MAGIC_BEAM.create(world);
projectile.setPosition(entity.getX(), entity.getEyeY() - 0.1F, entity.getZ());
projectile.setOwner(entity);
projectile.setItem(GemstoneItem.enchant(UItems.GEMSTONE.getDefaultStack(), spell.getType()));
projectile.getSpellSlot().put(this);
projectile.setVelocity(entity, entity.getPitch(), entity.getYaw(), 0, 1.5F, divergance);
projectile.setHydrophobic();
projectile.setNoGravity(true);
configureProjectile(projectile, caster);
world.spawnEntity(projectile);

View file

@ -22,6 +22,7 @@ import com.minelittlepony.unicopia.client.render.WingsFeatureRenderer;
import com.minelittlepony.unicopia.client.render.entity.ButterflyEntityRenderer;
import com.minelittlepony.unicopia.client.render.entity.CastSpellEntityRenderer;
import com.minelittlepony.unicopia.client.render.entity.FairyEntityRenderer;
import com.minelittlepony.unicopia.client.render.entity.MagicBeamEntityRenderer;
import com.minelittlepony.unicopia.client.render.entity.SpellbookEntityRenderer;
import com.minelittlepony.unicopia.entity.UEntities;
import com.minelittlepony.unicopia.item.ChameleonItem;
@ -70,6 +71,7 @@ public interface URenderers {
AccessoryFeatureRenderer.register(BatWingsFeatureRenderer::new);
EntityRendererRegistry.register(UEntities.THROWN_ITEM, FlyingItemEntityRenderer::new);
EntityRendererRegistry.register(UEntities.MAGIC_BEAM, MagicBeamEntityRenderer::new);
EntityRendererRegistry.register(UEntities.BUTTERFLY, ButterflyEntityRenderer::new);
EntityRendererRegistry.register(UEntities.FLOATING_ARTEFACT, FloatingArtefactEntityRenderer::new);
EntityRendererRegistry.register(UEntities.CAST_SPELL, CastSpellEntityRenderer::new);

View file

@ -59,12 +59,12 @@ public class DismissSpellScreen extends GameGui {
matrices.push();
matrices.translate(width - mouseX, height - mouseY, 0);
DrawableUtil.drawLine(matrices, 0, 0, relativeMouseX, relativeMouseY, 0xFFFFFF88);
DrawableUtil.drawArc(matrices, 40, 80, 0, DrawableUtil.TWO_PI, 0x00000010, false);
DrawableUtil.drawArc(matrices, 160, 1600, 0, DrawableUtil.TWO_PI, 0x00000020, false);
DrawableUtil.drawArc(matrices, 40, 80, 0, DrawableUtil.TAU, 0x00000010, false);
DrawableUtil.drawArc(matrices, 160, 1600, 0, DrawableUtil.TAU, 0x00000020, false);
super.render(matrices, mouseX, mouseY, delta);
DrawableUtil.drawCircle(matrices, 2, 0, DrawableUtil.TWO_PI, 0xFFAAFF99, false);
DrawableUtil.drawCircle(matrices, 2, 0, DrawableUtil.TAU, 0xFFAAFF99, false);
matrices.pop();
DrawableUtil.drawLine(matrices, mouseX, mouseY - 4, mouseX, mouseY + 4, 0xFFAAFF99);
@ -159,10 +159,10 @@ public class DismissSpellScreen extends GameGui {
int color = actualSpell.getType().getColor() << 2;
DrawableUtil.drawArc(matrices, 7, 8, 0, DrawableUtil.TWO_PI, color | 0x00000088, false);
DrawableUtil.drawArc(matrices, 7, 8, 0, DrawableUtil.TAU, color | 0x00000088, false);
if (isMouseOver(relativeMouseX, relativeMouseY)) {
DrawableUtil.drawArc(matrices, 0, 8, 0, DrawableUtil.TWO_PI, color | 0x000000FF, false);
DrawableUtil.drawArc(matrices, 0, 8, 0, DrawableUtil.TAU, color | 0x000000FF, false);
renderTooltip(matrices, tooltip, 0, 0);
if (!lastMouseOver) {

View file

@ -15,9 +15,10 @@ import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Matrix4f;
public class DrawableUtil {
public static final double TWO_PI = Math.PI * 2;
public static final double PI = Math.PI;
public static final double TAU = Math.PI * 2;
private static final double NUM_RINGS = 300;
private static final double INCREMENT = TWO_PI / NUM_RINGS;
private static final double INCREMENT = TAU / NUM_RINGS;
public static void renderItemIcon(ItemStack stack, double x, double y, float scale) {
@ -76,7 +77,7 @@ public class DrawableUtil {
return;
}
final double maxAngle = MathHelper.clamp(startAngle + arcAngle, 0, TWO_PI - INCREMENT);
final double maxAngle = MathHelper.clamp(startAngle + arcAngle, 0, TAU - INCREMENT);
if (!mirrorHorizontally) {
startAngle = -startAngle;
@ -137,7 +138,7 @@ public class DrawableUtil {
return;
}
final double maxAngle = MathHelper.clamp(startAngle + arcAngle, 0, TWO_PI - INCREMENT);
final double maxAngle = MathHelper.clamp(startAngle + arcAngle, 0, TAU - INCREMENT);
if (!mirrorHorizontally) {
startAngle = -startAngle;

View file

@ -62,8 +62,8 @@ class ManaRingSlot extends Slot {
}
private double renderRing(MatrixStack matrices, double outerRadius, double innerRadius, double offsetAngle, Bar bar, int color, float tickDelta) {
double fill = bar.getPercentFill() * DrawableUtil.TWO_PI;
double shadow = bar.getShadowFill() * DrawableUtil.TWO_PI;
double fill = bar.getPercentFill() * DrawableUtil.TAU;
double shadow = bar.getShadowFill() * DrawableUtil.TAU;
DrawableUtil.drawArc(matrices, innerRadius, outerRadius, offsetAngle, fill, color, true);

View file

@ -167,8 +167,8 @@ public class UHud extends DrawableHelper {
int color = spell.type().getColor() | 0x000000FF;
double radius = 2 + Math.sin(client.player.age / 9D) / 4;
DrawableUtil.drawArc(modelStack, radius, radius + 3, 0, DrawableUtil.TWO_PI, color & 0xFFFFFF2F, false);
DrawableUtil.drawArc(modelStack, radius + 3, radius + 4, 0, DrawableUtil.TWO_PI, color & 0xFFFFFFAF, false);
DrawableUtil.drawArc(modelStack, radius, radius + 3, 0, DrawableUtil.TAU, color & 0xFFFFFF2F, false);
DrawableUtil.drawArc(modelStack, radius + 3, radius + 4, 0, DrawableUtil.TAU, color & 0xFFFFFFAF, false);
modelStack.pop();
}

View file

@ -4,6 +4,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import com.minelittlepony.unicopia.client.gui.DrawableUtil;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Matrix4f;
@ -11,18 +13,15 @@ import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.Vector4f;
public class SphereModel {
protected static final double PI = Math.PI;
protected static final double TWO_PI = PI * 2F;
public static final SphereModel SPHERE = new SphereModel(40, 40, TWO_PI);
public static final SphereModel DISK = new SphereModel(40, 2, PI);
public static final SphereModel SPHERE = new SphereModel(40, 40, DrawableUtil.TAU);
public static final SphereModel DISK = new SphereModel(40, 2, DrawableUtil.PI);
private final List<Vector4f> vertices = new ArrayList<>();
private final Vector4f drawVert = new Vector4f();
public SphereModel(double rings, double sectors, double azimuthRange) {
double zenithIncrement = PI / rings;
double azimuthIncrement = TWO_PI / sectors;
double zenithIncrement = DrawableUtil.PI / rings;
double azimuthIncrement = DrawableUtil.TAU / sectors;
compileVertices(azimuthRange, zenithIncrement, azimuthIncrement, vertices::add);
}
@ -41,7 +40,7 @@ public class SphereModel {
}
private static void compileVertices(double azimuthRange, double zenithIncrement, double azimuthIncrement, Consumer<Vector4f> collector) {
for (double zenith = -PI; zenith < PI; zenith += zenithIncrement) {
for (double zenith = -DrawableUtil.PI; zenith < DrawableUtil.PI; zenith += zenithIncrement) {
for (double azimuth = -azimuthRange; azimuth < azimuthRange; azimuth += azimuthIncrement) {
collector.accept(convertToCartesianCoord(new Vector4f(), 1, zenith, azimuth));
collector.accept(convertToCartesianCoord(new Vector4f(), 1, zenith + zenithIncrement, azimuth));

View file

@ -0,0 +1,96 @@
package com.minelittlepony.unicopia.client.render.entity;
import com.minelittlepony.unicopia.client.render.RenderLayers;
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
import net.minecraft.client.model.Dilation;
import net.minecraft.client.model.ModelData;
import net.minecraft.client.model.ModelPart;
import net.minecraft.client.model.ModelPartBuilder;
import net.minecraft.client.model.ModelPartData;
import net.minecraft.client.model.ModelTransform;
import net.minecraft.client.model.TexturedModelData;
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.EntityRenderer;
import net.minecraft.client.render.entity.EntityRendererFactory;
import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.screen.PlayerScreenHandler;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
public class MagicBeamEntityRenderer extends EntityRenderer<MagicProjectileEntity> {
private final Model model;
public MagicBeamEntityRenderer(EntityRendererFactory.Context ctx) {
super(ctx);
this.model = new Model(Model.getData().createModel());
}
@Override
public Identifier getTexture(MagicProjectileEntity entity) {
return PlayerScreenHandler.BLOCK_ATLAS_TEXTURE;
}
@Override
protected int getBlockLight(MagicProjectileEntity entity, BlockPos pos) {
return 15;
}
@Override
public void render(MagicProjectileEntity entity, float yaw, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light) {
if (entity.age < 2 && dispatcher.camera.getFocusedEntity().squaredDistanceTo(entity) < 8) {
return;
}
matrices.push();
model.setAngles(entity, 0, 0, tickDelta,
entity.getYaw(tickDelta) * MathHelper.RADIANS_PER_DEGREE,
-entity.getPitch(tickDelta) * MathHelper.RADIANS_PER_DEGREE
);
RenderLayer layer = model.getLayer(getTexture(entity));
model.render(matrices, vertexConsumers.getBuffer(layer), light, OverlayTexture.DEFAULT_UV, 1, 1, 1, 1);
matrices.pop();
super.render(entity, yaw, tickDelta, matrices, vertexConsumers, light);
}
public class Model extends EntityModel<MagicProjectileEntity> {
private final ModelPart part;
public Model(ModelPart part) {
super(texture -> RenderLayers.getFairy());
this.part = part;
}
static TexturedModelData getData() {
ModelData data = new ModelData();
ModelPartData tree = data.getRoot();
tree.addChild("beam", ModelPartBuilder.create()
.cuboid(0, 0, 0, 1, 1, 17)
.cuboid(0, 0, 0, 1, 1, 17, new Dilation(0.25F)), ModelTransform.NONE);
return TexturedModelData.of(data, 64, 64);
}
@Override
public void setAngles(MagicProjectileEntity entity, float limbAngle, float limbDistance, float customAngle, float headYaw, float headPitch) {
part.pitch = headPitch;
part.yaw = headYaw;
}
@Override
public void render(MatrixStack matrices, VertexConsumer vertexConsumer, int light, int overlay, float red, float green, float blue, float alpha) {
part.render(matrices, vertexConsumer, light, overlay, red, green, blue, alpha);
}
}
}

View file

@ -11,8 +11,7 @@ import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.Identifier;
public class SpellbookEntityRenderer extends LivingEntityRenderer<SpellbookEntity, SpellbookModel> {
private static final Identifier BLUE = new Identifier("unicopia", "textures/entity/spellbook/blue.png");
private static final Identifier NORMAL = new Identifier("unicopia", "textures/entity/spellbook/normal.png");
private static final Identifier TEXTURE = new Identifier("unicopia", "textures/entity/spellbook/normal.png");
public SpellbookEntityRenderer(EntityRendererFactory.Context context) {
super(context, new SpellbookModel(SpellbookModel.getTexturedModelData().createModel()), 0);
@ -20,7 +19,7 @@ public class SpellbookEntityRenderer extends LivingEntityRenderer<SpellbookEntit
@Override
public Identifier getTexture(SpellbookEntity entity) {
return entity.isAltered() ? BLUE : NORMAL;
return TEXTURE;
}
@Override

View file

@ -25,6 +25,10 @@ public interface UEntities {
.trackRangeBlocks(100)
.trackedUpdateRate(2)
.dimensions(EntityDimensions.fixed(0.25F, 0.25F)));
EntityType<MagicProjectileEntity> MAGIC_BEAM = register("magic_beam", FabricEntityTypeBuilder.<MagicProjectileEntity>create(SpawnGroup.MISC, MagicProjectileEntity::new)
.trackRangeBlocks(100)
.trackedUpdateRate(2)
.dimensions(EntityDimensions.fixed(0.25F, 0.25F)));
EntityType<FloatingArtefactEntity> FLOATING_ARTEFACT = register("floating_artefact", FabricEntityTypeBuilder.create(SpawnGroup.MISC, FloatingArtefactEntity::new)
.trackRangeBlocks(200)
.dimensions(EntityDimensions.fixed(1, 1)));