mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Set position and render entities being carried by pegasi in their arms arms
This commit is contained in:
parent
e9070b87b0
commit
7ca2e63fae
12 changed files with 272 additions and 2 deletions
|
@ -73,6 +73,7 @@ public class CarryAbility implements Ability<Hit> {
|
|||
|
||||
if (rider != null) {
|
||||
rider.startRiding(player, true);
|
||||
Living.getOrEmpty(rider).ifPresent(living -> living.setCarrier(player));
|
||||
}
|
||||
|
||||
Living.transmitPassengers(player);
|
||||
|
|
|
@ -64,6 +64,7 @@ public interface URenderers {
|
|||
AccessoryFeatureRenderer.register(IcarusWingsFeatureRenderer::new);
|
||||
AccessoryFeatureRenderer.register(BatWingsFeatureRenderer::new);
|
||||
AccessoryFeatureRenderer.register(GlassesFeatureRenderer::new);
|
||||
AccessoryFeatureRenderer.register(HeldEntityFeatureRenderer::new);
|
||||
|
||||
EntityRendererRegistry.register(UEntities.THROWN_ITEM, FlyingItemEntityRenderer::new);
|
||||
EntityRendererRegistry.register(UEntities.MUFFIN, FlyingItemEntityRenderer::new);
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
package com.minelittlepony.unicopia.client.minelittlepony;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import com.minelittlepony.api.model.BodyPart;
|
||||
import com.minelittlepony.api.model.IModel;
|
||||
import com.minelittlepony.api.model.gear.IGear;
|
||||
import com.minelittlepony.client.model.IPonyModel;
|
||||
import com.minelittlepony.unicopia.client.render.HeldEntityFeatureRenderer;
|
||||
import com.minelittlepony.unicopia.entity.Living;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.render.entity.model.EntityModel;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
class HeldEntityGear extends HeldEntityFeatureRenderer<LivingEntity> implements IGear {
|
||||
|
||||
private LivingEntity entity;
|
||||
|
||||
public HeldEntityGear() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRender(IModel model, Entity entity) {
|
||||
return entity instanceof LivingEntity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BodyPart getGearLocation() {
|
||||
return BodyPart.BODY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Entity> Identifier getTexture(T entity, Context<T, ?> context) {
|
||||
return MinecraftClient.getInstance().getEntityRenderDispatcher().getRenderer(entity).getTexture(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <M extends EntityModel<?> & IPonyModel<?>> void transform(M model, MatrixStack matrices) {
|
||||
// noop
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pose(IModel model, Entity entity, boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) {
|
||||
this.entity = (LivingEntity)entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack stack, VertexConsumer consumer, int light, int overlay, float red, float green, float blue, float alpha, UUID interpolatorId) {
|
||||
render(
|
||||
stack,
|
||||
MinecraftClient.getInstance().getBufferBuilders().getEntityVertexConsumers(),
|
||||
light, entity,
|
||||
0, 0,
|
||||
MinecraftClient.getInstance().getTickDelta(), 0, 0, 0
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Vec3d getCarryPosition(Living<LivingEntity> entity, Living<?> passenger) {
|
||||
return super.getCarryPosition(entity, passenger);
|
||||
}
|
||||
}
|
|
@ -33,6 +33,7 @@ public class Main extends MineLPDelegate implements ClientModInitializer {
|
|||
PonyModelPrepareCallback.EVENT.register(this::onPonyModelPrepared);
|
||||
IGear.register(() -> new BangleGear(TrinketsDelegate.MAINHAND));
|
||||
IGear.register(() -> new BangleGear(TrinketsDelegate.OFFHAND));
|
||||
IGear.register(() -> new HeldEntityGear());
|
||||
IGear.register(AmuletGear::new);
|
||||
IGear.register(GlassesGear::new);
|
||||
}
|
||||
|
@ -54,6 +55,7 @@ public class Main extends MineLPDelegate implements ClientModInitializer {
|
|||
model.getAttributes().isGoingFast |= zMotion > 0.4F;
|
||||
}
|
||||
model.getAttributes().isGoingFast |= pony.getMotion().isRainbooming();
|
||||
model.getAttributes().isGoingFast &= !pony.getEntityInArms().isPresent();
|
||||
|
||||
if (pony.getAnimation() == Animation.SPREAD_WINGS) {
|
||||
model.getAttributes().wingAngle = -AnimationUtil.seeSitSaw(pony.getAnimationProgress(1), 1.5F) * (float)Math.PI / 1.2F;
|
||||
|
|
|
@ -47,7 +47,6 @@ public class AccessoryFeatureRenderer<
|
|||
void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, T entity, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch);
|
||||
|
||||
default void renderArm(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, T entity, ModelPart arm, Arm side) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
package com.minelittlepony.unicopia.client.render;
|
||||
|
||||
import com.minelittlepony.unicopia.client.minelittlepony.MineLPDelegate;
|
||||
import com.minelittlepony.unicopia.entity.Living;
|
||||
import com.minelittlepony.unicopia.entity.duck.EntityDuck;
|
||||
import com.minelittlepony.unicopia.entity.duck.LivingEntityDuck;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.model.ModelPart;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.render.entity.EntityRenderer;
|
||||
import net.minecraft.client.render.entity.feature.FeatureRendererContext;
|
||||
import net.minecraft.client.render.entity.model.BipedEntityModel;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.util.Arm;
|
||||
import net.minecraft.util.math.*;
|
||||
|
||||
public class HeldEntityFeatureRenderer<E extends LivingEntity> implements AccessoryFeatureRenderer.Feature<E> {
|
||||
|
||||
public HeldEntityFeatureRenderer(FeatureRendererContext<E, ? extends BipedEntityModel<E>> context) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, E entity, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) {
|
||||
Pony.of(entity).flatMap(Pony::getEntityInArms).ifPresent(passenger -> {
|
||||
Living<E> l = Living.living(entity);
|
||||
Vec3d carryPosition = getCarryPosition(l, passenger);
|
||||
|
||||
LivingEntity p = passenger.asEntity();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
EntityRenderer<LivingEntity> renderer = (EntityRenderer<LivingEntity>)MinecraftClient.getInstance().getEntityRenderDispatcher().getRenderer(p);
|
||||
|
||||
float f = tickDelta;
|
||||
|
||||
matrices.push();
|
||||
|
||||
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(180));
|
||||
|
||||
float leanAmount = ((LivingEntityDuck)entity).getLeaningPitch();
|
||||
|
||||
//matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(leanAmount * 0));
|
||||
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(-leanAmount * 90));
|
||||
|
||||
carryPosition = carryPosition.rotateX(-leanAmount * MathHelper.PI / 4F)
|
||||
.add(new Vec3d(0, -0.5F, 0).multiply(leanAmount));
|
||||
|
||||
matrices.translate(carryPosition.x, carryPosition.y, carryPosition.z);
|
||||
if (!(passenger instanceof Pony)) {
|
||||
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(90));
|
||||
}
|
||||
|
||||
float oldYaw = entity.bodyYaw;
|
||||
float prevOldYaw = entity.prevBodyYaw;
|
||||
|
||||
entity.bodyYaw = 0;
|
||||
entity.prevBodyYaw = 0;
|
||||
|
||||
Entity vehicle = p.getVehicle();
|
||||
((EntityDuck)p).setVehicle(null);
|
||||
|
||||
p.prevBodyYaw = 0;
|
||||
p.bodyYaw = 0;
|
||||
p.headYaw = 0;
|
||||
p.prevHeadYaw = 0;
|
||||
p.prevYaw = 0;
|
||||
p.setYaw(0);
|
||||
p.setBodyYaw(0);
|
||||
renderer.render(p, 0, f, matrices, vertexConsumers, light);
|
||||
|
||||
entity.bodyYaw = oldYaw;
|
||||
entity.prevBodyYaw = prevOldYaw;
|
||||
|
||||
((EntityDuck)p).setVehicle(vehicle);
|
||||
|
||||
matrices.pop();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderArm(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, E entity, ModelPart arm, Arm side) {
|
||||
render(matrices, vertexConsumers, light, entity, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
protected Vec3d getCarryPosition(Living<E> entity, Living<?> passenger) {
|
||||
float passengerHeight = passenger.asEntity().getHeight() / 2F;
|
||||
float carrierHeight = entity.asEntity().getHeight() / 5F;
|
||||
|
||||
if (entity instanceof Pony pony && !MineLPDelegate.getInstance().getPlayerPonyRace(pony.asEntity()).isDefault() && pony.getPhysics().isFlying()) {
|
||||
return new Vec3d(0,
|
||||
-passenger.asEntity().getHeight() - passengerHeight,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
return new Vec3d(0,
|
||||
-passengerHeight - carrierHeight,
|
||||
entity.asEntity().getWidth()
|
||||
);
|
||||
}
|
||||
}
|
|
@ -188,6 +188,22 @@ public class PlayerPoser {
|
|||
default:
|
||||
}
|
||||
|
||||
if (pony.getEntityInArms().isPresent()) {
|
||||
if (isPony && pony.getPhysics().isFlying()) {
|
||||
model.leftLeg.pitch = 1;
|
||||
model.rightLeg.pitch = 1;
|
||||
model.leftLeg.yaw = 0.3F;
|
||||
model.rightLeg.yaw = -0.3F;
|
||||
} else {
|
||||
model.leftArm.pitch = -1;
|
||||
model.rightArm.pitch = -1;
|
||||
}
|
||||
model.leftArm.yaw = -0.3F;
|
||||
model.rightArm.yaw = 0.3F;
|
||||
model.leftArm.roll = 0;
|
||||
model.rightArm.roll = 0;
|
||||
}
|
||||
|
||||
if (model instanceof PlayerEntityModel<?> m) {
|
||||
m.leftSleeve.copyTransform(m.leftArm);
|
||||
m.rightSleeve.copyTransform(m.rightArm);
|
||||
|
|
|
@ -104,6 +104,10 @@ public class WorldRenderDelegate {
|
|||
double x, double y, double z, float yaw,
|
||||
float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light) {
|
||||
|
||||
if (pony.isBeingCarried() && !(pony instanceof Pony && ((Pony)pony).isClientPlayer())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
matrices.push();
|
||||
|
||||
Entity owner = pony.asEntity();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.minelittlepony.unicopia.entity;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
|
@ -28,7 +29,7 @@ import com.minelittlepony.unicopia.util.VecHelper;
|
|||
|
||||
import net.minecraft.entity.*;
|
||||
import net.minecraft.entity.damage.DamageSource;
|
||||
import net.minecraft.entity.data.TrackedData;
|
||||
import net.minecraft.entity.data.*;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.projectile.ProjectileEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
@ -42,6 +43,7 @@ import net.minecraft.util.math.BlockPos;
|
|||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public abstract class Living<T extends LivingEntity> implements Equine<T>, Caster<T>, Transmittable {
|
||||
private static final TrackedData<Optional<UUID>> CARRIER_ID = DataTracker.registerData(LivingEntity.class, TrackedDataHandlerRegistry.OPTIONAL_UUID);
|
||||
|
||||
protected final T entity;
|
||||
|
||||
|
@ -69,6 +71,7 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
|
|||
this.effectDelegate = new EffectSync(this, effect);
|
||||
|
||||
entity.getDataTracker().startTracking(effect, new NbtCompound());
|
||||
entity.getDataTracker().startTracking(CARRIER_ID, Optional.empty());
|
||||
}
|
||||
|
||||
public boolean isInvisible() {
|
||||
|
@ -113,6 +116,23 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
|
|||
return entity;
|
||||
}
|
||||
|
||||
public Optional<UUID> getCarrierId() {
|
||||
return entity.getDataTracker().get(CARRIER_ID);
|
||||
}
|
||||
|
||||
public void setCarrier(UUID carrier) {
|
||||
entity.getDataTracker().set(CARRIER_ID, Optional.ofNullable(carrier));
|
||||
}
|
||||
|
||||
public void setCarrier(Entity carrier) {
|
||||
entity.getDataTracker().set(CARRIER_ID, Optional.ofNullable(carrier).map(Entity::getUuid));
|
||||
}
|
||||
|
||||
public boolean isBeingCarried() {
|
||||
Entity vehicle = entity.getVehicle();
|
||||
return vehicle != null && getCarrierId().filter(vehicle.getUuid()::equals).isPresent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
armour.update(this, getArmourStacks());
|
||||
|
@ -176,6 +196,10 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
|
|||
}
|
||||
}
|
||||
|
||||
public boolean onUpdatePassengerPosition(Entity passender, Entity.PositionUpdater positionUpdater) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void onJump() {
|
||||
if (getPhysics().isGravityNegative()) {
|
||||
entity.setVelocity(entity.getVelocity().multiply(1, -1, 1));
|
||||
|
@ -275,11 +299,13 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
|
|||
@Override
|
||||
public void toSyncronisedNbt(NbtCompound compound) {
|
||||
compound.put("armour", armour.toNBT());
|
||||
getCarrierId().ifPresent(id -> compound.putUuid("carrier", id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromSynchronizedNbt(NbtCompound compound) {
|
||||
armour.fromNBT(compound.getCompound("armour"));
|
||||
setCarrier(compound.containsUuid("carrier") ? compound.getUuid("carrier") : null);
|
||||
}
|
||||
|
||||
public void updateVelocity() {
|
||||
|
@ -294,6 +320,10 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
|
|||
return getOrEmpty(entity).orElse(null);
|
||||
}
|
||||
|
||||
public static <E extends LivingEntity> Living<E> living(E entity) {
|
||||
return Equine.<E, Living<E>>of(entity, e -> e instanceof Living<?>).orElse(null);
|
||||
}
|
||||
|
||||
public static void updateVelocity(Entity entity) {
|
||||
entity.velocityModified = true;
|
||||
//if (entity instanceof ServerPlayerEntity ply) {
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
package com.minelittlepony.unicopia.entity.duck;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.Entity.RemovalReason;
|
||||
|
||||
public interface EntityDuck extends LavaAffine {
|
||||
void setRemovalReason(RemovalReason reason);
|
||||
|
||||
void setVehicle(Entity vehicle);
|
||||
|
||||
@Override
|
||||
default void setLavaAffine(boolean lavaAffine) {
|
||||
|
||||
|
|
|
@ -451,6 +451,30 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
sendCapabilities();
|
||||
}
|
||||
|
||||
public Optional<Living<?>> getEntityInArms() {
|
||||
return Living.getOrEmpty(entity.getFirstPassenger()).filter(Living::isBeingCarried);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onUpdatePassengerPosition(Entity passender, Entity.PositionUpdater positionUpdater) {
|
||||
Entity passenger = entity.getFirstPassenger();
|
||||
if (Living.getOrEmpty(passenger).filter(Living::isBeingCarried).isPresent()) {
|
||||
|
||||
Vec3d carryPosition = new Vec3d(0, 0, entity.getWidth());
|
||||
|
||||
float leanAmount = ((LivingEntityDuck)entity).getLeaningPitch();
|
||||
carryPosition = carryPosition.rotateX(-leanAmount * MathHelper.PI / 4F)
|
||||
.add(new Vec3d(0, -0.5F, 0).multiply(leanAmount));
|
||||
|
||||
carryPosition = carryPosition.rotateY(-entity.getBodyYaw() * MathHelper.RADIANS_PER_DEGREE);
|
||||
|
||||
carryPosition = entity.getPos().add(carryPosition);
|
||||
positionUpdater.accept(passenger, carryPosition.x, carryPosition.y, carryPosition.z);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Optional<Float> modifyDamage(DamageSource cause, float amount) {
|
||||
|
||||
if (!cause.isUnblockable() && !cause.isMagic() && !cause.isFire() && !cause.isOutOfWorld()
|
||||
|
|
|
@ -4,12 +4,15 @@ import org.spongepowered.asm.mixin.Mixin;
|
|||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import com.minelittlepony.unicopia.entity.duck.LavaAffine;
|
||||
import com.minelittlepony.unicopia.entity.Living;
|
||||
import com.minelittlepony.unicopia.entity.duck.EntityDuck;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.Entity.PositionUpdater;
|
||||
import net.minecraft.entity.Entity.RemovalReason;
|
||||
|
||||
@Mixin(Entity.class)
|
||||
|
@ -18,6 +21,10 @@ abstract class MixinEntity implements EntityDuck {
|
|||
@Accessor
|
||||
public abstract void setRemovalReason(RemovalReason reason);
|
||||
|
||||
@Override
|
||||
@Accessor
|
||||
public abstract void setVehicle(Entity vehicle);
|
||||
|
||||
@Override
|
||||
public boolean isLavaAffine() {
|
||||
Entity self = (Entity)(Object)this;
|
||||
|
@ -30,4 +37,14 @@ abstract class MixinEntity implements EntityDuck {
|
|||
info.setReturnValue(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "updatePassengerPosition(Lnet/minecraft/entity/Entity;Lnet/minecraft/entity/Entity$PositionUpdater;)V",
|
||||
at = @At("HEAD"),
|
||||
cancellable = true
|
||||
)
|
||||
private void updatePassengerPosition(Entity passenger, PositionUpdater positionUpdater, CallbackInfo info) {
|
||||
if (Living.getOrEmpty((Entity)(Object)this).filter(l -> l.onUpdatePassengerPosition(passenger, positionUpdater)).isPresent()) {
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue