Fix mixins and rewrite dimension changing

This commit is contained in:
Sollace 2020-04-24 17:10:45 +02:00
parent 6678999dd0
commit 7a1b3aab98
16 changed files with 204 additions and 146 deletions

View file

@ -5,17 +5,14 @@ import java.util.Random;
import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.USounds;
import com.minelittlepony.unicopia.ability.FlightPredicate;
import com.minelittlepony.unicopia.ability.HeightPredicate;
import com.minelittlepony.unicopia.entity.FlightControl;
import com.minelittlepony.unicopia.entity.Updatable;
import com.minelittlepony.unicopia.magic.MagicEffect;
import com.minelittlepony.unicopia.mixin.MixinEntity;
import com.minelittlepony.unicopia.particles.MagicParticleEffect;
import com.minelittlepony.unicopia.util.NbtSerialisable;
import com.minelittlepony.unicopia.util.MutableVector;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityPose;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.sound.SoundCategory;
@ -25,9 +22,9 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
public class GravityDelegate implements Updatable, FlightControl, NbtSerialisable, FlightPredicate, HeightPredicate {
public class GravityDelegate implements Updatable, FlightControl, NbtSerialisable, FlightPredicate {
private final Pony player;
final Pony player;
private static final float MAXIMUM_FLIGHT_EXPERIENCE = 1500;
@ -42,10 +39,11 @@ public class GravityDelegate implements Updatable, FlightControl, NbtSerialisabl
private float gravity = 0;
private float eyeHeight;
private final PlayerDimensionsDelegate dimensions;
public GravityDelegate(Pony player) {
this.player = player;
this.dimensions = new PlayerDimensionsDelegate(this);
}
@Override
@ -64,53 +62,12 @@ public class GravityDelegate implements Updatable, FlightControl, NbtSerialisabl
return player.getSpecies().canFly();
}
protected boolean isRainboom(Pony player) {
protected boolean isRainboom() {
return Math.sqrt(getHorizontalMotion(player.getOwner())) > 0.4F;
}
public float getEyeHeight() {
return eyeHeight;
}
@Override
public float getTargetEyeHeight(Pony player) {
if (player.hasEffect()) {
MagicEffect effect = player.getEffect();
if (!effect.isDead() && effect instanceof HeightPredicate) {
float val = ((HeightPredicate)effect).getTargetEyeHeight(player);
if (val > 0) {
return val;
}
}
}
if (isFlying && isRainboom(player)) {
return 0.5F;
}
EntityPose pose = player.getOwner().getPose();
return player.getOwner().getActiveEyeHeight(pose, player.getOwner().getDimensions(pose));
}
@Override
public float getTargetBodyHeight(Pony player) {
if (player.hasEffect()) {
MagicEffect effect = player.getEffect();
if (!effect.isDead() && effect instanceof HeightPredicate) {
float val = ((HeightPredicate)effect).getTargetBodyHeight(player);
if (val > 0) {
return val;
}
}
}
// Player height is reset at this point, so we can use it as our baseline.
if (isFlying && isRainboom(player)) {
return player.getOwner().getHeight() / 2;
}
return player.getOwner().getHeight();
public PlayerDimensionsDelegate getDimensions() {
return dimensions;
}
public void setGraviationConstant(float constant) {
@ -170,26 +127,8 @@ public class GravityDelegate implements Updatable, FlightControl, NbtSerialisabl
}
}
float bodyHeight = getTargetBodyHeight(player);
eyeHeight = 0;
eyeHeight = getTargetEyeHeight(player);
if (gravity < 0) {
eyeHeight = bodyHeight - eyeHeight;
}
if (entity.age > 10) {
bodyHeight = player.getInterpolator().interpolate("standingHeight", bodyHeight, 10);
eyeHeight = player.getInterpolator().interpolate("eyeHeight", eyeHeight, 10);
}
((MixinEntity)entity).setSize(entity.getWidth(), bodyHeight);
if (gravity < 0) {
if (entity.isSneaking()) {
//entity.eyeHeight += 0.2F;
}
if (dimensions.update()) {
player.getOwner().calculateDimensions();
}
if (!entity.abilities.creativeMode && !entity.isFallFlying()) {
@ -228,7 +167,7 @@ public class GravityDelegate implements Updatable, FlightControl, NbtSerialisabl
player.addEnergy(2);
}
if (isRainbooming || (entity.isSneaking() && isRainboom(player))) {
if (isRainbooming || (entity.isSneaking() && isRainboom())) {
float forward = 0.5F * flightExperience / MAXIMUM_FLIGHT_EXPERIENCE;
velocity.x += - forward * MathHelper.sin(entity.yaw * 0.017453292F);

View file

@ -0,0 +1,96 @@
package com.minelittlepony.unicopia.entity.player;
import com.minelittlepony.unicopia.ability.HeightPredicate;
import com.minelittlepony.unicopia.magic.MagicEffect;
import net.minecraft.entity.EntityDimensions;
import net.minecraft.entity.EntityPose;
public final class PlayerDimensionsDelegate {
private float defaultEyeHeight;
private float defaultBodyHeight;
private float lastTargetEyeHeight;
private float lastTargetBodyHeight;
private final GravityDelegate gravity;
public PlayerDimensionsDelegate(GravityDelegate gravity) {
this.gravity = gravity;
}
public float getActiveEyeHeight(float original) {
defaultEyeHeight = original;
return calculateTargetEyeHeightWithGravity(calculateTargetBodyHeight());
}
public EntityDimensions getDimensions(EntityPose pos, EntityDimensions dimensions) {
defaultBodyHeight = dimensions.height;
return EntityDimensions.changing(dimensions.width, calculateTargetBodyHeight());
}
boolean update() {
float targetBodyHeight = calculateTargetBodyHeight();
float targetEyeHeight = calculateTargetEyeHeightWithGravity(targetBodyHeight);
if (targetEyeHeight != lastTargetEyeHeight || targetBodyHeight != lastTargetBodyHeight) {
lastTargetBodyHeight = targetBodyHeight;
lastTargetEyeHeight = targetEyeHeight;
return true;
}
return false;
}
private float calculateTargetEyeHeightWithGravity(float targetBodyHeight) {
float height = calculateTargetEyeHeight();
if (gravity.getGravitationConstant() < 0 && gravity.player.getOwner().isSneaking()) {
height += 0.2F;
}
if (gravity.getGravitationConstant() < 0) {
height = targetBodyHeight - height;
}
return height;
}
private float calculateTargetEyeHeight() {
if (gravity.player.hasEffect()) {
MagicEffect effect = gravity.player.getEffect();
if (!effect.isDead() && effect instanceof HeightPredicate) {
float val = ((HeightPredicate)effect).getTargetEyeHeight(gravity.player);
if (val > 0) {
return val;
}
}
}
if (gravity.isFlying && gravity.isRainboom()) {
return 0.5F;
}
return defaultEyeHeight;
}
private float calculateTargetBodyHeight() {
if (gravity.player.hasEffect()) {
MagicEffect effect = gravity.player.getEffect();
if (!effect.isDead() && effect instanceof HeightPredicate) {
float val = ((HeightPredicate)effect).getTargetBodyHeight(gravity.player);
if (val > 0) {
return val;
}
}
}
if (gravity.isFlying && gravity.isRainboom()) {
return defaultBodyHeight / 2;
}
return defaultBodyHeight;
}
}

View file

@ -8,7 +8,7 @@ import net.minecraft.advancement.criterion.Criterions;
@Mixin(Criterions.class)
public interface CriterionsRegistry {
@Invoker
@Invoker("register")
static <T extends Criterion<?>> T register(T object) {
throw new NullPointerException("mixin y u fail");
}

View file

@ -1,12 +0,0 @@
package com.minelittlepony.unicopia.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import net.minecraft.entity.Entity;
@Mixin(Entity.class)
public interface MixinEntity {
@Accessor("setSize")
void setSize(float width, float height);
}

View file

@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.minelittlepony.unicopia.ducks.Farmland;
@ -19,10 +20,11 @@ abstract class MixinFarmlandBlock extends Block {
method = "setToDirt(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;)V",
at = @At("HEAD"),
cancellable = true)
public static void setToDirt(BlockState state, World world, BlockPos pos) {
private static void setToDirt(BlockState state, World world, BlockPos pos, CallbackInfo info) {
if (state.getBlock() instanceof Farmland) {
BlockState dirtState = ((Farmland)state.getBlock()).getDirtState(state, world, pos);
world.setBlockState(pos, pushEntitiesUpBeforeBlockChange(state, dirtState, world, pos));
info.cancel();
}
}
}

View file

@ -1,6 +1,9 @@
package com.minelittlepony.unicopia.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.minelittlepony.unicopia.util.HoeUtil;
@ -13,19 +16,15 @@ import net.minecraft.util.ActionResult;
@Mixin(HoeItem.class)
abstract class MixinHoeItem extends ToolItem {
MixinHoeItem() {super(null, null);}
@Override
public ActionResult useOnBlock(ItemUsageContext context) {
@Inject(method = "useOnBlock(Lnet/minecraft/item/ItemUsageContext;)Lnet/minecraft/util/ActionResult;",
at = @At("HEAD"),
cancellable = true)
private void onUseOnBlock(ItemUsageContext context, CallbackInfoReturnable<ActionResult> info) {
BlockState state = context.getWorld().getBlockState(context.getBlockPos());
if (state.getBlock() instanceof HoeUtil.Tillable) {
if (!((HoeUtil.Tillable)state.getBlock()).canTill(context)) {
return ActionResult.PASS;
info.setReturnValue(ActionResult.PASS);
}
}
return null;
}
}

View file

@ -13,7 +13,7 @@ import net.minecraft.entity.Entity;
import net.minecraft.entity.ItemEntity;
@Mixin(ItemEntity.class)
public abstract class MixinItemEntity extends Entity implements IItemEntity {
abstract class MixinItemEntity extends Entity implements IItemEntity {
private final ItemEntityCapabilities caster = create();

View file

@ -14,7 +14,7 @@ import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
@Mixin(LivingEntity.class)
public abstract class MixinLivingEntity extends Entity implements PonyContainer<Ponylike> {
abstract class MixinLivingEntity extends Entity implements PonyContainer<Ponylike> {
private final Ponylike caster = create();
@ -30,15 +30,15 @@ public abstract class MixinLivingEntity extends Entity implements PonyContainer<
return caster;
}
@Inject(method = "canSee(Lnet/minecraft/entity/Entity)Z", at = @At("HEAD"))
@Inject(method = "canSee(Lnet/minecraft/entity/Entity;)Z", at = @At("HEAD"))
private void onCanSee(Entity other, CallbackInfoReturnable<Boolean> info) {
if (caster.isInvisible()) {
info.setReturnValue(false);
}
}
@Inject(method = "method_6040()V", at = @At("HEAD"))
protected void onFinishUsing(CallbackInfo info) {
@Inject(method = "tickActiveItemStack()V", at = @At("HEAD"))
private void onFinishUsing(CallbackInfo info) {
LivingEntity self = (LivingEntity)(Object)this;
if (!self.getActiveItem().isEmpty() && self.isUsingItem()) {
@ -63,7 +63,7 @@ public abstract class MixinLivingEntity extends Entity implements PonyContainer<
caster.onUpdate();
}
@Inject(method = "<clinit>()V", at = @At("RETURN"))
@Inject(method = "<clinit>()V", at = @At("RETURN"), remap = false)
private static void clinit(CallbackInfo info) {
LivingEntityCapabilities.boostrap();
}

View file

@ -3,7 +3,7 @@ package com.minelittlepony.unicopia.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
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.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@ -24,7 +24,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.GameMode;
@Mixin(PlayerEntity.class)
public abstract class MixinPlayerEntity extends LivingEntity implements PonyContainer<Pony> {
abstract class MixinPlayerEntity extends LivingEntity implements PonyContainer<Pony> {
private MixinPlayerEntity() { super(null, null); }
@Override
@ -32,9 +32,10 @@ public abstract class MixinPlayerEntity extends LivingEntity implements PonyCont
return new PlayerImpl((PlayerEntity)(Object)this);
}
@ModifyArg(method = "Lnet/minecraft/entity/LivingEntity;handleFallDamage(FF)V",
@ModifyVariable(method = "handleFallDamage(FF)Z",
at = @At("HEAD"),
index = 0)
ordinal = 0,
argsOnly = true)
private float onHandleFallDamage(float distance) {
return get().onImpact(distance);
}
@ -68,9 +69,13 @@ public abstract class MixinPlayerEntity extends LivingEntity implements PonyCont
at = @At("RETURN"),
cancellable = true)
private void onGetActiveEyeHeight(EntityPose pose, EntityDimensions dimensions, CallbackInfoReturnable<Float> info) {
float h = get().getGravity().getEyeHeight();
if (h != 0) {
info.setReturnValue(h);
}
info.setReturnValue(get().getGravity().getDimensions().getActiveEyeHeight(info.getReturnValue()));
}
@Inject(method = "getDimensions(Lnet/minecraft/entity/EntityPose;)Lnet/minecraft/entity/EntityDimensions;",
at = @At("RETURN"),
cancellable = true)
public void onGetDimensions(EntityPose pose, CallbackInfoReturnable<EntityDimensions> info) {
info.setReturnValue(get().getGravity().getDimensions().getDimensions(pose, info.getReturnValue()));
}
}

View file

@ -13,9 +13,8 @@ import net.minecraft.entity.projectile.ProjectileEntity;
import net.minecraft.util.hit.EntityHitResult;
@Mixin(ProjectileEntity.class)
public abstract class MixinProjectileEntity extends Entity implements Projectile {
public MixinProjectileEntity() { super(null, null); }
abstract class MixinProjectileEntity extends Entity implements Projectile {
private MixinProjectileEntity() { super(null, null); }
@Inject(method = "onEntityHit(Lnet/minecraft/util/hit/EntityHitResult;)V",
at = @At("HEAD"),

View file

@ -1,34 +1,59 @@
package com.minelittlepony.unicopia.mixin.client;
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.At.Shift;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.entity.player.PlayerCamera;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.Camera;
import net.minecraft.client.util.math.Vector3f;
import net.minecraft.entity.player.PlayerEntity;
@Mixin(Camera.class)
abstract class MixinCamera {
@Shadow
private float pitch;
@Shadow
private float yaw;
@Inject(method = "updateRotation()V", at = @At("HEAD"))
private void updateRotation() {
@ModifyVariable(method = "setRotation(FF)V",
at = @At("HEAD"),
ordinal = 0,
argsOnly = true)
private float modifyYaw(float yaw) {
PlayerEntity player = MinecraftClient.getInstance().player;
if (player != null) {
PlayerCamera view = Pony.of(player).getCamera();
if (player != null && MinecraftClient.getInstance().cameraEntity == player) {
return Pony.of(player).getCamera().calculateYaw(yaw);
}
//event.setRoll(view.calculateRoll());
pitch = view.calculatePitch(pitch);
yaw = view.calculateYaw(yaw);
return yaw;
}
@ModifyVariable(method = "setRotation(FF)V",
at = @At("HEAD"),
ordinal = 1,
argsOnly = true)
private float modifyPitch(float pitch) {
PlayerEntity player = MinecraftClient.getInstance().player;
if (player != null && MinecraftClient.getInstance().cameraEntity == player) {
return Pony.of(player).getCamera().calculatePitch(pitch);
}
return pitch;
}
@Inject(method = "setRotation(FF)V",
at = @At(value = "INVOKE",
target = "Lnet/minecraft/util/math/Quaternion;set(FFFF)V",
shift = Shift.AFTER)
)
private void onSetRotation(float yaw, float pitch, CallbackInfo info) {
PlayerEntity player = MinecraftClient.getInstance().player;
if (player != null && MinecraftClient.getInstance().cameraEntity == player) {
float roll = Pony.of(player).getCamera().calculateRoll();
((Camera)(Object)this).getRotation().hamiltonProduct(Vector3f.POSITIVE_Z.getDegreesQuaternion(roll));
}
}
}

View file

@ -15,7 +15,10 @@ import net.minecraft.entity.player.PlayerEntity;
@Mixin(EntityRenderDispatcher.class)
abstract class MixinEntityRenderDispatcher {
@Inject(method = "render(Lnet/minecraft/entity/Entity;DDDFFLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V", at = @At("HEAD"))
private static final String RENDER = "render(Lnet/minecraft/entity/Entity;DDDFFLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V";
@Inject(method = RENDER, at = @At("HEAD"))
private <E extends Entity> void beforeRender(E entity, double x, double y, double z, float yaw, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, CallbackInfo info) {
matrices.push();
@ -46,7 +49,7 @@ abstract class MixinEntityRenderDispatcher {
}
}
@Inject(method = "render(Lnet/minecraft/entity/Entity;DDDFFLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V", at = @At("HEAD"))
@Inject(method = RENDER, at = @At("HEAD"))
private <E extends Entity> void afterRender(E entity, double x, double y, double z, float yaw, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, CallbackInfo info) {
matrices.pop();

View file

@ -13,8 +13,8 @@ import net.minecraft.client.input.KeyboardInput;
@Mixin(KeyboardInput.class)
abstract class MixinKeyboardInput extends Input {
@Inject(method = "tick(ZZ)V", at = @At("RETURN"))
private void onTick(boolean one, boolean two, CallbackInfo info) {
@Inject(method = "tick(Z)V", at = @At("RETURN"))
private void onTick(boolean strafe, CallbackInfo info) {
Pony player = Pony.of(MinecraftClient.getInstance().player);
if (player.getGravity().getGravitationConstant() < 0) {

View file

@ -16,10 +16,11 @@ import net.minecraft.util.Hand;
import net.minecraft.util.hit.EntityHitResult;
@Mixin(MinecraftClient.class)
public class MixinMinecraftClient {
@Redirect(method = "doItemPick()V", at = @At(
value = "INVOKE",
target = "Lnet/minecraft/item/SpawnEggItem;forEntity(Lnet/minecraft/entity/EntityType;)Lnet/minecraft/item/SpawnEggItem;"))
abstract class MixinMinecraftClient {
@Redirect(method = "doItemPick()V",
at = @At(value = "INVOKE",
target = "Lnet/minecraft/item/SpawnEggItem;forEntity(Lnet/minecraft/entity/EntityType;)Lnet/minecraft/item/SpawnEggItem;")
)
private SpawnEggItem redirectSpawnEggForEntity(EntityType<?> type) {
MinecraftClient self = MinecraftClient.getInstance();

View file

@ -1,6 +1,5 @@
package com.minelittlepony.unicopia.mixin.client;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
@ -14,8 +13,6 @@ import net.minecraft.client.Mouse;
@Mixin(Mouse.class)
abstract class MixinMouse {
@Shadow
private @Final MinecraftClient client;
@Shadow
private double cursorDeltaX;
@Shadow
@ -23,7 +20,8 @@ abstract class MixinMouse {
@Inject(method = "updateMouse()V", at = @At("HEAD"))
private void onUpdateMouse(CallbackInfo info) {
if (Pony.of(client.player).getGravity().getGravitationConstant() < 0) {
Pony player = Pony.of(MinecraftClient.getInstance().player);
if (player != null&& player.getGravity().getGravitationConstant() < 0) {
cursorDeltaX = -cursorDeltaX;
cursorDeltaY = -cursorDeltaY;
}

View file

@ -4,20 +4,23 @@
"package": "com.minelittlepony.unicopia.mixin",
"refmap": "unicopia.client.mixin.refmap.json",
"compatibilityLevel": "JAVA_8",
"main": [
"MixinEntity",
"MixinFarmlandBlock",
"MixinHoeItem",
"MixinItemEntity",
"MixinPlayerEntity",
"MixinProjectileEntity",
"Walker"
"mixins": [
"CriterionsRegistry",
"MixinFarmlandBlock",
"MixinHoeItem",
"MixinItemEntity",
"MixinLivingEntity",
"MixinPlayerEntity",
"MixinProjectileEntity",
"Walker"
],
"client": [
"client.DefaultTexturesRegistry",
"client.MixinCamera",
"client.MixinEntityRenderDispatcher",
"client.MixinGameRenderer",
"client.MixinKeyboardInput",
"client.MixinMinecraftClient",
"client.MixinMouse"
],
"injectors": {