2024-07-11 13:43:54 -05:00
|
|
|
package one.oth3r.sit.mixin;
|
|
|
|
|
|
|
|
import net.minecraft.entity.*;
|
|
|
|
import net.minecraft.entity.decoration.DisplayEntity;
|
|
|
|
import net.minecraft.util.math.*;
|
|
|
|
import net.minecraft.world.World;
|
|
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
import org.spongepowered.asm.mixin.Mixin;
|
|
|
|
import org.spongepowered.asm.mixin.Unique;
|
|
|
|
|
|
|
|
@Mixin(DisplayEntity.TextDisplayEntity.class)
|
2024-09-30 13:32:35 -05:00
|
|
|
public abstract class TextDisplayDismountMixin extends DisplayEntity {
|
|
|
|
public TextDisplayDismountMixin(EntityType<?> entityType, World world) {
|
|
|
|
super(entityType, world);
|
2024-07-11 13:43:54 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Vec3d updatePassengerForDismount(LivingEntity passenger) {
|
2024-09-28 17:33:53 -05:00
|
|
|
// get the passenger's horizontal rotation, rotated counterclockwise, because the method rotates it clockwise for some reason
|
|
|
|
int[][] offset = Dismounting.getDismountOffsets(passenger.getHorizontalFacing().rotateYCounterclockwise());
|
2024-07-11 13:43:54 -05:00
|
|
|
// new array with another slot
|
|
|
|
int[][] dismountOffsets = new int[offset.length + 1][];
|
|
|
|
// add an empty offset to the start of the array
|
|
|
|
dismountOffsets[0] = new int[]{0, 0};
|
|
|
|
// copy the original elements into the new array starting from index 1
|
|
|
|
System.arraycopy(offset, 0, dismountOffsets, 1, offset.length);
|
|
|
|
|
|
|
|
BlockPos blockPos = this.getBlockPos();
|
|
|
|
|
|
|
|
for (EntityPose entityPose : passenger.getPoses()) {
|
|
|
|
Vec3d vec3d = getDismountPos(passenger, entityPose, dismountOffsets, blockPos);
|
|
|
|
|
|
|
|
// check around the block above
|
|
|
|
if (vec3d == null) vec3d = getDismountPos(passenger, entityPose, dismountOffsets, blockPos.up());
|
|
|
|
|
|
|
|
if (vec3d != null) return vec3d;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return super.updatePassengerForDismount(passenger);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* searches around the BlockPos for a stable dismount spot using the dismountOffsets
|
|
|
|
* @param passenger the passenger to check
|
|
|
|
* @param entityPose the pose of the passenger to check
|
|
|
|
* @param dismountOffsets the positions to check around the BlockPos
|
|
|
|
* @param blockPos the BlockPos to check around
|
|
|
|
* @return the Vec3d to dismount at, null if not found
|
|
|
|
*/
|
|
|
|
@Unique
|
|
|
|
private @Nullable Vec3d getDismountPos(LivingEntity passenger, EntityPose entityPose, int[][] dismountOffsets, BlockPos blockPos) {
|
|
|
|
// iterate through all dismount offsets
|
|
|
|
for (int[] offset : dismountOffsets) {
|
|
|
|
BlockPos.Mutable mutable = new BlockPos.Mutable();
|
|
|
|
mutable.set(blockPos.getX() + offset[0], blockPos.getY(), blockPos.getZ() + offset[1]);
|
|
|
|
|
|
|
|
double dismountHeight = this.getWorld().getDismountHeight(mutable);
|
|
|
|
if (Dismounting.canDismountInBlock(dismountHeight)) {
|
|
|
|
Vec3d vec3d = Vec3d.ofCenter(mutable, dismountHeight);
|
|
|
|
|
|
|
|
Box boundingBox = passenger.getBoundingBox(entityPose);
|
|
|
|
if (Dismounting.canPlaceEntityAt(this.getWorld(), passenger, boundingBox.offset(vec3d))) {
|
|
|
|
passenger.setPose(entityPose);
|
|
|
|
return vec3d;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|