Added an emote command, further refine animations, add some new animations

This commit is contained in:
Sollace 2022-01-04 17:57:57 +02:00
parent bce1e5c8c1
commit fbc82ec6bc
9 changed files with 190 additions and 28 deletions

View file

@ -107,14 +107,14 @@ public class UnicornCastingAbility implements Ability<Hit> {
player.spawnParticles(ParticleTypes.LARGE_SMOKE, 6);
player.playSound(SoundEvents.ENTITY_ITEM_BREAK, 1, 0.5F);
} else {
player.setAnimation(Animation.ARMS_UP, 5);
player.setAnimation(Animation.ARMS_UP);
if (s instanceof HomingSpell) {
RayTraceHelper.doTrace(player.getMaster(), 600, 1, EntityPredicates.CAN_COLLIDE).getEntity().ifPresent(((HomingSpell)s)::setTarget);
}
player.playSound(SoundEvents.BLOCK_BEACON_POWER_SELECT, 0.05F, 2.2F);
}
} else {
player.setAnimation(Animation.WOLOLO, 20);
player.setAnimation(Animation.WOLOLO);
}
}
}

View file

@ -75,7 +75,7 @@ public class UnicornDispellAbility implements Ability<Pos> {
@Override
public void apply(Pony player, Pos data) {
player.setAnimation(Animation.WOLOLO, 30);
player.setAnimation(Animation.WOLOLO);
Caster.stream(VecHelper.findInRange(player.getEntity(), player.getWorld(), data.vec(), 2, EquinePredicates.IS_PLACED_SPELL).stream()).forEach(target -> {
target.getSpellSlot().clear();
});

View file

@ -70,7 +70,7 @@ public class UnicornProjectileAbility implements Ability<Hit> {
Spell spell = thrown.getValue().create();
spell.toThrowable().throwProjectile(player).ifPresent(projectile -> {
player.setAnimation(Animation.ARMS_FORWARD, 5);
player.setAnimation(Animation.ARMS_FORWARD);
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

@ -5,14 +5,19 @@ import com.minelittlepony.unicopia.Race;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.player.PlayerEntity;
public final class MineLPConnector {
public static Race getPlayerPonyRace() {
if (!FabricLoader.getInstance().isModLoaded("minelp") || MinecraftClient.getInstance().player == null) {
return getPlayerPonyRace(MinecraftClient.getInstance().player);
}
public static Race getPlayerPonyRace(PlayerEntity player) {
if (!FabricLoader.getInstance().isModLoaded("minelp") || player == null) {
return Race.HUMAN;
}
switch (MineLittlePony.getInstance().getManager().getPony(MinecraftClient.getInstance().player).getRace(false)) {
switch (MineLittlePony.getInstance().getManager().getPony(player).getRace(false)) {
case ALICORN:
return Race.ALICORN;
case CHANGELING:

View file

@ -1,24 +1,33 @@
package com.minelittlepony.unicopia.client.render;
import java.util.Optional;
import com.minelittlepony.unicopia.client.minelittlepony.MineLPConnector;
import com.minelittlepony.unicopia.entity.player.Pony;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.entity.model.BipedEntityModel;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.sound.SoundEvent;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.Arm;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3f;
public class PlayerPoser {
public static final PlayerPoser INSTANCE = new PlayerPoser();
public void applyPosing(PlayerEntity entity, BipedEntityModel<?> model) {
Pony pony = Pony.of(entity);
public void applyPosing(MatrixStack matrices, PlayerEntity player, BipedEntityModel<?> model) {
Pony pony = Pony.of(player);
float progress = pony.getAnimationProgress(MinecraftClient.getInstance().getTickDelta());
Animation animation = pony.getAnimation();
boolean isPony = !MineLPConnector.getPlayerPonyRace(player).isDefault();
switch (pony.getAnimation()) {
switch (animation) {
case WOLOLO: {
float roll = MathHelper.sin(entity.age / 10F);
float yaw = MathHelper.cos(entity.age / 10F);
float roll = MathHelper.sin(player.age / 10F);
float yaw = MathHelper.cos(player.age / 10F);
model.leftArm.pitch += -1;
model.rightArm.pitch += -1;
@ -62,30 +71,138 @@ public class PlayerPoser {
model.rightArm.yaw = -yaw;
break;
}
case WAVE_ONE:
case WAVE_TWO: {
progress = seesaw(progress);
if (animation == Animation.WAVE_TWO && isPony) {
rearUp(matrices, model, progress);
model.head.pitch += progress;
model.hat.pitch += progress;
}
float wave = 2.5F + progress * MathHelper.sin(player.age / 3F);
if (animation == Animation.WAVE_TWO || player.getMainArm() == Arm.LEFT) {
model.leftArm.roll = -wave;
}
if (animation == Animation.WAVE_TWO || player.getMainArm() == Arm.RIGHT) {
model.rightArm.roll = wave;
}
break;
}
case KICK: {
if (isPony) {
float roll = (progress + 1) / 2F;
model.rightLeg.pitch = roll * 1.5F;
model.rightLeg.yaw = -roll / 7F;
model.leftLeg.pitch = roll * 1.5F;
model.leftLeg.yaw = roll / 7F;
model.leftArm.pitch = 0;
model.leftArm.roll = -roll / 7F;
model.rightArm.pitch = 0;
model.rightArm.roll = roll / 7F;
break;
}
float roll = (progress + 1) / 2F;
model.rightArm.pitch += roll / 5F;
model.leftArm.roll -= roll / 5F;
model.rightArm.roll += roll / 5F;
if (entity.getMainArm() == Arm.LEFT) {
if (player.getMainArm() == Arm.LEFT) {
model.rightLeg.pitch = -roll * 1.5F;
model.rightLeg.roll = roll / 10F;
} else {
model.leftLeg.pitch = -roll * 1.5F;
model.leftLeg.roll = -roll / 10F;
}
break;
}
case STOMP: {
progress = seesaw(progress);
if (!isPony) {
if (player.getMainArm() == Arm.LEFT) {
model.rightLeg.roll = -progress / 9F;
model.rightLeg.pivotY -= progress * 5;
} else {
model.leftLeg.roll = -progress / 9F;
model.leftLeg.pivotY -= progress * 5;
}
break;
}
rearUp(matrices, model, progress);
break;
}
case WIGGLE_NOSE: {
if (!isPony) {
break;
}
progress = seesaw(progress) * MathHelper.sin(player.age / 4F);
model.getHead().getChild("mare").pivotY += progress;
model.getHead().getChild("stallion").pivotY += progress;
break;
}
default:
}
}
private void rearUp(MatrixStack matrices, BipedEntityModel<?> model, float progress) {
matrices.translate(0, 0, 0.5);
matrices.multiply(Vec3f.POSITIVE_X.getDegreesQuaternion(-45 * progress));
matrices.translate(0, 0, -0.5);
float roll = progress / 2F;
model.rightLeg.pitch = roll * 1.5F;
model.rightLeg.yaw = -roll / 7F;
model.leftLeg.pitch = roll * 1.5F;
model.leftLeg.yaw = roll / 7F;
}
static float seesaw(float progress) {
return Math.max(0, MathHelper.cos((progress - 0.5F) * (float)Math.PI));
}
public enum Animation {
NONE,
WOLOLO,
ARMS_FORWARD,
ARMS_UP,
KICK
NONE(0),
WOLOLO(SoundEvents.ENTITY_EVOKER_PREPARE_WOLOLO, 40),
ARMS_FORWARD(5),
ARMS_UP(5),
WAVE_ONE(20),
WAVE_TWO(20),
KICK(SoundEvents.ENTITY_PHANTOM_FLAP, 5),
STOMP(5),
WIGGLE_NOSE(6);
private final int duration;
private final Optional<SoundEvent> sound;
Animation(int duration) {
this.duration = duration;
this.sound = Optional.empty();
}
Animation(SoundEvent sound, int duration) {
this.duration = duration;
this.sound = Optional.of(sound);
}
public int getDuration() {
return duration;
}
public Optional<SoundEvent> getSound() {
return sound;
}
}
}

View file

@ -15,6 +15,7 @@ public class Commands {
GravityCommand.register(dispatcher);
DisguiseCommand.register(dispatcher);
TraitCommand.register(dispatcher);
EmoteCommand.register(dispatcher);
});
Object game = FabricLoader.getInstance().getGameInstance();
if (game instanceof MinecraftServer) {

View file

@ -0,0 +1,36 @@
package com.minelittlepony.unicopia.command;
import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation;
import com.minelittlepony.unicopia.entity.player.Pony;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource;
public class EmoteCommand {
static void register(CommandDispatcher<ServerCommandSource> dispatcher) {
dispatcher.register(CommandManager
.literal("emote")
.then(CommandManager.argument("animation", EnumArgumentType.of(Animation.class)).executes(source -> apply(
source.getSource(),
source.getArgument("animation", Animation.class)
)
).then(CommandManager.argument("duration", IntegerArgumentType.integer(1, 99)).executes(source -> apply(
source.getSource(),
source.getArgument("animation", Animation.class),
source.getArgument("duration", Integer.class)
)
)
)));
}
static int apply(ServerCommandSource source, Animation animation) throws CommandSyntaxException {
return apply(source, animation, animation.getDuration());
}
static int apply(ServerCommandSource source, Animation animation, int duration) throws CommandSyntaxException {
Pony.of(source.getPlayer()).setAnimation(animation, duration);
return 0;
}
}

View file

@ -60,7 +60,6 @@ import net.minecraft.nbt.NbtCompound;
import net.minecraft.network.packet.s2c.play.EntityPassengersSetS2CPacket;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundEvents;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Hand;
@ -128,6 +127,10 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
builder.add(PlayerAttributes.ENTITY_GRAVTY_MODIFIER);
}
public void setAnimation(Animation animation) {
setAnimation(animation, animation.getDuration());
}
public void setAnimation(Animation animation, int duration) {
if (animation != this.animation && duration != animationDuration) {
this.animation = animation;
@ -138,9 +141,9 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
Channel.SERVER_PLAYER_ANIMATION_CHANGE.send(getWorld(), new MsgPlayerAnimationChange(this, animation, animationDuration));
}
if (animation == Animation.WOLOLO) {
playSound(SoundEvents.ENTITY_EVOKER_PREPARE_WOLOLO, 0.9F, 1);
}
animation.getSound().ifPresent(sound -> {
playSound(sound, 0.9F, 1);
});
}
}
@ -152,7 +155,7 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
if (animation == Animation.NONE) {
return 0;
}
return 1 - ((animationDuration + delta) / animationMaxDuration);
return 1 - (((float)animationDuration) / animationMaxDuration);
}
@Override
@ -324,7 +327,7 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
public void tick() {
if (animationDuration >= 0) {
if (--animationDuration <= 0) {
setAnimation(Animation.NONE, 0);
setAnimation(Animation.NONE);
}
}

View file

@ -37,13 +37,13 @@ abstract class MixinLivingEntityRenderer<T extends LivingEntity, M extends Entit
)
private void onRender(
T entity,
float f, float g,
MatrixStack matrixStack,
VertexConsumerProvider vertexConsumerProvider,
int i,
float yaw, float tickDelta,
MatrixStack matrices,
VertexConsumerProvider vertices,
int light,
CallbackInfo into) {
if (entity instanceof PlayerEntity player) {
PlayerPoser.INSTANCE.applyPosing(player, (BipedEntityModel<?>)getModel());
PlayerPoser.INSTANCE.applyPosing(matrices, player, (BipedEntityModel<?>)getModel());
}
}
}