diff --git a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/AntTeleportHelper.java b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/AntTeleportHelper.java index 61a55906..a8fcbf49 100644 --- a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/AntTeleportHelper.java +++ b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/AntTeleportHelper.java @@ -15,6 +15,7 @@ import net.minecraft.server.level.PlayerRespawnLogic; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundEvents; +import net.minecraft.util.Mth; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Mob; @@ -262,8 +263,11 @@ public final class AntTeleportHelper { return safeArrivalPos; } - BlockPos fallbackPos = preferredPos; - return Vec3.atBottomCenterOf(fallbackPos); + if (destination.hasChunkAt(preferredPos)) { + return Vec3.atBottomCenterOf(preferredPos); + } + + return Vec3.atBottomCenterOf(getClampedFallbackPosition(destination, preferredPos)); } @Nullable @@ -292,8 +296,10 @@ public final class AntTeleportHelper { } BlockPos searchPos = preferredPos.offset(xOffset, 0, zOffset); - addArrivalCandidate(candidates, destination.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, searchPos)); - addArrivalCandidate(candidates, destination.getHeightmapPos(Heightmap.Types.WORLD_SURFACE, searchPos)); + if (destination.hasChunkAt(searchPos)) { + addArrivalCandidate(candidates, destination.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, searchPos)); + addArrivalCandidate(candidates, destination.getHeightmapPos(Heightmap.Types.WORLD_SURFACE, searchPos)); + } } } } @@ -356,13 +362,22 @@ public final class AntTeleportHelper { @Nullable private static Vec3 tryFindSafeDismount(ServerPlayer player, ServerLevel destination, BlockPos candidate) { + if (!isSafeDismountAreaLoaded(destination, candidate)) { + return null; + } + Vec3 safePos = DismountHelper.findSafeDismountLocation(player.getType(), destination, candidate, true); if (safePos != null && isValidArrivalPosition(destination, safePos)) { return safePos; } for (Direction direction : Direction.Plane.HORIZONTAL) { - safePos = DismountHelper.findSafeDismountLocation(player.getType(), destination, candidate.relative(direction), true); + BlockPos offsetCandidate = candidate.relative(direction); + if (!isSafeDismountAreaLoaded(destination, offsetCandidate)) { + continue; + } + + safePos = DismountHelper.findSafeDismountLocation(player.getType(), destination, offsetCandidate, true); if (safePos != null && isValidArrivalPosition(destination, safePos)) { return safePos; } @@ -377,6 +392,31 @@ public final class AntTeleportHelper { } BlockPos standPos = BlockPos.containing(safePos); + if (!destination.hasChunkAt(standPos) || !destination.hasChunkAt(standPos.below())) { + return false; + } + return !destination.getBlockState(standPos.below()).is(Blocks.BEDROCK); } + + private static boolean isSafeDismountAreaLoaded(ServerLevel destination, BlockPos center) { + if (!destination.hasChunkAt(center) || !destination.hasChunkAt(center.above()) || !destination.hasChunkAt(center.below())) { + return false; + } + + for (Direction direction : Direction.Plane.HORIZONTAL) { + BlockPos offset = center.relative(direction); + if (!destination.hasChunkAt(offset) || !destination.hasChunkAt(offset.above()) || !destination.hasChunkAt(offset.below())) { + return false; + } + } + + return true; + } + + private static BlockPos getClampedFallbackPosition(ServerLevel destination, BlockPos preferredPos) { + int minY = destination.getMinBuildHeight() + 1; + int maxY = destination.getMaxBuildHeight() - 1; + return new BlockPos(preferredPos.getX(), Mth.clamp(preferredPos.getY(), minY, maxY), preferredPos.getZ()); + } } diff --git a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalTeleporter.java b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalTeleporter.java index 8fdf23e2..2b943769 100644 --- a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalTeleporter.java +++ b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalTeleporter.java @@ -127,8 +127,10 @@ public final class PermanentPortalTeleporter { } BlockPos horizontalPos = preferredPos.offset(xOff, 0, zOff); - addCandidate(candidates, destination.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, horizontalPos)); - addCandidate(candidates, destination.getHeightmapPos(Heightmap.Types.WORLD_SURFACE, horizontalPos)); + if (destination.hasChunkAt(horizontalPos)) { + addCandidate(candidates, destination.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, horizontalPos)); + addCandidate(candidates, destination.getHeightmapPos(Heightmap.Types.WORLD_SURFACE, horizontalPos)); + } for (int yOff = 0; yOff <= VERTICAL_SEARCH; yOff++) { addCandidate(candidates, horizontalPos.above(yOff)); if (yOff > 0) { @@ -186,13 +188,22 @@ public final class PermanentPortalTeleporter { @Nullable private static Vec3 tryFindSafePosition(Entity entity, ServerLevel destination, BlockPos candidate) { + if (!isSafeDismountAreaLoaded(destination, candidate)) { + return null; + } + Vec3 safe = DismountHelper.findSafeDismountLocation(entity.getType(), destination, candidate, true); if (safe != null && isValidArrivalPosition(destination, safe)) { return safe; } for (Direction direction : Direction.Plane.HORIZONTAL) { - safe = DismountHelper.findSafeDismountLocation(entity.getType(), destination, candidate.relative(direction), true); + BlockPos offsetCandidate = candidate.relative(direction); + if (!isSafeDismountAreaLoaded(destination, offsetCandidate)) { + continue; + } + + safe = DismountHelper.findSafeDismountLocation(entity.getType(), destination, offsetCandidate, true); if (safe != null && isValidArrivalPosition(destination, safe)) { return safe; } @@ -283,11 +294,30 @@ public final class PermanentPortalTeleporter { BlockPos standPos = BlockPos.containing(safePos); if (destination.dimension() == AntarchySettings.termiteDestinationDimension() || destination.dimension() == AntarchySettings.redAntDestinationDimension()) { + if (!destination.hasChunkAt(standPos) || !destination.hasChunkAt(standPos.below())) { + return false; + } + return !destination.getBlockState(standPos.below()).is(net.minecraft.world.level.block.Blocks.BEDROCK); } return true; } + private static boolean isSafeDismountAreaLoaded(ServerLevel destination, BlockPos center) { + if (!destination.hasChunkAt(center) || !destination.hasChunkAt(center.above()) || !destination.hasChunkAt(center.below())) { + return false; + } + + for (Direction direction : Direction.Plane.HORIZONTAL) { + BlockPos offset = center.relative(direction); + if (!destination.hasChunkAt(offset) || !destination.hasChunkAt(offset.above()) || !destination.hasChunkAt(offset.below())) { + return false; + } + } + + return true; + } + @Nullable private static Entity moveEntity(Entity entity, Transition transition) { ServerLevel destination = transition.newLevel(); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/AlphaMantisEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/AlphaMantisEntity.java index 58bca487..ebbdc864 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/AlphaMantisEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/AlphaMantisEntity.java @@ -4,6 +4,9 @@ import com.craisinlord.antarchy.config.AntarchySettings; import com.craisinlord.antarchy.content.AntarchyObjects; import com.craisinlord.antarchy.content.AntarchyTags; import com.craisinlord.antarchy.content.boss.BossCombatUtil; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; @@ -110,9 +113,14 @@ public class AlphaMantisEntity extends MantisEntity { } boolean atSurface = level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, pos).getY() <= pos.getY(); - boolean posOpen = level.isEmptyBlock(pos) && level.isEmptyBlock(pos.above()) && level.getFluidState(pos).isEmpty(); - boolean onSolidGround = level.getBlockState(pos.below()).isFaceSturdy(level, pos.below(), Direction.UP) + boolean hasFloorClearance = level.isEmptyBlock(pos.above()); + boolean hasCeilingClearance = level.isEmptyBlock(pos.below()); + boolean floorSupport = level.getBlockState(pos.below()).isFaceSturdy(level, pos.below(), Direction.UP) && !(level.getBlockState(pos.below()).getBlock() instanceof LeavesBlock); + boolean ceilingSupport = level.getBlockState(pos.above()).isFaceSturdy(level, pos.above(), Direction.DOWN) + && !(level.getBlockState(pos.above()).getBlock() instanceof LeavesBlock); + boolean posOpen = level.isEmptyBlock(pos) && (hasFloorClearance || hasCeilingClearance) && level.getFluidState(pos).isEmpty(); + boolean onSolidGround = floorSupport || ceilingSupport; if (!posOpen || !onSolidGround || !atSurface) { return false; @@ -344,7 +352,8 @@ public class AlphaMantisEntity extends MantisEntity { this.finishCommittedAttack(); this.stopFlightBurst(); this.getNavigation().stop(); - this.setDeltaMovement(0.0D, this.getDeltaMovement().y, 0.0D); + Vec3 localVelocity = this.toLocal(this.getDeltaMovement()); + this.setDeltaMovement(this.toWorld(0.0D, localVelocity.y, 0.0D)); this.setAggressive(false); this.summonCooldownTicks = Math.min(this.summonCooldownTicks, AntarchySettings.alphaMantisSummonIntervalTicks() / 2); } @@ -355,7 +364,8 @@ public class AlphaMantisEntity extends MantisEntity { } this.phaseTransitionTicks--; this.getNavigation().stop(); - this.setDeltaMovement(0.0D, this.getDeltaMovement().y, 0.0D); + Vec3 localVelocity = this.toLocal(this.getDeltaMovement()); + this.setDeltaMovement(this.toWorld(0.0D, localVelocity.y, 0.0D)); if (this.phaseTransitionTicks <= 0 && this.getTarget() != null) { this.setAggressive(true); } @@ -466,4 +476,16 @@ public class AlphaMantisEntity extends MantisEntity { this.setDeltaMovement(Vec3.ZERO); } } + + private AntarchyGravityDirection gravityDirection() { + return AntarchyGravityApi.getGravityDirection(this); + } + + private Vec3 toLocal(Vec3 worldVector) { + return AntarchyGravityRotationUtil.vecWorldToPlayer(worldVector, this.gravityDirection()); + } + + private Vec3 toWorld(double x, double y, double z) { + return AntarchyGravityRotationUtil.vecPlayerToWorld(x, y, z, this.gravityDirection()); + } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/AppleCowEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/AppleCowEntity.java index 0b08252f..78b7fde3 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/AppleCowEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/AppleCowEntity.java @@ -1,5 +1,8 @@ package com.craisinlord.antarchy.content.entity; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; @@ -294,7 +297,7 @@ public abstract class AppleCowEntity extends Cow implements GeoEntity, Shearable } private boolean isMovingForAnimation() { - return this.getDeltaMovement().horizontalDistanceSqr() > 1.0E-4D || this.getNavigation().isInProgress(); + return this.toLocal(this.getDeltaMovement()).horizontalDistanceSqr() > 1.0E-4D || this.getNavigation().isInProgress(); } private void startSleeping(int sleepTicks) { @@ -322,13 +325,25 @@ public abstract class AppleCowEntity extends Cow implements GeoEntity, Shearable } private void applySleepStillness() { - Vec3 motion = this.getDeltaMovement(); + Vec3 motion = this.toLocal(this.getDeltaMovement()); this.getNavigation().stop(); this.setJumping(false); this.setSprinting(false); this.zza = 0.0F; this.xxa = 0.0F; - this.setDeltaMovement(0.0D, motion.y < 0.0D ? motion.y : 0.0D, 0.0D); + this.setDeltaMovement(this.toWorld(0.0D, motion.y < 0.0D ? motion.y : 0.0D, 0.0D)); + } + + private AntarchyGravityDirection gravityDirection() { + return AntarchyGravityApi.getGravityDirection(this); + } + + private Vec3 toLocal(Vec3 worldVector) { + return AntarchyGravityRotationUtil.vecWorldToPlayer(worldVector, this.gravityDirection()); + } + + private Vec3 toWorld(double x, double y, double z) { + return AntarchyGravityRotationUtil.vecPlayerToWorld(x, y, z, this.gravityDirection()); } private int randomNapCooldown() { diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/BedBugEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/BedBugEntity.java index b2c0c3d8..192216ad 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/BedBugEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/BedBugEntity.java @@ -5,6 +5,9 @@ import com.craisinlord.antarchy.content.AntarchySoundEvents; import com.craisinlord.antarchy.content.AntarchyObjects; import com.craisinlord.antarchy.content.block.BedBugEggBlock; import com.craisinlord.antarchy.content.damage.AntarchyDamageSources; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.server.level.ServerLevel; @@ -383,13 +386,16 @@ public class BedBugEntity extends Animal implements GeoEntity { } private void commitLunge(LivingEntity target, double horizontalSpeed, double verticalSpeed) { - Vec3 lunge = target.position().subtract(this.position()); - Vec3 horizontal = new Vec3(lunge.x, 0.0D, lunge.z); + AntarchyGravityDirection direction = AntarchyGravityApi.getGravityDirection(this); + Vec3 localLunge = AntarchyGravityRotationUtil.vecWorldToPlayer(target.position().subtract(this.position()), direction); + Vec3 horizontal = new Vec3(localLunge.x, 0.0D, localLunge.z); if (horizontal.lengthSqr() < 1.0E-4D) { return; } horizontal = horizontal.normalize().scale(horizontalSpeed); - this.setDeltaMovement(this.getDeltaMovement().add(horizontal.x, verticalSpeed, horizontal.z)); + Vec3 localImpulse = new Vec3(horizontal.x, verticalSpeed, horizontal.z); + Vec3 worldImpulse = AntarchyGravityRotationUtil.vecPlayerToWorld(localImpulse, direction); + this.setDeltaMovement(this.getDeltaMovement().add(worldImpulse.x, worldImpulse.y, worldImpulse.z)); this.hasImpulse = true; } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/BomberEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/BomberEntity.java index aeae40e7..75f601ee 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/BomberEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/BomberEntity.java @@ -2,6 +2,9 @@ package com.craisinlord.antarchy.content.entity; import com.craisinlord.antarchy.config.AntarchySettings; import com.craisinlord.antarchy.content.AntarchySoundEvents; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil; import java.util.Objects; import net.minecraft.core.BlockPos; import net.minecraft.core.particles.ParticleTypes; @@ -99,7 +102,7 @@ public class BomberEntity extends Monster implements GeoEntity { return level.getDifficulty() != Difficulty.PEACEFUL && level.isEmptyBlock(pos) - && level.isEmptyBlock(pos.above()) + && (level.isEmptyBlock(pos.above()) || level.isEmptyBlock(pos.below())) && Monster.checkMonsterSpawnRules(entityType, level, spawnReason, pos, random); } @@ -282,9 +285,10 @@ public class BomberEntity extends Monster implements GeoEntity { return; } - double x = this.getX(); - double y = this.getY(0.0625D); - double z = this.getZ(); + Vec3 explosionCenter = this.position().add(this.toWorld(0.0D, this.getBbHeight() * 0.0625D, 0.0D)); + double x = explosionCenter.x; + double y = explosionCenter.y; + double z = explosionCenter.z; float radius = (float) (AntarchySettings.bomberExplosionRadius() * EXPLOSION_RADIUS_MULTIPLIER); serverLevel.playSound(null, x, y, z, SoundEvents.GENERIC_EXPLODE.value(), SoundSource.HOSTILE, 0.55F, 1.0F); serverLevel.explode( @@ -306,7 +310,7 @@ public class BomberEntity extends Monster implements GeoEntity { if (extraDamage > 0.0D) { AABB damageBox = this.getBoundingBox().inflate(radius * 2.0D); for (LivingEntity livingEntity : serverLevel.getEntitiesOfClass(LivingEntity.class, damageBox, entity -> entity.isAlive() && entity != this)) { - double distance = Math.sqrt(this.distanceToSqr(livingEntity)); + double distance = explosionCenter.distanceTo(livingEntity.position()); double falloff = radius <= 0.0F ? 0.0D : Math.max(0.0D, 1.0D - distance / radius); if (falloff <= 0.0D) { continue; @@ -332,19 +336,37 @@ public class BomberEntity extends Monster implements GeoEntity { return; } - double dx = this.getX() - sourceEntity.getX(); - double dz = this.getZ() - sourceEntity.getZ(); - double distance = Math.sqrt(dx * dx + dz * dz); + Vec3 localAway = this.toLocalPlane(this.position().subtract(sourceEntity.position())); + double distance = localAway.length(); if (distance < 1.0E-4D) { return; } double strength = 0.4D * KNOCKBACK_MULTIPLIER; - this.push(dx / distance * strength, 0.08D, dz / distance * strength); + Vec3 localImpulse = localAway.scale(strength / distance); + Vec3 worldImpulse = this.toWorld(localImpulse.x, 0.08D, localImpulse.z); + this.push(worldImpulse.x, worldImpulse.y, worldImpulse.z); } private boolean isMovingForAnimation() { - return this.getDeltaMovement().horizontalDistanceSqr() > 1.0E-4D || this.getNavigation().isInProgress(); + return this.toLocal(this.getDeltaMovement()).horizontalDistanceSqr() > 1.0E-4D || this.getNavigation().isInProgress(); + } + + private AntarchyGravityDirection gravityDirection() { + return AntarchyGravityApi.getGravityDirection(this); + } + + private Vec3 toLocal(Vec3 worldVector) { + return AntarchyGravityRotationUtil.vecWorldToPlayer(worldVector, this.gravityDirection()); + } + + private Vec3 toWorld(double x, double y, double z) { + return AntarchyGravityRotationUtil.vecPlayerToWorld(x, y, z, this.gravityDirection()); + } + + private Vec3 toLocalPlane(Vec3 worldVector) { + Vec3 local = this.toLocal(worldVector); + return new Vec3(local.x, 0.0D, local.z); } private final class BomberAttackGoal extends MeleeAttackGoal { diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ButterflyEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ButterflyEntity.java index 02ba6c82..e2217ce3 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ButterflyEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ButterflyEntity.java @@ -5,6 +5,8 @@ import com.craisinlord.antarchy.config.AntarchySettings; import com.craisinlord.antarchy.content.AntarchyObjects; import com.craisinlord.antarchy.content.AntarchyTags; import com.craisinlord.antarchy.content.AntarchySoundEvents; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil; import java.util.EnumSet; import java.util.Optional; import java.util.function.Predicate; @@ -182,7 +184,8 @@ public class ButterflyEntity extends Animal implements FlyingAnimal, GeoEntity { FlyingPathNavigation navigation = new FlyingPathNavigation(this, level) { @Override public boolean isStableDestination(BlockPos pos) { - return !this.level.getBlockState(pos.below()).isAir(); + BlockPos support = AntarchyGravityApi.isGravityInverted(ButterflyEntity.this) ? pos.above() : pos.below(); + return !this.level.getBlockState(support).isAir(); } @Override @@ -429,7 +432,7 @@ public class ButterflyEntity extends Animal implements FlyingAnimal, GeoEntity { @Override protected void jumpInLiquid(net.minecraft.tags.TagKey fluidTag) { - this.setDeltaMovement(this.getDeltaMovement().add(0.0D, 0.01D, 0.0D)); + this.setDeltaMovement(this.getDeltaMovement().add(AntarchyGravityRotationUtil.vecPlayerToWorld(0.0D, 0.01D, 0.0D, AntarchyGravityApi.getGravityDirection(this)))); } @Override diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/CreepingHorrorEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/CreepingHorrorEntity.java index 5a278639..783ad791 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/CreepingHorrorEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/CreepingHorrorEntity.java @@ -2,6 +2,9 @@ package com.craisinlord.antarchy.content.entity; import com.craisinlord.antarchy.config.AntarchySettings; import com.craisinlord.antarchy.content.AntarchySoundEvents; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.util.RandomSource; @@ -85,16 +88,22 @@ public class CreepingHorrorEntity extends Monster implements GeoEntity { return true; } BlockPos belowPos = pos.below(); + BlockPos abovePos = pos.above(); BlockState belowState = level.getBlockState(belowPos); - boolean validSupport = !belowState.is(Blocks.BEDROCK) + BlockState aboveState = level.getBlockState(abovePos); + boolean floorSupport = !belowState.is(Blocks.BEDROCK) && belowState.blocksMotion() && belowState.isFaceSturdy(level, belowPos, Direction.UP) && belowState.isCollisionShapeFullBlock(level, belowPos); + boolean ceilingSupport = !aboveState.is(Blocks.BEDROCK) + && aboveState.blocksMotion() + && aboveState.isFaceSturdy(level, abovePos, Direction.DOWN) + && aboveState.isCollisionShapeFullBlock(level, abovePos); return level.getDifficulty() != Difficulty.PEACEFUL - && validSupport + && (floorSupport || ceilingSupport) && level.isEmptyBlock(pos) - && level.isEmptyBlock(pos.above()) + && (level.isEmptyBlock(pos.above()) || level.isEmptyBlock(pos.below())) && Monster.checkMonsterSpawnRules(entityType, level, spawnReason, pos, random); } @@ -202,23 +211,35 @@ public class CreepingHorrorEntity extends Monster implements GeoEntity { if (climbing && this.getTarget() != null) { LivingEntity target = this.getTarget(); - Vec3 toTarget = target.position().subtract(this.position()); + Vec3 toTarget = this.toLocal(target.position().subtract(this.position())); double hDist = Math.sqrt(toTarget.x * toTarget.x + toTarget.z * toTarget.z); double speed = this.getAttributeValue(Attributes.MOVEMENT_SPEED) * 2.8D; if (hDist > 0.01D) { - this.setDeltaMovement( + this.setDeltaMovement(this.toWorld( (toTarget.x / hDist) * speed, 0.22D, (toTarget.z / hDist) * speed - ); + )); } else { - Vec3 mov = this.getDeltaMovement(); - this.setDeltaMovement(mov.x, 0.22D, mov.z); + Vec3 mov = this.toLocal(this.getDeltaMovement()); + this.setDeltaMovement(this.toWorld(mov.x, 0.22D, mov.z)); } this.getNavigation().stop(); } } + private AntarchyGravityDirection gravityDirection() { + return AntarchyGravityApi.getGravityDirection(this); + } + + private Vec3 toLocal(Vec3 worldVector) { + return AntarchyGravityRotationUtil.vecWorldToPlayer(worldVector, this.gravityDirection()); + } + + private Vec3 toWorld(double x, double y, double z) { + return AntarchyGravityRotationUtil.vecPlayerToWorld(x, y, z, this.gravityDirection()); + } + @Override public boolean isInWall() { return false; diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/DorrieEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/DorrieEntity.java index 44b9613d..fc49ecb3 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/DorrieEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/DorrieEntity.java @@ -1,6 +1,9 @@ package com.craisinlord.antarchy.content.entity; import com.craisinlord.antarchy.config.AntarchySettings; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil; import java.util.EnumSet; import java.util.List; import net.minecraft.core.BlockPos; @@ -416,14 +419,15 @@ public class DorrieEntity extends Animal implements GeoEntity { if (!this.isInWater() && !this.isInLava() && !this.onGround()) { Vec3 mov = this.getDeltaMovement(); - this.setDeltaMovement(mov.x * 0.91D, mov.y - 0.08D, mov.z * 0.91D); + Vec3 localMotion = this.toLocal(mov); + this.setDeltaMovement(this.toWorld(localMotion.x * 0.91D, localMotion.y - 0.08D, localMotion.z * 0.91D)); this.move(net.minecraft.world.entity.MoverType.SELF, this.getDeltaMovement()); return; } if (this.isInWater() || this.isInLava()) { this.moveRelative(this.getSpeed(), new Vec3(riddenInput.x, 0.0D, riddenInput.z)); - Vec3 motion = this.getDeltaMovement(); + Vec3 localMotion = this.toLocal(this.getDeltaMovement()); double vertical = 0.0D; if (this.isUnderWater()) { vertical = riddenInput.y * 0.025D; @@ -433,11 +437,11 @@ public class DorrieEntity extends Animal implements GeoEntity { if (this.pressingJump) { vertical += ASCEND_SPEED; } - this.setDeltaMovement( - motion.x * 0.92D, - motion.y * 0.90D + vertical, - motion.z * 0.92D - ); + this.setDeltaMovement(this.toWorld( + localMotion.x * 0.92D, + localMotion.y * 0.90D + vertical, + localMotion.z * 0.92D + )); this.move(net.minecraft.world.entity.MoverType.SELF, this.getDeltaMovement()); return; } @@ -450,15 +454,15 @@ public class DorrieEntity extends Animal implements GeoEntity { float power = this.getJumpCharge() / 100f; if (power > 0.05f) { Vec3 look = this.getLookAngle(); - Vec3 flatLook = new Vec3(look.x, 0.0D, look.z).normalize(); - Vec3 current = this.getDeltaMovement(); + Vec3 flatLook = this.toLocalPlane(look).normalize(); + Vec3 current = this.toLocal(this.getDeltaMovement()); double forwardAdd = 0.15D + power * 0.45D; double vertical = 0.55D + power * 0.80D; - this.setDeltaMovement( + this.setDeltaMovement(this.toWorld( current.x + flatLook.x * forwardAdd, vertical, current.z + flatLook.z * forwardAdd - ); + )); } } @@ -467,15 +471,15 @@ public class DorrieEntity extends Animal implements GeoEntity { float power = chargeTicks / (float) MAX_CHARGE_TICKS; if (power > 0.05F) { Vec3 look = this.getLookAngle(); - Vec3 flatLook = new Vec3(look.x, 0.0D, look.z).normalize(); - Vec3 current = this.getDeltaMovement(); + Vec3 flatLook = this.toLocalPlane(look).normalize(); + Vec3 current = this.toLocal(this.getDeltaMovement()); double forwardAdd = 0.15D + power * 0.45D; double vertical = 0.55D + power * 0.80D; - this.setDeltaMovement( + this.setDeltaMovement(this.toWorld( current.x + flatLook.x * forwardAdd, vertical, current.z + flatLook.z * forwardAdd - ); + )); this.hasImpulse = true; isLeaping = true; this.triggerAnim("main_controller", "jump_start"); @@ -489,11 +493,13 @@ public class DorrieEntity extends Animal implements GeoEntity { @Override protected void positionRider(Entity passenger, MoveFunction moveFunction) { if (this.hasPassenger(passenger)) { - Vec3 forward = this.getLookAngle().multiply(1.0D, 0.0D, 1.0D); + Vec3 localForward = this.toLocalPlane(this.getLookAngle()).normalize(); + Vec3 worldForward = this.toWorld(localForward); + Vec3 seatOffset = this.toWorld(0.0D, 0.5D, 0.0D).subtract(worldForward.scale(0.65D)); moveFunction.accept(passenger, - this.getX() - forward.x * 0.65D, - this.getY() + 0.5D, - this.getZ() - forward.z * 0.65D); + this.getX() + seatOffset.x, + this.getY() + seatOffset.y, + this.getZ() + seatOffset.z); } } @@ -706,10 +712,11 @@ public class DorrieEntity extends Animal implements GeoEntity { int bottom = Math.max(minY, this.level().getMinBuildHeight() + 1); for (int y = top; y >= bottom; y--) { BlockPos pos = BlockPos.containing(x, y, z); - if (!this.isWaterAt(pos) || this.isWaterAt(pos.above())) { + BlockPos localUp = this.relativeLocal(pos, 0, 1, 0); + if (!this.isWaterAt(pos) || this.isWaterAt(localUp)) { continue; } - return new Vec3(x + 0.5D, y + 0.85D, z + 0.5D); + return Vec3.atCenterOf(pos).add(this.toWorld(0.0D, 0.35D, 0.0D)); } return null; } @@ -737,10 +744,11 @@ public class DorrieEntity extends Animal implements GeoEntity { int bottom = Math.max(minY, this.level().getMinBuildHeight() + 1); for (int y = top; y >= bottom; y--) { BlockPos pos = BlockPos.containing(x, y, z); - if (!this.isWaterAt(pos) || !this.isWaterAt(pos.below())) { + BlockPos localDown = this.relativeLocal(pos, 0, -1, 0); + if (!this.isWaterAt(pos) || !this.isWaterAt(localDown)) { continue; } - return new Vec3(x + 0.5D, y + 0.3D, z + 0.5D); + return Vec3.atCenterOf(pos).add(this.toWorld(0.0D, -0.2D, 0.0D)); } return null; } @@ -756,10 +764,36 @@ public class DorrieEntity extends Animal implements GeoEntity { if (this.getControllingPassenger() instanceof Player player) { return Math.abs(player.zza) > 0.05F || Math.abs(player.xxa) > 0.05F; } - return this.getDeltaMovement().horizontalDistanceSqr() > MOVING_ANIM_THRESHOLD_SQ + return this.toLocal(this.getDeltaMovement()).horizontalDistanceSqr() > MOVING_ANIM_THRESHOLD_SQ || this.getNavigation().isInProgress(); } + private AntarchyGravityDirection gravityDirection() { + return AntarchyGravityApi.getGravityDirection(this); + } + + private Vec3 toLocal(Vec3 worldVector) { + return AntarchyGravityRotationUtil.vecWorldToPlayer(worldVector, this.gravityDirection()); + } + + private Vec3 toWorld(Vec3 localVector) { + return AntarchyGravityRotationUtil.vecPlayerToWorld(localVector, this.gravityDirection()); + } + + private Vec3 toWorld(double x, double y, double z) { + return AntarchyGravityRotationUtil.vecPlayerToWorld(x, y, z, this.gravityDirection()); + } + + private Vec3 toLocalPlane(Vec3 worldVector) { + Vec3 local = this.toLocal(worldVector); + return new Vec3(local.x, 0.0D, local.z); + } + + private BlockPos relativeLocal(BlockPos pos, int x, int y, int z) { + Vec3 worldOffset = this.toWorld(x, y, z); + return pos.offset(Mth.floor(worldOffset.x), Mth.floor(worldOffset.y), Mth.floor(worldOffset.z)); + } + private class DolphinSwimGoal extends Goal { private static final int COOLDOWN_MIN_TICKS = 120; private static final int COOLDOWN_MAX_TICKS = 180; diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/EmperorScorpionEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/EmperorScorpionEntity.java index 5ef3c5f1..22a499e4 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/EmperorScorpionEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/EmperorScorpionEntity.java @@ -6,8 +6,11 @@ import com.craisinlord.antarchy.content.AntarchySoundEvents; import com.craisinlord.antarchy.content.AntarchyObjects; import com.craisinlord.antarchy.content.boss.BossCombatUtil; import com.craisinlord.antarchy.content.damage.AntarchyDamageSources; -import com.craisinlord.antarchy.content.entity.ScorpionEntity; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.core.registries.Registries; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.syncher.EntityDataAccessor; @@ -401,8 +404,9 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity { } } case ACTIVE -> { - Vec3 motion = this.getDeltaMovement(); - this.setDeltaMovement(0.0D, motion.y, 0.0D); + AntarchyGravityDirection direction = AntarchyGravityApi.getGravityDirection(this); + Vec3 motion = AntarchyGravityRotationUtil.vecWorldToPlayer(this.getDeltaMovement(), direction); + this.setDeltaMovement(AntarchyGravityRotationUtil.vecPlayerToWorld(0.0D, motion.y, 0.0D, direction)); if (--this.hardenDurationTicks <= 0) { this.beginHardeningEnd(); return; @@ -413,8 +417,9 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity { } } case END -> { - Vec3 motion = this.getDeltaMovement(); - this.setDeltaMovement(0.0D, motion.y, 0.0D); + AntarchyGravityDirection direction = AntarchyGravityApi.getGravityDirection(this); + Vec3 motion = AntarchyGravityRotationUtil.vecWorldToPlayer(this.getDeltaMovement(), direction); + this.setDeltaMovement(AntarchyGravityRotationUtil.vecPlayerToWorld(0.0D, motion.y, 0.0D, direction)); if (--this.hardenStateTicks <= 0) { this.setHardenPhase(HardenPhase.NONE); this.hardenCooldownTicks = Math.max(1, AntarchySettings.emperorScorpionHardenCooldownTicks()); @@ -475,10 +480,13 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity { } Vec3 anchor = this.getTarget() != null ? this.getTarget().position() : this.position(); - Vec3 ring = Vec3.directionFromRotation(0.0F, this.random.nextFloat() * 360.0F) + AntarchyGravityDirection direction = AntarchyGravityApi.getGravityDirection(this); + Vec3 localRing = Vec3.directionFromRotation(0.0F, this.random.nextFloat() * 360.0F) .scale(2.75D + this.random.nextDouble() * 1.75D); - BlockPos spawnPos = BlockPos.containing(anchor.x + ring.x, this.getY(), anchor.z + ring.z); - scorpion.moveTo(spawnPos.getX() + 0.5D, spawnPos.getY(), spawnPos.getZ() + 0.5D, this.random.nextFloat() * 360.0F, 0.0F); + Vec3 worldRing = AntarchyGravityRotationUtil.vecPlayerToWorld(localRing, direction); + BlockPos spawnPos = this.findSummonSpawnPos(anchor.add(worldRing)); + Vec3 spawnCenter = Vec3.atCenterOf(spawnPos); + scorpion.moveTo(spawnCenter.x, spawnCenter.y, spawnCenter.z, this.random.nextFloat() * 360.0F, 0.0F); scorpion.finalizeSpawn(serverLevel, serverLevel.getCurrentDifficultyAt(spawnPos), MobSpawnType.MOB_SUMMONED, null); scorpion.setPersistenceRequired(); scorpion.setSummonOwner(this.getUUID()); @@ -490,16 +498,36 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity { } private void commitLunge(LivingEntity target, double horizontalSpeed, double verticalSpeed) { - Vec3 lunge = target.position().subtract(this.position()); - Vec3 horizontal = new Vec3(lunge.x, 0.0D, lunge.z); + AntarchyGravityDirection direction = AntarchyGravityApi.getGravityDirection(this); + Vec3 localLunge = AntarchyGravityRotationUtil.vecWorldToPlayer(target.position().subtract(this.position()), direction); + Vec3 horizontal = new Vec3(localLunge.x, 0.0D, localLunge.z); if (horizontal.lengthSqr() < 1.0E-4D) { return; } horizontal = horizontal.normalize().scale(horizontalSpeed); - this.setDeltaMovement(this.getDeltaMovement().add(horizontal.x, verticalSpeed, horizontal.z)); + Vec3 localImpulse = new Vec3(horizontal.x, verticalSpeed, horizontal.z); + Vec3 worldImpulse = AntarchyGravityRotationUtil.vecPlayerToWorld(localImpulse, direction); + this.setDeltaMovement(this.getDeltaMovement().add(worldImpulse.x, worldImpulse.y, worldImpulse.z)); this.hasImpulse = true; } + private BlockPos findSummonSpawnPos(Vec3 center) { + BlockPos base = BlockPos.containing(center); + Direction gravityDown = AntarchyGravityRotationUtil.getGravityDownDirection(this); + Direction gravityUp = gravityDown.getOpposite(); + BlockPos fallback = base; + for (int step = -2; step <= 2; step++) { + BlockPos candidate = base.relative(gravityUp, step); + BlockPos support = candidate.relative(gravityDown); + if (this.level().isEmptyBlock(candidate) + && this.level().isEmptyBlock(candidate.relative(gravityUp)) + && this.level().getBlockState(support).isFaceSturdy(this.level(), support, gravityUp)) { + return candidate; + } + } + return fallback; + } + @Override public void handleEntityEvent(byte id) { if (id == CLAW_ATTACK_EVENT) { @@ -824,12 +852,12 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity { } Vec3 homeCenter = Vec3.atCenterOf(this.encounterHome); if (this.distanceToSqr(homeCenter) > FORCED_RETURN_RADIUS * FORCED_RETURN_RADIUS) { - this.moveTo(homeCenter.x, this.encounterHome.getY(), homeCenter.z, this.getYRot(), this.getXRot()); + this.moveTo(homeCenter.x, homeCenter.y, homeCenter.z, this.getYRot(), this.getXRot()); this.setDeltaMovement(Vec3.ZERO); this.hasImpulse = true; return; } - this.getNavigation().moveTo(homeCenter.x, this.encounterHome.getY(), homeCenter.z, HOME_RETURN_SPEED); + this.getNavigation().moveTo(homeCenter.x, homeCenter.y, homeCenter.z, HOME_RETURN_SPEED); } private void resetEncounter(boolean restoreHealth) { @@ -853,7 +881,7 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity { this.discardOwnedScorpions(); if (this.encounterHome != null) { Vec3 homeCenter = Vec3.atCenterOf(this.encounterHome); - this.moveTo(homeCenter.x, this.encounterHome.getY(), homeCenter.z, this.getYRot(), this.getXRot()); + this.moveTo(homeCenter.x, homeCenter.y, homeCenter.z, this.getYRot(), this.getXRot()); this.setDeltaMovement(Vec3.ZERO); } } @@ -949,7 +977,11 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity { if (EmperorScorpionEntity.this.isWithinMeleeAttackRange(target) && EmperorScorpionEntity.this.hasLineOfSight(target)) { EmperorScorpionEntity.this.getNavigation().stop(); - EmperorScorpionEntity.this.setDeltaMovement(0.0D, EmperorScorpionEntity.this.getDeltaMovement().y, 0.0D); + AntarchyGravityDirection direction = AntarchyGravityApi.getGravityDirection(EmperorScorpionEntity.this); + Vec3 localMotion = AntarchyGravityRotationUtil.vecWorldToPlayer(EmperorScorpionEntity.this.getDeltaMovement(), direction); + Vec3 localStopped = new Vec3(0.0D, localMotion.y, 0.0D); + Vec3 worldStopped = AntarchyGravityRotationUtil.vecPlayerToWorld(localStopped, direction); + EmperorScorpionEntity.this.setDeltaMovement(worldStopped); AttackType attackType = EmperorScorpionEntity.this.selectAttack(target); if (attackType != AttackType.NONE) { EmperorScorpionEntity.this.beginAttack(target, attackType); @@ -968,8 +1000,10 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity { } private void approachDirectly(LivingEntity target) { - double dx = target.getX() - EmperorScorpionEntity.this.getX(); - double dz = target.getZ() - EmperorScorpionEntity.this.getZ(); + AntarchyGravityDirection direction = AntarchyGravityApi.getGravityDirection(EmperorScorpionEntity.this); + Vec3 localDelta = AntarchyGravityRotationUtil.vecWorldToPlayer(target.position().subtract(EmperorScorpionEntity.this.position()), direction); + double dx = localDelta.x; + double dz = localDelta.z; if (dx * dx + dz * dz < 1.0E-4D) { return; } @@ -981,14 +1015,15 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity { EmperorScorpionEntity.this.yBodyRot = newYaw; EmperorScorpionEntity.this.yBodyRotO = newYaw; - Vec3 currentMotion = EmperorScorpionEntity.this.getDeltaMovement(); + Vec3 currentMotion = AntarchyGravityRotationUtil.vecWorldToPlayer(EmperorScorpionEntity.this.getDeltaMovement(), direction); float headingError = Math.abs(Mth.wrapDegrees(targetYaw - currentYaw)); if (headingError <= DIRECT_APPROACH_ALIGN_THRESHOLD) { double speed = EmperorScorpionEntity.this.getAttributeValue(Attributes.MOVEMENT_SPEED) * CHASE_SPEED; Vec3 forward = Vec3.directionFromRotation(0.0F, newYaw).scale(speed); - EmperorScorpionEntity.this.setDeltaMovement(forward.x, currentMotion.y, forward.z); + Vec3 worldForward = AntarchyGravityRotationUtil.vecPlayerToWorld(forward.x, currentMotion.y, forward.z, direction); + EmperorScorpionEntity.this.setDeltaMovement(worldForward); } else { - EmperorScorpionEntity.this.setDeltaMovement(0.0D, currentMotion.y, 0.0D); + EmperorScorpionEntity.this.setDeltaMovement(AntarchyGravityRotationUtil.vecPlayerToWorld(0.0D, currentMotion.y, 0.0D, direction)); } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/HerculesBeetleEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/HerculesBeetleEntity.java index 0ea07a61..1f3c5ca5 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/HerculesBeetleEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/HerculesBeetleEntity.java @@ -6,6 +6,9 @@ import com.craisinlord.antarchy.content.AntarchyGameRules; import com.craisinlord.antarchy.content.AntarchySoundEvents; import com.craisinlord.antarchy.content.AntarchyTags; import com.craisinlord.antarchy.content.damage.AntarchyDamageSources; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil; import com.craisinlord.antarchy.content.item.BigBerthaItem; import com.craisinlord.antarchy.content.network.HerculesBeetleImpactShakeSync; import java.util.EnumSet; @@ -218,10 +221,13 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl if (spawnReason == MobSpawnType.SPAWN_EGG || spawnReason == MobSpawnType.SPAWNER || spawnReason == MobSpawnType.COMMAND) { return true; } - return level.getDifficulty() != Difficulty.PEACEFUL - && level.getBlockState(pos.below()).isFaceSturdy(level, pos.below(), Direction.UP) + boolean floorSpawn = level.getBlockState(pos.below()).isFaceSturdy(level, pos.below(), Direction.UP) && level.isEmptyBlock(pos) && level.isEmptyBlock(pos.above()); + boolean ceilingSpawn = level.getBlockState(pos.above()).isFaceSturdy(level, pos.above(), Direction.DOWN) + && level.isEmptyBlock(pos) + && level.isEmptyBlock(pos.below()); + return level.getDifficulty() != Difficulty.PEACEFUL && (floorSpawn || ceilingSpawn); } @Override @@ -416,8 +422,8 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl private void tickKnockedDown() { this.getNavigation().stop(); - Vec3 motion = this.getDeltaMovement(); - this.setDeltaMovement(0.0D, Math.min(motion.y, 0.0D), 0.0D); + Vec3 motion = this.toLocal(this.getDeltaMovement()); + this.setDeltaMovement(this.toWorld(0.0D, Math.min(motion.y, 0.0D), 0.0D)); if (this.getAnimationState() == ANIM_KNOCKED_DOWN && this.actionTicks > 0) { this.actionTicks--; if (this.actionTicks <= 0) { @@ -454,8 +460,8 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl case ANIM_OPEN_WINGS -> { this.setFlying(true); if (this.getControllingPassenger() instanceof Player) { - Vec3 motion = this.getDeltaMovement(); - this.setDeltaMovement(motion.x, Math.max(motion.y, MOUNTED_FLIGHT_LIFT), motion.z); + Vec3 motion = this.toLocal(this.getDeltaMovement()); + this.setDeltaMovement(this.toWorld(motion.x, Math.max(motion.y, MOUNTED_FLIGHT_LIFT), motion.z)); this.hasImpulse = true; } if (this.pendingChargeStart) { @@ -533,9 +539,9 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl this.setNoGravity(true); this.noPhysics = false; this.fallDistance = 0.0F; - if (this.onGround() && this.getDeltaMovement().y <= 0.0D) { - Vec3 motion = this.getDeltaMovement(); - this.setDeltaMovement(motion.x, MOUNTED_FLIGHT_LIFT, motion.z); + Vec3 motion = this.toLocal(this.getDeltaMovement()); + if (this.onGround() && motion.y <= 0.0D) { + this.setDeltaMovement(this.toWorld(motion.x, MOUNTED_FLIGHT_LIFT, motion.z)); this.hasImpulse = true; } } else { @@ -753,7 +759,7 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl } private boolean isMountedFlightPoseActive() { - return this.isFlying() && (!this.onGround() || this.getDeltaMovement().y > 0.08D); + return this.isFlying() && (!this.onGround() || this.toLocal(this.getDeltaMovement()).y > 0.08D); } private void startMountedFlight() { @@ -763,8 +769,8 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl this.noPhysics = false; this.fallDistance = 0.0F; this.groundedTicks = 0; - Vec3 motion = this.getDeltaMovement(); - this.setDeltaMovement(motion.x, Math.max(motion.y, MOUNTED_FLIGHT_LIFT), motion.z); + Vec3 motion = this.toLocal(this.getDeltaMovement()); + this.setDeltaMovement(this.toWorld(motion.x, Math.max(motion.y, MOUNTED_FLIGHT_LIFT), motion.z)); this.hasImpulse = true; this.setAnimationState(ANIM_FLY); } @@ -883,23 +889,24 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl ? target.hurt(AntarchyDamageSources.herculesBeetleObliteration(serverLevel, this), damage) : target.hurt(this.damageSources().mobAttack(this), damage); if (hurt) { - Vec3 push = target.position().subtract(this.position()).multiply(1.0D, 0.0D, 1.0D); + Vec3 push = this.toLocalPlane(target.position().subtract(this.position())); if (push.lengthSqr() < 1.0E-4D) { - push = this.getLookAngle().multiply(1.0D, 0.0D, 1.0D); + push = this.toLocalPlane(this.getLookAngle()); } push = push.normalize().scale(horizontalKnockback); - target.setDeltaMovement(target.getDeltaMovement().add(push.x, 1.25D, push.z)); + Vec3 worldPush = this.toWorld(push.x, 1.25D, push.z); + target.setDeltaMovement(target.getDeltaMovement().add(worldPush.x, worldPush.y, worldPush.z)); target.hurtMarked = true; } return hurt; } private void startCharge(Vec3 direction, int durationTicks, boolean mountedCharge) { - Vec3 horizontal = direction.multiply(1.0D, 0.0D, 1.0D); + Vec3 horizontal = this.toLocalPlane(direction); if (horizontal.lengthSqr() < 1.0E-4D) { - horizontal = this.getLookAngle().multiply(1.0D, 0.0D, 1.0D); + horizontal = this.toLocalPlane(this.getLookAngle()); } - this.chargeDirection = horizontal.normalize(); + this.chargeDirection = this.toWorld(horizontal.normalize()); this.pendingChargeDuration = Mth.clamp(durationTicks, MIN_MOUNTED_CHARGE_TICKS, MAX_CHARGE_TICKS); this.pendingMountedCharge = mountedCharge; @@ -954,12 +961,17 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl continue; } if (victim.hurt(AntarchyDamageSources.herculesBeetleObliteration(serverLevel, this), damage)) { - Vec3 push = victim.position().subtract(this.position()); + Vec3 push = this.toLocal(victim.position().subtract(this.position())); if (push.lengthSqr() < 1.0E-4D) { - push = this.chargeDirection; + push = this.toLocal(this.chargeDirection); } - push = push.normalize(); - victim.setDeltaMovement(victim.getDeltaMovement().add(push.x * 1.25D, 0.9D, push.z * 1.25D)); + Vec3 horizontal = new Vec3(push.x, 0.0D, push.z); + if (horizontal.lengthSqr() < 1.0E-4D) { + horizontal = this.toLocalPlane(this.getLookAngle()); + } + horizontal = horizontal.normalize(); + Vec3 worldPush = this.toWorld(horizontal.x * 1.25D, 0.9D, horizontal.z * 1.25D); + victim.setDeltaMovement(victim.getDeltaMovement().add(worldPush.x, worldPush.y, worldPush.z)); victim.hurtMarked = true; } } @@ -1169,7 +1181,8 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl @Override protected void positionRider(Entity passenger, MoveFunction moveFunction) { if (this.hasPassenger(passenger)) { - Vec3 forward = this.getLookAngle().multiply(1.0D, 0.0D, 1.0D); + Vec3 localForward = this.toLocalPlane(this.getLookAngle()); + Vec3 forward = localForward.lengthSqr() > 1.0E-4D ? this.toWorld(localForward.normalize()) : this.toWorld(0.0D, 0.0D, 1.0D); boolean mountedFlightPose = this.isMountedFlightPoseActive(); double yOffset = mountedFlightPose ? 5.3D : 3.0D; double forwardOffset = mountedFlightPose ? 2.2D : 1.25D; @@ -1177,11 +1190,12 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl yOffset -= 0.25D; forwardOffset += 0.25D; } + Vec3 seatOffset = forward.scale(forwardOffset).add(this.toWorld(0.0D, yOffset, 0.0D)); moveFunction.accept( passenger, - this.getX() + forward.x * forwardOffset, - this.getY() + yOffset, - this.getZ() + forward.z * forwardOffset + this.getX() + seatOffset.x, + this.getY() + seatOffset.y, + this.getZ() + seatOffset.z ); } } @@ -1209,14 +1223,15 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl super.travel(new Vec3(riddenInput.x, travelVector.y, riddenInput.z)); if (Math.abs(rider.zza) < 0.05F && Math.abs(rider.xxa) < 0.05F && this.onGround()) { - Vec3 dampedMotion = this.getDeltaMovement(); - this.setDeltaMovement(dampedMotion.x * MOUNTED_GROUND_BRAKE, dampedMotion.y, dampedMotion.z * MOUNTED_GROUND_BRAKE); + Vec3 dampedMotion = this.toLocal(this.getDeltaMovement()); + this.setDeltaMovement(this.toWorld(dampedMotion.x * MOUNTED_GROUND_BRAKE, dampedMotion.y, dampedMotion.z * MOUNTED_GROUND_BRAKE)); } } else { - Vec3 motion = new Vec3(0.0D, this.getDeltaMovement().y, 0.0D); + Vec3 motion = this.toLocal(this.getDeltaMovement()); this.moveRelative(this.getSpeed(), new Vec3(riddenInput.x, 0.0D, riddenInput.z)); - motion = motion.add(this.getDeltaMovement().x, riddenInput.y, this.getDeltaMovement().z); - this.setDeltaMovement(motion); + Vec3 moved = this.toLocal(this.getDeltaMovement()); + motion = new Vec3(moved.x, motion.y + riddenInput.y, moved.z); + this.setDeltaMovement(this.toWorld(motion)); this.move(MoverType.SELF, this.getDeltaMovement()); } } @@ -1292,10 +1307,11 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl } private void lookInDirection(Vec3 direction) { - if (direction.lengthSqr() <= 1.0E-4D) { + Vec3 localDirection = this.toLocalPlane(direction); + if (localDirection.lengthSqr() <= 1.0E-4D) { return; } - float yaw = (float) (Mth.atan2(direction.z, direction.x) * (180.0D / Math.PI)) - 90.0F; + float yaw = (float) (Mth.atan2(localDirection.z, localDirection.x) * (180.0D / Math.PI)) - 90.0F; this.setYRot(yaw); this.yBodyRot = yaw; this.yHeadRot = yaw; @@ -1313,10 +1329,10 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl private List getFrontTargets(double range, double inflation) { AABB box = this.getBoundingBox().expandTowards(this.getLookAngle().scale(range)).inflate(inflation); - Vec3 forward = this.getLookAngle().multiply(1.0D, 0.0D, 1.0D); + Vec3 forward = this.toLocalPlane(this.getLookAngle()); return this.level().getEntitiesOfClass(LivingEntity.class, box, this::canHarm).stream() .filter(entity -> { - Vec3 toTarget = entity.position().subtract(this.position()).multiply(1.0D, 0.0D, 1.0D); + Vec3 toTarget = this.toLocalPlane(entity.position().subtract(this.position())); if (forward.lengthSqr() < 1.0E-4D || toTarget.lengthSqr() < 1.0E-4D) { return true; } @@ -1325,6 +1341,27 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl .toList(); } + private AntarchyGravityDirection gravityDirection() { + return AntarchyGravityApi.getGravityDirection(this); + } + + private Vec3 toLocal(Vec3 worldVector) { + return AntarchyGravityRotationUtil.vecWorldToPlayer(worldVector, this.gravityDirection()); + } + + private Vec3 toWorld(Vec3 localVector) { + return AntarchyGravityRotationUtil.vecPlayerToWorld(localVector, this.gravityDirection()); + } + + private Vec3 toWorld(double x, double y, double z) { + return AntarchyGravityRotationUtil.vecPlayerToWorld(x, y, z, this.gravityDirection()); + } + + private Vec3 toLocalPlane(Vec3 worldVector) { + Vec3 local = this.toLocal(worldVector); + return new Vec3(local.x, 0.0D, local.z); + } + @Nullable private LivingEntity findFrontTarget(double range, double inflation) { List targets = this.getFrontTargets(range, inflation); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/JerryEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/JerryEntity.java index bcfa5f80..1acc8f96 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/JerryEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/JerryEntity.java @@ -2,6 +2,9 @@ package com.craisinlord.antarchy.content.entity; import com.craisinlord.antarchy.config.AntarchySettings; import com.craisinlord.antarchy.content.AntarchySoundEvents; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil; import com.craisinlord.antarchy.content.horde.CavarynHordeManager; import net.minecraft.nbt.CompoundTag; import net.minecraft.core.registries.BuiltInRegistries; @@ -208,7 +211,7 @@ public class JerryEntity extends Monster implements GeoEntity { return; } - Vec3 targetPos = target.getEyePosition().add(0.0D, -0.15D, 0.0D); + Vec3 targetPos = target.getEyePosition().add(this.toWorld(0.0D, -0.15D, 0.0D)); Vec3 toTarget = targetPos.subtract(this.position()); double distance = toTarget.length(); if (distance > 0.01D) { @@ -242,15 +245,15 @@ public class JerryEntity extends Monster implements GeoEntity { Stage stage = this.getStage(); Vec3 targetPos = target.getEyePosition(); - Vec3 hoverPos = targetPos.add(0.0D, 5.0D, 0.0D); + Vec3 hoverPos = targetPos.add(this.toWorld(0.0D, 5.0D, 0.0D)); Vec3 toHover = hoverPos.subtract(this.position()); Vec3 toTarget = targetPos.subtract(this.position()); double hoverDistance = toHover.length(); double targetDistance = toTarget.length(); - double horizontalDistance = this.position().subtract(targetPos).horizontalDistance(); + double horizontalDistance = this.toLocalPlane(this.position().subtract(targetPos)).length(); this.faceTarget(target); if (this.alphaDiveCooldownTicks > 0) { - this.setDeltaMovement(this.getDeltaMovement().scale(0.8D).add(toTarget.normalize().scale(0.28D)).add(0.0D, -0.08D, 0.0D)); + this.setDeltaMovement(this.getDeltaMovement().scale(0.8D).add(toTarget.normalize().scale(0.28D)).add(this.toWorld(0.0D, -0.08D, 0.0D))); } else if (hoverDistance > 0.01D) { Vec3 desiredMotion = toHover.normalize().scale(0.20D); this.setDeltaMovement(this.getDeltaMovement().scale(0.72D).add(desiredMotion)); @@ -258,7 +261,7 @@ public class JerryEntity extends Monster implements GeoEntity { if (this.alphaDiveCooldownTicks <= 0 && targetDistance < 9.0D && horizontalDistance < 7.0D) { this.alphaDiveCooldownTicks = 30; - this.setDeltaMovement(this.getDeltaMovement().add(0.0D, -0.55D, 0.0D).add(toTarget.normalize().scale(0.42D))); + this.setDeltaMovement(this.getDeltaMovement().add(this.toWorld(0.0D, -0.55D, 0.0D)).add(toTarget.normalize().scale(0.42D))); } if (targetDistance < 2.3D && this.attackCooldownTicks <= 0) { @@ -271,11 +274,12 @@ public class JerryEntity extends Monster implements GeoEntity { } private void faceTarget(LivingEntity target) { - Vec3 toTarget = target.position().subtract(this.position()); - if (toTarget.horizontalDistanceSqr() <= 0.0001D) { + Vec3 toTarget = this.toLocal(target.position().subtract(this.position())); + Vec3 horizontal = new Vec3(toTarget.x, 0.0D, toTarget.z); + if (horizontal.lengthSqr() <= 0.0001D) { return; } - float targetYaw = (float) (Mth.atan2(toTarget.z, toTarget.x) * (180.0F / Math.PI)) - 90.0F; + float targetYaw = (float) (Mth.atan2(horizontal.z, horizontal.x) * (180.0F / Math.PI)) - 90.0F; this.setYRot(Mth.approachDegrees(this.getYRot(), targetYaw, 30.0F)); this.yBodyRot = this.getYRot(); this.yHeadRot = this.getYRot(); @@ -304,6 +308,23 @@ public class JerryEntity extends Monster implements GeoEntity { : super.doHurtTarget(target); } + private AntarchyGravityDirection gravityDirection() { + return AntarchyGravityApi.getGravityDirection(this); + } + + private Vec3 toLocal(Vec3 worldVector) { + return AntarchyGravityRotationUtil.vecWorldToPlayer(worldVector, this.gravityDirection()); + } + + private Vec3 toWorld(double x, double y, double z) { + return AntarchyGravityRotationUtil.vecPlayerToWorld(x, y, z, this.gravityDirection()); + } + + private Vec3 toLocalPlane(Vec3 worldVector) { + Vec3 local = this.toLocal(worldVector); + return new Vec3(local.x, 0.0D, local.z); + } + @Override @Nullable protected SoundEvent getAmbientSound() { diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/JumpyBugEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/JumpyBugEntity.java index 576f5025..b2a3f39c 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/JumpyBugEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/JumpyBugEntity.java @@ -3,6 +3,9 @@ package com.craisinlord.antarchy.content.entity; import com.craisinlord.antarchy.config.AntarchySettings; import com.craisinlord.antarchy.content.AntarchySoundEvents; import com.craisinlord.antarchy.content.damage.AntarchyDamageSources; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil; import com.mojang.serialization.Codec; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -409,7 +412,7 @@ public class JumpyBugEntity extends Monster implements GeoEntity { this.getNavigation().stop(); this.setDeltaMovement(Vec3.ZERO); this.move(MoverType.SELF, Vec3.ZERO); - this.setPos(this.getX(), clingPos.getY() - this.getBbHeight() - 0.01D, this.getZ()); + this.setPos(this.getX(), AntarchyGravityApi.isGravityInverted(this) ? clingPos.getY() + 1.01D : clingPos.getY() - this.getBbHeight() - 0.01D, this.getZ()); } private void tickPouncing() { @@ -460,7 +463,7 @@ public class JumpyBugEntity extends Monster implements GeoEntity { boolean playerNearby = this.level().getNearestPlayer(this, CAMOUFLAGE_PLAYER_RANGE) != null; boolean idle = this.getTarget() == null && this.recoveryTicks <= 0 - && this.getDeltaMovement().horizontalDistanceSqr() < 0.003D + && this.toLocal(this.getDeltaMovement()).horizontalDistanceSqr() < 0.003D && this.onGround(); boolean movingQuickly = this.getDeltaMovement().lengthSqr() > QUICK_MOVE_SQR; boolean inAmbushCover = this.findCeilingWithinRange(this.directCeilingSearchHeight()) != null; @@ -480,7 +483,7 @@ public class JumpyBugEntity extends Monster implements GeoEntity { private BlockPos findCeilingWithinRange(int maxBlocks) { BlockPos origin = this.blockPosition(); for (int dy = 1; dy <= maxBlocks; dy++) { - BlockPos candidate = origin.above(dy); + BlockPos candidate = this.relativeLocal(origin, 0, dy, 0); if (this.isUsableCeiling(candidate)) { return candidate; } @@ -504,7 +507,7 @@ public class JumpyBugEntity extends Monster implements GeoEntity { continue; } for (int dy = minHeight; dy <= maxHeight; dy++) { - BlockPos candidate = origin.offset(dx, dy, dz); + BlockPos candidate = this.relativeLocal(origin, dx, dy, dz); if (!this.isUsableCeiling(candidate)) { continue; } @@ -525,7 +528,7 @@ public class JumpyBugEntity extends Monster implements GeoEntity { } private boolean isCeilingBlock(BlockPos pos) { - return this.level().getBlockState(pos).isFaceSturdy(this.level(), pos, Direction.DOWN); + return this.level().getBlockState(pos).isFaceSturdy(this.level(), pos, this.gravityDownDirection()); } private int minimumCeilingHeight() { @@ -541,7 +544,9 @@ public class JumpyBugEntity extends Monster implements GeoEntity { return false; } double x = pos.getX() + 0.5D; - double y = pos.getY() - this.getBbHeight() - 0.01D; + double y = AntarchyGravityApi.isGravityInverted(this) + ? pos.getY() + 1.01D + : pos.getY() - this.getBbHeight() - 0.01D; double z = pos.getZ() + 0.5D; return this.canOccupy(x, y, z); } @@ -590,11 +595,14 @@ public class JumpyBugEntity extends Monster implements GeoEntity { this.leapingTicks = 0; this.getNavigation().stop(); - double dy = ceilingPos.getY() - this.getY(); + Vec3 localDelta = this.toLocal(Vec3.atCenterOf(ceilingPos).subtract(this.position())); + double dy = localDelta.y; double upwardSpeed = Math.min(2.5D, Math.sqrt(0.16D * Math.max(dy, 1.0D)) + 0.4D); - double dx = ceilingPos.getX() + 0.5D - this.getX(); - double dz = ceilingPos.getZ() + 0.5D - this.getZ(); - this.setDeltaMovement(Mth.clamp(dx * 0.18D, -0.35D, 0.35D), upwardSpeed, Mth.clamp(dz * 0.18D, -0.35D, 0.35D)); + this.setDeltaMovement(this.toWorld( + Mth.clamp(localDelta.x * 0.18D, -0.35D, 0.35D), + upwardSpeed, + Mth.clamp(localDelta.z * 0.18D, -0.35D, 0.35D) + )); this.hasImpulse = true; this.playSound(AntarchySoundEvents.JUMPY_BUG_JUMP.get(), 1.0F, 0.95F + this.random.nextFloat() * 0.1F); } @@ -615,12 +623,11 @@ public class JumpyBugEntity extends Monster implements GeoEntity { this.pounceCooldownTicks = DEFAULT_POUNCE_COOLDOWN; this.pounceTicks = 0; - Vec3 from = this.position(); - Vec3 to = target.getEyePosition().subtract(from); + Vec3 to = this.toLocal(target.getEyePosition().subtract(this.position())); Vec3 horizontal = new Vec3(to.x, 0.0D, to.z); - Vec3 direction = horizontal.lengthSqr() > 1.0E-4D ? horizontal.normalize() : target.getLookAngle(); + Vec3 direction = horizontal.lengthSqr() > 1.0E-4D ? horizontal.normalize() : this.toLocalPlane(target.getLookAngle()).normalize(); double upward = POUNCE_UPWARD_SPEED + Mth.clamp(to.y * 0.08D, -0.04D, 0.22D); - this.setDeltaMovement(direction.x * POUNCE_HORIZONTAL_SPEED, upward, direction.z * POUNCE_HORIZONTAL_SPEED); + this.setDeltaMovement(this.toWorld(direction.x * POUNCE_HORIZONTAL_SPEED, upward, direction.z * POUNCE_HORIZONTAL_SPEED)); this.hasImpulse = true; this.playSound(AntarchySoundEvents.JUMPY_BUG_JUMP.get(), 1.0F, 0.95F + this.random.nextFloat() * 0.1F); } @@ -635,10 +642,10 @@ public class JumpyBugEntity extends Monster implements GeoEntity { this.pounceCooldownTicks = DEFAULT_POUNCE_COOLDOWN; this.pounceTicks = 0; - Vec3 to = target.position().add(0.0D, target.getBbHeight() * 0.35D, 0.0D).subtract(this.position()); + Vec3 to = this.toLocal(target.position().add(this.toWorld(0.0D, target.getBbHeight() * 0.35D, 0.0D)).subtract(this.position())); Vec3 horizontal = new Vec3(to.x, 0.0D, to.z); - Vec3 direction = horizontal.lengthSqr() > 1.0E-4D ? horizontal.normalize() : target.getLookAngle(); - this.setDeltaMovement(direction.x * CEILING_DROP_HORIZONTAL_SPEED, CEILING_DROP_UPWARD_SPEED, direction.z * CEILING_DROP_HORIZONTAL_SPEED); + Vec3 direction = horizontal.lengthSqr() > 1.0E-4D ? horizontal.normalize() : this.toLocalPlane(target.getLookAngle()).normalize(); + this.setDeltaMovement(this.toWorld(direction.x * CEILING_DROP_HORIZONTAL_SPEED, CEILING_DROP_UPWARD_SPEED, direction.z * CEILING_DROP_HORIZONTAL_SPEED)); this.hasImpulse = true; this.playSound(AntarchySoundEvents.JUMPY_BUG_JUMP.get(), 1.0F, 0.9F + this.random.nextFloat() * 0.1F); } @@ -646,8 +653,8 @@ public class JumpyBugEntity extends Monster implements GeoEntity { private void finishPounce(boolean keepMomentum) { this.pounceTicks = 0; if (!keepMomentum) { - Vec3 movement = this.getDeltaMovement(); - this.setDeltaMovement(movement.x * 0.25D, Math.max(0.0D, movement.y), movement.z * 0.25D); + Vec3 movement = this.toLocal(this.getDeltaMovement()); + this.setDeltaMovement(this.toWorld(movement.x * 0.25D, Math.max(0.0D, movement.y), movement.z * 0.25D)); } this.setAttackState(AttackState.RECOVERING); this.recoveryTicks = DEFAULT_RECOVERY_TICKS; @@ -906,12 +913,12 @@ public class JumpyBugEntity extends Monster implements GeoEntity { JumpyBugEntity.this.getNavigation().moveTo(target, 1.05D); } else if (distSqr > CHASE_LEAP_RANGE_SQR) { if (JumpyBugEntity.this.onGround() && JumpyBugEntity.this.chaseJumpCooldownTicks <= 0) { - Vec3 dir = target.position().subtract(JumpyBugEntity.this.position()).normalize(); - JumpyBugEntity.this.setDeltaMovement( + Vec3 dir = JumpyBugEntity.this.toLocalPlane(target.position().subtract(JumpyBugEntity.this.position())).normalize(); + JumpyBugEntity.this.setDeltaMovement(JumpyBugEntity.this.toWorld( dir.x * CHASE_LEAP_HORIZONTAL, CHASE_LEAP_VERTICAL, dir.z * CHASE_LEAP_HORIZONTAL - ); + )); JumpyBugEntity.this.hasImpulse = true; JumpyBugEntity.this.chaseJumpCooldownTicks = CHASE_JUMP_COOLDOWN; } @@ -944,4 +951,30 @@ public class JumpyBugEntity extends Monster implements GeoEntity { && super.canContinueToUse(); } } + + private AntarchyGravityDirection gravityDirection() { + return AntarchyGravityApi.getGravityDirection(this); + } + + private Direction gravityDownDirection() { + return this.gravityDirection().isInverted() ? Direction.UP : Direction.DOWN; + } + + private Vec3 toLocal(Vec3 worldVector) { + return AntarchyGravityRotationUtil.vecWorldToPlayer(worldVector, this.gravityDirection()); + } + + private Vec3 toWorld(double x, double y, double z) { + return AntarchyGravityRotationUtil.vecPlayerToWorld(x, y, z, this.gravityDirection()); + } + + private Vec3 toLocalPlane(Vec3 worldVector) { + Vec3 local = this.toLocal(worldVector); + return new Vec3(local.x, 0.0D, local.z); + } + + private BlockPos relativeLocal(BlockPos origin, int x, int y, int z) { + Vec3 worldOffset = this.toWorld(x, y, z); + return origin.offset(Mth.floor(worldOffset.x), Mth.floor(worldOffset.y), Mth.floor(worldOffset.z)); + } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/LurkingTerrorEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/LurkingTerrorEntity.java index 456667fd..9037d8a3 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/LurkingTerrorEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/LurkingTerrorEntity.java @@ -74,16 +74,22 @@ public class LurkingTerrorEntity extends Monster implements GeoEntity { return true; } BlockPos belowPos = pos.below(); + BlockPos abovePos = pos.above(); BlockState belowState = level.getBlockState(belowPos); - boolean validSupport = !belowState.is(Blocks.BEDROCK) + BlockState aboveState = level.getBlockState(abovePos); + boolean floorSupport = !belowState.is(Blocks.BEDROCK) && belowState.blocksMotion() && belowState.isFaceSturdy(level, belowPos, Direction.UP) && belowState.isCollisionShapeFullBlock(level, belowPos); + boolean ceilingSupport = !aboveState.is(Blocks.BEDROCK) + && aboveState.blocksMotion() + && aboveState.isFaceSturdy(level, abovePos, Direction.DOWN) + && aboveState.isCollisionShapeFullBlock(level, abovePos); return level.getDifficulty() != Difficulty.PEACEFUL - && validSupport + && (floorSupport || ceilingSupport) && level.isEmptyBlock(pos) - && level.isEmptyBlock(pos.above()) + && (level.isEmptyBlock(pos.above()) || level.isEmptyBlock(pos.below())) && Monster.checkMonsterSpawnRules(entityType, level, spawnReason, pos, random); } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/MantisEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/MantisEntity.java index 6b1274c2..e4b9301a 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/MantisEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/MantisEntity.java @@ -134,9 +134,14 @@ public class MantisEntity extends Monster implements GeoEntity { } boolean atSurface = level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, pos).getY() <= pos.getY(); - boolean posOpen = level.isEmptyBlock(pos) && level.isEmptyBlock(pos.above()) && level.getFluidState(pos).isEmpty(); - boolean onSolidGround = level.getBlockState(pos.below()).isFaceSturdy(level, pos.below(), Direction.UP) + boolean hasFloorClearance = level.isEmptyBlock(pos.above()); + boolean hasCeilingClearance = level.isEmptyBlock(pos.below()); + boolean floorSupport = level.getBlockState(pos.below()).isFaceSturdy(level, pos.below(), Direction.UP) && !(level.getBlockState(pos.below()).getBlock() instanceof LeavesBlock); + boolean ceilingSupport = level.getBlockState(pos.above()).isFaceSturdy(level, pos.above(), Direction.DOWN) + && !(level.getBlockState(pos.above()).getBlock() instanceof LeavesBlock); + boolean posOpen = level.isEmptyBlock(pos) && (hasFloorClearance || hasCeilingClearance) && level.getFluidState(pos).isEmpty(); + boolean onSolidGround = floorSupport || ceilingSupport; if (!posOpen || !onSolidGround) { return false; @@ -652,5 +657,3 @@ public class MantisEntity extends Monster implements GeoEntity { } - - diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/MissileSquidEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/MissileSquidEntity.java index 0e94916e..60262c9e 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/MissileSquidEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/MissileSquidEntity.java @@ -3,6 +3,9 @@ package com.craisinlord.antarchy.content.entity; import com.craisinlord.antarchy.config.AntarchySettings; import com.craisinlord.antarchy.content.AntarchySoundEvents; import com.craisinlord.antarchy.content.entity.kraken.KrakenEntity; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil; import net.minecraft.core.BlockPos; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.nbt.CompoundTag; @@ -446,7 +449,7 @@ public class MissileSquidEntity extends Monster implements GeoEntity { this.move(MoverType.SELF, velocity); Vec3 movedVelocity = this.getDeltaMovement(); if (!this.isNoGravity()) { - movedVelocity = movedVelocity.add(0.0D, -0.08D, 0.0D); + movedVelocity = movedVelocity.add(this.toWorld(0.0D, -0.08D, 0.0D)); } this.setDeltaMovement(movedVelocity.scale(this.isInWater() ? 0.9D : 0.98D)); @@ -513,9 +516,9 @@ public class MissileSquidEntity extends Monster implements GeoEntity { } private void tickGroundAggroMovement(LivingEntity target) { - Vec3 horizontal = target.position().subtract(this.position()).multiply(1.0D, 0.0D, 1.0D); + Vec3 horizontal = this.toLocalPlane(target.position().subtract(this.position())); if (horizontal.lengthSqr() > 1.0E-4D && this.onGround()) { - Vec3 lunge = horizontal.normalize().scale(0.16D).add(0.0D, 0.24D, 0.0D); + Vec3 lunge = this.toWorld(horizontal.normalize().scale(0.16D).add(new Vec3(0.0D, 0.24D, 0.0D))); this.setDeltaMovement(this.getDeltaMovement().add(lunge)); this.hasImpulse = true; } @@ -540,7 +543,7 @@ public class MissileSquidEntity extends Monster implements GeoEntity { } private void updateSwimRotation() { - Vec3 velocity = this.getDeltaMovement(); + Vec3 velocity = this.toLocal(this.getDeltaMovement()); if (velocity.horizontalDistanceSqr() > 1.0E-4D) { float targetYaw = (float) (Mth.atan2(velocity.z, velocity.x) * (180.0D / Math.PI)) - 90.0F; this.setYRot(Mth.approachDegrees(this.getYRot(), targetYaw, 10.0F)); @@ -658,15 +661,11 @@ public class MissileSquidEntity extends Monster implements GeoEntity { } private Vec3 createLatchAnchor(LivingEntity target) { - return target.position().add( - 0.0D, - target.getBbHeight() + 0.15D, - 0.0D - ); + return target.position().add(this.toWorld(0.0D, target.getBbHeight() + 0.15D, 0.0D)); } private void updateAttachedRotation(LivingEntity target) { - Vec3 direction = target.position().subtract(this.position()); + Vec3 direction = this.toLocal(target.position().subtract(this.position())); if (direction.horizontalDistanceSqr() > 1.0E-4D) { float targetYaw = (float)(Mth.atan2(direction.z, direction.x) * (180.0D / Math.PI)) - 90.0F; this.setYRot(targetYaw); @@ -721,11 +720,32 @@ public class MissileSquidEntity extends Monster implements GeoEntity { if (this.launchedFromSquidzooka || this.getTarget() != null || velocity.lengthSqr() > 1.0E-3D - || (this.isInWater() && velocity.horizontalDistanceSqr() > 1.0E-4D)) { + || (this.isInWater() && this.toLocal(velocity).horizontalDistanceSqr() > 1.0E-4D)) { this.setAnimationState(ANIM_SWIM); return; } this.setAnimationState(ANIM_IDLE); } + + private AntarchyGravityDirection gravityDirection() { + return AntarchyGravityApi.getGravityDirection(this); + } + + private Vec3 toLocal(Vec3 worldVector) { + return AntarchyGravityRotationUtil.vecWorldToPlayer(worldVector, this.gravityDirection()); + } + + private Vec3 toWorld(double x, double y, double z) { + return AntarchyGravityRotationUtil.vecPlayerToWorld(x, y, z, this.gravityDirection()); + } + + private Vec3 toWorld(Vec3 localVector) { + return AntarchyGravityRotationUtil.vecPlayerToWorld(localVector, this.gravityDirection()); + } + + private Vec3 toLocalPlane(Vec3 worldVector) { + Vec3 local = this.toLocal(worldVector); + return new Vec3(local.x, 0.0D, local.z); + } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/MolevoreEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/MolevoreEntity.java index 87e2b4b8..13c31f07 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/MolevoreEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/MolevoreEntity.java @@ -4,6 +4,9 @@ import com.craisinlord.antarchy.Antarchy; import com.craisinlord.antarchy.config.AntarchySettings; import com.craisinlord.antarchy.content.AntarchyTags; import com.craisinlord.antarchy.content.AntarchySoundEvents; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil; import java.util.HashSet; import java.util.Set; import java.util.UUID; @@ -475,12 +478,13 @@ public class MolevoreEntity extends Monster implements GeoEntity { } if (entity.hurt(this.damageSources().mobAttack(this), (float) this.getAttributeValue(Attributes.ATTACK_DAMAGE))) { - Vec3 push = entity.position().subtract(this.position()).multiply(1.0D, 0.0D, 1.0D); + Vec3 push = this.toLocalPlane(entity.position().subtract(this.position())); if (push.lengthSqr() < 1.0E-4D) { - push = this.getViewVector(1.0F).multiply(1.0D, 0.0D, 1.0D); + push = this.toLocalPlane(this.getViewVector(1.0F)); } push = push.normalize().scale(0.8D); - entity.push(push.x, 0.25D, push.z); + Vec3 worldPush = this.toWorld(push.x, 0.25D, push.z); + entity.push(worldPush.x, worldPush.y, worldPush.z); entity.hurtMarked = true; } } @@ -493,12 +497,12 @@ public class MolevoreEntity extends Monster implements GeoEntity { } private void startSpinCharge(LivingEntity target) { - Vec3 horizontal = target.position().subtract(this.position()).multiply(1.0D, 0.0D, 1.0D); + Vec3 horizontal = this.toLocalPlane(target.position().subtract(this.position())); if (horizontal.lengthSqr() < 1.0E-4D) { return; } - this.spinDirection = horizontal.normalize(); + this.spinDirection = this.toWorld(horizontal.normalize()); this.spinHitEntities.clear(); this.setActionState(ACTION_SPIN_CHARGE); this.actionTicks = SPIN_TOTAL_TICKS; @@ -514,15 +518,15 @@ public class MolevoreEntity extends Monster implements GeoEntity { if (target != null && inWindup) { this.getLookControl().setLookAt(target, 35.0F, 20.0F); - Vec3 horizontal = target.position().subtract(this.position()).multiply(1.0D, 0.0D, 1.0D); + Vec3 horizontal = this.toLocalPlane(target.position().subtract(this.position())); if (horizontal.lengthSqr() > 1.0E-4D) { - this.spinDirection = horizontal.normalize(); + this.spinDirection = this.toWorld(horizontal.normalize()); } this.setDeltaMovement(this.getDeltaMovement().scale(0.2D)); } else { Vec3 lookTarget = this.position().add(this.spinDirection); - this.getLookControl().setLookAt(lookTarget.x, this.getEyeY(), lookTarget.z, 360.0F, 0.0F); - Vec3 motion = this.spinDirection.scale(SPIN_SPEED).add(0.0D, this.onGround() ? 0.08D : 0.0D, 0.0D); + this.getLookControl().setLookAt(lookTarget.x, lookTarget.y, lookTarget.z, 360.0F, 0.0F); + Vec3 motion = this.spinDirection.scale(SPIN_SPEED).add(this.toWorld(0.0D, this.onGround() ? 0.08D : 0.0D, 0.0D)); this.setDeltaMovement(motion); this.hasImpulse = true; this.performSpinChargeHit(); @@ -553,8 +557,15 @@ public class MolevoreEntity extends Monster implements GeoEntity { } if (entity.hurt(this.damageSources().mobAttack(this), (float) this.getAttributeValue(Attributes.ATTACK_DAMAGE) * 1.65F)) { - Vec3 push = this.spinDirection.lengthSqr() > 0.0D ? this.spinDirection : entity.position().subtract(this.position()).normalize(); - entity.push(push.x * 1.15D, 0.35D, push.z * 1.15D); + Vec3 push = this.spinDirection.lengthSqr() > 0.0D + ? this.toLocalPlane(this.spinDirection) + : this.toLocalPlane(entity.position().subtract(this.position())); + if (push.lengthSqr() < 1.0E-4D) { + push = this.toLocalPlane(this.getViewVector(1.0F)); + } + push = push.normalize(); + Vec3 worldPush = this.toWorld(push.x * 1.15D, 0.35D, push.z * 1.15D); + entity.push(worldPush.x, worldPush.y, worldPush.z); entity.hurtMarked = true; this.playSound(AntarchySoundEvents.MOLEVORE_ATTACK.get(), 1.0F, 0.65F + this.random.nextFloat() * 0.1F); } @@ -593,21 +604,21 @@ public class MolevoreEntity extends Monster implements GeoEntity { Vec3 forward = this.getViewVector(1.0F).normalize(); Vec3 digCenter = this.position() .add(forward.scale(1.0D)) - .add(0.0D, -0.5D, 0.0D); + .add(this.toWorld(0.0D, -0.5D, 0.0D)); double halfWidth = 0.9D; double digDepth = 1.5D; BlockPos min = BlockPos.containing(digCenter.x - halfWidth, digCenter.y - digDepth, digCenter.z - halfWidth); BlockPos max = BlockPos.containing(digCenter.x + halfWidth, digCenter.y + 0.4D, digCenter.z + halfWidth); - Vec3 hForward = forward.multiply(1.0D, 0.0D, 1.0D); + Vec3 hForward = this.toLocalPlane(forward); for (BlockPos pos : BlockPos.betweenClosed(min, max)) { BlockState state = this.level().getBlockState(pos); if (!state.is(AntarchyTags.Blocks.MOLEVORE_BREAKABLE_BLOCKS) || state.isAir()) { continue; } if (hForward.lengthSqr() > 1.0E-4D) { - Vec3 toBlock = Vec3.atCenterOf(pos).subtract(this.position()).multiply(1.0D, 0.0D, 1.0D); + Vec3 toBlock = this.toLocalPlane(Vec3.atCenterOf(pos).subtract(this.position())); if (toBlock.lengthSqr() > 1.0E-4D && hForward.normalize().dot(toBlock.normalize()) < -0.2D) { continue; } @@ -642,12 +653,12 @@ public class MolevoreEntity extends Monster implements GeoEntity { } Vec3 forward = direction.normalize(); - Vec3 center = this.position().add(forward.scale(range * 0.5D)).add(0.0D, this.getBbHeight() * 0.4D, 0.0D); + Vec3 center = this.position().add(forward.scale(range * 0.5D)).add(this.toWorld(0.0D, this.getBbHeight() * 0.4D, 0.0D)); BlockPos min = BlockPos.containing(center.x - halfWidth, center.y - verticalRange * 0.5D, center.z - halfWidth); BlockPos max = BlockPos.containing(center.x + halfWidth, center.y + verticalRange * 0.5D, center.z + halfWidth); boolean broke = false; - Vec3 hForward = forward.multiply(1.0D, 0.0D, 1.0D); + Vec3 hForward = this.toLocalPlane(forward); for (BlockPos pos : BlockPos.betweenClosed(min, max)) { BlockState state = this.level().getBlockState(pos); if (!state.is(AntarchyTags.Blocks.MOLEVORE_BREAKABLE_BLOCKS) || state.isAir()) { @@ -655,7 +666,7 @@ public class MolevoreEntity extends Monster implements GeoEntity { } Vec3 blockCenter = Vec3.atCenterOf(pos); - Vec3 toBlock = blockCenter.subtract(this.position()).multiply(1.0D, 0.0D, 1.0D); + Vec3 toBlock = this.toLocalPlane(blockCenter.subtract(this.position())); if (hForward.lengthSqr() > 1.0E-4D && toBlock.lengthSqr() > 1.0E-4D && hForward.normalize().dot(toBlock.normalize()) < -0.15D) { continue; @@ -668,14 +679,31 @@ public class MolevoreEntity extends Monster implements GeoEntity { } private boolean isInFront(Vec3 position, double minimumDot) { - Vec3 forward = this.getViewVector(1.0F).multiply(1.0D, 0.0D, 1.0D); - Vec3 toTarget = position.subtract(this.position()).multiply(1.0D, 0.0D, 1.0D); + Vec3 forward = this.toLocalPlane(this.getViewVector(1.0F)); + Vec3 toTarget = this.toLocalPlane(position.subtract(this.position())); if (forward.lengthSqr() < 1.0E-4D || toTarget.lengthSqr() < 1.0E-4D) { return true; } return forward.normalize().dot(toTarget.normalize()) >= minimumDot; } + private AntarchyGravityDirection gravityDirection() { + return AntarchyGravityApi.getGravityDirection(this); + } + + private Vec3 toWorld(double x, double y, double z) { + return AntarchyGravityRotationUtil.vecPlayerToWorld(x, y, z, this.gravityDirection()); + } + + private Vec3 toWorld(Vec3 localVector) { + return AntarchyGravityRotationUtil.vecPlayerToWorld(localVector, this.gravityDirection()); + } + + private Vec3 toLocalPlane(Vec3 worldVector) { + Vec3 local = AntarchyGravityRotationUtil.vecWorldToPlayer(worldVector, this.gravityDirection()); + return new Vec3(local.x, 0.0D, local.z); + } + private int getActionState() { return this.entityData.get(ACTION_STATE); } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/OuranwoodDeerEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/OuranwoodDeerEntity.java index b2876469..32631a33 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/OuranwoodDeerEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/OuranwoodDeerEntity.java @@ -3,6 +3,9 @@ package com.craisinlord.antarchy.content.entity; import com.craisinlord.antarchy.config.AntarchySettings; import com.craisinlord.antarchy.content.AntarchyObjects; import com.craisinlord.antarchy.content.AntarchyTags; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil; import java.util.EnumSet; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.syncher.EntityDataAccessor; @@ -222,7 +225,7 @@ public class OuranwoodDeerEntity extends Animal implements GeoEntity { } private PlayState mainAnimController(AnimationState state) { - double speedSqr = this.getDeltaMovement().horizontalDistanceSqr(); + double speedSqr = this.toLocal(this.getDeltaMovement()).horizontalDistanceSqr(); if (this.hurtTime > 0 || speedSqr > RUN_SPEED_THRESHOLD_SQR) { return state.setAndContinue(RUN_ANIM); } @@ -242,6 +245,14 @@ public class OuranwoodDeerEntity extends Animal implements GeoEntity { return MIN_QUIRK_COOLDOWN + this.random.nextInt(MAX_QUIRK_COOLDOWN - MIN_QUIRK_COOLDOWN + 1); } + private AntarchyGravityDirection gravityDirection() { + return AntarchyGravityApi.getGravityDirection(this); + } + + private Vec3 toLocal(Vec3 worldVector) { + return AntarchyGravityRotationUtil.vecWorldToPlayer(worldVector, this.gravityDirection()); + } + @Override public AnimatableInstanceCache getAnimatableInstanceCache() { return this.geoCache; diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/RollyPollyEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/RollyPollyEntity.java index b8ed3af7..3cf799eb 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/RollyPollyEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/RollyPollyEntity.java @@ -4,6 +4,9 @@ import com.craisinlord.antarchy.Antarchy; import com.craisinlord.antarchy.config.AntarchySettings; import com.craisinlord.antarchy.content.AntarchyTags; import com.craisinlord.antarchy.content.AntarchySoundEvents; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil; import java.util.EnumSet; import net.minecraft.core.BlockPos; @@ -111,14 +114,16 @@ public class RollyPollyEntity extends TamableAnimal implements GeoEntity { } BlockPos belowPos = pos.below(); + BlockPos abovePos = pos.above(); if (level.getDifficulty() == Difficulty.PEACEFUL) { return false; } return level.getBlockState(pos).isAir() - && level.getBlockState(pos.above()).isAir() + && (level.getBlockState(pos.above()).isAir() || level.getBlockState(pos.below()).isAir()) && level.getFluidState(pos).isEmpty() - && level.getFluidState(pos.above()).isEmpty() - && level.getBlockState(belowPos).isFaceSturdy(level, belowPos, Direction.UP); + && (level.getFluidState(pos.above()).isEmpty() || level.getFluidState(pos.below()).isEmpty()) + && (level.getBlockState(belowPos).isFaceSturdy(level, belowPos, Direction.UP) + || level.getBlockState(abovePos).isFaceSturdy(level, abovePos, Direction.DOWN)); } public static AttributeSupplier.Builder createAttributes() { @@ -347,7 +352,7 @@ public class RollyPollyEntity extends TamableAnimal implements GeoEntity { } private void tickRollSound() { - if (!this.isRolled() || this.rollTransitionTicks > 0 || this.getDeltaMovement().horizontalDistanceSqr() <= 0.003D) { + if (!this.isRolled() || this.rollTransitionTicks > 0 || this.toLocal(this.getDeltaMovement()).horizontalDistanceSqr() <= 0.003D) { this.rollSoundCooldown = 0; return; } @@ -700,9 +705,12 @@ public class RollyPollyEntity extends TamableAnimal implements GeoEntity { return; } - double dx = RollyPollyEntity.this.getX() - target.getX(); - double dz = RollyPollyEntity.this.getZ() - target.getZ(); - target.knockback(AntarchySettings.rollyPollyBowlingKnockback(), dx, dz); + Vec3 localAway = RollyPollyEntity.this.toLocalPlane(RollyPollyEntity.this.position().subtract(target.position())); + if (localAway.lengthSqr() < 1.0E-4D) { + localAway = new Vec3(1.0D, 0.0D, 0.0D); + } + Vec3 worldAway = RollyPollyEntity.this.toWorld(localAway.normalize()); + target.knockback(AntarchySettings.rollyPollyBowlingKnockback(), worldAway.x, worldAway.z); RollyPollyEntity.this.playSound(AntarchySoundEvents.ROLLY_POLLY_ROLL.get(), 1.0F, 0.8F + RollyPollyEntity.this.random.nextFloat() * 0.2F); } } @@ -848,8 +856,8 @@ public class RollyPollyEntity extends TamableAnimal implements GeoEntity { RollyPollyEntity.this.startUnroll(); } } else { - RollyPollyEntity.this.getNavigation().moveTo( - this.bedPos.getX() + 0.5D, this.bedPos.getY() + 1.0D, this.bedPos.getZ() + 0.5D, 1.1D); + Vec3 bedTarget = Vec3.atCenterOf(this.bedPos).add(RollyPollyEntity.this.toWorld(0.0D, 0.5D, 0.0D)); + RollyPollyEntity.this.getNavigation().moveTo(bedTarget.x, bedTarget.y, bedTarget.z, 1.1D); } return; } @@ -861,4 +869,25 @@ public class RollyPollyEntity extends TamableAnimal implements GeoEntity { } } } + + private AntarchyGravityDirection gravityDirection() { + return AntarchyGravityApi.getGravityDirection(this); + } + + private Vec3 toLocal(Vec3 worldVector) { + return AntarchyGravityRotationUtil.vecWorldToPlayer(worldVector, this.gravityDirection()); + } + + private Vec3 toWorld(Vec3 localVector) { + return AntarchyGravityRotationUtil.vecPlayerToWorld(localVector, this.gravityDirection()); + } + + private Vec3 toWorld(double x, double y, double z) { + return AntarchyGravityRotationUtil.vecPlayerToWorld(x, y, z, this.gravityDirection()); + } + + private Vec3 toLocalPlane(Vec3 worldVector) { + Vec3 local = this.toLocal(worldVector); + return new Vec3(local.x, 0.0D, local.z); + } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ScorpionEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ScorpionEntity.java index fa573daf..c037fcd5 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ScorpionEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ScorpionEntity.java @@ -2,6 +2,9 @@ package com.craisinlord.antarchy.content.entity; import com.craisinlord.antarchy.config.AntarchySettings; import com.craisinlord.antarchy.content.AntarchySoundEvents; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.syncher.EntityDataAccessor; @@ -195,13 +198,16 @@ public class ScorpionEntity extends Monster implements GeoEntity { } private void commitLunge(LivingEntity target, double horizontalSpeed, double verticalSpeed) { - Vec3 lunge = target.position().subtract(this.position()); - Vec3 horizontal = new Vec3(lunge.x, 0.0D, lunge.z); + AntarchyGravityDirection direction = AntarchyGravityApi.getGravityDirection(this); + Vec3 localLunge = AntarchyGravityRotationUtil.vecWorldToPlayer(target.position().subtract(this.position()), direction); + Vec3 horizontal = new Vec3(localLunge.x, 0.0D, localLunge.z); if (horizontal.lengthSqr() < 1.0E-4D) { return; } horizontal = horizontal.normalize().scale(horizontalSpeed); - this.setDeltaMovement(this.getDeltaMovement().add(horizontal.x, verticalSpeed, horizontal.z)); + Vec3 localImpulse = new Vec3(horizontal.x, verticalSpeed, horizontal.z); + Vec3 worldImpulse = AntarchyGravityRotationUtil.vecPlayerToWorld(localImpulse, direction); + this.setDeltaMovement(this.getDeltaMovement().add(worldImpulse.x, worldImpulse.y, worldImpulse.z)); this.hasImpulse = true; } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/SpitBugEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/SpitBugEntity.java index e7130b87..e62d83ae 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/SpitBugEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/SpitBugEntity.java @@ -3,6 +3,9 @@ package com.craisinlord.antarchy.content.entity; import com.craisinlord.antarchy.Antarchy; import com.craisinlord.antarchy.content.AntarchySoundEvents; import com.craisinlord.antarchy.content.damage.AntarchyDamageSources; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil; import net.minecraft.core.BlockPos; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.syncher.EntityDataAccessor; @@ -89,7 +92,7 @@ public class SpitBugEntity extends Monster implements GeoEntity { } return level.getDifficulty() != Difficulty.PEACEFUL && level.isEmptyBlock(pos) - && level.isEmptyBlock(pos.above()) + && (level.isEmptyBlock(pos.above()) || level.isEmptyBlock(pos.below())) && Monster.checkMonsterSpawnRules(entityType, level, spawnReason, pos, random); } @@ -221,7 +224,7 @@ public class SpitBugEntity extends Monster implements GeoEntity { SpitBugProjectileEntity projectile = new SpitBugProjectileEntity(projectileType, this, serverLevel); Vec3 origin = this.position() - .add(0.0D, this.getBbHeight() * 0.55D, 0.0D) + .add(this.toWorld(0.0D, this.getBbHeight() * 0.55D, 0.0D)) .add(this.getViewVector(0.0F).scale(1.35D)); Vec3 aimPoint = target.getEyePosition().add(target.getDeltaMovement().scale(0.45D)); Vec3 direction = aimPoint.subtract(origin).normalize(); @@ -232,6 +235,14 @@ public class SpitBugEntity extends Monster implements GeoEntity { this.playSound(AntarchySoundEvents.SPIT_BUG_SPIT.get(), 1.0F, 0.85F + this.random.nextFloat() * 0.15F); } + private AntarchyGravityDirection gravityDirection() { + return AntarchyGravityApi.getGravityDirection(this); + } + + private Vec3 toWorld(double x, double y, double z) { + return AntarchyGravityRotationUtil.vecPlayerToWorld(x, y, z, this.gravityDirection()); + } + private final class SpitAttackGoal extends Goal { SpitAttackGoal() { this.setFlags(EnumSet.of(Flag.MOVE, Flag.LOOK)); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/StinkBugEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/StinkBugEntity.java index cac976e1..322b3571 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/StinkBugEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/StinkBugEntity.java @@ -70,14 +70,16 @@ public class StinkBugEntity extends Animal implements GeoEntity { return true; } BlockPos belowPos = pos.below(); + BlockPos abovePos = pos.above(); if (level.getDifficulty() == Difficulty.PEACEFUL) { return false; } return level.getBlockState(pos).isAir() - && level.getBlockState(pos.above()).isAir() + && (level.getBlockState(pos.above()).isAir() || level.getBlockState(pos.below()).isAir()) && level.getFluidState(pos).isEmpty() - && level.getFluidState(pos.above()).isEmpty() - && level.getBlockState(belowPos).isFaceSturdy(level, belowPos, Direction.UP); + && (level.getFluidState(pos.above()).isEmpty() || level.getFluidState(pos.below()).isEmpty()) + && (level.getBlockState(belowPos).isFaceSturdy(level, belowPos, Direction.UP) + || level.getBlockState(abovePos).isFaceSturdy(level, abovePos, Direction.DOWN)); } @Override diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/WaspEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/WaspEntity.java index b48b9d83..35a2526d 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/WaspEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/WaspEntity.java @@ -3,6 +3,9 @@ package com.craisinlord.antarchy.content.entity; import com.craisinlord.antarchy.config.AntarchySettings; import com.craisinlord.antarchy.content.AntarchySoundEvents; import com.craisinlord.antarchy.content.block.entity.WaspNestBlockEntity; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil; import java.util.EnumSet; import java.util.Objects; import net.minecraft.core.BlockPos; @@ -100,7 +103,7 @@ public class WaspEntity extends Monster implements GeoEntity, FlyingAnimal { return level.getDifficulty() != Difficulty.PEACEFUL && level.isEmptyBlock(pos) - && level.isEmptyBlock(pos.above()); + && (level.isEmptyBlock(pos.above()) || level.isEmptyBlock(pos.below())); } @Override @@ -304,7 +307,7 @@ public class WaspEntity extends Monster implements GeoEntity, FlyingAnimal { @Override public Vec3 getLeashOffset() { - return new Vec3(0.0D, 0.2D, 0.0D); + return this.toWorld(0.0D, 0.2D, 0.0D); } public boolean isPandaVariant() { @@ -328,6 +331,14 @@ public class WaspEntity extends Monster implements GeoEntity, FlyingAnimal { return !this.onGround(); } + private AntarchyGravityDirection gravityDirection() { + return AntarchyGravityApi.getGravityDirection(this); + } + + private Vec3 toWorld(double x, double y, double z) { + return AntarchyGravityRotationUtil.vecPlayerToWorld(x, y, z, this.gravityDirection()); + } + private void realignHitbox() { double halfWidth = this.getBbWidth() * 0.5D; double height = this.getBbHeight(); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/AntTeleportHelper.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/AntTeleportHelper.java index a4ecee6c..3e713c36 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/AntTeleportHelper.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/AntTeleportHelper.java @@ -15,6 +15,7 @@ import net.minecraft.server.level.PlayerRespawnLogic; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundEvents; +import net.minecraft.util.Mth; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Mob; @@ -253,8 +254,12 @@ public final class AntTeleportHelper { return safeArrivalPos; } - BlockPos fallbackPos = player.adjustSpawnLocation(destination, preferredPos); - return Vec3.atBottomCenterOf(fallbackPos); + if (destination.hasChunkAt(preferredPos)) { + BlockPos fallbackPos = player.adjustSpawnLocation(destination, preferredPos); + return Vec3.atBottomCenterOf(fallbackPos); + } + + return Vec3.atBottomCenterOf(getClampedFallbackPosition(destination, preferredPos)); } @Nullable @@ -283,8 +288,10 @@ public final class AntTeleportHelper { } BlockPos searchPos = preferredPos.offset(xOffset, 0, zOffset); - addArrivalCandidate(candidates, destination.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, searchPos)); - addArrivalCandidate(candidates, destination.getHeightmapPos(Heightmap.Types.WORLD_SURFACE, searchPos)); + if (destination.hasChunkAt(searchPos)) { + addArrivalCandidate(candidates, destination.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, searchPos)); + addArrivalCandidate(candidates, destination.getHeightmapPos(Heightmap.Types.WORLD_SURFACE, searchPos)); + } } } } @@ -347,13 +354,22 @@ public final class AntTeleportHelper { @Nullable private static Vec3 tryFindSafeDismount(ServerPlayer player, ServerLevel destination, BlockPos candidate) { + if (!isSafeDismountAreaLoaded(destination, candidate)) { + return null; + } + Vec3 safePos = DismountHelper.findSafeDismountLocation(player.getType(), destination, candidate, true); if (safePos != null && isValidArrivalPosition(destination, safePos)) { return safePos; } for (Direction direction : Direction.Plane.HORIZONTAL) { - safePos = DismountHelper.findSafeDismountLocation(player.getType(), destination, candidate.relative(direction), true); + BlockPos offsetCandidate = candidate.relative(direction); + if (!isSafeDismountAreaLoaded(destination, offsetCandidate)) { + continue; + } + + safePos = DismountHelper.findSafeDismountLocation(player.getType(), destination, offsetCandidate, true); if (safePos != null && isValidArrivalPosition(destination, safePos)) { return safePos; } @@ -368,6 +384,31 @@ public final class AntTeleportHelper { } BlockPos standPos = BlockPos.containing(safePos); + if (!destination.hasChunkAt(standPos) || !destination.hasChunkAt(standPos.below())) { + return false; + } + return !destination.getBlockState(standPos.below()).is(Blocks.BEDROCK); } + + private static boolean isSafeDismountAreaLoaded(ServerLevel destination, BlockPos center) { + if (!destination.hasChunkAt(center) || !destination.hasChunkAt(center.above()) || !destination.hasChunkAt(center.below())) { + return false; + } + + for (Direction direction : Direction.Plane.HORIZONTAL) { + BlockPos offset = center.relative(direction); + if (!destination.hasChunkAt(offset) || !destination.hasChunkAt(offset.above()) || !destination.hasChunkAt(offset.below())) { + return false; + } + } + + return true; + } + + private static BlockPos getClampedFallbackPosition(ServerLevel destination, BlockPos preferredPos) { + int minY = destination.getMinBuildHeight() + 1; + int maxY = destination.getMaxBuildHeight() - 1; + return new BlockPos(preferredPos.getX(), Mth.clamp(preferredPos.getY(), minY, maxY), preferredPos.getZ()); + } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/brutalfly/BrutalflyEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/brutalfly/BrutalflyEntity.java index c87fc896..85b771e8 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/brutalfly/BrutalflyEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/brutalfly/BrutalflyEntity.java @@ -4,6 +4,8 @@ import com.craisinlord.antarchy.config.AntarchySettings; import com.craisinlord.antarchy.content.boss.BossCombatUtil; import com.craisinlord.antarchy.content.AntarchyObjects; import com.craisinlord.antarchy.content.AntarchySoundEvents; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil; import java.util.EnumSet; import java.util.Objects; import net.minecraft.core.BlockPos; @@ -568,7 +570,9 @@ public class BrutalflyEntity extends Monster implements GeoEntity { private boolean shouldSwipe(LivingEntity target, FightPhase phase) { double horizontalDistanceSqr = new Vec3(target.getX() - this.getX(), 0.0D, target.getZ() - this.getZ()).lengthSqr(); - boolean beneathBoss = horizontalDistanceSqr <= 16.0D && target.getY() <= this.getY() + 2.0D; + Vec3 localDelta = AntarchyGravityRotationUtil.vecWorldToPlayer(target.position().subtract(this.position()), AntarchyGravityApi.getGravityDirection(this)); + horizontalDistanceSqr = new Vec3(localDelta.x, 0.0D, localDelta.z).lengthSqr(); + boolean beneathBoss = horizontalDistanceSqr <= 16.0D && localDelta.y <= 2.0D; return beneathBoss || this.distanceToSqr(target) <= phase.swipeRangeSqr; } @@ -579,7 +583,7 @@ public class BrutalflyEntity extends Monster implements GeoEntity { } private void tickSwipe(LivingEntity target) { - Vec3 divePoint = target.position().add(0.0D, 1.0D, 0.0D); + Vec3 divePoint = target.position().add(AntarchyGravityRotationUtil.vecPlayerToWorld(0.0D, 1.0D, 0.0D, AntarchyGravityApi.getGravityDirection(this))); this.getMoveControl().setWantedPosition(divePoint.x, divePoint.y, divePoint.z, 1.45D); if (this.animationTicks == 8) { @@ -608,7 +612,7 @@ public class BrutalflyEntity extends Monster implements GeoEntity { dz = this.random.nextDouble() - 0.5D; } target.knockback(SWIPE_KNOCKBACK, -dx, -dz); - target.setDeltaMovement(target.getDeltaMovement().add(0.0D, 0.3D, 0.0D)); + target.setDeltaMovement(target.getDeltaMovement().add(AntarchyGravityRotationUtil.vecPlayerToWorld(0.0D, 0.3D, 0.0D, AntarchyGravityApi.getGravityDirection(this)))); } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/cloud_shark/CloudSharkEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/cloud_shark/CloudSharkEntity.java index fefd21d1..b55512d0 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/cloud_shark/CloudSharkEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/cloud_shark/CloudSharkEntity.java @@ -2,6 +2,9 @@ package com.craisinlord.antarchy.content.entity.cloud_shark; import com.craisinlord.antarchy.config.AntarchySettings; import com.craisinlord.antarchy.content.AntarchySoundEvents; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil; import net.minecraft.core.BlockPos; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.server.level.ServerLevel; @@ -121,7 +124,7 @@ public class CloudSharkEntity extends Monster implements GeoEntity { MobSpawnType spawnReason, BlockPos pos, RandomSource random) { return level.getDifficulty() != Difficulty.PEACEFUL && level.isEmptyBlock(pos) - && level.isEmptyBlock(pos.above()) + && (level.isEmptyBlock(pos.above()) || level.isEmptyBlock(pos.below())) && level.getFluidState(pos).isEmpty(); } @@ -303,15 +306,15 @@ public class CloudSharkEntity extends Monster implements GeoEntity { public boolean doHurtTarget(Entity target) { boolean hurt = super.doHurtTarget(target); if (hurt && target instanceof LivingEntity livingTarget) { - Vec3 push = livingTarget.position().subtract(this.position()); - Vec3 horizontal = new Vec3(push.x, 0.0D, push.z); - if (horizontal.lengthSqr() < 1.0E-4D) horizontal = this.getForward().multiply(1.0D, 0.0D, 1.0D); + Vec3 horizontal = this.toLocalPlane(livingTarget.position().subtract(this.position())); + if (horizontal.lengthSqr() < 1.0E-4D) horizontal = this.toLocalPlane(this.getForward()); if (horizontal.lengthSqr() < 1.0E-4D) horizontal = new Vec3(1.0D, 0.0D, 0.0D); horizontal = horizontal.normalize(); Vec3 sideways = new Vec3(-horizontal.z, 0.0D, horizontal.x); if (this.random.nextBoolean()) sideways = sideways.scale(-1.0D); Vec3 knockback = horizontal.scale(0.7D).add(sideways.scale(0.45D)); - livingTarget.push(knockback.x, 0.28D, knockback.z); + Vec3 worldKnockback = this.toWorld(knockback.x, 0.28D, knockback.z); + livingTarget.push(worldKnockback.x, worldKnockback.y, worldKnockback.z); this.playSound(AntarchySoundEvents.CLOUD_SHARK_BITE.get(), 1.0F, 0.85F + this.random.nextFloat() * 0.2F); } return hurt; @@ -366,7 +369,7 @@ public class CloudSharkEntity extends Monster implements GeoEntity { } boolean isFlyingAnim = this.getAnimationState() == ANIM_SWIM; - boolean isMoving = this.getDeltaMovement().horizontalDistanceSqr() > 0.0125D; + boolean isMoving = this.toLocal(this.getDeltaMovement()).horizontalDistanceSqr() > 0.0125D; if (!isFlyingAnim || !isMoving) { this.flySoundCooldown = 0; return; @@ -462,9 +465,10 @@ public class CloudSharkEntity extends Monster implements GeoEntity { if (this.diveCooldown > 0 || !this.hasLineOfSight(target)) return false; if (this.strafeTicks > Math.max(6, this.currentStrafeDuration / 2)) return false; double distanceToTarget = this.distanceToSqr(target); + double localHeight = this.toLocal(target.position().subtract(this.position())).y; return distanceToTarget >= 9.0D && distanceToTarget <= 144.0D - && this.getY() > target.getY() + 0.5D; + && localHeight < -0.5D; } private boolean canConnectDive(LivingEntity target) { @@ -479,27 +483,30 @@ public class CloudSharkEntity extends Monster implements GeoEntity { private Vec3 getStrafePoint(LivingEntity target) { double angle = this.tickCount * 0.18D * this.orbitDirection + this.currentStrafeAngleOffset; - double x = target.getX() + Math.cos(angle) * this.currentStrafeRadius; - double z = target.getZ() + Math.sin(angle) * this.currentStrafeRadius; - double y = target.getY() + this.currentStrafeHeightOffset - + Math.sin((this.tickCount + this.getId()) * 0.14D) * 0.5D; - return new Vec3(x, y, z); + Vec3 localOffset = new Vec3( + Math.cos(angle) * this.currentStrafeRadius, + this.currentStrafeHeightOffset + Math.sin((this.tickCount + this.getId()) * 0.14D) * 0.5D, + Math.sin(angle) * this.currentStrafeRadius + ); + return target.position().add(this.toWorld(localOffset)); } private Vec3 createRecoveryTarget(Vec3 strikeTarget) { double radius = this.currentStrafeRadius + 1.5D + this.random.nextDouble() * 1.2D; double angle = this.currentStrafeAngleOffset + (Math.PI / 2.0D) * this.orbitDirection; - double x = strikeTarget.x + Math.cos(angle) * radius; - double z = strikeTarget.z + Math.sin(angle) * radius; - double y = strikeTarget.y + 2.0D + this.random.nextDouble() * 1.2D; - return new Vec3(x, y, z); + Vec3 localOffset = new Vec3( + Math.cos(angle) * radius, + 2.0D + this.random.nextDouble() * 1.2D, + Math.sin(angle) * radius + ); + return strikeTarget.add(this.toWorld(localOffset)); } private Vec3 createDiveStrikeTarget(LivingEntity target) { Vec3 predictedOffset = target.getDeltaMovement().scale(5.0D); return target.position() .add(predictedOffset) - .add(0.0D, target.getBbHeight() * 0.45D, 0.0D); + .add(this.toWorld(0.0D, target.getBbHeight() * 0.45D, 0.0D)); } private Vec3 findPatrolTarget() { @@ -575,7 +582,7 @@ public class CloudSharkEntity extends Monster implements GeoEntity { } private void updateFlightRotation() { - Vec3 velocity = this.getDeltaMovement(); + Vec3 velocity = this.toLocal(this.getDeltaMovement()); if (velocity.horizontalDistanceSqr() > 1.0E-4D) { float targetYaw = (float) (Mth.atan2(velocity.z, velocity.x) * (180.0D / Math.PI)) - 90.0F; this.setYRot(Mth.approachDegrees(this.getYRot(), targetYaw, 8.0F)); @@ -589,6 +596,27 @@ public class CloudSharkEntity extends Monster implements GeoEntity { } } + private AntarchyGravityDirection gravityDirection() { + return AntarchyGravityApi.getGravityDirection(this); + } + + private Vec3 toLocal(Vec3 worldVector) { + return AntarchyGravityRotationUtil.vecWorldToPlayer(worldVector, this.gravityDirection()); + } + + private Vec3 toWorld(Vec3 localVector) { + return AntarchyGravityRotationUtil.vecPlayerToWorld(localVector, this.gravityDirection()); + } + + private Vec3 toWorld(double x, double y, double z) { + return AntarchyGravityRotationUtil.vecPlayerToWorld(x, y, z, this.gravityDirection()); + } + + private Vec3 toLocalPlane(Vec3 worldVector) { + Vec3 local = this.toLocal(worldVector); + return new Vec3(local.x, 0.0D, local.z); + } + private int nextStrafeDuration() { return STRAFE_MIN_TICKS + this.random.nextInt(STRAFE_MAX_TICKS - STRAFE_MIN_TICKS + 1); } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/nightmare/NightmareEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/nightmare/NightmareEntity.java index 9ec5d719..b30b0f5e 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/nightmare/NightmareEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/nightmare/NightmareEntity.java @@ -6,6 +6,9 @@ import com.craisinlord.antarchy.content.AntarchySoundEvents; import com.craisinlord.antarchy.content.AntarchyTags; import com.craisinlord.antarchy.content.boss.BossCombatUtil; import com.craisinlord.antarchy.content.damage.AntarchyDamageSources; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.particles.ParticleTypes; @@ -256,10 +259,10 @@ public class NightmareEntity extends Monster implements GeoEntity { } public static boolean canSpawn(EntityType entityType, ServerLevelAccessor level, MobSpawnType spawnReason, BlockPos pos, RandomSource random) { - boolean sturdy = level.getBlockState(pos.below()).isFaceSturdy(level, pos.below(), Direction.UP); boolean posEmpty = level.isEmptyBlock(pos); - boolean aboveEmpty = level.isEmptyBlock(pos.above()); - return level.getDifficulty() != Difficulty.PEACEFUL && sturdy && posEmpty && aboveEmpty; + boolean floorSpawn = level.getBlockState(pos.below()).isFaceSturdy(level, pos.below(), Direction.UP) && level.isEmptyBlock(pos.above()); + boolean ceilingSpawn = level.getBlockState(pos.above()).isFaceSturdy(level, pos.above(), Direction.DOWN) && level.isEmptyBlock(pos.below()); + return level.getDifficulty() != Difficulty.PEACEFUL && posEmpty && (floorSpawn || ceilingSpawn); } @Override @@ -730,21 +733,23 @@ public class NightmareEntity extends Monster implements GeoEntity { this.getNavigation().stop(); this.faceTowardTarget(target, 180.0F); Vec3 lungeTarget = this.shouldUseFlyingLocomotion() - ? new Vec3(target.getX(), this.getFlyingAttackTargetY(target), target.getZ()) + ? this.getFlyingAttackTargetPos(target) : target.getEyePosition(); Vec3 lunge = lungeTarget.subtract(this.getEyePosition()); if (lunge.lengthSqr() > 1.0E-4D) { - Vec3 normalized = lunge.normalize(); + AntarchyGravityDirection direction = this.gravityDirection(); + Vec3 normalized = AntarchyGravityRotationUtil.vecWorldToPlayer(lunge, direction).normalize(); double verticalBoost = this.shouldUseFlyingLocomotion() ? 0.34D : 0.18D; - Vec3 current = this.getDeltaMovement(); + Vec3 current = AntarchyGravityRotationUtil.vecWorldToPlayer(this.getDeltaMovement(), direction); double upward = this.shouldUseFlyingLocomotion() ? Math.max(normalized.y * verticalBoost, -0.08D) : normalized.y * verticalBoost; - this.setDeltaMovement( + this.setDeltaMovement(AntarchyGravityRotationUtil.vecPlayerToWorld( normalized.x * 0.85D, current.y * 0.18D + upward, - normalized.z * 0.85D - ); + normalized.z * 0.85D, + direction + )); this.hasImpulse = true; } } @@ -990,26 +995,27 @@ public class NightmareEntity extends Monster implements GeoEntity { } private void performAttackHit(@Nullable LivingEntity target) { - Vec3 forward = this.getViewVector(1.0F).multiply(1.0D, 0.0D, 1.0D); + Vec3 forward = this.getPlaneForward(this.getViewVector(1.0F)); if (forward.lengthSqr() < 1.0E-4D) { - float yawRadians = this.getYRot() * Mth.DEG_TO_RAD; - forward = new Vec3(-Mth.sin(yawRadians), 0.0D, Mth.cos(yawRadians)); + forward = this.toWorld(new Vec3(-Mth.sin(this.getYRot() * Mth.DEG_TO_RAD), 0.0D, Mth.cos(this.getYRot() * Mth.DEG_TO_RAD))); } if (forward.lengthSqr() < 1.0E-4D) { - forward = new Vec3(0.0D, 0.0D, 1.0D); + forward = this.toWorld(new Vec3(0.0D, 0.0D, 1.0D)); } forward = forward.normalize(); Vec3 strikeOrigin = this.position() - .add(0.0D, this.getBbHeight() * 0.55D, 0.0D) + .add(this.toWorld(new Vec3(0.0D, this.getBbHeight() * 0.55D, 0.0D))) .add(forward.scale(0.4D)); Vec3 strikeCenter = strikeOrigin .add(forward.scale(ATTACK_HIT_FORWARD_OFFSET)); + Vec3 strikeMin = strikeOrigin.add(this.toWorld(new Vec3(0.0D, ATTACK_HIT_MIN_Y_OFFSET, 0.0D))); + Vec3 strikeMax = strikeOrigin.add(this.toWorld(new Vec3(0.0D, ATTACK_HIT_MAX_Y_OFFSET, 0.0D))); AABB hitBox = new AABB( Math.min(strikeOrigin.x, strikeCenter.x) - ATTACK_HIT_HALF_WIDTH, - this.getBoundingBox().minY + ATTACK_HIT_MIN_Y_OFFSET, + Math.min(strikeMin.y, strikeMax.y), Math.min(strikeOrigin.z, strikeCenter.z) - ATTACK_HIT_HALF_WIDTH, Math.max(strikeOrigin.x, strikeCenter.x) + ATTACK_HIT_HALF_WIDTH, - this.getBoundingBox().minY + ATTACK_HIT_MAX_Y_OFFSET, + Math.max(strikeMin.y, strikeMax.y), Math.max(strikeOrigin.z, strikeCenter.z) + ATTACK_HIT_HALF_WIDTH ); List victims = new ArrayList<>(this.level().getEntitiesOfClass(LivingEntity.class, hitBox, this::canTargetEntity)); @@ -1041,17 +1047,20 @@ public class NightmareEntity extends Monster implements GeoEntity { if (victim.getBoundingBox().inflate(0.1D).intersects(hitBox)) { return true; } - Vec3 toVictim = victimCenter.subtract(this.position()).multiply(1.0D, 0.0D, 1.0D); - double forwardDistance = toVictim.dot(forward); + Vec3 localForward = this.toLocalPlane(forward); + Vec3 toVictim = this.toLocalPlane(victimCenter.subtract(this.position())); + double forwardDistance = toVictim.dot(localForward.normalize()); if (forwardDistance < 0.15D || forwardDistance > ATTACK_HIT_FORWARD_OFFSET + 1.25D) { return false; } - Vec3 lateral = toVictim.subtract(forward.scale(forwardDistance)); + Vec3 lateral = toVictim.subtract(localForward.normalize().scale(forwardDistance)); if (lateral.lengthSqr() > (ATTACK_HIT_HALF_WIDTH + 0.55D) * (ATTACK_HIT_HALF_WIDTH + 0.55D)) { return false; } - double minY = this.getBoundingBox().minY + ATTACK_HIT_MIN_Y_OFFSET; - double maxY = this.getBoundingBox().minY + ATTACK_HIT_MAX_Y_OFFSET + 0.4D; + Vec3 minOffset = this.toWorld(new Vec3(0.0D, ATTACK_HIT_MIN_Y_OFFSET, 0.0D)); + Vec3 maxOffset = this.toWorld(new Vec3(0.0D, ATTACK_HIT_MAX_Y_OFFSET + 0.4D, 0.0D)); + double minY = Math.min(this.position().y + minOffset.y, this.position().y + maxOffset.y); + double maxY = Math.max(this.position().y + minOffset.y, this.position().y + maxOffset.y); return victim.getBoundingBox().maxY >= minY && victim.getBoundingBox().minY <= maxY; } @@ -1088,14 +1097,67 @@ public class NightmareEntity extends Monster implements GeoEntity { } private void knockAway(LivingEntity target, double horizontalStrength, double verticalStrength) { - Vec3 direction = target.position().subtract(this.position()).multiply(1.0D, 0.0D, 1.0D); - if (direction.lengthSqr() < 1.0E-4D) direction = this.getViewVector(1.0F).multiply(1.0D, 0.0D, 1.0D); - if (direction.lengthSqr() < 1.0E-4D) direction = new Vec3(1.0D, 0.0D, 0.0D); - Vec3 push = direction.normalize().scale(horizontalStrength); - target.push(push.x, verticalStrength, push.z); + AntarchyGravityDirection direction = this.gravityDirection(); + Vec3 localDirection = this.toLocalPlane(target.position().subtract(this.position())); + if (localDirection.lengthSqr() < 1.0E-4D) localDirection = this.toLocalPlane(this.getViewVector(1.0F)); + if (localDirection.lengthSqr() < 1.0E-4D) localDirection = new Vec3(1.0D, 0.0D, 0.0D); + Vec3 localPush = localDirection.normalize().scale(horizontalStrength); + Vec3 worldPush = AntarchyGravityRotationUtil.vecPlayerToWorld(localPush.x, verticalStrength, localPush.z, direction); + target.push(worldPush.x, worldPush.y, worldPush.z); target.hurtMarked = true; } + private AntarchyGravityDirection gravityDirection() { + return AntarchyGravityApi.getGravityDirection(this); + } + + private Vec3 toLocal(Vec3 worldVector) { + return AntarchyGravityRotationUtil.vecWorldToPlayer(worldVector, this.gravityDirection()); + } + + private Vec3 toWorld(Vec3 localVector) { + return AntarchyGravityRotationUtil.vecPlayerToWorld(localVector, this.gravityDirection()); + } + + private Vec3 toLocalPlane(Vec3 worldVector) { + Vec3 local = this.toLocal(worldVector); + return new Vec3(local.x, 0.0D, local.z); + } + + private Vec3 localDeltaTo(Vec3 worldPosition) { + return this.toLocal(worldPosition.subtract(this.position())); + } + + private double verticalDistanceTo(LivingEntity target) { + return Math.abs(this.toLocal(target.getEyePosition().subtract(this.getEyePosition())).y); + } + + private double overheadGapTo(LivingEntity target) { + return -this.localDeltaTo(target.position()).y; + } + + private Vec3 getPlaneForward(Vec3 worldVector) { + Vec3 local = this.toLocalPlane(worldVector); + if (local.lengthSqr() < 1.0E-4D) { + return Vec3.ZERO; + } + return this.toWorld(local.normalize()); + } + + private Vec3 getLocalRight(Vec3 worldForward) { + Vec3 localForward = this.toLocalPlane(worldForward); + if (localForward.lengthSqr() < 1.0E-4D) { + return Vec3.ZERO; + } + Vec3 normalized = localForward.normalize(); + return this.toWorld(new Vec3(-normalized.z, 0.0D, normalized.x)); + } + + private Vec3 getFlyingAttackTargetPos(LivingEntity target) { + double targetHeight = Mth.clamp(target.getBbHeight() * 0.4D, FLYING_ATTACK_MIN_TARGET_HEIGHT, FLYING_ATTACK_BODY_TARGET_HEIGHT); + return target.position().add(this.toWorld(new Vec3(0.0D, targetHeight, 0.0D))); + } + private DamageSource nightmareDamageSource() { return this.level() instanceof ServerLevel serverLevel ? AntarchyDamageSources.nightmareMauling(serverLevel, this) @@ -1103,13 +1165,9 @@ public class NightmareEntity extends Monster implements GeoEntity { } private boolean tryBreakBlocksToTarget(LivingEntity target) { - int startY = Mth.floor(this.getY()); - int endY = Math.max(Mth.floor(target.getY()), startY - 16); - int x = Mth.floor(this.getX()); - int z = Mth.floor(this.getZ()); - BlockPos.MutableBlockPos cursor = new BlockPos.MutableBlockPos(); - for (int y = startY; y >= endY; y--) { - cursor.set(x, y, z); + Direction gravityDown = AntarchyGravityRotationUtil.getGravityDownDirection(this); + BlockPos.MutableBlockPos cursor = this.blockPosition().mutable(); + for (int i = 0; i <= 16; i++) { if (this.level().getBlockState(cursor).is(AntarchyTags.Blocks.NIGHTMARE_BREAKABLE)) { if (this.blockBreakCooldown <= 0) { this.level().destroyBlock(cursor.immutable(), true, this); @@ -1118,6 +1176,7 @@ public class NightmareEntity extends Monster implements GeoEntity { this.getMoveControl().setWantedPosition(this.getX(), this.getY(), this.getZ(), 0.0D); return true; } + cursor.move(gravityDown); } return false; } @@ -1134,9 +1193,9 @@ public class NightmareEntity extends Monster implements GeoEntity { private boolean canStartAttackOn(LivingEntity target) { if (!this.hasLineOfSight(target) || this.distanceToSqr(target) > ATTACK_START_RANGE_SQR) return false; double hdSqr = this.horizontalDistanceToSqr(target); - double verticalDistance = Math.abs(target.getEyeY() - this.getEyeY()); + double verticalDistance = this.verticalDistanceTo(target); if (this.shouldUseFlyingLocomotion()) { - double overheadGap = this.getY() - target.getY(); + double overheadGap = this.overheadGapTo(target); return hdSqr <= ATTACK_COMMIT_HORIZONTAL_RANGE_SQR && verticalDistance <= 2.5D && overheadGap <= FLYING_ATTACK_MAX_OVERHEAD_COMMIT_HEIGHT; @@ -1153,9 +1212,9 @@ public class NightmareEntity extends Monster implements GeoEntity { return true; } double distanceSqr = this.distanceToSqr(target); - double verticalDistance = Math.abs(target.getEyeY() - this.getEyeY()); + double verticalDistance = this.verticalDistanceTo(target); double horizontalDistanceSqr = this.horizontalDistanceToSqr(target); - double overheadGap = this.getY() - target.getY(); + double overheadGap = this.overheadGapTo(target); if (lowProfileTarget && horizontalDistanceSqr <= LOW_PROFILE_FLIGHT_DISENGAGE_RANGE_SQR && verticalDistance <= LOW_PROFILE_FLIGHT_DISENGAGE_VERTICAL @@ -1179,24 +1238,23 @@ public class NightmareEntity extends Monster implements GeoEntity { } private Vec3 getFlightApproachPosition(LivingEntity target) { - Vec3 toTarget = target.position().subtract(this.position()).multiply(1.0D, 0.0D, 1.0D); - if (toTarget.lengthSqr() < 1.0E-4D) { - toTarget = target.getLookAngle().multiply(1.0D, 0.0D, 1.0D); + Vec3 forward = this.getPlaneForward(target.position().subtract(this.position())); + if (forward.lengthSqr() < 1.0E-4D) { + forward = this.getPlaneForward(target.getLookAngle()); } - if (toTarget.lengthSqr() < 1.0E-4D) { - toTarget = this.getViewVector(1.0F).multiply(1.0D, 0.0D, 1.0D); + if (forward.lengthSqr() < 1.0E-4D) { + forward = this.getPlaneForward(this.getViewVector(1.0F)); } - if (toTarget.lengthSqr() < 1.0E-4D) { - toTarget = new Vec3(0.0D, 0.0D, 1.0D); + if (forward.lengthSqr() < 1.0E-4D) { + forward = this.toWorld(new Vec3(0.0D, 0.0D, 1.0D)); } - Vec3 forward = toTarget.normalize(); - Vec3 right = new Vec3(-forward.z, 0.0D, forward.x); + Vec3 right = this.getLocalRight(forward); double strafe = this.tickCount % 32 < 16 ? FLYING_APPROACH_STRAFE_OFFSET : -FLYING_APPROACH_STRAFE_OFFSET; double height = this.isPhaseTwo() ? FLYING_APPROACH_HEIGHT_PHASE_TWO : FLYING_APPROACH_HEIGHT; double horizontalDistanceSqr = this.horizontalDistanceToSqr(target); - double overheadGap = this.getY() - target.getY(); + double overheadGap = this.overheadGapTo(target); boolean lowProfileTarget = this.isLowProfileFlightTarget(target); - double attackTargetY = this.getFlyingAttackTargetY(target); + Vec3 attackTarget = this.getFlyingAttackTargetPos(target); Vec3 anchor = target.position().subtract(forward.scale(1.8D)).add(right.scale(strafe)); if (horizontalDistanceSqr <= FLYING_OVERHEAD_STALL_RANGE_SQR && overheadGap >= FLYING_OVERHEAD_STALL_HEIGHT) { double sideOffset = lowProfileTarget ? LOW_PROFILE_OVERHEAD_DESCENT_SIDE_OFFSET : FLYING_OVERHEAD_DESCENT_SIDE_OFFSET; @@ -1204,26 +1262,26 @@ public class NightmareEntity extends Monster implements GeoEntity { anchor = target.position() .add(right.scale(strafe > 0.0D ? sideOffset : -sideOffset)) .subtract(forward.scale(backOffset)); - return new Vec3(anchor.x, attackTargetY, anchor.z); + return new Vec3(anchor.x, attackTarget.y, anchor.z); } if (horizontalDistanceSqr <= FLYING_APPROACH_TOO_CLOSE_RANGE_SQR) { double backOffset = lowProfileTarget ? LOW_PROFILE_TOO_CLOSE_BACK_OFFSET : 2.8D; double strafeScale = lowProfileTarget ? LOW_PROFILE_TOO_CLOSE_STRAFE_SCALE : 0.6D; anchor = target.position().subtract(forward.scale(backOffset)).add(right.scale(strafe * strafeScale)); } - return new Vec3(anchor.x, attackTargetY + height, anchor.z); + Vec3 elevated = attackTarget.add(this.toWorld(new Vec3(0.0D, height, 0.0D))); + return new Vec3(anchor.x, elevated.y, anchor.z); } private Vec3 getFlightDescentPosition(LivingEntity target) { - Vec3 toTarget = target.position().subtract(this.position()).multiply(1.0D, 0.0D, 1.0D); - if (toTarget.lengthSqr() < 1.0E-4D) { - toTarget = this.getViewVector(1.0F).multiply(1.0D, 0.0D, 1.0D); + Vec3 forward = this.getPlaneForward(target.position().subtract(this.position())); + if (forward.lengthSqr() < 1.0E-4D) { + forward = this.getPlaneForward(this.getViewVector(1.0F)); } - if (toTarget.lengthSqr() < 1.0E-4D) { - toTarget = new Vec3(0.0D, 0.0D, 1.0D); + if (forward.lengthSqr() < 1.0E-4D) { + forward = this.toWorld(new Vec3(0.0D, 0.0D, 1.0D)); } - Vec3 forward = toTarget.normalize(); - Vec3 right = new Vec3(-forward.z, 0.0D, forward.x); + Vec3 right = this.getLocalRight(forward); double side = this.tickCount % 20 < 10 ? 1.0D : -1.0D; boolean lowProfileTarget = this.isLowProfileFlightTarget(target); double sideOffset = lowProfileTarget ? 1.15D : 0.9D; @@ -1231,33 +1289,29 @@ public class NightmareEntity extends Monster implements GeoEntity { Vec3 anchor = target.position() .subtract(forward.scale(backOffset)) .add(right.scale(side * sideOffset)); - return new Vec3(anchor.x, this.getFlyingAttackTargetY(target), anchor.z); + return new Vec3(anchor.x, this.getFlyingAttackTargetPos(target).y, anchor.z); } private boolean isLowProfileFlightTarget(LivingEntity target) { return target.getBbHeight() <= LOW_PROFILE_TARGET_MAX_HEIGHT; } - private double getFlyingAttackTargetY(LivingEntity target) { - double targetHeight = Mth.clamp(target.getBbHeight() * 0.4D, FLYING_ATTACK_MIN_TARGET_HEIGHT, FLYING_ATTACK_BODY_TARGET_HEIGHT); - return target.getY() + targetHeight; - } - private double horizontalDistanceToSqr(LivingEntity target) { - double dx = target.getX() - this.getX(); - double dz = target.getZ() - this.getZ(); + Vec3 delta = this.localDeltaTo(target.position()); + double dx = delta.x; + double dz = delta.z; return dx * dx + dz * dz; } private boolean isInFront(Vec3 position, double minimumDot) { - Vec3 forward = this.getViewVector(1.0F).multiply(1.0D, 0.0D, 1.0D); - Vec3 toTarget = position.subtract(this.position()).multiply(1.0D, 0.0D, 1.0D); + Vec3 forward = this.toLocalPlane(this.getViewVector(1.0F)); + Vec3 toTarget = this.toLocalPlane(position.subtract(this.position())); if (forward.lengthSqr() < 1.0E-4D || toTarget.lengthSqr() < 1.0E-4D) return true; return forward.normalize().dot(toTarget.normalize()) >= minimumDot; } private void faceTowardTarget(LivingEntity target, float maxTurnDegrees) { - Vec3 toTarget = target.getEyePosition().subtract(this.getEyePosition()); + Vec3 toTarget = this.toLocal(target.getEyePosition().subtract(this.getEyePosition())); double horizontal = Math.sqrt(toTarget.x * toTarget.x + toTarget.z * toTarget.z); if (horizontal > 1.0E-4D) { float targetYaw = (float) (Mth.atan2(toTarget.z, toTarget.x) * (180.0D / Math.PI)) - 90.0F; @@ -1273,35 +1327,41 @@ public class NightmareEntity extends Monster implements GeoEntity { } private boolean isTooCloseToCeiling() { - BlockPos current = BlockPos.containing(this.getX(), this.getY(), this.getZ()); + Direction gravityUp = AntarchyGravityRotationUtil.getGravityDownDirection(this).getOpposite(); + BlockPos current = this.blockPosition(); for (int i = 1; i <= FLIGHT_CEILING_CLEARANCE_BLOCKS; i++) { - if (!this.level().isEmptyBlock(current.above(i))) return true; + if (!this.level().isEmptyBlock(current.relative(gravityUp, i))) return true; } return false; } private Vec3 getPortalEntryPosition() { - return this.position().add(this.getViewVector(1.0F).multiply(1.6D, 0.0D, 1.6D)); + Vec3 forward = this.getPlaneForward(this.getViewVector(1.0F)); + if (forward.lengthSqr() < 1.0E-4D) { + forward = this.toWorld(new Vec3(0.0D, 0.0D, 1.0D)); + } + return this.position().add(forward.scale(1.6D)); } @Nullable private Vec3 findPortalExitPos(LivingEntity target, Vec3 entryPos) { - Vec3 forward = target.getLookAngle().multiply(1.0D, 0.0D, 1.0D); + Vec3 forward = this.getPlaneForward(target.getLookAngle()); if (forward.lengthSqr() < 1.0E-4D) { - forward = this.getViewVector(1.0F).multiply(1.0D, 0.0D, 1.0D); + forward = this.getPlaneForward(this.getViewVector(1.0F)); } if (forward.lengthSqr() < 1.0E-4D) { - forward = new Vec3(0.0D, 0.0D, 1.0D); + forward = this.toWorld(new Vec3(0.0D, 0.0D, 1.0D)); } forward = forward.normalize(); - Vec3 right = new Vec3(-forward.z, 0.0D, forward.x); + Vec3 right = this.getLocalRight(forward); + Vec3 airOffset = this.toWorld(new Vec3(0.0D, PORTAL_EXIT_AIR_HEIGHT, 0.0D)); Vec3[] candidates = new Vec3[] { target.position().subtract(forward.scale(PORTAL_EXIT_OFFSET)), - target.position().subtract(forward.scale(PORTAL_EXIT_OFFSET)).add(0.0D, PORTAL_EXIT_AIR_HEIGHT, 0.0D), + target.position().subtract(forward.scale(PORTAL_EXIT_OFFSET)).add(airOffset), target.position().subtract(forward.scale(PORTAL_EXIT_OFFSET)).add(right.scale(PORTAL_EXIT_SIDE_OFFSET)), target.position().subtract(forward.scale(PORTAL_EXIT_OFFSET)).subtract(right.scale(PORTAL_EXIT_SIDE_OFFSET)), - target.position().subtract(forward.scale(PORTAL_EXIT_OFFSET)).add(right.scale(PORTAL_EXIT_SIDE_OFFSET)).add(0.0D, PORTAL_EXIT_AIR_HEIGHT, 0.0D), - target.position().subtract(forward.scale(PORTAL_EXIT_OFFSET)).subtract(right.scale(PORTAL_EXIT_SIDE_OFFSET)).add(0.0D, PORTAL_EXIT_AIR_HEIGHT, 0.0D) + target.position().subtract(forward.scale(PORTAL_EXIT_OFFSET)).add(right.scale(PORTAL_EXIT_SIDE_OFFSET)).add(airOffset), + target.position().subtract(forward.scale(PORTAL_EXIT_OFFSET)).subtract(right.scale(PORTAL_EXIT_SIDE_OFFSET)).add(airOffset) }; for (Vec3 candidate : candidates) { Vec3 adjusted = this.findValidPortalPosition(candidate); @@ -1318,7 +1378,7 @@ public class NightmareEntity extends Monster implements GeoEntity { private Vec3 findValidPortalPosition(Vec3 base) { EntityDimensions dimensions = this.getType().getDimensions(); for (int yOffset = 4; yOffset >= -3; yOffset--) { - Vec3 candidate = new Vec3(base.x, base.y + yOffset, base.z); + Vec3 candidate = base.add(this.toWorld(new Vec3(0.0D, yOffset, 0.0D))); AABB box = dimensions.makeBoundingBox(candidate); if (this.level().noCollision(this, box)) { return candidate; @@ -1351,7 +1411,7 @@ public class NightmareEntity extends Monster implements GeoEntity { } private void updateFlightRotation() { - Vec3 velocity = this.getDeltaMovement(); + Vec3 velocity = this.toLocal(this.getDeltaMovement()); if (velocity.horizontalDistanceSqr() > 1.0E-4D) { float targetYaw = (float) (Mth.atan2(velocity.z, velocity.x) * (180.0D / Math.PI)) - 90.0F; float nextYaw = Mth.approachDegrees(this.getYRot(), targetYaw, 4.0F); @@ -1392,7 +1452,7 @@ public class NightmareEntity extends Monster implements GeoEntity { this.tickWingFlapSound(); return; } - Vec3 horizontalVelocity = this.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D); + Vec3 horizontalVelocity = this.toLocalPlane(this.getDeltaMovement()); if (horizontalVelocity.lengthSqr() > ANIMATION_MOVEMENT_THRESHOLD_SQR) { this.groundMoveTicks = 6; } @@ -1617,11 +1677,11 @@ public class NightmareEntity extends Monster implements GeoEntity { return; } if (NightmareEntity.this.onGround() && NightmareEntity.this.distanceToSqr(target) >= FLIGHT_DISENGAGE_RANGE_SQR) { - NightmareEntity.this.setDeltaMovement(NightmareEntity.this.getDeltaMovement().add(0.0D, 0.38D, 0.0D)); + NightmareEntity.this.setDeltaMovement(NightmareEntity.this.getDeltaMovement().add(NightmareEntity.this.toWorld(new Vec3(0.0D, 0.38D, 0.0D)))); NightmareEntity.this.hasImpulse = true; } double horizontalDistanceSqr = NightmareEntity.this.horizontalDistanceToSqr(target); - double overheadGap = NightmareEntity.this.getY() - target.getY(); + double overheadGap = NightmareEntity.this.overheadGapTo(target); if (horizontalDistanceSqr <= ATTACK_COMMIT_HORIZONTAL_RANGE_SQR && overheadGap > FLYING_ATTACK_MAX_OVERHEAD_COMMIT_HEIGHT) { Vec3 descentPos = NightmareEntity.this.getFlightDescentPosition(target); @@ -1681,7 +1741,7 @@ public class NightmareEntity extends Monster implements GeoEntity { LivingEntity target = NightmareEntity.this.getTarget(); if (target != null) { double hdSqr = NightmareEntity.this.horizontalDistanceToSqr(target); - double vertDelta = NightmareEntity.this.getY() - target.getY(); + double vertDelta = NightmareEntity.this.overheadGapTo(target); if (target.onGround() && hdSqr <= 25.0D && vertDelta > 1.6D) { NightmareEntity.this.tryBreakBlocksToTarget(target); } @@ -1716,9 +1776,11 @@ public class NightmareEntity extends Monster implements GeoEntity { if (NightmareEntity.this.random.nextInt(40) != 0) return false; double angle = NightmareEntity.this.random.nextDouble() * Math.PI * 2; double dist = 4 + NightmareEntity.this.random.nextDouble() * 10; - this.x = NightmareEntity.this.getX() + Math.cos(angle) * dist; - this.z = NightmareEntity.this.getZ() + Math.sin(angle) * dist; - this.y = NightmareEntity.this.getY(); + Vec3 localOffset = new Vec3(Math.cos(angle) * dist, 0.0D, Math.sin(angle) * dist); + Vec3 worldOffset = NightmareEntity.this.toWorld(localOffset); + this.x = NightmareEntity.this.getX() + worldOffset.x; + this.y = NightmareEntity.this.getY() + worldOffset.y; + this.z = NightmareEntity.this.getZ() + worldOffset.z; return true; } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/gravity/AntarchyGravityApi.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/gravity/AntarchyGravityApi.java index 6301b5bf..d36901f9 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/gravity/AntarchyGravityApi.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/gravity/AntarchyGravityApi.java @@ -1,6 +1,7 @@ package com.craisinlord.antarchy.content.gravity; import net.minecraft.world.entity.Entity; +import net.minecraft.world.phys.Vec3; public final class AntarchyGravityApi { public interface GravitySyncDispatcher { @@ -99,6 +100,122 @@ public final class AntarchyGravityApi { syncDispatcher.onGravityStateChanged(entity); } + public static Vec3 getWorldVelocity(Entity entity) { + return AntarchyGravityRotationUtil.vecPlayerToWorld(entity.getDeltaMovement(), getGravityDirection(entity)); + } + + public static void setWorldVelocity(Entity entity, Vec3 worldVelocity) { + entity.setDeltaMovement(AntarchyGravityRotationUtil.vecWorldToPlayer(worldVelocity, getGravityDirection(entity))); + } + + public static Vec3 getEyeOffset(Entity entity) { + return AntarchyGravityRotationUtil.getEyeOffset(entity, entity.getEyeHeight()); + } + + public static double eyeX(Entity entity) { + return isGravityInverted(entity) ? entity.getEyePosition().x : entity.getX(); + } + + public static double eyeY(Entity entity) { + return isGravityInverted(entity) ? entity.getEyePosition().y : entity.getY(); + } + + public static double eyeZ(Entity entity) { + return isGravityInverted(entity) ? entity.getEyePosition().z : entity.getZ(); + } + + public static Vec3 deltaMovement(net.minecraft.world.entity.LivingEntity target) { + return isGravityInverted(target) ? getWorldVelocity(target) : target.getDeltaMovement(); + } + + public static double projectileSpawnX(net.minecraft.world.entity.LivingEntity shooter) { + return projectileSpawnVec(shooter).x; + } + + public static double projectileSpawnY(net.minecraft.world.entity.LivingEntity shooter) { + return projectileSpawnVec(shooter).y; + } + + public static double projectileSpawnZ(net.minecraft.world.entity.LivingEntity shooter) { + return projectileSpawnVec(shooter).z; + } + + public static double rangedBodyTargetX(net.minecraft.world.entity.LivingEntity target) { + if (!isGravityInverted(target)) { + return target.getX(); + } + return target.position().add(AntarchyGravityRotationUtil.vecPlayerToWorld( + 0.0D, + target.getBbHeight() * 0.3333333333333333D, + 0.0D, + getGravityDirection(target) + )).x; + } + + public static double rangedBodyTargetY(net.minecraft.world.entity.LivingEntity target, double heightScale) { + if (!isGravityInverted(target)) { + return target.getY(heightScale); + } + return target.position().add(AntarchyGravityRotationUtil.vecPlayerToWorld( + 0.0D, + target.getBbHeight() * 0.3333333333333333D, + 0.0D, + getGravityDirection(target) + )).y; + } + + public static double rangedBodyTargetZ(net.minecraft.world.entity.LivingEntity target) { + if (!isGravityInverted(target)) { + return target.getZ(); + } + return target.position().add(AntarchyGravityRotationUtil.vecPlayerToWorld( + 0.0D, + target.getBbHeight() * 0.3333333333333333D, + 0.0D, + getGravityDirection(target) + )).z; + } + + public static double rangedEyeTargetX(net.minecraft.world.entity.LivingEntity target) { + if (!isGravityInverted(target)) { + return target.getX(); + } + return target.position().add(AntarchyGravityRotationUtil.vecPlayerToWorld( + 0.0D, + target.getEyeHeight() - 1.100000023841858D, + 0.0D, + getGravityDirection(target) + )).x; + } + + public static double rangedEyeTargetY(net.minecraft.world.entity.LivingEntity target) { + if (!isGravityInverted(target)) { + return target.getEyeY(); + } + return target.position().add(AntarchyGravityRotationUtil.vecPlayerToWorld( + 0.0D, + target.getEyeHeight() - 1.100000023841858D, + 0.0D, + getGravityDirection(target) + )).y + 1.100000023841858D; + } + + public static double rangedEyeTargetZ(net.minecraft.world.entity.LivingEntity target) { + if (!isGravityInverted(target)) { + return target.getZ(); + } + return target.position().add(AntarchyGravityRotationUtil.vecPlayerToWorld( + 0.0D, + target.getEyeHeight() - 1.100000023841858D, + 0.0D, + getGravityDirection(target) + )).z; + } + + public static double rangedSqrt(double value, net.minecraft.world.entity.LivingEntity target) { + return isGravityInverted(target) ? Math.sqrt(Math.sqrt(value)) : Math.sqrt(value); + } + private static AntarchyGravityAccess access(Entity entity) { if (entity instanceof AntarchyGravityAccess access) { return access; @@ -106,4 +223,12 @@ public final class AntarchyGravityApi { throw new IllegalStateException("Entity " + entity + " is missing Antarchy gravity state"); } + + private static Vec3 projectileSpawnVec(net.minecraft.world.entity.LivingEntity shooter) { + AntarchyGravityDirection direction = getGravityDirection(shooter); + if (!direction.isInverted()) { + return new Vec3(shooter.getX(), shooter.getEyeY() - 0.1D, shooter.getZ()); + } + return shooter.getEyePosition().subtract(AntarchyGravityRotationUtil.vecPlayerToWorld(0.0D, 0.1D, 0.0D, direction)); + } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/gravity/GravityWalkNodeEvaluator.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/gravity/GravityWalkNodeEvaluator.java index 66f88121..4b689e59 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/gravity/GravityWalkNodeEvaluator.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/gravity/GravityWalkNodeEvaluator.java @@ -12,6 +12,7 @@ import net.minecraft.world.level.pathfinder.WalkNodeEvaluator; public class GravityWalkNodeEvaluator extends WalkNodeEvaluator { private static final Logger LOGGER = LoggerFactory.getLogger("Antarchy/Pathfinding"); + private static final int[] START_Y_SEARCH = {0, 1, -1, 2, -2, 3, -3, 4, -4}; private static final int[][] INVERTED_NEIGHBOR_OFFSETS = { {1, 0, 0}, {-1, 0, 0}, @@ -68,10 +69,10 @@ public class GravityWalkNodeEvaluator extends WalkNodeEvaluator { int x = Mth.floor(this.mob.getX()); int z = Mth.floor(this.mob.getZ()); int y = Mth.floor(this.mob.getY() + this.mob.getBbHeight()) - 1; - - Node node = this.getNode(x, y, z); - node.type = PathType.WALKABLE; - node.costMalus = this.mob.getPathfindingMalus(PathType.WALKABLE); + Node node = this.antarchy$findStartNode(x, y, z); + if (node == null) { + return super.getStart(); + } if (this.antarchy$loggedGetStart < 8) { LOGGER.debug( @@ -89,6 +90,43 @@ public class GravityWalkNodeEvaluator extends WalkNodeEvaluator { return node; } + private Node antarchy$findStartNode(int x, int y, int z) { + for (int dy : START_Y_SEARCH) { + int candidateY = y + dy; + for (int dx = -1; dx <= 1; dx++) { + for (int dz = -1; dz <= 1; dz++) { + Node node = this.antarchy$createStartNode(x + dx, candidateY, z + dz); + if (node != null) { + return node; + } + } + } + } + return null; + } + + private Node antarchy$createStartNode(int x, int y, int z) { + if (!this.antarchy$hasCeilingSupport(x, y, z)) { + return null; + } + + PathType type = this.getPathTypeOfMob(this.currentContext, x, y, z, this.mob); + float malus = this.mob.getPathfindingMalus(type); + if (malus < 0.0F || type == PathType.OPEN) { + return null; + } + + Node node = this.getNode(x, y, z); + node.type = type; + node.costMalus = malus; + return node; + } + + private boolean antarchy$hasCeilingSupport(int x, int y, int z) { + PathType ceilingType = this.getPathType(this.currentContext, x, y + 1, z); + return this.mob.getPathfindingMalus(ceilingType) < 0.0F; + } + @Override public PathType getPathTypeOfMob(PathfindingContext context, int x, int y, int z, Mob mob) { if (!AntarchyGravityApi.isGravityInverted(mob)) { diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalTeleporter.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalTeleporter.java index a27bb465..3c4e586a 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalTeleporter.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalTeleporter.java @@ -125,8 +125,10 @@ public final class PermanentPortalTeleporter { } BlockPos horizontalPos = preferredPos.offset(xOff, 0, zOff); - addCandidate(candidates, destination.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, horizontalPos)); - addCandidate(candidates, destination.getHeightmapPos(Heightmap.Types.WORLD_SURFACE, horizontalPos)); + if (destination.hasChunkAt(horizontalPos)) { + addCandidate(candidates, destination.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, horizontalPos)); + addCandidate(candidates, destination.getHeightmapPos(Heightmap.Types.WORLD_SURFACE, horizontalPos)); + } for (int yOff = 0; yOff <= VERTICAL_SEARCH; yOff++) { addCandidate(candidates, horizontalPos.above(yOff)); if (yOff > 0) { @@ -184,13 +186,22 @@ public final class PermanentPortalTeleporter { @Nullable private static Vec3 tryFindSafePosition(Entity entity, ServerLevel destination, BlockPos candidate) { + if (!isSafeDismountAreaLoaded(destination, candidate)) { + return null; + } + Vec3 safe = DismountHelper.findSafeDismountLocation(entity.getType(), destination, candidate, true); if (safe != null && isValidArrivalPosition(destination, safe)) { return safe; } for (Direction direction : Direction.Plane.HORIZONTAL) { - safe = DismountHelper.findSafeDismountLocation(entity.getType(), destination, candidate.relative(direction), true); + BlockPos offsetCandidate = candidate.relative(direction); + if (!isSafeDismountAreaLoaded(destination, offsetCandidate)) { + continue; + } + + safe = DismountHelper.findSafeDismountLocation(entity.getType(), destination, offsetCandidate, true); if (safe != null && isValidArrivalPosition(destination, safe)) { return safe; } @@ -281,11 +292,30 @@ public final class PermanentPortalTeleporter { BlockPos standPos = BlockPos.containing(safePos); if (destination.dimension() == AntarchySettings.termiteDestinationDimension() || destination.dimension() == AntarchySettings.redAntDestinationDimension()) { + if (!destination.hasChunkAt(standPos) || !destination.hasChunkAt(standPos.below())) { + return false; + } + return !destination.getBlockState(standPos.below()).is(net.minecraft.world.level.block.Blocks.BEDROCK); } return true; } + private static boolean isSafeDismountAreaLoaded(ServerLevel destination, BlockPos center) { + if (!destination.hasChunkAt(center) || !destination.hasChunkAt(center.above()) || !destination.hasChunkAt(center.below())) { + return false; + } + + for (Direction direction : Direction.Plane.HORIZONTAL) { + BlockPos offset = center.relative(direction); + if (!destination.hasChunkAt(offset) || !destination.hasChunkAt(offset.above()) || !destination.hasChunkAt(offset.below())) { + return false; + } + } + + return true; + } + @Nullable private static Entity moveEntity(Entity entity, DimensionTransition transition) { ServerLevel destination = transition.newLevel(); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/AntarchyMixinPlugin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/AntarchyMixinPlugin.java index c804109e..e6202b3a 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/AntarchyMixinPlugin.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/AntarchyMixinPlugin.java @@ -11,6 +11,8 @@ import org.spongepowered.asm.mixin.extensibility.IMixinInfo; * Mixin plugin for compat-gated mixins and optional deps. */ public final class AntarchyMixinPlugin implements IMixinConfigPlugin { + private static final AntarchyRangedAttackPatcher RANGED_ATTACK_PATCHER = new AntarchyRangedAttackPatcher(); + @Override public void onLoad(String mixinPackage) { Mixins.registerErrorHandlerClass(AntarchyMixinErrorHandler.class.getName()); @@ -51,5 +53,6 @@ public final class AntarchyMixinPlugin implements IMixinConfigPlugin { @Override public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { + RANGED_ATTACK_PATCHER.patch(targetClass); } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/AntarchyRangedAttackPatcher.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/AntarchyRangedAttackPatcher.java new file mode 100644 index 00000000..4b7d628d --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/AntarchyRangedAttackPatcher.java @@ -0,0 +1,227 @@ +package com.craisinlord.antarchy.mixins; + +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.AbstractInsnNode; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.InsnList; +import org.objectweb.asm.tree.MethodInsnNode; +import org.objectweb.asm.tree.MethodNode; +import org.objectweb.asm.tree.VarInsnNode; + +final class AntarchyRangedAttackPatcher { + private static final String RANGED_ATTACK_DESC = "(Lnet/minecraft/world/entity/LivingEntity;F)V"; + private static final String LIVING_DESC = "(Lnet/minecraft/world/entity/LivingEntity;)D"; + private static final String LIVING_D_DESC = "(Lnet/minecraft/world/entity/LivingEntity;D)D"; + private static final String D_LIVING_DESC = "(DLnet/minecraft/world/entity/LivingEntity;)D"; + private static final String DELTA_MOVEMENT_DESC = "(Lnet/minecraft/world/entity/LivingEntity;)Lnet/minecraft/world/phys/Vec3;"; + private static final String API_OWNER = "com/craisinlord/antarchy/content/gravity/AntarchyGravityApi"; + + private enum AimMode { + BODY, + EYE + } + + int patch(ClassNode classNode) { + int total = 0; + for (MethodNode method : classNode.methods) { + if (!RANGED_ATTACK_DESC.equals(method.desc)) { + continue; + } + if (!isPerformRangedAttack(method.name)) { + continue; + } + if (!hasRangedAimSqrt(method)) { + continue; + } + total += applyPatch(method); + } + return total; + } + + private boolean isPerformRangedAttack(String methodName) { + return "performRangedAttack".equals(methodName) + || "m_6504_".equals(methodName) + || "m_31448_".equals(methodName) + || "m_31457_".equals(methodName); + } + + private boolean hasRangedAimSqrt(MethodNode method) { + for (AbstractInsnNode insn = method.instructions.getFirst(); insn != null; insn = insn.getNext()) { + if (insn instanceof MethodInsnNode call + && call.getOpcode() == Opcodes.INVOKESTATIC + && "java/lang/Math".equals(call.owner) + && "sqrt".equals(call.name) + && "(D)D".equals(call.desc)) { + return true; + } + } + return false; + } + + private AimMode detectAimMode(MethodNode method) { + for (AbstractInsnNode insn = method.instructions.getFirst(); insn != null; insn = insn.getNext()) { + if (!(insn instanceof MethodInsnNode call)) { + continue; + } + int opcode = call.getOpcode(); + if (opcode != Opcodes.INVOKEVIRTUAL && opcode != Opcodes.INVOKEINTERFACE) { + continue; + } + if (isGetYScaled(call)) { + return AimMode.BODY; + } + } + return AimMode.EYE; + } + + private int applyPatch(MethodNode method) { + AimMode mode = detectAimMode(method); + int total = 0; + int ordX = 0; + int ordZ = 0; + int ordYScaled = 0; + int ordEyeY = 0; + InsnList list = method.instructions; + for (AbstractInsnNode cur = list.getFirst(); cur != null; cur = cur.getNext()) { + if (!(cur instanceof MethodInsnNode call)) { + continue; + } + int opcode = call.getOpcode(); + if (opcode != Opcodes.INVOKEVIRTUAL && opcode != Opcodes.INVOKEINTERFACE) { + continue; + } + if (isGetX(call)) { + if (ordX++ != 0) { + continue; + } + list.set(cur, new MethodInsnNode( + Opcodes.INVOKESTATIC, + API_OWNER, + mode == AimMode.BODY ? "rangedBodyTargetX" : "rangedEyeTargetX", + LIVING_DESC, + false + )); + total++; + continue; + } + if (isGetZ(call)) { + if (ordZ++ != 0) { + continue; + } + list.set(cur, new MethodInsnNode( + Opcodes.INVOKESTATIC, + API_OWNER, + mode == AimMode.BODY ? "rangedBodyTargetZ" : "rangedEyeTargetZ", + LIVING_DESC, + false + )); + total++; + continue; + } + if (mode == AimMode.BODY && isGetYScaled(call)) { + if (ordYScaled++ != 0) { + continue; + } + list.set(cur, new MethodInsnNode( + Opcodes.INVOKESTATIC, + API_OWNER, + "rangedBodyTargetY", + LIVING_D_DESC, + false + )); + total++; + continue; + } + if (mode == AimMode.EYE && isGetEyeY(call)) { + if (ordEyeY++ != 0) { + continue; + } + list.set(cur, new MethodInsnNode( + Opcodes.INVOKESTATIC, + API_OWNER, + "rangedEyeTargetY", + LIVING_DESC, + false + )); + total++; + } + } + total += patchSqrtAndDelta(method); + return total; + } + + private int patchSqrtAndDelta(MethodNode method) { + int total = 0; + InsnList list = method.instructions; + for (AbstractInsnNode cur = list.getFirst(); cur != null; cur = cur.getNext()) { + if (!(cur instanceof MethodInsnNode call)) { + continue; + } + if ((call.getOpcode() == Opcodes.INVOKEVIRTUAL || call.getOpcode() == Opcodes.INVOKEINTERFACE) + && isGetDeltaMovement(call) + && isAload1(previousSignificant(cur))) { + list.set(cur, new MethodInsnNode( + Opcodes.INVOKESTATIC, + API_OWNER, + "deltaMovement", + DELTA_MOVEMENT_DESC, + false + )); + total++; + continue; + } + if (call.getOpcode() == Opcodes.INVOKESTATIC + && "java/lang/Math".equals(call.owner) + && "sqrt".equals(call.name) + && "(D)D".equals(call.desc)) { + list.insertBefore(cur, new VarInsnNode(Opcodes.ALOAD, 1)); + list.set(cur, new MethodInsnNode( + Opcodes.INVOKESTATIC, + API_OWNER, + "rangedSqrt", + D_LIVING_DESC, + false + )); + total++; + } + } + return total; + } + + private boolean isGetX(MethodInsnNode call) { + return "()D".equals(call.desc) && ("getX".equals(call.name) || "m_20185_".equals(call.name)); + } + + private boolean isGetZ(MethodInsnNode call) { + return "()D".equals(call.desc) && ("getZ".equals(call.name) || "m_20189_".equals(call.name)); + } + + private boolean isGetYScaled(MethodInsnNode call) { + return "(D)D".equals(call.desc) && ("getY".equals(call.name) || "m_20227_".equals(call.name)); + } + + private boolean isGetEyeY(MethodInsnNode call) { + return "()D".equals(call.desc) && ("getEyeY".equals(call.name) || "m_20188_".equals(call.name)); + } + + private boolean isGetDeltaMovement(MethodInsnNode call) { + return "()Lnet/minecraft/world/phys/Vec3;".equals(call.desc) + && ("getDeltaMovement".equals(call.name) || "m_20184_".equals(call.name)); + } + + private boolean isAload1(AbstractInsnNode insn) { + return insn instanceof VarInsnNode varInsn && varInsn.getOpcode() == Opcodes.ALOAD && varInsn.var == 1; + } + + private AbstractInsnNode previousSignificant(AbstractInsnNode node) { + AbstractInsnNode previous = node.getPrevious(); + while (previous != null) { + int type = previous.getType(); + if (type != AbstractInsnNode.LABEL && type != AbstractInsnNode.LINE) { + return previous; + } + previous = previous.getPrevious(); + } + return null; + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/AbstractArrowGravityMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/AbstractArrowGravityMixin.java index a5402726..86dba05e 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/AbstractArrowGravityMixin.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/AbstractArrowGravityMixin.java @@ -5,7 +5,7 @@ import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection; import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil; import com.craisinlord.antarchy.config.AntarchySettings; import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.projectile.AbstractArrow; import net.minecraft.world.phys.Vec3; import org.spongepowered.asm.mixin.Mixin; @@ -21,10 +21,12 @@ public abstract class AbstractArrowGravityMixin { @ModifyVariable(method = "tick", at = @At(value = "STORE"), ordinal = 0) private Vec3 antarchy$fixArrowGravityDroop(Vec3 velocity) { AbstractArrow self = (AbstractArrow) (Object) this; - if (!AntarchySettings.invertProjectilesFromInvertedPlayers()) return velocity; Entity owner = self.getOwner(); - if (!(owner instanceof Player player)) return velocity; - AntarchyGravityDirection direction = AntarchyGravityApi.getGravityDirection(player); + if (!(owner instanceof LivingEntity living)) return velocity; + if (owner instanceof net.minecraft.world.entity.player.Player && !AntarchySettings.invertProjectilesFromInvertedPlayers()) { + return velocity; + } + AntarchyGravityDirection direction = AntarchyGravityApi.getGravityDirection(living); if (!direction.isInverted()) return velocity; velocity = new Vec3(velocity.x, velocity.y + 0.05D, velocity.z); velocity = AntarchyGravityRotationUtil.vecWorldToPlayer(velocity, direction); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/BehaviorUtilsGravityMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/BehaviorUtilsGravityMixin.java new file mode 100644 index 00000000..4c7a89e3 --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/BehaviorUtilsGravityMixin.java @@ -0,0 +1,68 @@ +package com.craisinlord.antarchy.mixins.gravity; + +import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi; +import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.llamalad7.mixinextras.sugar.Local; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.behavior.BehaviorUtils; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.Vec3; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(BehaviorUtils.class) +public abstract class BehaviorUtilsGravityMixin { + @WrapOperation( + method = "throwItem(Lnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/phys/Vec3;F)V", + at = @At( + value = "NEW", + target = "(Lnet/minecraft/world/level/Level;DDDLnet/minecraft/world/item/ItemStack;)Lnet/minecraft/world/entity/item/ItemEntity;" + ) + ) + private static ItemEntity antarchy$fixThrownItemSpawn( + Level level, + double x, + double y, + double z, + ItemStack stack, + Operation original, + @Local float yOffset, + @Local LivingEntity entity + ) { + if (!AntarchyGravityApi.isGravityInverted(entity)) { + return original.call(level, x, y, z, stack); + } + + Vec3 eyeOffset = AntarchyGravityRotationUtil.getEyeOffset(entity, entity.getEyeHeight()); + Vec3 offset = eyeOffset.normalize().scale(yOffset); + Vec3 itemPos = entity.position().add(eyeOffset).subtract(offset); + ItemEntity itemEntity = original.call(level, itemPos.x(), itemPos.y(), itemPos.z(), stack); + AntarchyGravityApi.setGravityDirection(itemEntity, AntarchyGravityApi.getGravityDirection(entity)); + return itemEntity; + } + + @WrapOperation( + method = "throwItem(Lnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/phys/Vec3;F)V", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/entity/item/ItemEntity;setDeltaMovement(Lnet/minecraft/world/phys/Vec3;)V" + ) + ) + private static void antarchy$fixThrownItemVelocity( + ItemEntity itemEntity, + Vec3 deltaMovement, + Operation original, + @Local LivingEntity entity + ) { + if (!AntarchyGravityApi.isGravityInverted(entity)) { + original.call(itemEntity, deltaMovement); + return; + } + + AntarchyGravityApi.setWorldVelocity(itemEntity, deltaMovement); + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/CrossbowItemGravityMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/CrossbowItemGravityMixin.java index 2381dc47..ee7ebbe3 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/CrossbowItemGravityMixin.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/CrossbowItemGravityMixin.java @@ -7,7 +7,6 @@ import com.craisinlord.antarchy.config.AntarchySettings; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.CrossbowItem; import net.minecraft.world.phys.Vec3; import org.spongepowered.asm.mixin.Mixin; @@ -25,7 +24,7 @@ public abstract class CrossbowItemGravityMixin { at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;getX()D", ordinal = 0)) private static double antarchy$fixCrossbowSpawnX(LivingEntity shooter, Operation original) { - if (!AntarchySettings.invertProjectilesFromInvertedPlayers() || !(shooter instanceof Player)) return original.call(shooter); + if (!antarchy$shouldFixProjectileSpawn(shooter)) return original.call(shooter); AntarchyGravityDirection direction = AntarchyGravityApi.getGravityDirection(shooter); if (!direction.isInverted()) return original.call(shooter); Vec3 offset = AntarchyGravityRotationUtil.vecPlayerToWorld(0.0D, BOLT_OFFSET, 0.0D, direction); @@ -36,7 +35,7 @@ public abstract class CrossbowItemGravityMixin { at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;getEyeY()D", ordinal = 0)) private static double antarchy$fixCrossbowSpawnY(LivingEntity shooter, Operation original) { - if (!AntarchySettings.invertProjectilesFromInvertedPlayers() || !(shooter instanceof Player)) return original.call(shooter); + if (!antarchy$shouldFixProjectileSpawn(shooter)) return original.call(shooter); AntarchyGravityDirection direction = AntarchyGravityApi.getGravityDirection(shooter); if (!direction.isInverted()) return original.call(shooter); Vec3 offset = AntarchyGravityRotationUtil.vecPlayerToWorld(0.0D, BOLT_OFFSET, 0.0D, direction); @@ -47,10 +46,15 @@ public abstract class CrossbowItemGravityMixin { at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;getZ()D", ordinal = 0)) private static double antarchy$fixCrossbowSpawnZ(LivingEntity shooter, Operation original) { - if (!AntarchySettings.invertProjectilesFromInvertedPlayers() || !(shooter instanceof Player)) return original.call(shooter); + if (!antarchy$shouldFixProjectileSpawn(shooter)) return original.call(shooter); AntarchyGravityDirection direction = AntarchyGravityApi.getGravityDirection(shooter); if (!direction.isInverted()) return original.call(shooter); Vec3 offset = AntarchyGravityRotationUtil.vecPlayerToWorld(0.0D, BOLT_OFFSET, 0.0D, direction); return shooter.getEyePosition().subtract(offset).z; } + + private static boolean antarchy$shouldFixProjectileSpawn(LivingEntity shooter) { + return !(shooter instanceof net.minecraft.world.entity.player.Player) + || AntarchySettings.invertProjectilesFromInvertedPlayers(); + } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/EntityGravityFrameMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/EntityGravityFrameMixin.java index 63efe599..4854d607 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/EntityGravityFrameMixin.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/EntityGravityFrameMixin.java @@ -51,6 +51,18 @@ public abstract class EntityGravityFrameMixin { cir.setReturnValue(entity.position().add(AntarchyGravityRotationUtil.getEyeOffset(entity, entity.getEyeHeight())).y); } + @Inject(method = "getY(D)D", at = @At("HEAD"), cancellable = true) + private void antarchy$fixScaledY(double scale, CallbackInfoReturnable cir) { + Entity entity = (Entity) (Object) this; + AntarchyGravityDirection direction = AntarchyGravityApi.getGravityDirection(entity); + if (!direction.isInverted()) { + return; + } + cir.setReturnValue(entity.position().add( + AntarchyGravityRotationUtil.vecPlayerToWorld(0.0D, entity.getBbHeight() * scale, 0.0D, direction) + ).y); + } + @Inject(method = "getEyePosition()Lnet/minecraft/world/phys/Vec3;", at = @At("HEAD"), cancellable = true) private void antarchy$fixEyePosition(CallbackInfoReturnable cir) { Entity entity = (Entity) (Object) this; diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/GroundPathNavigationMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/GroundPathNavigationMixin.java index c643f810..2c6a226f 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/GroundPathNavigationMixin.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/gravity/GroundPathNavigationMixin.java @@ -21,16 +21,14 @@ public abstract class GroundPathNavigationMixin { @Inject(method = "createPathFinder", at = @At("HEAD"), cancellable = true) private void antarchy$useGravityEvaluator(int maxVisitedNodes, CallbackInfoReturnable cir) { var mob = ((PathNavigationAccessor) (Object) this).antarchy$getMob(); - if (!AntarchyGravityApi.isGravityInverted(mob)) { - return; + if (AntarchyGravityApi.isGravityInverted(mob)) { + LOGGER.debug( + "[Path] swap evaluator mob={} maxVisitedNodes={}", + mob.getClass().getSimpleName(), + maxVisitedNodes + ); } - LOGGER.debug( - "[Path] swap evaluator mob={} maxVisitedNodes={}", - mob.getClass().getSimpleName(), - maxVisitedNodes - ); - cir.setReturnValue(new PathFinder(new GravityWalkNodeEvaluator(), maxVisitedNodes)); } } diff --git a/common-1.21.1/src/main/resources/antarchy-common.mixins.json b/common-1.21.1/src/main/resources/antarchy-common.mixins.json index f4307548..948c2d00 100644 --- a/common-1.21.1/src/main/resources/antarchy-common.mixins.json +++ b/common-1.21.1/src/main/resources/antarchy-common.mixins.json @@ -46,6 +46,7 @@ "TigerEyeCamouflageMixin", "TigerEyeVisibilityMixin", "gravity.AbstractArrowGravityMixin", + "gravity.BehaviorUtilsGravityMixin", "gravity.BucketItemGravityMixin", "gravity.ChunkMapAccessor", "gravity.CrossbowItemGravityMixin", diff --git a/common-1.21.1/src/main/resources/assets/antarchy/sounds/music/game/elythia/idyll.ogg b/common-1.21.1/src/main/resources/assets/antarchy/sounds/music/game/elythia/idyll.ogg new file mode 100644 index 00000000..aca6e786 Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/sounds/music/game/elythia/idyll.ogg differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/sounds/records/underside.ogg b/common-1.21.1/src/main/resources/assets/antarchy/sounds/records/underside.ogg new file mode 100644 index 00000000..e30e654e Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/sounds/records/underside.ogg differ diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/a_lovely_world.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/a_lovely_world.json index d490ace1..aff9ec92 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/a_lovely_world.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/a_lovely_world.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:visit_elythia", "criteria": { "discover_stampys_house": { "conditions": { diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/anger_the_hive_mind.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/anger_the_hive_mind.json new file mode 100644 index 00000000..0b31a7ed --- /dev/null +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/anger_the_hive_mind.json @@ -0,0 +1,36 @@ +{ + "parent": "antarchy:visit_cavaryn", + "criteria": { + "kill_horde_common": { + "conditions": { + "entity": { + "type": { + "tag": "antarchy:horde_common" + } + } + }, + "trigger": "minecraft:player_killed_entity" + } + }, + "display": { + "announce_to_chat": true, + "description": { + "text": "Kill one of Cavaryn's horde-common creatures" + }, + "frame": "task", + "icon": { + "count": 1, + "id": "antarchy:creeping_horror_spawn_egg" + }, + "show_toast": true, + "title": { + "text": "Anger the Hive Mind" + } + }, + "requirements": [ + [ + "kill_horde_common" + ] + ], + "sends_telemetry_event": true +} diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/ant_arch_of_elythia.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/ant_arch_of_elythia.json new file mode 100644 index 00000000..e19595ba --- /dev/null +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/ant_arch_of_elythia.json @@ -0,0 +1,58 @@ +{ + "parent": "antarchy:visit_elythia", + "criteria": { + "kill_basilisk": { + "conditions": { + "entity": { + "type": "antarchy:basilisk" + } + }, + "trigger": "minecraft:player_killed_entity" + }, + "kill_toreterror": { + "conditions": { + "entity": { + "type": "antarchy:toreterror" + } + }, + "trigger": "minecraft:player_killed_entity" + }, + "obtain_brutalfly_elytra": { + "conditions": { + "items": [ + { + "items": "antarchy:brutalfly_elytra" + } + ] + }, + "trigger": "minecraft:inventory_changed" + } + }, + "display": { + "announce_to_chat": true, + "description": { + "text": "Defeat Basilisk, Toreterror, and Brutalfly to claim mastery of Elythia" + }, + "frame": "challenge", + "icon": { + "count": 1, + "id": "antarchy:brutalfly_elytra" + }, + "show_toast": true, + "title": { + "text": "Ant-arch of Elythia" + } + }, + "requirements": [ + [ + "kill_basilisk" + ], + [ + "kill_toreterror" + ], + [ + "obtain_brutalfly_elytra" + ] + ], + "sends_telemetry_event": true +} diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/apple_of_my_eye.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/apple_of_my_eye.json index da282d0d..65b0a56e 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/apple_of_my_eye.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/apple_of_my_eye.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:visit_elythia", "criteria": { "impossible": { "trigger": "minecraft:impossible" diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/beetle_buddies.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/beetle_buddies.json index 1df7e2a0..e5837da4 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/beetle_buddies.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/beetle_buddies.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:anger_the_hive_mind", "criteria": { "tame_hercules_beetle": { "conditions": { diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/behavioral_correction.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/behavioral_correction.json index 4b6e4d2a..f8a7ed03 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/behavioral_correction.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/behavioral_correction.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:herculean_task", "criteria": { "obtain_attitude_adjuster": { "conditions": { @@ -24,7 +24,7 @@ }, "show_toast": true, "title": { - "translate": "advancements.antarchy.behavioral_correction.title" + "text": "Ant-ger Management" } }, "requirements": [ diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/brutalfly.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/brutalfly.json index 9f6cc42f..6cf7e04a 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/brutalfly.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/brutalfly.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:visit_elythia", "criteria": { "brutalfly": { "conditions": { diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/bug_apetit.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/bug_apetit.json index fe7e3477..c76db0e8 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/bug_apetit.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/bug_apetit.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:anger_the_hive_mind", "criteria": { "eat_cooked_bug_meat": { "conditions": { diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/bugged_out.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/bugged_out.json index b89e1637..a3f500bf 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/bugged_out.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/bugged_out.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:visit_elythia", "criteria": { "kill_alpha_mantis": { "conditions": { diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/challenge_games.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/challenge_games.json index c5db58d6..10510c63 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/challenge_games.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/challenge_games.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:visit_elythia", "criteria": { "discover_ruined_arena": { "conditions": { diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/cops_n_robbers.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/cops_n_robbers.json index 56822396..00a17b4a 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/cops_n_robbers.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/cops_n_robbers.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:visit_elythia", "criteria": { "discover_ruined_prison": { "conditions": { diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/deerly_beloved.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/deerly_beloved.json index f0c07944..3ac0b74d 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/deerly_beloved.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/deerly_beloved.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:visit_elythia", "criteria": { "impossible": { "trigger": "minecraft:impossible" diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/dont_let_the_bed_bugs_bite.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/dont_let_the_bed_bugs_bite.json index 18d4c0a0..d7724e5a 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/dont_let_the_bed_bugs_bite.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/dont_let_the_bed_bugs_bite.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:visit_thoraxis", "criteria": { "kill_bed_bug": { "conditions": { diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/elkcellent_choice.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/elkcellent_choice.json index 924d3655..294cc956 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/elkcellent_choice.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/elkcellent_choice.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:visit_elythia", "criteria": { "impossible": { "trigger": "minecraft:impossible" diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/fallen_kingdom_castle.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/fallen_kingdom_castle.json index dde5987a..98ff40ab 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/fallen_kingdom_castle.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/fallen_kingdom_castle.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:visit_elythia", "criteria": { "discover_castle": { "conditions": { diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/gravity_gun_craft.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/gravity_gun_craft.json index 5767a80a..4c612dc1 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/gravity_gun_craft.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/gravity_gun_craft.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:visit_thoraxis", "criteria": { "craft_gravity_gun": { "conditions": { diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/herculean_task.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/herculean_task.json index 4299904f..70dc5d59 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/herculean_task.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/herculean_task.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:anger_the_hive_mind", "criteria": { "kill_hercules_beetle": { "conditions": { diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/hey_listen.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/hey_listen.json index 61057b6e..8d624e78 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/hey_listen.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/hey_listen.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:visit_thoraxis", "criteria": { "impossible": { "trigger": "minecraft:impossible" diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/hoppy_together.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/hoppy_together.json index db152869..9d5bdb62 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/hoppy_together.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/hoppy_together.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:visit_elythia", "criteria": { "impossible": { "trigger": "minecraft:impossible" diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/i_am_the_nightmare.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/i_am_the_nightmare.json new file mode 100644 index 00000000..8d5a8a76 --- /dev/null +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/i_am_the_nightmare.json @@ -0,0 +1,61 @@ +{ + "parent": "antarchy:visit_thoraxis", + "criteria": { + "kill_emperor_scorpion": { + "conditions": { + "entity": { + "type": "antarchy:emperor_scorpion" + } + }, + "trigger": "minecraft:player_killed_entity" + }, + "kill_lucid": { + "conditions": { + "entity": { + "type": "antarchy:lucid" + } + }, + "trigger": "minecraft:player_killed_entity" + }, + "kill_nightmare": { + "conditions": { + "entity": { + "type": "antarchy:nightmare" + } + }, + "trigger": "minecraft:player_killed_entity" + } + }, + "display": { + "announce_to_chat": true, + "description": { + "text": "Defeat Emperor Scorpion, Lucid, and Nightmare" + }, + "frame": "challenge", + "icon": { + "count": 1, + "id": "minecraft:potion", + "components": { + "minecraft:potion_contents": { + "potion": "antarchy:dread" + } + } + }, + "show_toast": true, + "title": { + "text": "I Am the Nightmare" + } + }, + "requirements": [ + [ + "kill_emperor_scorpion" + ], + [ + "kill_lucid" + ], + [ + "kill_nightmare" + ] + ], + "sends_telemetry_event": true +} diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/in_the_upside_down.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/in_the_upside_down.json index 22000057..e1f2e4aa 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/in_the_upside_down.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/in_the_upside_down.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:visit_thoraxis", "criteria": { "become_inverted": { "conditions": { diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/kill_toreterror.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/kill_toreterror.json index 8a19a910..040750d4 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/kill_toreterror.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/kill_toreterror.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:visit_elythia", "criteria": { "kill_toreterror": { "conditions": { diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/lucid_dreams.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/lucid_dreams.json index a29635fd..3793958b 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/lucid_dreams.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/lucid_dreams.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:visit_thoraxis", "criteria": { "kill_lucid": { "conditions": { diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/moley_poley.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/moley_poley.json index 25b1c358..844c93b3 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/moley_poley.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/moley_poley.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:anger_the_hive_mind", "criteria": { "kill_molevore": { "conditions": { diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/now_watch_me_whip.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/now_watch_me_whip.json index 1a1d87de..9e066933 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/now_watch_me_whip.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/now_watch_me_whip.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:sting_operation", "criteria": { "now_watch_me_whip": { "conditions": { diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/shark_weak.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/shark_weak.json index 00079069..66b5ab4c 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/shark_weak.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/shark_weak.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:visit_elythia", "criteria": { "kill_cloud_shark": { "conditions": { diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/soups_up.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/soups_up.json index 7594279e..1ca68d32 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/soups_up.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/soups_up.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:shark_weak", "criteria": { "eat_soup": { "conditions": { diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/spirant_animal.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/spirant_animal.json index 87c986a6..9b9508b5 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/spirant_animal.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/spirant_animal.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:visit_elythia", "criteria": { "impossible": { "trigger": "minecraft:impossible" diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/sting_operation.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/sting_operation.json new file mode 100644 index 00000000..40fdb1fa --- /dev/null +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/sting_operation.json @@ -0,0 +1,34 @@ +{ + "parent": "antarchy:visit_thoraxis", + "criteria": { + "kill_emperor_scorpion": { + "conditions": { + "entity": { + "type": "antarchy:emperor_scorpion" + } + }, + "trigger": "minecraft:player_killed_entity" + } + }, + "display": { + "announce_to_chat": true, + "description": { + "text": "Defeat the Emperor Scorpion" + }, + "frame": "challenge", + "icon": { + "count": 1, + "id": "antarchy:emperor_scorpion_spawn_egg" + }, + "show_toast": true, + "title": { + "text": "Sting Operation" + } + }, + "requirements": [ + [ + "kill_emperor_scorpion" + ] + ], + "sends_telemetry_event": true +} diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/stone_cold.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/stone_cold.json index fb73c71b..6a228241 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/stone_cold.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/stone_cold.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:visit_elythia", "criteria": { "kill_basilisk": { "conditions": { diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/sweater_dreams.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/sweater_dreams.json index f8eacf00..c54c949a 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/sweater_dreams.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/sweater_dreams.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:visit_thoraxis", "criteria": { "kill_nightmare": { "conditions": { diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/the_lab.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/the_lab.json index 284afaaa..09d9dcfb 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/the_lab.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/the_lab.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:visit_elythia", "criteria": { "discover_lab": { "conditions": { diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/visit_cavaryn.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/visit_cavaryn.json index b8e311d0..27995abf 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/visit_cavaryn.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/visit_cavaryn.json @@ -1,5 +1,4 @@ { - "parent": "minecraft:adventure/root", "criteria": { "entered_cavaryn": { "conditions": { @@ -10,6 +9,7 @@ }, "display": { "announce_to_chat": true, + "background": "antarchy:block/myrmite", "description": { "translate": "advancements.antarchy.visit_cavaryn.description" }, diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/visit_elythia.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/visit_elythia.json index 374f54ea..5b935177 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/visit_elythia.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/visit_elythia.json @@ -1,5 +1,4 @@ { - "parent": "minecraft:adventure/root", "criteria": { "entered_elythia": { "conditions": { @@ -10,6 +9,7 @@ }, "display": { "announce_to_chat": true, + "background": "antarchy:block/ouranwood/mossy_ouranwood_log", "description": { "translate": "advancements.antarchy.visit_elythia.description" }, diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/visit_thoraxis.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/visit_thoraxis.json index e8e96b70..f605b113 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/visit_thoraxis.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/visit_thoraxis.json @@ -1,5 +1,4 @@ { - "parent": "minecraft:adventure/root", "criteria": { "entered_thoraxis": { "conditions": { @@ -10,6 +9,7 @@ }, "display": { "announce_to_chat": true, + "background": "antarchy:block/nyxite", "description": { "translate": "advancements.antarchy.visit_thoraxis.description" }, diff --git a/common-1.21.1/src/main/resources/data/antarchy/advancement/whoever_smelt_it_dealt_it.json b/common-1.21.1/src/main/resources/data/antarchy/advancement/whoever_smelt_it_dealt_it.json index d17316aa..9e10d2ca 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/advancement/whoever_smelt_it_dealt_it.json +++ b/common-1.21.1/src/main/resources/data/antarchy/advancement/whoever_smelt_it_dealt_it.json @@ -1,5 +1,5 @@ { - "parent": "minecraft:adventure/root", + "parent": "antarchy:visit_thoraxis", "criteria": { "become_stinky": { "conditions": { diff --git a/common-1.21.1/src/main/resources/data/antarchy/tags/entity_type/inverted_immune.json b/common-1.21.1/src/main/resources/data/antarchy/tags/entity_type/inverted_immune.json index 186c34bc..aa39f4dd 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/tags/entity_type/inverted_immune.json +++ b/common-1.21.1/src/main/resources/data/antarchy/tags/entity_type/inverted_immune.json @@ -2,9 +2,7 @@ "replace": false, "values": [ "minecraft:ender_dragon", - "antarchy:emperor_scorpion", "antarchy:kraken", - "antarchy:nightmare", "antarchy:reverie", "antarchy:lucid", "antarchy:triffid"