mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Fix fall damage, ladders, hitbox calculations, clipping, camera offset, and unicorn's teleportation when in inverted gravity
This commit is contained in:
parent
b4a847e4b5
commit
692db5a070
17 changed files with 203 additions and 158 deletions
|
@ -27,6 +27,7 @@ import net.minecraft.sound.SoundCategory;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.util.shape.VoxelShape;
|
import net.minecraft.util.shape.VoxelShape;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
@ -89,8 +90,10 @@ public class UnicornTeleportAbility implements Ability<Pos> {
|
||||||
return trace.getBlockOrEntityPos().map(pos -> {
|
return trace.getBlockOrEntityPos().map(pos -> {
|
||||||
final BlockPos originalPos = pos;
|
final BlockPos originalPos = pos;
|
||||||
|
|
||||||
|
Direction globalUp = player.getPhysics().isGravityNegative() ? Direction.DOWN : Direction.UP;
|
||||||
|
|
||||||
boolean originalPosHasSupport = exception(w, pos, player.asEntity());
|
boolean originalPosHasSupport = exception(w, pos, player.asEntity());
|
||||||
boolean originalPosValid = enterable(w, pos.up()) && enterable(w, pos.up(2));
|
boolean originalPosValid = enterable(w, pos.offset(globalUp)) && enterable(w, pos.offset(globalUp, 2));
|
||||||
|
|
||||||
if (w.getBlockState(pos).isOf(Blocks.POWDER_SNOW) && !PowderSnowBlock.canWalkOnPowderSnow(player.asEntity())) {
|
if (w.getBlockState(pos).isOf(Blocks.POWDER_SNOW) && !PowderSnowBlock.canWalkOnPowderSnow(player.asEntity())) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -111,11 +114,11 @@ public class UnicornTeleportAbility implements Ability<Pos> {
|
||||||
if (pos.getX() != originalPos.getX() || pos.getZ() != originalPos.getZ()) {
|
if (pos.getX() != originalPos.getX() || pos.getZ() != originalPos.getZ()) {
|
||||||
// check support
|
// check support
|
||||||
int steps = 0;
|
int steps = 0;
|
||||||
while (enterable(w, pos.down())) {
|
while (enterable(w, pos.offset(globalUp.getOpposite()))) {
|
||||||
pos = pos.down();
|
pos = pos.offset(globalUp.getOpposite());
|
||||||
if (++steps > 2) {
|
if (++steps > 2) {
|
||||||
if (originalPosValid) {
|
if (originalPosValid) {
|
||||||
pos = originalPos.up();
|
pos = originalPos.offset(globalUp);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
|
@ -125,7 +128,7 @@ public class UnicornTeleportAbility implements Ability<Pos> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!enterable(w, pos) && exception(w, pos, player.asEntity()))
|
if ((!enterable(w, pos) && exception(w, pos, player.asEntity()))
|
||||||
|| (!enterable(w, pos.up()) && exception(w, pos.up(), player.asEntity()))) {
|
|| (!enterable(w, pos.offset(globalUp)) && exception(w, pos.offset(globalUp), player.asEntity()))) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -175,43 +175,39 @@ public class WorldRenderDelegate {
|
||||||
|
|
||||||
boolean negative = pony.getPhysics().isGravityNegative();
|
boolean negative = pony.getPhysics().isGravityNegative();
|
||||||
|
|
||||||
float roll = negative ? 180 : 0;
|
|
||||||
|
|
||||||
roll = pony instanceof Pony ? ((Pony)pony).getInterpolator().interpolate("g_roll", roll, 15) : roll;
|
|
||||||
|
|
||||||
matrices.translate(x, y + owner.getHeight() / 2, z);
|
matrices.translate(x, y + owner.getHeight() / 2, z);
|
||||||
|
|
||||||
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(roll));
|
|
||||||
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(roll));
|
|
||||||
|
|
||||||
if (pony instanceof Pony p) {
|
if (pony instanceof Pony p) {
|
||||||
roll = p.getCamera().calculateRoll();
|
float sidewaysRoll = p.getCamera().calculateRoll();
|
||||||
if (negative) {
|
|
||||||
roll -= 180;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p.getAcrobatics().isFloppy()) {
|
if (p.getAcrobatics().isFloppy()) {
|
||||||
matrices.translate(0, -0.5, 0);
|
matrices.translate(0, -0.5, 0);
|
||||||
p.asEntity().setBodyYaw(0);
|
p.asEntity().setBodyYaw(0);
|
||||||
p.asEntity().setYaw(0);
|
p.asEntity().setYaw(0);
|
||||||
matrices.multiply(RotationAxis.NEGATIVE_X.rotationDegrees(90));
|
sidewaysRoll += 90;
|
||||||
}
|
}
|
||||||
|
|
||||||
matrices.multiply(RotationAxis.NEGATIVE_Y.rotationDegrees(yaw));
|
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(90));
|
||||||
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(roll));
|
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(sidewaysRoll));
|
||||||
|
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-90));
|
||||||
|
|
||||||
float diveAngle = p.getInterpolator().interpolate("g_kdive", p.getMotion().isDiving() ? 80 : 0, 15);
|
float forwardPitch = p.getInterpolator().interpolate("g_kdive", p.getMotion().isDiving() ? 80 : 0, 15);
|
||||||
|
|
||||||
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(diveAngle));
|
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(forwardPitch));
|
||||||
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(yaw));
|
|
||||||
|
|
||||||
if (p.getCompositeRace().includes(Race.SEAPONY)
|
if (p.getCompositeRace().includes(Race.SEAPONY)
|
||||||
&& pony.asEntity().isSubmergedInWater()
|
&& pony.asEntity().isSubmergedInWater()
|
||||||
&& MineLPDelegate.getInstance().getPlayerPonyRace(p.asEntity()) != Race.SEAPONY) {
|
&& MineLPDelegate.getInstance().getPlayerPonyRace(p.asEntity()) != Race.SEAPONY) {
|
||||||
ModelPartHooks.startCollecting();
|
ModelPartHooks.startCollecting();
|
||||||
}
|
}
|
||||||
} else if (pony instanceof Creature creature && smittenEyesRenderer.isSmitten(creature)) {
|
} else {
|
||||||
ModelPartHooks.startCollecting();
|
float roll = negative ? 180 : 0;
|
||||||
|
|
||||||
|
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(roll));
|
||||||
|
|
||||||
|
if (pony instanceof Creature creature && smittenEyesRenderer.isSmitten(creature)) {
|
||||||
|
ModelPartHooks.startCollecting();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
matrices.translate(-x, -y - owner.getHeight() / 2, -z);
|
matrices.translate(-x, -y - owner.getHeight() / 2, -z);
|
||||||
|
@ -224,7 +220,7 @@ public class WorldRenderDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void flipAngles(Entity entity) {
|
private void flipAngles(Entity entity) {
|
||||||
if (entity instanceof PlayerEntity) {
|
if (entity instanceof PlayerEntity player) {
|
||||||
entity.prevYaw *= -1;
|
entity.prevYaw *= -1;
|
||||||
entity.setYaw(entity.getYaw() * -1);
|
entity.setYaw(entity.getYaw() * -1);
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
package com.minelittlepony.unicopia.command;
|
package com.minelittlepony.unicopia.command;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Collection;
|
||||||
import java.util.stream.Stream;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import com.google.common.collect.Streams;
|
import com.minelittlepony.unicopia.entity.Living;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
|
||||||
import com.mojang.brigadier.arguments.FloatArgumentType;
|
import com.mojang.brigadier.arguments.FloatArgumentType;
|
||||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
|
|
||||||
import net.minecraft.command.argument.EntityArgumentType;
|
import net.minecraft.command.argument.EntityArgumentType;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.server.command.CommandManager;
|
import net.minecraft.server.command.CommandManager;
|
||||||
import net.minecraft.server.command.ServerCommandSource;
|
import net.minecraft.server.command.ServerCommandSource;
|
||||||
|
@ -22,45 +22,48 @@ class GravityCommand {
|
||||||
return CommandManager.literal("gravity").requires(s -> s.hasPermissionLevel(2))
|
return CommandManager.literal("gravity").requires(s -> s.hasPermissionLevel(2))
|
||||||
.then(CommandManager.literal("get")
|
.then(CommandManager.literal("get")
|
||||||
.executes(context -> get(context.getSource(), context.getSource().getPlayer(), true))
|
.executes(context -> get(context.getSource(), context.getSource().getPlayer(), true))
|
||||||
.then(CommandManager.argument("target", EntityArgumentType.player())
|
.then(CommandManager.argument("target", EntityArgumentType.entity())
|
||||||
.executes(context -> get(context.getSource(), EntityArgumentType.getPlayer(context, "target"), false))
|
.executes(context -> get(context.getSource(), EntityArgumentType.getEntity(context, "target"), false))
|
||||||
))
|
))
|
||||||
.then(CommandManager.literal("set")
|
.then(CommandManager.literal("set")
|
||||||
.then(CommandManager.argument("gravity", FloatArgumentType.floatArg(-99, 99))
|
.then(CommandManager.argument("gravity", FloatArgumentType.floatArg(-99, 99))
|
||||||
.executes(context -> set(context.getSource(), context.getSource().getPlayer(), FloatArgumentType.getFloat(context, "gravity"), true))
|
.executes(context -> set(context.getSource(), List.of(context.getSource().getPlayer()), FloatArgumentType.getFloat(context, "gravity"), true))
|
||||||
.then(CommandManager.argument("target", EntityArgumentType.player())
|
.then(CommandManager.argument("target", EntityArgumentType.entities())
|
||||||
.executes(context -> set(context.getSource(), EntityArgumentType.getPlayer(context, "target"), FloatArgumentType.getFloat(context, "gravity"), false))
|
.executes(context -> set(context.getSource(), EntityArgumentType.getEntities(context, "target"), FloatArgumentType.getFloat(context, "gravity"), false))
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get(ServerCommandSource source, PlayerEntity player, boolean isSelf) throws CommandSyntaxException {
|
static int get(ServerCommandSource source, Entity target, boolean isSelf) throws CommandSyntaxException {
|
||||||
sendFeedback(source, player, "get", false, Pony.of(player).getPhysics().getGravityModifier());
|
Living<?> l = Living.living(target);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int set(ServerCommandSource source, PlayerEntity player, float gravity, boolean isSelf) {
|
float gravity = l == null ? 1 : l.getPhysics().getGravityModifier();
|
||||||
|
if (source.getEntity() == target) {
|
||||||
Pony iplayer = Pony.of(player);
|
source.sendFeedback(() -> Text.translatable("commands.gravity.get.self", gravity), true);
|
||||||
|
|
||||||
iplayer.getPhysics().setBaseGravityModifier(gravity);
|
|
||||||
iplayer.setDirty();
|
|
||||||
|
|
||||||
sendFeedback(source, player, "set", true, gravity);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void sendFeedback(ServerCommandSource source, PlayerEntity player, String key, boolean notifyTarget, Object...arguments) {
|
|
||||||
String translationKey = "commands.gravity." + key;
|
|
||||||
|
|
||||||
if (source.getEntity() == player) {
|
|
||||||
source.sendFeedback(() -> Text.translatable(translationKey + ".self", arguments), true);
|
|
||||||
} else {
|
} else {
|
||||||
if (notifyTarget && source.getWorld().getGameRules().getBoolean(GameRules.SEND_COMMAND_FEEDBACK)) {
|
source.sendFeedback(() -> Text.translatable("commands.gravity.get.other", target.getDisplayName(), gravity), true);
|
||||||
player.sendMessage(Text.translatable(translationKey, arguments));
|
|
||||||
}
|
|
||||||
|
|
||||||
source.sendFeedback(() -> Text.translatable(translationKey + ".other", Streams.concat(Stream.of(player.getDisplayName()), Arrays.stream(arguments)).toArray()), true);
|
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set(ServerCommandSource source, Collection<? extends Entity> targets, float gravity, boolean isSelf) {
|
||||||
|
List<Entity> affected = targets.stream().map(Living::living).filter(Objects::nonNull).map(l -> {
|
||||||
|
l.getPhysics().setBaseGravityModifier(gravity);
|
||||||
|
l.setDirty();
|
||||||
|
if (l.asEntity() instanceof PlayerEntity player) {
|
||||||
|
if (source.getEntity() == player) {
|
||||||
|
player.sendMessage(Text.translatable("commands.gravity.set.self", gravity));
|
||||||
|
} else if (source.getWorld().getGameRules().getBoolean(GameRules.SEND_COMMAND_FEEDBACK)) {
|
||||||
|
player.sendMessage(Text.translatable("commands.gravity.set.other", l.asEntity().getDisplayName(), gravity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (Entity)l.asEntity();
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
if (affected.size() == 1) {
|
||||||
|
source.sendFeedback(() -> Text.translatable("commands.gravity.set.other", affected.get(0).getDisplayName()), true);
|
||||||
|
} else {
|
||||||
|
source.sendFeedback(() -> Text.translatable("commands.gravity.set.multiple", affected.size()), true);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,18 +4,13 @@ import com.minelittlepony.unicopia.entity.mob.UEntityAttributes;
|
||||||
import com.minelittlepony.unicopia.util.Copyable;
|
import com.minelittlepony.unicopia.util.Copyable;
|
||||||
import com.minelittlepony.unicopia.util.Tickable;
|
import com.minelittlepony.unicopia.util.Tickable;
|
||||||
|
|
||||||
import net.minecraft.block.BlockRenderType;
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.FenceGateBlock;
|
import net.minecraft.block.FenceGateBlock;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityPose;
|
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.entity.MovementType;
|
|
||||||
import net.minecraft.entity.data.TrackedData;
|
import net.minecraft.entity.data.TrackedData;
|
||||||
import net.minecraft.entity.mob.MobEntity;
|
import net.minecraft.entity.mob.MobEntity;
|
||||||
import net.minecraft.nbt.NbtCompound;
|
import net.minecraft.nbt.NbtCompound;
|
||||||
import net.minecraft.particle.BlockStateParticleEffect;
|
|
||||||
import net.minecraft.particle.ParticleTypes;
|
|
||||||
import net.minecraft.registry.tag.BlockTags;
|
import net.minecraft.registry.tag.BlockTags;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
@ -37,22 +32,12 @@ public class EntityPhysics<T extends Entity> implements Physics, Copyable<Entity
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
if (isGravityNegative()) {
|
if (isGravityNegative()) {
|
||||||
if (isGravityNegative() && !entity.isSneaking() && entity.isInSneakingPose()) {
|
|
||||||
float currentHeight = entity.getDimensions(entity.getPose()).height;
|
|
||||||
float sneakingHeight = entity.getDimensions(EntityPose.STANDING).height;
|
|
||||||
|
|
||||||
entity.move(MovementType.SELF, new Vec3d(0, -(currentHeight - sneakingHeight), 0));
|
|
||||||
entity.setPose(EntityPose.STANDING);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entity.getY() > entity.getWorld().getHeight() + 64) {
|
if (entity.getY() > entity.getWorld().getHeight() + 64) {
|
||||||
entity.damage(entity.getDamageSources().outOfWorld(), 4.0F);
|
entity.damage(entity.getDamageSources().outOfWorld(), 4.0F);
|
||||||
}
|
}
|
||||||
|
|
||||||
entity.setOnGround(entity.verticalCollision && entity.getVelocity().getY() > 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float gravity = this.getGravityModifier();
|
float gravity = getGravityModifier();
|
||||||
if (gravity != lastGravity) {
|
if (gravity != lastGravity) {
|
||||||
lastGravity = gravity;
|
lastGravity = gravity;
|
||||||
|
|
||||||
|
@ -87,8 +72,6 @@ public class EntityPhysics<T extends Entity> implements Physics, Copyable<Entity
|
||||||
@Override
|
@Override
|
||||||
public BlockPos getHeadPosition() {
|
public BlockPos getHeadPosition() {
|
||||||
|
|
||||||
entity.setOnGround(false);
|
|
||||||
|
|
||||||
BlockPos pos = new BlockPos(
|
BlockPos pos = new BlockPos(
|
||||||
MathHelper.floor(entity.getX()),
|
MathHelper.floor(entity.getX()),
|
||||||
MathHelper.floor(entity.getY() + entity.getHeight() + 0.20000000298023224D),
|
MathHelper.floor(entity.getY() + entity.getHeight() + 0.20000000298023224D),
|
||||||
|
@ -99,29 +82,13 @@ public class EntityPhysics<T extends Entity> implements Physics, Copyable<Entity
|
||||||
BlockPos below = pos.down();
|
BlockPos below = pos.down();
|
||||||
BlockState block = entity.getWorld().getBlockState(below);
|
BlockState block = entity.getWorld().getBlockState(below);
|
||||||
if (block.isIn(BlockTags.FENCES) || block.isIn(BlockTags.WALLS) || block.getBlock() instanceof FenceGateBlock) {
|
if (block.isIn(BlockTags.FENCES) || block.isIn(BlockTags.WALLS) || block.getBlock() instanceof FenceGateBlock) {
|
||||||
entity.setOnGround(true);
|
|
||||||
return below;
|
return below;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
entity.setOnGround(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void spawnSprintingParticles() {
|
|
||||||
BlockState state = entity.getWorld().getBlockState(getHeadPosition());
|
|
||||||
if (state.getRenderType() != BlockRenderType.INVISIBLE) {
|
|
||||||
Vec3d vel = entity.getVelocity();
|
|
||||||
entity.getWorld().addParticle(new BlockStateParticleEffect(ParticleTypes.BLOCK, state),
|
|
||||||
entity.getX() + (entity.getWorld().random.nextFloat() - 0.5D) * entity.getWidth(),
|
|
||||||
entity.getY() + entity.getHeight() - 0.1D,
|
|
||||||
entity.getZ() + (entity.getWorld().random.nextFloat() - 0.5D) * entity.getWidth(),
|
|
||||||
vel.x * -4, -1.5D, vel.z * -4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBaseGravityModifier(float constant) {
|
public void setBaseGravityModifier(float constant) {
|
||||||
entity.getDataTracker().set(gravity, constant);
|
entity.getDataTracker().set(gravity, constant);
|
||||||
|
|
|
@ -476,12 +476,6 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onJump() {
|
|
||||||
if (getPhysics().isGravityNegative()) {
|
|
||||||
entity.setVelocity(entity.getVelocity().multiply(1, -1, 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public final Caster<?> getAttacker() {
|
public final Caster<?> getAttacker() {
|
||||||
return attacker;
|
return attacker;
|
||||||
|
|
|
@ -21,8 +21,6 @@ public interface Physics extends NbtSerialisable {
|
||||||
|
|
||||||
BlockPos getHeadPosition();
|
BlockPos getHeadPosition();
|
||||||
|
|
||||||
void spawnSprintingParticles();
|
|
||||||
|
|
||||||
default boolean isGravityNegative() {
|
default boolean isGravityNegative() {
|
||||||
return getGravityModifier() < 0;
|
return getGravityModifier() < 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,11 +25,7 @@ public final class PlayerDimensions {
|
||||||
.or(() -> physics.isFlyingSurvival ? FLYING_EYE_HEIGHT : physics.isGravityNegative() ? Optional.of(dimensions.height) : Optional.empty())
|
.or(() -> physics.isFlyingSurvival ? FLYING_EYE_HEIGHT : physics.isGravityNegative() ? Optional.of(dimensions.height) : Optional.empty())
|
||||||
.map(h -> {
|
.map(h -> {
|
||||||
if (physics.isGravityNegative()) {
|
if (physics.isGravityNegative()) {
|
||||||
if (pony.asEntity().isSneaking()) {
|
return dimensions.height - h + 0.1F;
|
||||||
h += 0.2F;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dimensions.height - h;
|
|
||||||
}
|
}
|
||||||
return h;
|
return h;
|
||||||
});
|
});
|
||||||
|
|
|
@ -301,10 +301,6 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
||||||
if (entity.isOnGround() || (!creative && entity.horizontalCollision)) {
|
if (entity.isOnGround() || (!creative && entity.horizontalCollision)) {
|
||||||
cancelFlight(false);
|
cancelFlight(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity.isClimbing() && (entity.horizontalCollision || ((LivingEntityDuck)entity).isJumping())) {
|
|
||||||
velocity.y = -0.2F;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isFlyingSurvival = entity.getAbilities().flying && !creative;
|
isFlyingSurvival = entity.getAbilities().flying && !creative;
|
||||||
|
|
|
@ -631,7 +631,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
||||||
float max = 0.6F;
|
float max = 0.6F;
|
||||||
return Optional.of(new Vec3d(
|
return Optional.of(new Vec3d(
|
||||||
MathHelper.clamp(speed.x * factor, -max, max),
|
MathHelper.clamp(speed.x * factor, -max, max),
|
||||||
speed.y * ((speed.y * getPhysics().getGravitySignum()) > 0 ? 1.2 : 1.101),
|
speed.y * (speed.y > 0 ? 1.2 : 1.101),
|
||||||
MathHelper.clamp(speed.z * factor, -max, max)
|
MathHelper.clamp(speed.z * factor, -max, max)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -715,11 +715,8 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<Float> onImpact(float distance, float damageMultiplier, DamageSource cause) {
|
public Optional<Float> onImpact(float distance, float damageMultiplier, DamageSource cause) {
|
||||||
|
|
||||||
float originalDistance = distance;
|
float originalDistance = distance;
|
||||||
|
|
||||||
distance *= gravity.getGravityModifier();
|
|
||||||
|
|
||||||
boolean extraProtection = getSpellSlot().get(SpellType.SHIELD, false).isPresent();
|
boolean extraProtection = getSpellSlot().get(SpellType.SHIELD, false).isPresent();
|
||||||
|
|
||||||
if (!entity.isCreative() && !entity.isSpectator()) {
|
if (!entity.isCreative() && !entity.isSpectator()) {
|
||||||
|
|
|
@ -128,11 +128,6 @@ abstract class MixinLivingEntity extends Entity implements LivingEntityDuck, Equ
|
||||||
get().adjustMovementSpeedInWater(info.getReturnValue()).ifPresent(info::setReturnValue);
|
get().adjustMovementSpeedInWater(info.getReturnValue()).ifPresent(info::setReturnValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "jump()V", at = @At("RETURN"))
|
|
||||||
private void onJump(CallbackInfo info) {
|
|
||||||
get().onJump();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "tick()V", at = @At("HEAD"), cancellable = true)
|
@Inject(method = "tick()V", at = @At("HEAD"), cancellable = true)
|
||||||
private void beforeTick(CallbackInfo info) {
|
private void beforeTick(CallbackInfo info) {
|
||||||
if (get().beforeUpdate()) {
|
if (get().beforeUpdate()) {
|
||||||
|
@ -186,21 +181,4 @@ abstract class MixinLivingEntity extends Entity implements LivingEntityDuck, Equ
|
||||||
setLivingFlag(2, hand == Hand.OFF_HAND);
|
setLivingFlag(2, hand == Hand.OFF_HAND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockPos getBlockPos() {
|
|
||||||
if (get().getPhysics().isGravityNegative()) {
|
|
||||||
return get().getPhysics().getHeadPosition();
|
|
||||||
}
|
|
||||||
return super.getBlockPos();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void spawnSprintingParticles() {
|
|
||||||
if (get().getPhysics().isGravityNegative()) {
|
|
||||||
get().getPhysics().spawnSprintingParticles();
|
|
||||||
} else {
|
|
||||||
super.spawnSprintingParticles();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,12 +27,6 @@ abstract class MixinKeyboardInput extends Input {
|
||||||
pressingRight = tmp;
|
pressingRight = tmp;
|
||||||
|
|
||||||
movementSideways = -movementSideways;
|
movementSideways = -movementSideways;
|
||||||
|
|
||||||
/*if (player.asEntity().getAbilities().flying && !player.getPhysics().isFlying()) {
|
|
||||||
tmp = jumping;
|
|
||||||
jumping = sneaking;
|
|
||||||
sneaking = tmp;
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EffectUtils.getAmplifier(MinecraftClient.getInstance().player, UEffects.PARALYSIS) > 1) {
|
if (EffectUtils.getAmplifier(MinecraftClient.getInstance().player, UEffects.PARALYSIS) > 1) {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.At.Shift;
|
import org.spongepowered.asm.mixin.injection.At.Shift;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||||
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
@ -12,7 +13,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
import com.minelittlepony.unicopia.entity.Equine;
|
import com.minelittlepony.unicopia.entity.Equine;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityPose;
|
||||||
import net.minecraft.entity.MovementType;
|
import net.minecraft.entity.MovementType;
|
||||||
|
import net.minecraft.util.math.Box;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
@Mixin(value = Entity.class, priority = 29000)
|
@Mixin(value = Entity.class, priority = 29000)
|
||||||
|
@ -21,7 +24,7 @@ abstract class MixinEntity {
|
||||||
// we invert y when moving
|
// we invert y when moving
|
||||||
@ModifyVariable(method = "move", at = @At("HEAD"), argsOnly = true)
|
@ModifyVariable(method = "move", at = @At("HEAD"), argsOnly = true)
|
||||||
private Vec3d modifyMovement(Vec3d movement) {
|
private Vec3d modifyMovement(Vec3d movement) {
|
||||||
if (this instanceof Equine.Container eq && eq.get().getPhysics().isGravityNegative()) {
|
if (unicopiaIsGravityInverted()) {
|
||||||
return movement.multiply(1, -1, 1);
|
return movement.multiply(1, -1, 1);
|
||||||
}
|
}
|
||||||
return movement;
|
return movement;
|
||||||
|
@ -35,14 +38,6 @@ abstract class MixinEntity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// invert jumping velocity so we can jump
|
|
||||||
@Inject(method = "getJumpVelocityMultiplier", at = @At("RETURN"), cancellable = true)
|
|
||||||
private void onGetJumpVelocityMultiplier(CallbackInfoReturnable<Float> info) {
|
|
||||||
if (this instanceof Equine.Container eq && eq.get().getPhysics().isGravityNegative()) {
|
|
||||||
info.setReturnValue(-info.getReturnValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// invert offsets so it can properly find the block we're walking on
|
// invert offsets so it can properly find the block we're walking on
|
||||||
@ModifyVariable(method = "getPosWithYOffset", at = @At("HEAD"), argsOnly = true)
|
@ModifyVariable(method = "getPosWithYOffset", at = @At("HEAD"), argsOnly = true)
|
||||||
private float onGetPosWithYOffset(float offset) {
|
private float onGetPosWithYOffset(float offset) {
|
||||||
|
@ -53,12 +48,27 @@ abstract class MixinEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
// fix sprinting particles
|
// fix sprinting particles
|
||||||
@Inject(method = "spawnSprintingParticles", at = @At("HEAD"), cancellable = true)
|
@ModifyArg(method = "spawnSprintingParticles",
|
||||||
protected void spawnSprintingParticles(CallbackInfo info) {
|
at = @At(value = "INVOKE",
|
||||||
|
target = "net/minecraft/world/World.addParticle(Lnet/minecraft/particle/ParticleEffect;DDDDDD)V"),
|
||||||
|
index = 2)
|
||||||
|
private double modifyParticleY(double y) {
|
||||||
if (this instanceof Equine.Container eq && eq.get().getPhysics().isGravityNegative()) {
|
if (this instanceof Equine.Container eq && eq.get().getPhysics().isGravityNegative()) {
|
||||||
eq.get().getPhysics().spawnSprintingParticles();
|
Entity self = eq.get().asEntity();
|
||||||
info.cancel();
|
return self.getHeight() - y + (self.getY() * 2);
|
||||||
}
|
}
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fix fall damage
|
||||||
|
@ModifyArg(
|
||||||
|
method = "move",
|
||||||
|
at = @At(value = "INVOKE", target = "net/minecraft/entity/Entity.fall(DZLnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;)V"))
|
||||||
|
private double modifyFallDistance(double heightDifference) {
|
||||||
|
if (unicopiaIsGravityInverted()) {
|
||||||
|
return -heightDifference;
|
||||||
|
}
|
||||||
|
return heightDifference;
|
||||||
}
|
}
|
||||||
|
|
||||||
// invert check for walking up a step
|
// invert check for walking up a step
|
||||||
|
@ -68,9 +78,43 @@ abstract class MixinEntity {
|
||||||
argsOnly = true)
|
argsOnly = true)
|
||||||
|
|
||||||
private static Vec3d modifyMovementForStepheight(Vec3d movement, @Nullable Entity entity) {
|
private static Vec3d modifyMovementForStepheight(Vec3d movement, @Nullable Entity entity) {
|
||||||
if (entity != null && movement.getY() == entity.getStepHeight()) {
|
if (entity instanceof Equine.Container eq && eq.get().getPhysics().isGravityNegative() && movement.getY() == entity.getStepHeight()) {
|
||||||
return movement.multiply(1, -1, 1);
|
return movement.multiply(1, -1, 1);
|
||||||
}
|
}
|
||||||
return movement;
|
return movement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Inject(method = {"calculateBoundsForPose"}, at = @At("RETURN"), cancellable = true)
|
||||||
|
private void adjustPoseBoxForGravity(EntityPose pos, CallbackInfoReturnable<Box> info) {
|
||||||
|
unicopiaReAnchorBoundingBox(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = {"calculateBoundingBox"}, at = @At("RETURN"), cancellable = true)
|
||||||
|
private void adjustPoseBoxForGravity(CallbackInfoReturnable<Box> info) {
|
||||||
|
if (unicopiaReAnchorBoundingBox(info)) {
|
||||||
|
Entity self = (Entity)(Object)this;
|
||||||
|
self.setPos(self.getX(), info.getReturnValue().minY, self.getZ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean unicopiaReAnchorBoundingBox(CallbackInfoReturnable<Box> info) {
|
||||||
|
if (this instanceof Equine.Container eq && eq.get().getPhysics().isGravityNegative()) {
|
||||||
|
Entity self = eq.get().asEntity();
|
||||||
|
Box box = info.getReturnValue();
|
||||||
|
Box oldBox = self.getBoundingBox();
|
||||||
|
double newHeight = box.getYLength();
|
||||||
|
if (newHeight > oldBox.getYLength()) {
|
||||||
|
double targetMaxY = oldBox.maxY;
|
||||||
|
Vec3d min = new Vec3d(box.minX, targetMaxY - newHeight, box.minZ);
|
||||||
|
Vec3d max = new Vec3d(box.maxX, targetMaxY, box.maxZ);
|
||||||
|
info.setReturnValue(new Box(min, max));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean unicopiaIsGravityInverted() {
|
||||||
|
return this instanceof Equine.Container eq && eq.get().getPhysics().isGravityNegative();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
package com.minelittlepony.unicopia.mixin.gravity;
|
package com.minelittlepony.unicopia.mixin.gravity;
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.*;
|
import org.spongepowered.asm.mixin.*;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Constant;
|
import org.spongepowered.asm.mixin.injection.Constant;
|
||||||
|
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||||
import org.spongepowered.asm.mixin.injection.ModifyConstant;
|
import org.spongepowered.asm.mixin.injection.ModifyConstant;
|
||||||
import com.minelittlepony.unicopia.entity.*;
|
import com.minelittlepony.unicopia.entity.*;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
@Mixin(LivingEntity.class)
|
@Mixin(LivingEntity.class)
|
||||||
abstract class MixinLivingEntity extends Entity implements Equine.Container<Living<?>> {
|
abstract class MixinLivingEntity extends Entity implements Equine.Container<Living<?>> {
|
||||||
|
@ -19,4 +23,23 @@ abstract class MixinLivingEntity extends Entity implements Equine.Container<Livi
|
||||||
private double modifyGravity(double initial) {
|
private double modifyGravity(double initial) {
|
||||||
return Math.abs(get().getPhysics().calcGravity(initial));
|
return Math.abs(get().getPhysics().calcGravity(initial));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ModifyArg(method = "fall",
|
||||||
|
at = @At(value = "INVOKE",
|
||||||
|
target = "net/minecraft/server/world/ServerWorld.spawnParticles(Lnet/minecraft/particle/ParticleEffect;DDDIDDDD)I"),
|
||||||
|
index = 2)
|
||||||
|
private double modifyParticleY(double y) {
|
||||||
|
if (get().getPhysics().isGravityNegative()) {
|
||||||
|
return y + getHeight();
|
||||||
|
}
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockPos getBlockPos() {
|
||||||
|
if (get().getPhysics().isGravityNegative()) {
|
||||||
|
return get().getPhysics().getHeadPosition();
|
||||||
|
}
|
||||||
|
return super.getBlockPos();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.minelittlepony.unicopia.mixin.gravity;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||||
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
|
|
||||||
|
import net.minecraft.network.listener.ServerPlayPacketListener;
|
||||||
|
import net.minecraft.network.listener.TickablePacketListener;
|
||||||
|
import net.minecraft.server.network.ServerPlayNetworkHandler;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.server.world.EntityTrackingListener;
|
||||||
|
|
||||||
|
@Mixin(ServerPlayNetworkHandler.class)
|
||||||
|
abstract class MixinServerPlayNetworkHandler
|
||||||
|
implements EntityTrackingListener,
|
||||||
|
TickablePacketListener,
|
||||||
|
ServerPlayPacketListener {
|
||||||
|
@Shadow public ServerPlayerEntity player;
|
||||||
|
|
||||||
|
@ModifyVariable(method = "onPlayerMove", at = @At("STORE"), ordinal = 0)
|
||||||
|
private boolean flipLandingFlag(boolean value) {
|
||||||
|
if (Pony.of(this.player).getPhysics().isGravityNegative()) {
|
||||||
|
return !value;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.minelittlepony.unicopia.mixin.gravity;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.*;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.entity.Equine;
|
||||||
|
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
|
||||||
|
@Mixin(ServerPlayerEntity.class)
|
||||||
|
abstract class MixinServerPlayerEntity {
|
||||||
|
@ModifyVariable(
|
||||||
|
method = "handleFall(DDDZ)V",
|
||||||
|
at = @At("HEAD"),
|
||||||
|
ordinal = 1,
|
||||||
|
argsOnly = true)
|
||||||
|
private double modifyFallDistance(double value) {
|
||||||
|
if (this instanceof Equine.Container eq && eq.get().getPhysics().isGravityNegative()) {
|
||||||
|
return -value;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1383,6 +1383,7 @@
|
||||||
"commands.gravity.set": "Your gravity has been updated to %f",
|
"commands.gravity.set": "Your gravity has been updated to %f",
|
||||||
"commands.gravity.set.self": "Set own gravity to %f",
|
"commands.gravity.set.self": "Set own gravity to %f",
|
||||||
"commands.gravity.set.other": "Set %s's gravity to %f",
|
"commands.gravity.set.other": "Set %s's gravity to %f",
|
||||||
|
"commands.gravity.set.multiple": "Updated %s entities",
|
||||||
|
|
||||||
"unicopia.options.title": "Unicopia Options",
|
"unicopia.options.title": "Unicopia Options",
|
||||||
"unicopia.options.ignore_mine_lp": "Ignore Mine Little Pony",
|
"unicopia.options.ignore_mine_lp": "Ignore Mine Little Pony",
|
||||||
|
|
|
@ -59,6 +59,8 @@
|
||||||
"gravity.MixinMobEntity",
|
"gravity.MixinMobEntity",
|
||||||
"gravity.MixinWorld",
|
"gravity.MixinWorld",
|
||||||
"gravity.MixinServerWorld",
|
"gravity.MixinServerWorld",
|
||||||
|
"gravity.MixinServerPlayerEntity",
|
||||||
|
"gravity.MixinServerPlayNetworkHandler",
|
||||||
"gravity.MixinWorldChunk",
|
"gravity.MixinWorldChunk",
|
||||||
"trinkets.MixinTrinketSurvivalSlot",
|
"trinkets.MixinTrinketSurvivalSlot",
|
||||||
"trinkets.MixinTrinketItem",
|
"trinkets.MixinTrinketItem",
|
||||||
|
|
Loading…
Reference in a new issue