Fixed batpony hanging ability and fixed rendering of upside down players

This commit is contained in:
Sollace 2022-09-19 17:33:38 +02:00
parent 869d900f14
commit 3916e4810f
6 changed files with 56 additions and 44 deletions

View file

@ -2,15 +2,11 @@ package com.minelittlepony.unicopia.ability;
import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.ability.data.Multi;
import com.minelittlepony.unicopia.entity.UEntityAttributes;
import com.minelittlepony.unicopia.entity.player.PlayerAttributes;
import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.util.RayTraceHelper;
import net.minecraft.entity.attribute.EntityAttributeInstance;
import net.minecraft.predicate.entity.EntityPredicates;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
/**
* A magic casting ability for unicorns.
@ -47,7 +43,7 @@ public class BatPonyHangAbility implements Ability<Multi> {
return RayTraceHelper.doTrace(player.getMaster(), 5, 1, EntityPredicates.EXCEPT_SPECTATOR).getBlockPos()
.map(BlockPos::down)
.filter(pos -> player.getReferenceWorld().isAir(pos) && player.getReferenceWorld().isAir(pos.down()) && player.canHangAt(pos))
.filter(player::canHangAt)
.map(pos -> new Multi(pos, 1))
.orElse(null);
}
@ -59,20 +55,13 @@ public class BatPonyHangAbility implements Ability<Multi> {
@Override
public void apply(Pony player, Multi data) {
EntityAttributeInstance attr = player.getMaster().getAttributeInstance(UEntityAttributes.ENTITY_GRAVTY_MODIFIER);
if (data.hitType == 0 && attr.hasModifier(PlayerAttributes.BAT_HANGING)) {
attr.removeModifier(PlayerAttributes.BAT_HANGING);
if (data.hitType == 0 && player.isHanging()) {
player.stopHanging();
return;
}
if (data.hitType == 1 && player.canHangAt(data.pos())) {
player.getMaster().teleport(data.x + 0.5, data.y - 2, data.z + 0.5);
player.getMaster().setVelocity(Vec3d.ZERO);
if (!attr.hasModifier(PlayerAttributes.BAT_HANGING)) {
attr.addPersistentModifier(PlayerAttributes.BAT_HANGING);
}
player.startHanging(data.pos());
}
}

View file

@ -88,11 +88,15 @@ public class WorldRenderDelegate {
roll = pony instanceof Pony ? ((Pony)pony).getInterpolator().interpolate("g_roll", roll, 15) : roll;
matrices.translate(x, y + owner.getHeight() / 2, z);
matrices.multiply(Vec3f.POSITIVE_X.getDegreesQuaternion(roll));
matrices.multiply(Vec3f.POSITIVE_Y.getDegreesQuaternion(roll));
if (pony instanceof Pony) {
roll = ((Pony)pony).getCamera().calculateRoll();
if (negative) {
roll -= 180;
}
matrices.multiply(Vec3f.NEGATIVE_Y.getDegreesQuaternion(yaw));
matrices.multiply(Vec3f.POSITIVE_Z.getDegreesQuaternion(roll));

View file

@ -22,7 +22,7 @@ public final class PlayerDimensions {
return getPredicate()
.flatMap(e -> e.getTargetEyeHeight(pony))
.filter(h -> h > 0)
.or(() -> physics.isFlyingSurvival ? FLYING_EYE_HEIGHT : Optional.empty())
.or(() -> physics.isFlyingSurvival ? FLYING_EYE_HEIGHT : physics.isGravityNegative() ? Optional.of(dimensions.height) : Optional.empty())
.map(h -> {
if (physics.isGravityNegative()) {
if (pony.getMaster().isSneaking()) {

View file

@ -294,7 +294,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
entity.setVelocity(velocity.toImmutable());
if (isFlying() && !entity.isFallFlying()) {
if (isFlying() && !entity.isFallFlying() && !pony.isHanging()) {
float pitch = ((LivingEntityDuck)entity).getLeaningPitch();
if (pitch < 1) {
@ -429,7 +429,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
&& (horMotion > 0.2 || (motion > 0.2 && velocity.y < -0.02 * getGravitySignum()));
boolean fallingTakeOffCondition = !entity.isOnGround() && velocity.y < -1.6 * getGravitySignum();
if (takeOffCondition || fallingTakeOffCondition) {
if ((takeOffCondition || fallingTakeOffCondition) && !pony.isHanging()) {
entity.getAbilities().flying = true;
isFlyingEither = true;
isFlyingSurvival = true;

View file

@ -20,6 +20,7 @@ import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
import com.minelittlepony.unicopia.ability.magic.spell.trait.TraitDiscovery;
import com.minelittlepony.unicopia.advancement.UCriteria;
import com.minelittlepony.unicopia.entity.*;
import com.minelittlepony.unicopia.entity.duck.LivingEntityDuck;
import com.minelittlepony.unicopia.entity.effect.SunBlindnessStatusEffect;
import com.minelittlepony.unicopia.entity.effect.UEffects;
import com.minelittlepony.unicopia.item.FriendshipBraceletItem;
@ -30,10 +31,8 @@ import com.minelittlepony.unicopia.network.MsgOtherPlayerCapabilities;
import com.minelittlepony.unicopia.network.MsgPlayerAnimationChange;
import com.minelittlepony.unicopia.network.MsgRequestSpeciesChange;
import com.minelittlepony.unicopia.network.datasync.Transmittable;
import com.minelittlepony.unicopia.util.*;
import com.minelittlepony.unicopia.network.datasync.EffectSync.UpdateCallback;
import com.minelittlepony.unicopia.util.Copieable;
import com.minelittlepony.unicopia.util.MagicalDamageSource;
import com.minelittlepony.unicopia.util.Tickable;
import com.minelittlepony.common.util.animation.LinearInterpolator;
import com.google.common.collect.Lists;
import com.google.common.collect.Streams;
@ -44,6 +43,7 @@ import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.attribute.DefaultAttributeContainer;
import net.minecraft.entity.attribute.EntityAttributeInstance;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.damage.EntityDamageSource;
import net.minecraft.entity.data.DataTracker;
@ -59,8 +59,7 @@ import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundEvents;
import net.minecraft.text.Text;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.*;
public class Pony extends Living<PlayerEntity> implements Transmittable, Copieable<Pony>, UpdateCallback {
@ -97,6 +96,7 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
private boolean speciesSet;
private boolean speciesPersisted;
private Optional<BlockPos> hangingPosition = Optional.empty();
private int ticksHanging;
private float magicExhaustion = 0;
@ -323,41 +323,53 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
return entity.getAttributeInstance(UEntityAttributes.ENTITY_GRAVTY_MODIFIER).hasModifier(PlayerAttributes.BAT_HANGING);
}
public void stopHanging() {
entity.getAttributeInstance(UEntityAttributes.ENTITY_GRAVTY_MODIFIER).removeModifier(PlayerAttributes.BAT_HANGING);
entity.calculateDimensions();
ticksHanging = 0;
hangingPosition = Optional.empty();
}
public void startHanging(BlockPos pos) {
hangingPosition = Optional.of(pos);
EntityAttributeInstance attr = entity.getAttributeInstance(UEntityAttributes.ENTITY_GRAVTY_MODIFIER);
if (!attr.hasModifier(PlayerAttributes.BAT_HANGING)) {
attr.addPersistentModifier(PlayerAttributes.BAT_HANGING);
}
entity.teleport(pos.getX() + 0.5, pos.getY() - 1, pos.getZ() + 0.5);
entity.setVelocity(Vec3d.ZERO);
entity.setSneaking(false);
entity.stopFallFlying();
}
public boolean canHangAt(BlockPos pos) {
if (!getReferenceWorld().isAir(pos) || !getReferenceWorld().isAir(pos.down())) {
return false;
}
pos = pos.up();
BlockState state = getReferenceWorld().getBlockState(pos);
return state.isSolidSurface(getReferenceWorld(), pos, getEntity(), Direction.DOWN);
}
private BlockPos getHangingPos() {
BlockPos pos = getOrigin();
return new BlockPos(pos.getX(), pos.getY() + entity.getEyeHeight(entity.getPose()) + 2, pos.getZ());
}
@Override
public void tick() {
if (animationDuration >= 0) {
if (--animationDuration <= 0) {
setAnimation(Animation.NONE);
}
if (animationDuration >= 0 && --animationDuration <= 0) {
setAnimation(Animation.NONE);
}
if (isHanging()) {
if (ticksHanging++ > 40) {
if (entity.getVelocity().horizontalLengthSquared() > 0.01
|| entity.isSneaking()
|| !canHangAt(getHangingPos())) {
entity.getAttributes().getCustomInstance(UEntityAttributes.ENTITY_GRAVTY_MODIFIER).removeModifier(PlayerAttributes.BAT_HANGING);
entity.calculateDimensions();
}
((LivingEntityDuck)entity).setLeaningPitch(0);
if (!isClient() && (getSpecies() != Race.BAT || (ticksHanging++ > 40 && hangingPosition.filter(getOrigin()::equals).filter(this::canHangAt).isPresent()))) {
stopHanging();
}
} else {
ticksHanging = 0;
}
if (getSpecies() == Race.BAT) {
if (getSpecies() == Race.BAT && !entity.hasPortalCooldown()) {
if (SunBlindnessStatusEffect.hasSunExposure(entity)) {
if (ticksInSun < 200) {
ticksInSun++;
@ -542,6 +554,10 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
super.toNBT(compound);
compound.putString("playerSpecies", Race.REGISTRY.getId(getSpecies()).toString());
compound.putFloat("magicExhaustion", magicExhaustion);
compound.putInt("ticksHanging", ticksHanging);
NbtSerialisable.writeBlockPos("hangingPosition", hangingPosition, compound);
compound.putInt("ticksInSun", ticksInSun);
compound.putBoolean("hasShades", hasShades);
compound.put("powers", powers.toNBT());
compound.put("gravity", gravity.toNBT());
compound.put("charms", charms.toNBT());
@ -566,7 +582,6 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
super.fromNBT(compound);
speciesPersisted = true;
setSpecies(Race.fromName(compound.getString("playerSpecies"), Race.HUMAN));
powers.fromNBT(compound.getCompound("powers"));
gravity.fromNBT(compound.getCompound("gravity"));
charms.fromNBT(compound.getCompound("charms"));
@ -576,6 +591,10 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
mana.fromNBT(compound.getCompound("mana"));
magicExhaustion = compound.getFloat("magicExhaustion");
ticksHanging = compound.getInt("ticksHanging");
hangingPosition = NbtSerialisable.readBlockPos("hangingPosition", compound);
ticksInSun = compound.getInt("ticksInSun");
hasShades = compound.getBoolean("hasShades");
if (compound.contains("effect")) {
getSpellSlot().put(Spell.readNbt(compound.getCompound("effect")));

View file

@ -42,7 +42,7 @@ public interface NbtSerialisable {
}
static void writeBlockPos(String name, Optional<BlockPos> pos, NbtCompound nbt) {
pos.map(NbtHelper::fromBlockPos).ifPresent(p -> nbt.put("hoveringPosition", p));
pos.map(NbtHelper::fromBlockPos).ifPresent(p -> nbt.put(name, p));
}
static Optional<BlockPos> readBlockPos(String name, NbtCompound nbt) {