Implement nirik vision

This commit is contained in:
Sollace 2023-10-09 22:54:57 +01:00
parent 6e3bc75619
commit 1b0505375a
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
5 changed files with 121 additions and 29 deletions

View file

@ -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<EntityType<?>> defaultTypes = List.of(
EntityType.ZOMBIE,
EntityType.CREEPER,
EntityType.HUSK,
EntityType.SKELETON,
EntityType.BLAZE,
EntityType.DROWNED
);
private final Map<EntityType<?>, List<EntityType<?>>> 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<Disguise> getAppearanceFor(Caster<?> caster) {
if (isRageApplicable(caster.asEntity()) && EquinePredicates.RAGING.test(MinecraftClient.getInstance().player)) {
List<EntityType<?>> 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<EntityType<?>> 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;
}
}

View file

@ -4,8 +4,6 @@ import org.jetbrains.annotations.Nullable;
import com.minelittlepony.client.util.render.RenderLayerUtil; import com.minelittlepony.client.util.render.RenderLayerUtil;
import com.minelittlepony.unicopia.Unicopia; 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.compat.pehkui.PehkUtil;
import com.minelittlepony.unicopia.entity.Creature; import com.minelittlepony.unicopia.entity.Creature;
import com.minelittlepony.unicopia.entity.Equine; import com.minelittlepony.unicopia.entity.Equine;
@ -157,39 +155,35 @@ public class WorldRenderDelegate {
flipAngles(owner); 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 -> { return EntityReplacementRenderManager.INSTANCE.getAppearanceFor(pony).map(effect -> {
effect.update(pony, false); effect.update(pony, false);
EntityAppearance ve = effect.getDisguise(); EntityAppearance ve = effect.getDisguise();
Entity e = ve.getAppearance(); Entity e = ve.getAppearance();
if (e != null) { if (e != null) {
PehkUtil.copyScale(pony.asEntity(), e); PehkUtil.copyScale(pony.asEntity(), e);
if (dispatcher.shouldRenderHitboxes()) { if (dispatcher.shouldRenderHitboxes()) {
e.setBoundingBox(pony.asEntity().getBoundingBox()); 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;
} }
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) { public void afterEntityRender(Equine<?> pony, MatrixStack matrices, int light) {

View file

@ -386,6 +386,10 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
.isEmpty(); .isEmpty();
} }
public Optional<Vec3d> adjustMovementSpeedInWater(Vec3d speed) {
return Optional.empty();
}
private void updateDragonBreath() { private void updateDragonBreath() {
if (!entity.getWorld().isClient && (entity instanceof PlayerEntity || entity.hasCustomName())) { if (!entity.getWorld().isClient && (entity instanceof PlayerEntity || entity.hasCustomName())) {

View file

@ -638,6 +638,14 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
return super.canBeSeenBy(entity); return super.canBeSeenBy(entity);
} }
@Override
public Optional<Vec3d> adjustMovementSpeedInWater(Vec3d speed) {
if (getObservedSpecies() == Race.KIRIN) {
return Optional.of(speed.multiply(0.5, 1, 0.5));
}
return Optional.empty();
}
public Optional<Living<?>> getEntityInArms() { public Optional<Living<?>> getEntityInArms() {
return Living.getOrEmpty(entity.getFirstPassenger()).filter(Living::isBeingCarried); return Living.getOrEmpty(entity.getFirstPassenger()).filter(Living::isBeingCarried);
} }

View file

@ -26,6 +26,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
@Mixin(LivingEntity.class) @Mixin(LivingEntity.class)
abstract class MixinLivingEntity extends Entity implements LivingEntityDuck, Equine.Container<Living<?>> { abstract class MixinLivingEntity extends Entity implements LivingEntityDuck, Equine.Container<Living<?>> {
@ -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<Vec3d> info) {
get().adjustMovementSpeedInWater(info.getReturnValue()).ifPresent(info::setReturnValue);
}
@Inject(method = "jump()V", at = @At("RETURN")) @Inject(method = "jump()V", at = @At("RETURN"))
private void onJump(CallbackInfo info) { private void onJump(CallbackInfo info) {
get().onJump(); get().onJump();