mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-01 03:26:44 +01:00
Improved animations when casting or dispelling spells and added animations when using magic staffs. #151
This commit is contained in:
parent
3dec711b78
commit
b337709f78
20 changed files with 304 additions and 168 deletions
|
@ -76,7 +76,7 @@ public class BatEeeeAbility implements Ability<Hit> {
|
|||
}, rng.nextInt(10));
|
||||
|
||||
if (!player.getPhysics().isFlying()) {
|
||||
player.setAnimation(Animation.SPREAD_WINGS);
|
||||
player.setAnimation(Animation.SPREAD_WINGS, Animation.Recipient.ANYONE);
|
||||
}
|
||||
|
||||
Vec3d origin = player.getOriginVector();
|
||||
|
|
|
@ -88,14 +88,14 @@ public class EarthPonyKickAbility implements Ability<Pos> {
|
|||
entity.takeKnockback(calculatedStrength, origin.x - entity.getX(), origin.z - entity.getZ());
|
||||
Living.updateVelocity(entity);
|
||||
player.subtractEnergyCost(3);
|
||||
player.setAnimation(Animation.KICK);
|
||||
player.setAnimation(Animation.KICK, Animation.Recipient.ANYONE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
BlockPos pos = kickLocation.pos();
|
||||
EarthPonyStompAbility.stompBlock(w, pos, 10 * (1 + player.getLevel().getScaled(5)) * w.getBlockState(pos).calcBlockBreakingDelta(player.asEntity(), w, pos));
|
||||
player.setAnimation(Animation.KICK);
|
||||
player.setAnimation(Animation.KICK, Animation.Recipient.ANYONE);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -153,7 +153,7 @@ public class EarthPonyKickAbility implements Ability<Pos> {
|
|||
BlockPos pos = data.pos();
|
||||
TreeType tree = TreeType.at(pos, iplayer.asWorld());
|
||||
|
||||
iplayer.setAnimation(Animation.KICK);
|
||||
iplayer.setAnimation(Animation.KICK, Animation.Recipient.ANYONE);
|
||||
iplayer.subtractEnergyCost(tree == TreeType.NONE ? 1 : 3);
|
||||
|
||||
if (tree == TreeType.NONE) {
|
||||
|
|
|
@ -95,7 +95,7 @@ public class EarthPonyStompAbility implements Ability<Hit> {
|
|||
public void apply(Pony iplayer, Hit data) {
|
||||
PlayerEntity player = iplayer.asEntity();
|
||||
|
||||
iplayer.setAnimation(Animation.STOMP, 10);
|
||||
iplayer.setAnimation(Animation.STOMP, Animation.Recipient.ANYONE, 10);
|
||||
|
||||
thrustDownwards(iplayer);
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ public class PegasusFlightToggleAbility implements Ability<Hit> {
|
|||
player.getPhysics().cancelFlight(true);
|
||||
}
|
||||
player.setDirty();
|
||||
player.setAnimation(Animation.SPREAD_WINGS);
|
||||
player.setAnimation(Animation.SPREAD_WINGS, Animation.Recipient.ANYONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -111,14 +111,14 @@ public class UnicornCastingAbility extends AbstractSpellCastingAbility {
|
|||
player.spawnParticles(ParticleTypes.LARGE_SMOKE, 6);
|
||||
player.playSound(USounds.SPELL_CAST_FAIL, 1, 0.5F);
|
||||
} else {
|
||||
player.setAnimation(Animation.ARMS_UP);
|
||||
player.setAnimation(Animation.ARMS_UP, Animation.Recipient.HUMAN);
|
||||
if (s instanceof HomingSpell homer) {
|
||||
TraceHelper.findEntity(player.asEntity(), homer.getRange(player), 1, EntityPredicates.VALID_ENTITY).ifPresent(homer::setTarget);
|
||||
}
|
||||
player.playSound(USounds.SPELL_CAST_SUCCESS, 0.05F, 2.2F);
|
||||
}
|
||||
} else {
|
||||
player.setAnimation(Animation.WOLOLO);
|
||||
player.setAnimation(Animation.WOLOLO, Animation.Recipient.ANYONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ public class UnicornDispellAbility implements Ability<Pos> {
|
|||
|
||||
if (player.getSpecies() != Race.CHANGELING) {
|
||||
if (type.getTapCount() > 1) {
|
||||
player.setAnimation(Animation.WOLOLO, 10);
|
||||
player.setAnimation(Animation.WOLOLO, Animation.Recipient.ANYONE, 10);
|
||||
if (player.getSpellSlot().clear()) {
|
||||
player.asEntity().sendMessage(Text.translatable("gui.unicopia.action.spells_cleared"), true);
|
||||
} else {
|
||||
|
@ -90,7 +90,7 @@ public class UnicornDispellAbility implements Ability<Pos> {
|
|||
|
||||
@Override
|
||||
public void apply(Pony player, Pos data) {
|
||||
player.setAnimation(Animation.WOLOLO);
|
||||
player.setAnimation(Animation.WOLOLO, Animation.Recipient.ANYONE);
|
||||
Caster.stream(VecHelper.findInRange(player.asEntity(), player.asWorld(), data.vec(), 3, EquinePredicates.IS_PLACED_SPELL).stream()).forEach(target -> {
|
||||
target.getSpellSlot().clear();
|
||||
});
|
||||
|
|
|
@ -43,7 +43,7 @@ public class UnicornProjectileAbility extends AbstractSpellCastingAbility {
|
|||
if (thrown.getResult() != ActionResult.FAIL) {
|
||||
thrown.getValue().create().toThrowable().throwProjectile(player).ifPresent(projectile -> {
|
||||
player.subtractEnergyCost(getCostEstimate(player));
|
||||
player.setAnimation(Animation.ARMS_FORWARD, 2);
|
||||
player.setAnimation(Animation.ARMS_FORWARD, Animation.Recipient.ANYONE, 2);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ public class UnicornProjectileAbility extends AbstractSpellCastingAbility {
|
|||
|
||||
spell.toThrowable().throwProjectile(player).ifPresent(projectile -> {
|
||||
player.subtractEnergyCost(getCostEstimate(player));
|
||||
player.setAnimation(Animation.ARMS_FORWARD);
|
||||
player.setAnimation(Animation.ARMS_FORWARD, Animation.Recipient.ANYONE);
|
||||
projectile.setHydrophobic();
|
||||
|
||||
if (spell instanceof HomingSpell) {
|
||||
|
|
|
@ -6,6 +6,7 @@ import java.util.stream.Collectors;
|
|||
import java.util.stream.Stream;
|
||||
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.command.CommandArgumentEnum;
|
||||
|
||||
import net.minecraft.command.argument.EnumArgumentType;
|
||||
import net.minecraft.item.Item;
|
||||
|
@ -17,7 +18,7 @@ import net.minecraft.util.Formatting;
|
|||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.StringIdentifiable;
|
||||
|
||||
public enum Trait implements StringIdentifiable {
|
||||
public enum Trait implements CommandArgumentEnum<Trait> {
|
||||
/**
|
||||
* Imparts physical strength or enhances endurance.
|
||||
* Spells with more of the strength trait hit harder and last longer.
|
||||
|
|
|
@ -51,7 +51,7 @@ public class Main extends MineLPDelegate implements ClientModInitializer {
|
|||
model.getAttributes().isGoingFast |= pony.getMotion().isRainbooming();
|
||||
model.getAttributes().isGoingFast &= !pony.getEntityInArms().isPresent();
|
||||
|
||||
if (pony.getAnimation() == Animation.SPREAD_WINGS) {
|
||||
if (pony.getAnimation().isOf(Animation.SPREAD_WINGS)) {
|
||||
model.getAttributes().wingAngle = -AnimationUtil.seeSitSaw(pony.getAnimationProgress(1), 1.5F) * (float)Math.PI / 1.2F;
|
||||
model.getAttributes().isFlying = true;
|
||||
}
|
||||
|
|
|
@ -2,8 +2,10 @@ package com.minelittlepony.unicopia.client.render;
|
|||
|
||||
import java.util.Optional;
|
||||
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.USounds;
|
||||
import com.minelittlepony.unicopia.client.minelittlepony.MineLPDelegate;
|
||||
import com.minelittlepony.unicopia.command.CommandArgumentEnum;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.item.GlassesItem;
|
||||
import com.minelittlepony.unicopia.util.AnimationUtil;
|
||||
|
@ -30,8 +32,12 @@ public class PlayerPoser {
|
|||
public void applyPosing(MatrixStack matrices, PlayerEntity player, BipedEntityModel<?> model, Context context) {
|
||||
Pony pony = Pony.of(player);
|
||||
float progress = pony.getAnimationProgress(MinecraftClient.getInstance().getTickDelta());
|
||||
Animation animation = pony.getAnimation();
|
||||
boolean isPony = MineLPDelegate.getInstance().getPlayerPonyRace(player).isEquine();
|
||||
AnimationInstance animation = pony.getAnimation();
|
||||
Race ponyRace = MineLPDelegate.getInstance().getPlayerPonyRace(player);
|
||||
Arm mainArm = player.getMainArm();
|
||||
|
||||
boolean liftLeftArm = mainArm == Arm.LEFT || !ponyRace.isEquine();
|
||||
boolean liftRightArm = mainArm == Arm.RIGHT || !ponyRace.isEquine();
|
||||
|
||||
ItemStack glasses = GlassesItem.getForEntity(player);
|
||||
|
||||
|
@ -43,7 +49,7 @@ public class PlayerPoser {
|
|||
|
||||
float beat30 = bop / 30F;
|
||||
|
||||
if (isPony) {
|
||||
if (ponyRace.isEquine()) {
|
||||
float beat50 = bop / 50F;
|
||||
float beat20 = bop / 20F;
|
||||
|
||||
|
@ -60,143 +66,160 @@ public class PlayerPoser {
|
|||
}
|
||||
}
|
||||
|
||||
switch (animation) {
|
||||
case NECK_SNAP: {
|
||||
head.yaw += 3F;
|
||||
head.pitch *= -1;
|
||||
break;
|
||||
}
|
||||
case WOLOLO: {
|
||||
float roll = MathHelper.sin(player.age / 10F);
|
||||
float yaw = MathHelper.cos(player.age / 10F);
|
||||
|
||||
model.leftArm.pitch += -1;
|
||||
model.rightArm.pitch += -1;
|
||||
|
||||
model.leftArm.roll = -roll;
|
||||
model.rightArm.roll = roll;
|
||||
|
||||
model.leftArm.yaw = yaw;
|
||||
model.rightArm.yaw = yaw;
|
||||
break;
|
||||
}
|
||||
case ARMS_FORWARD: {
|
||||
float roll = (progress + 1) / 2F;
|
||||
|
||||
float pitch = 1.5F * roll;
|
||||
float yaw = 0.5F * roll;
|
||||
|
||||
model.leftArm.pitch -= pitch;
|
||||
model.rightArm.pitch -= pitch;
|
||||
|
||||
model.leftArm.roll = 0;
|
||||
model.rightArm.roll = 0;
|
||||
|
||||
model.leftArm.yaw = yaw;
|
||||
model.rightArm.yaw = -yaw;
|
||||
break;
|
||||
}
|
||||
case ARMS_UP: {
|
||||
float roll = (progress + 1) / 2F;
|
||||
|
||||
float pitch = 3F * roll;
|
||||
float yaw = 0.5F * roll;
|
||||
|
||||
model.leftArm.pitch -= pitch;
|
||||
model.rightArm.pitch -= pitch;
|
||||
|
||||
model.leftArm.roll = 0;
|
||||
model.rightArm.roll = 0;
|
||||
|
||||
model.leftArm.yaw = yaw;
|
||||
model.rightArm.yaw = -yaw;
|
||||
break;
|
||||
}
|
||||
case WAVE_ONE:
|
||||
case WAVE_TWO: {
|
||||
progress = AnimationUtil.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;
|
||||
if (animation.canPlay(ponyRace.isEquine())) {
|
||||
switch (animation.animation()) {
|
||||
case NECK_SNAP: {
|
||||
head.yaw += 3F;
|
||||
head.pitch *= -1;
|
||||
break;
|
||||
}
|
||||
case WOLOLO: {
|
||||
float roll = MathHelper.sin(player.age / 10F);
|
||||
float yaw = MathHelper.cos(player.age / 10F);
|
||||
|
||||
float roll = (progress + 1) / 2F;
|
||||
if (liftLeftArm) {
|
||||
rotateArm(model.leftArm, 1, yaw, -roll);
|
||||
}
|
||||
|
||||
model.rightArm.pitch += roll / 5F;
|
||||
model.leftArm.roll -= roll / 5F;
|
||||
model.rightArm.roll += roll / 5F;
|
||||
if (liftRightArm) {
|
||||
rotateArm(model.leftArm, 1, yaw, roll);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case STOMP: {
|
||||
progress = AnimationUtil.seesaw(progress);
|
||||
case ARMS_FORWARD: {
|
||||
float roll = (progress + 1) / 2F;
|
||||
|
||||
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;
|
||||
float pitch = 1.5F * roll;
|
||||
float yaw = -0.5F * roll;
|
||||
|
||||
if (liftLeftArm) {
|
||||
rotateArm(model.leftArm, pitch, -yaw, 0);
|
||||
}
|
||||
|
||||
if (liftRightArm) {
|
||||
rotateArm(model.rightArm, pitch, yaw, 0);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case ARMS_UP: {
|
||||
float saw = AnimationUtil.seesaw(progress);
|
||||
|
||||
float pitch = 3F * saw;
|
||||
float yaw = 0.5F * saw;
|
||||
float roll = saw;
|
||||
|
||||
if (ponyRace.isEquine()) {
|
||||
rearUp(matrices, model, saw);
|
||||
pitch = roll * 2F;
|
||||
model.head.pitch += saw * 0.5F;
|
||||
}
|
||||
|
||||
if (liftLeftArm) {
|
||||
rotateArm(model.leftArm, pitch, -yaw, yaw);
|
||||
} else if (ponyRace.isEquine()) {
|
||||
model.leftArm.pitch += saw / 4F;
|
||||
model.leftArm.roll -= saw / 4F;
|
||||
}
|
||||
|
||||
if (liftRightArm) {
|
||||
rotateArm(model.rightArm, pitch, yaw, -yaw);
|
||||
} else if (ponyRace.isEquine()) {
|
||||
model.rightArm.pitch += saw / 4F;
|
||||
model.rightArm.roll += saw / 4F;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case WAVE_ONE:
|
||||
case WAVE_TWO: {
|
||||
progress = AnimationUtil.seesaw(progress);
|
||||
|
||||
if (animation.isOf(Animation.WAVE_TWO) && ponyRace.isEquine()) {
|
||||
rearUp(matrices, model, progress);
|
||||
model.head.pitch += progress * 0.5F;
|
||||
}
|
||||
|
||||
float wave = 2.5F + progress * MathHelper.sin(player.age / 3F);
|
||||
|
||||
if (animation.isOf(Animation.WAVE_TWO) || mainArm == Arm.LEFT) {
|
||||
model.leftArm.roll = -wave;
|
||||
}
|
||||
if (animation.isOf(Animation.WAVE_TWO) || mainArm == Arm.RIGHT) {
|
||||
model.rightArm.roll = wave;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case KICK: {
|
||||
if (ponyRace.isEquine()) {
|
||||
float roll = (progress + 1) / 2F;
|
||||
|
||||
rearUp(matrices, model, progress);
|
||||
break;
|
||||
}
|
||||
case WIGGLE_NOSE: {
|
||||
if (!isPony) {
|
||||
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 = MathHelper.lerp(progress, model.leftArm.roll, 0);
|
||||
model.rightArm.pitch = 0;
|
||||
model.rightArm.roll = MathHelper.lerp(progress, model.rightArm.roll, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
float roll = (progress + 1) / 2F;
|
||||
|
||||
model.rightArm.pitch += roll / 5F;
|
||||
model.leftArm.roll -= roll / 5F;
|
||||
model.rightArm.roll += roll / 5F;
|
||||
|
||||
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 = AnimationUtil.seesaw(progress);
|
||||
|
||||
progress = AnimationUtil.seesaw(progress) * MathHelper.sin(player.age) / 7F;
|
||||
if (!ponyRace.isEquine()) {
|
||||
if (mainArm == Arm.LEFT) {
|
||||
model.rightLeg.roll = -progress / 9F;
|
||||
model.rightLeg.pivotY -= progress * 5;
|
||||
} else {
|
||||
model.leftLeg.roll = -progress / 9F;
|
||||
model.leftLeg.pivotY -= progress * 5;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
model.getHead().getChild("mare").pivotY = progress;
|
||||
model.getHead().getChild("stallion").pivotY = progress;
|
||||
break;
|
||||
rearUp(matrices, model, progress);
|
||||
model.head.pitch += progress * 0.5F;
|
||||
model.leftArm.pitch += progress / 2F;
|
||||
model.rightArm.pitch += progress / 2F;
|
||||
break;
|
||||
}
|
||||
case WIGGLE_NOSE: {
|
||||
if (!ponyRace.isEquine()) {
|
||||
break;
|
||||
}
|
||||
|
||||
progress = AnimationUtil.seesaw(progress) * MathHelper.sin(player.age) / 7F;
|
||||
|
||||
model.getHead().getChild("mare").pivotY = progress;
|
||||
model.getHead().getChild("stallion").pivotY = progress;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
}
|
||||
default:
|
||||
}
|
||||
|
||||
if (pony.getEntityInArms().isPresent()) {
|
||||
if (isPony && pony.getPhysics().isFlying()) {
|
||||
if (ponyRace.isEquine() && pony.getPhysics().isFlying()) {
|
||||
model.leftLeg.pitch = 1;
|
||||
model.rightLeg.pitch = 1;
|
||||
model.leftLeg.yaw = 0.3F;
|
||||
|
@ -220,6 +243,12 @@ public class PlayerPoser {
|
|||
model.hat.copyTransform(model.head);
|
||||
}
|
||||
|
||||
private void rotateArm(ModelPart arm, float pitch, float yaw, float roll) {
|
||||
arm.pitch -= pitch;
|
||||
arm.roll = roll;
|
||||
arm.yaw = yaw;
|
||||
}
|
||||
|
||||
private void rearUp(MatrixStack matrices, BipedEntityModel<?> model, float progress) {
|
||||
matrices.translate(0, 0, 0.5);
|
||||
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(-45 * progress));
|
||||
|
@ -234,7 +263,19 @@ public class PlayerPoser {
|
|||
model.leftLeg.yaw = roll / 7F;
|
||||
}
|
||||
|
||||
public enum Animation implements StringIdentifiable {
|
||||
public record AnimationInstance(Animation animation, Animation.Recipient recipient) {
|
||||
public static final AnimationInstance NONE = new AnimationInstance(Animation.NONE, Animation.Recipient.ANYONE);
|
||||
|
||||
public boolean isOf(Animation animation) {
|
||||
return animation() == animation;
|
||||
}
|
||||
|
||||
public boolean canPlay(boolean isPony) {
|
||||
return !isOf(Animation.NONE) && (recipient == Animation.Recipient.ANYONE || isPony == (recipient == Animation.Recipient.PONY));
|
||||
}
|
||||
}
|
||||
|
||||
public enum Animation implements CommandArgumentEnum<Animation> {
|
||||
NONE(0),
|
||||
WOLOLO(USounds.ENTITY_PLAYER_WOLOLO, 40),
|
||||
ARMS_FORWARD(5),
|
||||
|
@ -268,11 +309,6 @@ public class PlayerPoser {
|
|||
return sound;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String asString() {
|
||||
return name();
|
||||
}
|
||||
|
||||
public static EnumArgumentType<Animation> argument() {
|
||||
return new ArgumentType();
|
||||
}
|
||||
|
@ -286,6 +322,24 @@ public class PlayerPoser {
|
|||
}
|
||||
}
|
||||
|
||||
public enum Recipient implements CommandArgumentEnum<Recipient> {
|
||||
HUMAN,
|
||||
PONY,
|
||||
ANYONE;
|
||||
|
||||
public static EnumArgumentType<Recipient> argument() {
|
||||
return new ArgumentType();
|
||||
}
|
||||
|
||||
public static final class ArgumentType extends EnumArgumentType<Recipient> {
|
||||
@SuppressWarnings("deprecation")
|
||||
static final Codec<Recipient> CODEC = StringIdentifiable.createCodec(Recipient::values);
|
||||
|
||||
protected ArgumentType() {
|
||||
super(CODEC, Recipient::values);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum Context {
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package com.minelittlepony.unicopia.command;
|
||||
|
||||
import net.minecraft.util.StringIdentifiable;
|
||||
|
||||
public interface CommandArgumentEnum<T extends Enum<T> & CommandArgumentEnum<T>> extends StringIdentifiable {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
default T asSelf() {
|
||||
return (T)this;
|
||||
}
|
||||
|
||||
@Override
|
||||
default String asString() {
|
||||
return asSelf().name();
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@ public class Commands {
|
|||
@SuppressWarnings("deprecation")
|
||||
public static void bootstrap() {
|
||||
ArgumentTypeRegistry.registerArgumentType(Unicopia.id("animation"), Animation.ArgumentType.class, ConstantArgumentSerializer.of(Animation::argument));
|
||||
ArgumentTypeRegistry.registerArgumentType(Unicopia.id("animation_recipient"), Animation.Recipient.ArgumentType.class, ConstantArgumentSerializer.of(Animation.Recipient::argument));
|
||||
ArgumentTypeRegistry.registerArgumentType(Unicopia.id("mana_type"), ManaType.ArgumentType.class, ConstantArgumentSerializer.of(ManaType::argument));
|
||||
ArgumentTypeRegistry.registerArgumentType(Unicopia.id("trait_type"), Trait.ArgumentType.class, ConstantArgumentSerializer.of(Trait::argument));
|
||||
ArgumentTypeRegistry.registerArgumentType(Unicopia.id("spell_traits"), TraitsArgumentType.class, ConstantArgumentSerializer.of(TraitsArgumentType::traits));
|
||||
|
|
|
@ -15,23 +15,31 @@ public class EmoteCommand {
|
|||
.literal("emote")
|
||||
.then(CommandManager.argument("animation", Animation.argument()).executes(source -> apply(
|
||||
source.getSource(),
|
||||
source.getArgument("animation", Animation.class)
|
||||
source.getArgument("animation", Animation.class),
|
||||
Animation.Recipient.ANYONE
|
||||
)
|
||||
).then(CommandManager.argument("duration", IntegerArgumentType.integer(1, 99)).executes(source -> apply(
|
||||
source.getSource(),
|
||||
source.getArgument("animation", Animation.class),
|
||||
source.getArgument("duration", Integer.class)
|
||||
Animation.Recipient.ANYONE,
|
||||
IntegerArgumentType.getInteger(source, "duration")
|
||||
)
|
||||
)
|
||||
).then(CommandManager.argument("recipient_type", Animation.Recipient.argument()).executes(source -> apply(
|
||||
source.getSource(),
|
||||
source.getArgument("animation", Animation.class),
|
||||
source.getArgument("recipient_type", Animation.Recipient.class),
|
||||
IntegerArgumentType.getInteger(source, "duration")
|
||||
)
|
||||
))
|
||||
)));
|
||||
}
|
||||
|
||||
static int apply(ServerCommandSource source, Animation animation) throws CommandSyntaxException {
|
||||
return apply(source, animation, animation.getDuration());
|
||||
static int apply(ServerCommandSource source, Animation animation, Animation.Recipient recipient) throws CommandSyntaxException {
|
||||
return apply(source, animation, recipient, animation.getDuration());
|
||||
}
|
||||
|
||||
static int apply(ServerCommandSource source, Animation animation, int duration) throws CommandSyntaxException {
|
||||
Pony.of(source.getPlayer()).setAnimation(animation, duration);
|
||||
static int apply(ServerCommandSource source, Animation animation, Animation.Recipient recipient, int duration) throws CommandSyntaxException {
|
||||
Pony.of(source.getPlayer()).setAnimation(animation, recipient, duration);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ public class ManaCommand {
|
|||
);
|
||||
}
|
||||
|
||||
enum ManaType implements StringIdentifiable {
|
||||
enum ManaType implements CommandArgumentEnum<ManaType> {
|
||||
EXERTION(MagicReserves::getExertion),
|
||||
EXHAUSTION(MagicReserves::getExhaustion),
|
||||
ENERGY(MagicReserves::getEnergy),
|
||||
|
@ -61,11 +61,6 @@ public class ManaCommand {
|
|||
return getter.apply(reserves);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String asString() {
|
||||
return name();
|
||||
}
|
||||
|
||||
public static EnumArgumentType<ManaType> argument() {
|
||||
return new ArgumentType();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.minelittlepony.unicopia.entity.player;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.minelittlepony.unicopia.*;
|
||||
import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
|
@ -120,7 +122,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
@Override
|
||||
public float getWingAngle() {
|
||||
|
||||
if (pony.getAnimation() == Animation.SPREAD_WINGS) {
|
||||
if (pony.getAnimation().isOf(Animation.SPREAD_WINGS)) {
|
||||
return AnimationUtil.seeSitSaw(pony.getAnimationProgress(1), 1.5F);
|
||||
}
|
||||
|
||||
|
@ -485,6 +487,14 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
isFlyingSurvival = true;
|
||||
thrustScale = 0;
|
||||
entity.calculateDimensions();
|
||||
|
||||
|
||||
|
||||
if (entity.isOnGround() || !force) {
|
||||
Supplier<Vec3d> vec = VecHelper.sphere(pony.asWorld().getRandom(), 0.5D);
|
||||
pony.spawnParticles(ParticleTypes.CAMPFIRE_COSY_SMOKE, vec, vec, 5);
|
||||
pony.spawnParticles(ParticleTypes.CLOUD, vec, vec, 5);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleWallCollission(MutableVector velocity) {
|
||||
|
|
|
@ -6,6 +6,7 @@ import java.util.stream.Stream;
|
|||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation;
|
||||
import com.minelittlepony.unicopia.client.render.PlayerPoser.AnimationInstance;
|
||||
import com.minelittlepony.unicopia.*;
|
||||
import com.minelittlepony.unicopia.ability.*;
|
||||
import com.minelittlepony.unicopia.ability.magic.*;
|
||||
|
@ -100,7 +101,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
private boolean hasShades;
|
||||
private int ticksSunImmunity = INITIAL_SUN_IMMUNITY;
|
||||
|
||||
private Animation animation = Animation.NONE;
|
||||
private AnimationInstance animation = new AnimationInstance(Animation.NONE, Animation.Recipient.ANYONE);
|
||||
private int animationMaxDuration;
|
||||
private int animationDuration;
|
||||
|
||||
|
@ -124,34 +125,53 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
builder.add(UEntityAttributes.ENTITY_GRAVTY_MODIFIER);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setAnimation(Animation animation) {
|
||||
setAnimation(animation, animation.getDuration());
|
||||
setAnimation(new AnimationInstance(animation, Animation.Recipient.ANYONE));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setAnimation(Animation animation, int duration) {
|
||||
if (animation != this.animation && duration != animationDuration) {
|
||||
setAnimation(new AnimationInstance(animation, Animation.Recipient.ANYONE));
|
||||
}
|
||||
|
||||
public void setAnimation(Animation animation, Animation.Recipient recipient) {
|
||||
setAnimation(new AnimationInstance(animation, recipient), animation.getDuration());
|
||||
}
|
||||
|
||||
public void setAnimation(Animation animation, Animation.Recipient recipient, int duration) {
|
||||
setAnimation(new AnimationInstance(animation, recipient), duration);
|
||||
}
|
||||
|
||||
public void setAnimation(AnimationInstance animation) {
|
||||
setAnimation(animation, animation.animation().getDuration());
|
||||
}
|
||||
|
||||
public void setAnimation(AnimationInstance animation, int duration) {
|
||||
if (!animation.equals(this.animation) || duration != animationDuration) {
|
||||
this.animation = animation;
|
||||
this.animationDuration = animation == Animation.NONE ? 0 : Math.max(0, duration);
|
||||
this.animationDuration = animation.isOf(Animation.NONE) ? 0 : Math.max(0, duration);
|
||||
this.animationMaxDuration = animationDuration;
|
||||
|
||||
if (!isClient()) {
|
||||
Channel.SERVER_PLAYER_ANIMATION_CHANGE.sendToAllPlayers(new MsgPlayerAnimationChange(this, animation, animationDuration), asWorld());
|
||||
}
|
||||
|
||||
animation.getSound().ifPresent(sound -> {
|
||||
animation.animation().getSound().ifPresent(sound -> {
|
||||
playSound(sound, sound == USounds.ENTITY_PLAYER_WOLOLO ? 0.1F : 0.9F, 1);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public Animation getAnimation() {
|
||||
public AnimationInstance getAnimation() {
|
||||
return animation;
|
||||
}
|
||||
|
||||
public float getAnimationProgress(float delta) {
|
||||
if (animation == Animation.NONE) {
|
||||
if (animation.isOf(Animation.NONE)) {
|
||||
return 0;
|
||||
}
|
||||
System.out.println(animationMaxDuration);
|
||||
return 1 - (((float)animationDuration) / animationMaxDuration);
|
||||
}
|
||||
|
||||
|
@ -378,8 +398,8 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
}
|
||||
|
||||
private void updateAnimations() {
|
||||
if (animationDuration >= 0 && --animationDuration <= 0) {
|
||||
setAnimation(Animation.NONE);
|
||||
if (animationDuration > 0 && --animationDuration <= 0) {
|
||||
setAnimation(AnimationInstance.NONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import com.minelittlepony.unicopia.ability.magic.Caster;
|
|||
import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation;
|
||||
import com.minelittlepony.unicopia.entity.CastSpellEntity;
|
||||
import com.minelittlepony.unicopia.entity.UEntities;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
|
@ -131,6 +132,7 @@ public class EnchantedStaffItem extends StaffItem implements EnchantableItem, Ch
|
|||
pony.subtractEnergyCost(4);
|
||||
stack.damage(1, pony.asEntity(), p -> p.sendEquipmentBreakStatus(EquipmentSlot.MAINHAND));
|
||||
getSpellEffect(stack).create().toThrowable().throwProjectile(pony);
|
||||
pony.setAnimation(Animation.ARMS_UP, Animation.Recipient.ANYONE, 10);
|
||||
});
|
||||
ChargeableItem.consumeEnergy(stack, 1);
|
||||
} else if (i > 5) {
|
||||
|
@ -138,6 +140,7 @@ public class EnchantedStaffItem extends StaffItem implements EnchantableItem, Ch
|
|||
pony.subtractEnergyCost(4);
|
||||
stack.damage(1, pony.asEntity(), p -> p.sendEquipmentBreakStatus(EquipmentSlot.MAINHAND));
|
||||
getSpellEffect(stack).create().toThrowable().throwProjectile(pony);
|
||||
pony.setAnimation(Animation.ARMS_UP, Animation.Recipient.ANYONE, 10);
|
||||
});
|
||||
ChargeableItem.consumeEnergy(stack, 1);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.network;
|
|||
import java.util.UUID;
|
||||
|
||||
import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation;
|
||||
import com.minelittlepony.unicopia.client.render.PlayerPoser.AnimationInstance;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.sollace.fabwork.api.packets.HandledPacket;
|
||||
|
||||
|
@ -15,22 +16,23 @@ import net.minecraft.network.PacketByteBuf;
|
|||
*/
|
||||
public record MsgPlayerAnimationChange (
|
||||
UUID playerId,
|
||||
Animation animation,
|
||||
AnimationInstance animation,
|
||||
int duration
|
||||
) implements HandledPacket<PlayerEntity> {
|
||||
|
||||
MsgPlayerAnimationChange(PacketByteBuf buffer) {
|
||||
this(buffer.readUuid(), buffer.readEnumConstant(Animation.class), buffer.readInt());
|
||||
this(buffer.readUuid(), new AnimationInstance(buffer.readEnumConstant(Animation.class), buffer.readEnumConstant(Animation.Recipient.class)), buffer.readInt());
|
||||
}
|
||||
|
||||
public MsgPlayerAnimationChange(Pony player, Animation animation, int duration) {
|
||||
public MsgPlayerAnimationChange(Pony player, AnimationInstance animation, int duration) {
|
||||
this(player.asEntity().getUuid(), animation, duration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toBuffer(PacketByteBuf buffer) {
|
||||
buffer.writeUuid(playerId);
|
||||
buffer.writeEnumConstant(animation);
|
||||
buffer.writeEnumConstant(animation.animation());
|
||||
buffer.writeEnumConstant(animation.recipient());
|
||||
buffer.writeInt(duration);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.minelittlepony.unicopia.particle;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.minelittlepony.unicopia.EntityConvertable;
|
||||
import com.minelittlepony.unicopia.util.shape.PointGenerator;
|
||||
|
@ -11,6 +12,16 @@ import net.minecraft.util.math.Vec3d;
|
|||
|
||||
public interface ParticleSource<E extends Entity> extends ParticleSpawner, EntityConvertable<E> {
|
||||
|
||||
default void spawnParticles(ParticleEffect particleId, Supplier<Vec3d> posSupplier, Supplier<Vec3d> velSupplier, int count) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
spawnParticle(particleId, posSupplier, velSupplier);
|
||||
}
|
||||
}
|
||||
|
||||
default void spawnParticle(ParticleEffect particleId, Supplier<Vec3d> posSupplier, Supplier<Vec3d> velSupplier) {
|
||||
addParticle(particleId, getOriginVector().add(posSupplier.get()), velSupplier.get());
|
||||
}
|
||||
|
||||
default void spawnParticles(ParticleEffect particleId, int count) {
|
||||
ParticleUtils.spawnParticles(particleId, asEntity(), count);
|
||||
}
|
||||
|
|
|
@ -3,11 +3,14 @@ package com.minelittlepony.unicopia.util;
|
|||
import java.util.List;
|
||||
import java.util.function.DoubleSupplier;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.math.Box;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
import net.minecraft.world.EntityView;
|
||||
|
||||
public interface VecHelper {
|
||||
|
@ -20,6 +23,18 @@ public interface VecHelper {
|
|||
return new Vec3d(rng.getAsDouble(), rng.getAsDouble(), rng.getAsDouble());
|
||||
}
|
||||
|
||||
static Supplier<Vec3d> supplier(DoubleSupplier rng) {
|
||||
return () -> supply(rng);
|
||||
}
|
||||
|
||||
static Supplier<Vec3d> sphere(Random rng) {
|
||||
return sphere(rng, 1);
|
||||
}
|
||||
|
||||
static Supplier<Vec3d> sphere(Random rng, double radius) {
|
||||
return supplier(() -> (rng.nextGaussian() - 0.5) * radius);
|
||||
}
|
||||
|
||||
static Predicate<Entity> inRange(Vec3d center, double range) {
|
||||
double rad = Math.pow(range, 2);
|
||||
return e -> {
|
||||
|
|
Loading…
Reference in a new issue