Added an option to turn off third person magic and make arm animations for unicorns consistent with other races

This commit is contained in:
Sollace 2021-06-20 02:25:06 +02:00
parent 556b4d780e
commit 53625f6b44
9 changed files with 26 additions and 74 deletions

View file

@ -1,13 +1,6 @@
package com.minelittlepony.api.model;
import net.minecraft.util.Arm;
public interface IUnicorn<ArmModel> extends IModel {
/**
* Gets the arm used for holding items in their magic.
*/
ArmModel getUnicornArmForSide(Arm side);
public interface IUnicorn extends IModel {
/**
* Returns true if this model is being applied to a race that can use magic.
*/

View file

@ -529,13 +529,15 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
float sin = MathHelper.sin(ticks * 0.067F) * 0.05F;
if (shouldLiftArm(rightArmPose, leftArmPose, -1)) {
rightArm.roll += cos;
rightArm.pitch += sin;
ModelPart arm = getArm(Arm.RIGHT);
arm.roll += cos;
arm.pitch += sin;
}
if (shouldLiftArm(leftArmPose, rightArmPose, 1)) {
leftArm.roll += cos;
leftArm.pitch += sin;
ModelPart arm = getArm(Arm.LEFT);
arm.roll += cos;
arm.pitch += sin;
}
}

View file

@ -106,13 +106,7 @@ public interface IPonyMixinModel<T extends LivingEntity, M extends IPonyModel<T>
return mixin().getBodyPart(part);
}
interface Caster<T extends LivingEntity, M extends IPonyModel<T> & IUnicorn<ArmModel>, ArmModel> extends IPonyMixinModel<T, M>, IUnicorn<ArmModel> {
@Override
default ArmModel getUnicornArmForSide(Arm side) {
return mixin().getUnicornArmForSide(side);
}
interface Caster<T extends LivingEntity, M extends IPonyModel<T> & IUnicorn, ArmModel> extends IPonyMixinModel<T, M>, IUnicorn {
@Override
default boolean isCasting() {
return mixin().isCasting();

View file

@ -2,6 +2,7 @@ package com.minelittlepony.client.model.entity.race;
import com.minelittlepony.api.model.BodyPart;
import com.minelittlepony.api.model.IUnicorn;
import com.minelittlepony.client.MineLittlePony;
import com.minelittlepony.client.model.part.UnicornHorn;
import com.minelittlepony.mson.api.ModelContext;
@ -10,12 +11,11 @@ import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.Arm;
import net.minecraft.util.math.MathHelper;
/**
* Used for both unicorns and alicorns since there's no logical way to keep them distinct and not duplicate stuff.
*/
public class UnicornModel<T extends LivingEntity> extends EarthPonyModel<T> implements IUnicorn<ModelPart> {
public class UnicornModel<T extends LivingEntity> extends EarthPonyModel<T> implements IUnicorn {
protected final ModelPart unicornArmRight;
protected final ModelPart unicornArmLeft;
@ -36,10 +36,7 @@ public class UnicornModel<T extends LivingEntity> extends EarthPonyModel<T> impl
@Override
public float getWobbleAmount() {
if (isCasting()) {
return 0;
}
return super.getWobbleAmount();
return isCasting() ? 0 : super.getWobbleAmount();
}
@Override
@ -53,34 +50,10 @@ public class UnicornModel<T extends LivingEntity> extends EarthPonyModel<T> impl
unicornArmLeft.setPivot(-7, 12, -2);
}
@Override
protected void animateBreathing(float ticks) {
if (canCast()) {
float cos = MathHelper.cos(ticks * 0.09F) * 0.05F + 0.05F;
float sin = MathHelper.sin(ticks * 0.067F) * 0.05F;
if (rightArmPose != ArmPose.EMPTY) {
unicornArmRight.roll += cos;
unicornArmRight.pitch += sin;
}
if (leftArmPose != ArmPose.EMPTY) {
unicornArmLeft.roll += cos;
unicornArmLeft.pitch += sin;
}
} else {
super.animateBreathing(ticks);
}
}
@Override
public ModelPart getUnicornArmForSide(Arm side) {
return side == Arm.LEFT ? unicornArmLeft : unicornArmRight;
}
@Override
public boolean isCasting() {
return rightArmPose != ArmPose.EMPTY || leftArmPose != ArmPose.EMPTY;
return MineLittlePony.getInstance().getConfig().tpsmagic.get()
&& (rightArmPose != ArmPose.EMPTY || leftArmPose != ArmPose.EMPTY);
}
@Override
@ -115,8 +88,8 @@ public class UnicornModel<T extends LivingEntity> extends EarthPonyModel<T> impl
@Override
public ModelPart getArm(Arm side) {
if (canCast() && getArmPoseForSide(side) != ArmPose.EMPTY) {
return getUnicornArmForSide(side);
if (canCast() && getArmPoseForSide(side) != ArmPose.EMPTY && MineLittlePony.getInstance().getConfig().tpsmagic.get()) {
return side == Arm.LEFT ? unicornArmLeft : unicornArmRight;
}
return super.getArm(side);
}

View file

@ -17,7 +17,6 @@ import com.minelittlepony.client.render.entity.feature.SkullFeature;
import com.minelittlepony.client.render.entity.feature.ElytraFeature;
import com.minelittlepony.mson.api.ModelKey;
import net.minecraft.client.model.ModelPart;
import net.minecraft.client.render.Frustum;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.EntityRendererFactory;
@ -128,7 +127,7 @@ public abstract class PonyRenderer<T extends MobEntity, M extends EntityModel<T>
return MineLittlePony.getInstance().getManager().getPony(findTexture(entity));
}
public abstract static class Caster<T extends MobEntity, M extends ClientPonyModel<T> & IUnicorn<ModelPart>> extends PonyRenderer<T, M> {
public abstract static class Caster<T extends MobEntity, M extends ClientPonyModel<T> & IUnicorn> extends PonyRenderer<T, M> {
public Caster(EntityRendererFactory.Context context, ModelKey<? super M> key) {
super(context, key);

View file

@ -1,11 +1,11 @@
package com.minelittlepony.client.render.entity.feature;
import com.minelittlepony.api.model.IUnicorn;
import com.minelittlepony.client.MineLittlePony;
import com.minelittlepony.client.model.IPonyModel;
import com.minelittlepony.client.render.IPonyRenderContext;
import com.minelittlepony.client.render.PonyRenderDispatcher;
import net.minecraft.client.model.ModelPart;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.client.render.model.json.ModelTransformation;
@ -23,20 +23,21 @@ public class GlowingItemFeature<T extends LivingEntity, M extends EntityModel<T>
}
protected boolean isUnicorn() {
return getContextModel() instanceof IUnicorn<?> && ((IUnicorn<?>)getContextModel()).canCast();
return MineLittlePony.getInstance().getConfig().tpsmagic.get()
&& getContextModel() instanceof IUnicorn
&& ((IUnicorn)getContextModel()).canCast();
}
@Override
protected void preItemRender(T entity, ItemStack drop, ModelTransformation.Mode transform, Arm hand, MatrixStack stack) {
float left = hand == Arm.LEFT ? 1 : -1;
super.preItemRender(entity, drop, transform, hand, stack);
float left = hand == Arm.LEFT ? 1 : -1;
if (isUnicorn()) {
stack.translate(-0.3F - (0.3F * left), 0.375F, 0.6F);
}
UseAction action = drop.getUseAction();
if (isUnicorn() && (action == UseAction.SPYGLASS || action == UseAction.BOW) && entity.getItemUseTimeLeft() > 0) {
@ -48,23 +49,12 @@ public class GlowingItemFeature<T extends LivingEntity, M extends EntityModel<T>
stack.translate(-0.1F + (0.3F * left), -0.1F, -1.1F);
}
}
}
@Override
protected void postItemRender(T entity, ItemStack drop, ModelTransformation.Mode transform, Arm hand, MatrixStack stack, VertexConsumerProvider renderContext) {
if (isUnicorn()) {
PonyRenderDispatcher.getInstance().getMagicRenderer().renderItemGlow(entity, drop, transform, hand, ((IUnicorn<?>)getContextModel()).getMagicColor(), stack, renderContext);
}
}
@SuppressWarnings("unchecked")
@Override
protected void renderArm(Arm arm, MatrixStack stack) {
if (isUnicorn()) {
((IUnicorn<ModelPart>)getContextModel()).getUnicornArmForSide(arm).rotate(stack);
} else {
super.renderArm(arm, stack);
PonyRenderDispatcher.getInstance().getMagicRenderer().renderItemGlow(entity, drop, transform, hand, ((IUnicorn)getContextModel()).getMagicColor(), stack, renderContext);
}
}
}

View file

@ -1,6 +1,5 @@
package com.minelittlepony.client.render.entity.npc;
import net.minecraft.client.model.ModelPart;
import net.minecraft.client.render.entity.EntityRendererFactory;
import net.minecraft.client.render.entity.model.ModelWithHat;
import net.minecraft.entity.mob.MobEntity;
@ -17,7 +16,7 @@ import com.minelittlepony.mson.api.ModelKey;
abstract class AbstractNpcRenderer<
T extends MobEntity & VillagerDataContainer,
M extends ClientPonyModel<T> & IUnicorn<ModelPart> & ModelWithHat> extends PonyRenderer.Caster<T, M> {
M extends ClientPonyModel<T> & IUnicorn & ModelWithHat> extends PonyRenderer.Caster<T, M> {
private final TextureSupplier<T> baseTextures;

View file

@ -23,6 +23,7 @@ public class PonyConfig extends JsonConfig {
public final Setting<Boolean> fillycam = value("settings", "fillycam", true);
private final Setting<Boolean> showscale = value("settings", "showscale", true);
public final Setting<Boolean> fpsmagic = value("settings", "fpsmagic", true);
public final Setting<Boolean> tpsmagic = value("settings", "tpsmagic", true);
public final Setting<Boolean> ponyskulls = value("settings", "ponyskulls", true);
public final Setting<Boolean> frustrum = value("settings", "frustrum", true);

View file

@ -17,6 +17,7 @@
"minelp.options.fillycam": "Filly Cam",
"minelp.options.showscale": "Show-accurate scaling",
"minelp.options.fpsmagic": "Magic in first-person",
"minelp.options.tpsmagic": "Magic in third-person",
"minelp.options.ponyskulls": "Pony Skulls",
"minelp.options.frustrum": "Frustum checks",
"minelp.options.button": "Display On Title Screen",