From 1b0505375a231ce7f950b492b5b2bd80c8fbfd1e Mon Sep 17 00:00:00 2001 From: Sollace Date: Mon, 9 Oct 2023 22:54:57 +0100 Subject: [PATCH] Implement nirik vision --- .../EntityReplacementRenderManager.java | 80 +++++++++++++++++++ .../client/render/WorldRenderDelegate.java | 52 ++++++------ .../unicopia/entity/Living.java | 4 + .../unicopia/entity/player/Pony.java | 8 ++ .../unicopia/mixin/MixinLivingEntity.java | 6 ++ 5 files changed, 121 insertions(+), 29 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/client/render/EntityReplacementRenderManager.java diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/EntityReplacementRenderManager.java b/src/main/java/com/minelittlepony/unicopia/client/render/EntityReplacementRenderManager.java new file mode 100644 index 00000000..8e9e6113 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/client/render/EntityReplacementRenderManager.java @@ -0,0 +1,80 @@ +package com.minelittlepony.unicopia.client.render; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.jetbrains.annotations.Nullable; + +import com.minelittlepony.unicopia.EquinePredicates; +import com.minelittlepony.unicopia.ability.magic.Caster; +import com.minelittlepony.unicopia.ability.magic.SpellPredicate; +import com.minelittlepony.unicopia.entity.behaviour.Disguise; +import com.minelittlepony.unicopia.entity.behaviour.EntityAppearance; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.passive.PassiveEntity; +import net.minecraft.entity.player.PlayerEntity; + +class EntityReplacementRenderManager implements Disguise { + public static final EntityReplacementRenderManager INSTANCE = new EntityReplacementRenderManager(); + + @Nullable + private EntityType currentType; + private final EntityAppearance disguise = new EntityAppearance(); + private final List> defaultTypes = List.of( + EntityType.ZOMBIE, + EntityType.CREEPER, + EntityType.HUSK, + EntityType.SKELETON, + EntityType.BLAZE, + EntityType.DROWNED + ); + private final Map, List>> pools = Map.of( + EntityType.VILLAGER, List.of(EntityType.PILLAGER), + EntityType.PLAYER, List.of(EntityType.ZOMBIE), + EntityType.PIGLIN, List.of(EntityType.ZOMBIFIED_PIGLIN, EntityType.PIGLIN_BRUTE), + EntityType.SQUID, List.of(EntityType.DROWNED), + EntityType.DOLPHIN, List.of(EntityType.DROWNED), + EntityType.ENDER_DRAGON, List.of(EntityType.CHICKEN) + ); + + public Optional getAppearanceFor(Caster caster) { + + if (isRageApplicable(caster.asEntity()) && EquinePredicates.RAGING.test(MinecraftClient.getInstance().player)) { + List> mobTypes = getMobTypePool(caster.asEntity().getType()); + EntityType type = mobTypes.get(Math.abs((int)caster.asEntity().getUuid().getMostSignificantBits()) % mobTypes.size()); + if (type != currentType) { + currentType = type; + disguise.setAppearance(type.create(caster.asWorld())); + } + return Optional.of(this); + } + + return caster.getSpellSlot().get(SpellPredicate.IS_DISGUISE, false).map(Disguise.class::cast); + } + + private List> getMobTypePool(EntityType type) { + return pools.getOrDefault(type, defaultTypes); + } + + private boolean isRageApplicable(Entity entity) { + return entity instanceof PassiveEntity || entity instanceof PlayerEntity || pools.containsKey(entity.getType()); + } + + @Override + public EntityAppearance getDisguise() { + return disguise; + } + + @Override + public void setDirty() { + } + + @Override + public boolean isDead() { + return false; + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/WorldRenderDelegate.java b/src/main/java/com/minelittlepony/unicopia/client/render/WorldRenderDelegate.java index 3288ec9c..b0a28a6e 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/WorldRenderDelegate.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/WorldRenderDelegate.java @@ -4,8 +4,6 @@ import org.jetbrains.annotations.Nullable; import com.minelittlepony.client.util.render.RenderLayerUtil; import com.minelittlepony.unicopia.Unicopia; -import com.minelittlepony.unicopia.ability.magic.Caster; -import com.minelittlepony.unicopia.ability.magic.SpellPredicate; import com.minelittlepony.unicopia.compat.pehkui.PehkUtil; import com.minelittlepony.unicopia.entity.Creature; import com.minelittlepony.unicopia.entity.Equine; @@ -157,39 +155,35 @@ public class WorldRenderDelegate { flipAngles(owner); } - if (pony instanceof Caster) { - int fireTicks = owner.doesRenderOnFire() ? 1 : 0; + int fireTicks = owner.doesRenderOnFire() ? 1 : 0; - return ((Caster)pony).getSpellSlot().get(SpellPredicate.IS_DISGUISE, false).map(effect -> { - effect.update(pony, false); + return EntityReplacementRenderManager.INSTANCE.getAppearanceFor(pony).map(effect -> { + effect.update(pony, false); - EntityAppearance ve = effect.getDisguise(); - Entity e = ve.getAppearance(); + EntityAppearance ve = effect.getDisguise(); + Entity e = ve.getAppearance(); - if (e != null) { - PehkUtil.copyScale(pony.asEntity(), e); + if (e != null) { + PehkUtil.copyScale(pony.asEntity(), e); - if (dispatcher.shouldRenderHitboxes()) { - e.setBoundingBox(pony.asEntity().getBoundingBox()); - } - - renderDisguise(dispatcher, ve, e, x, y, z, fireTicks, tickDelta, matrices, vertexConsumers, light); - ve.getAttachments().forEach(ee -> { - PehkUtil.copyScale(pony.asEntity(), ee); - Vec3d difference = ee.getPos().subtract(e.getPos()); - renderDisguise(dispatcher, ve, ee, x + difference.x, y + difference.y, z + difference.z, fireTicks, tickDelta, matrices, vertexConsumers, light); - PehkUtil.clearScale(ee); - }); - - afterEntityRender(pony, matrices, light); - PehkUtil.clearScale(e); - return true; + if (dispatcher.shouldRenderHitboxes()) { + e.setBoundingBox(pony.asEntity().getBoundingBox()); } - return false; - }).orElse(false); - } - return false; + renderDisguise(dispatcher, ve, e, x, y, z, fireTicks, tickDelta, matrices, vertexConsumers, light); + ve.getAttachments().forEach(ee -> { + PehkUtil.copyScale(pony.asEntity(), ee); + Vec3d difference = ee.getPos().subtract(e.getPos()); + renderDisguise(dispatcher, ve, ee, x + difference.x, y + difference.y, z + difference.z, fireTicks, tickDelta, matrices, vertexConsumers, light); + PehkUtil.clearScale(ee); + }); + + afterEntityRender(pony, matrices, light); + PehkUtil.clearScale(e); + return true; + } + return false; + }).orElse(false); } public void afterEntityRender(Equine pony, MatrixStack matrices, int light) { diff --git a/src/main/java/com/minelittlepony/unicopia/entity/Living.java b/src/main/java/com/minelittlepony/unicopia/entity/Living.java index 72bb95a7..ed657348 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/Living.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/Living.java @@ -386,6 +386,10 @@ public abstract class Living implements Equine, Caste .isEmpty(); } + public Optional adjustMovementSpeedInWater(Vec3d speed) { + return Optional.empty(); + } + private void updateDragonBreath() { if (!entity.getWorld().isClient && (entity instanceof PlayerEntity || entity.hasCustomName())) { diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java b/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java index 356d099f..5451ed02 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java @@ -638,6 +638,14 @@ public class Pony extends Living implements Copyable, Update return super.canBeSeenBy(entity); } + @Override + public Optional adjustMovementSpeedInWater(Vec3d speed) { + if (getObservedSpecies() == Race.KIRIN) { + return Optional.of(speed.multiply(0.5, 1, 0.5)); + } + return Optional.empty(); + } + public Optional> getEntityInArms() { return Living.getOrEmpty(entity.getFirstPassenger()).filter(Living::isBeingCarried); } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java index 917c401c..27d286c6 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java @@ -26,6 +26,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NbtCompound; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; @Mixin(LivingEntity.class) abstract class MixinLivingEntity extends Entity implements LivingEntityDuck, Equine.Container> { @@ -123,6 +124,11 @@ abstract class MixinLivingEntity extends Entity implements LivingEntityDuck, Equ } } + @Inject(method = "applyFluidMovingSpeed", at = @At("RETURN"), cancellable = true) + private void applyFluidMovingSpeed(double gravity, boolean falling, Vec3d motion, CallbackInfoReturnable info) { + get().adjustMovementSpeedInWater(info.getReturnValue()).ifPresent(info::setReturnValue); + } + @Inject(method = "jump()V", at = @At("RETURN")) private void onJump(CallbackInfo info) { get().onJump();