idk why all these line seperators are freaking out

This commit is contained in:
craisinlord committed 2026-08-14 13:35:46 -05:00
1 parent 05c9dd5e66
commit 700030eefd
77 files changed
+1651 -375

No files matched your search

@@ -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());
}
}
@@ -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();
@@ -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());
}
}
@@ -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() {
@@ -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;
}
@@ -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 {
@@ -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<Fluid> 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
@@ -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;
@@ -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;
@@ -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));
}
}
@@ -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<LivingEntity> 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<LivingEntity> targets = this.getFrontTargets(range, inflation);
@@ -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() {
@@ -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));
}
}
@@ -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);
}
@@ -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 {
}
@@ -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);
}
}
@@ -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);
}
@@ -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<OuranwoodDeerEntity> 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;
@@ -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);
}
}
@@ -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;
}
@@ -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));
@@ -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
@@ -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();
@@ -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());
}
}
@@ -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))));
}
}
@@ -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);
}
@@ -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<NightmareEntity> 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<LivingEntity> 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;
}
@@ -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));
}
}
@@ -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)) {
@@ -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();
@@ -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);
}
}
@@ -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;
}
}
@@ -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);
@@ -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<ItemEntity> 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<Void> original,
@Local LivingEntity entity
) {
if (!AntarchyGravityApi.isGravityInverted(entity)) {
original.call(itemEntity, deltaMovement);
return;
}
AntarchyGravityApi.setWorldVelocity(itemEntity, deltaMovement);
}
}
@@ -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<Double> 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<Double> 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<Double> 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();
}
}
@@ -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<Double> 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<Vec3> cir) {
Entity entity = (Entity) (Object) this;
@@ -21,16 +21,14 @@ public abstract class GroundPathNavigationMixin {
@Inject(method = "createPathFinder", at = @At("HEAD"), cancellable = true)
private void antarchy$useGravityEvaluator(int maxVisitedNodes, CallbackInfoReturnable<PathFinder> 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));
}
}
@@ -46,6 +46,7 @@
"TigerEyeCamouflageMixin",
"TigerEyeVisibilityMixin",
"gravity.AbstractArrowGravityMixin",
"gravity.BehaviorUtilsGravityMixin",
"gravity.BucketItemGravityMixin",
"gravity.ChunkMapAccessor",
"gravity.CrossbowItemGravityMixin",
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:visit_elythia",
"criteria": {
"discover_stampys_house": {
"conditions": {
@@ -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
}
@@ -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
}
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:visit_elythia",
"criteria": {
"impossible": {
"trigger": "minecraft:impossible"
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:anger_the_hive_mind",
"criteria": {
"tame_hercules_beetle": {
"conditions": {
@@ -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": [
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:visit_elythia",
"criteria": {
"brutalfly": {
"conditions": {
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:anger_the_hive_mind",
"criteria": {
"eat_cooked_bug_meat": {
"conditions": {
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:visit_elythia",
"criteria": {
"kill_alpha_mantis": {
"conditions": {
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:visit_elythia",
"criteria": {
"discover_ruined_arena": {
"conditions": {
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:visit_elythia",
"criteria": {
"discover_ruined_prison": {
"conditions": {
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:visit_elythia",
"criteria": {
"impossible": {
"trigger": "minecraft:impossible"
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:visit_thoraxis",
"criteria": {
"kill_bed_bug": {
"conditions": {
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:visit_elythia",
"criteria": {
"impossible": {
"trigger": "minecraft:impossible"
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:visit_elythia",
"criteria": {
"discover_castle": {
"conditions": {
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:visit_thoraxis",
"criteria": {
"craft_gravity_gun": {
"conditions": {
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:anger_the_hive_mind",
"criteria": {
"kill_hercules_beetle": {
"conditions": {
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:visit_thoraxis",
"criteria": {
"impossible": {
"trigger": "minecraft:impossible"
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:visit_elythia",
"criteria": {
"impossible": {
"trigger": "minecraft:impossible"
@@ -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
}
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:visit_thoraxis",
"criteria": {
"become_inverted": {
"conditions": {
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:visit_elythia",
"criteria": {
"kill_toreterror": {
"conditions": {
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:visit_thoraxis",
"criteria": {
"kill_lucid": {
"conditions": {
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:anger_the_hive_mind",
"criteria": {
"kill_molevore": {
"conditions": {
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:sting_operation",
"criteria": {
"now_watch_me_whip": {
"conditions": {
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:visit_elythia",
"criteria": {
"kill_cloud_shark": {
"conditions": {
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:shark_weak",
"criteria": {
"eat_soup": {
"conditions": {
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:visit_elythia",
"criteria": {
"impossible": {
"trigger": "minecraft:impossible"
@@ -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
}
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:visit_elythia",
"criteria": {
"kill_basilisk": {
"conditions": {
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:visit_thoraxis",
"criteria": {
"kill_nightmare": {
"conditions": {
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:visit_elythia",
"criteria": {
"discover_lab": {
"conditions": {
@@ -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"
},
@@ -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"
},
@@ -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"
},
@@ -1,5 +1,5 @@
{
"parent": "minecraft:adventure/root",
"parent": "antarchy:visit_thoraxis",
"criteria": {
"become_stinky": {
"conditions": {
@@ -2,9 +2,7 @@
"replace": false,
"values": [
"minecraft:ender_dragon",
"antarchy:emperor_scorpion",
"antarchy:kraken",
"antarchy:nightmare",
"antarchy:reverie",
"antarchy:lucid",
"antarchy:triffid"