diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/config/AntarchySettings.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/config/AntarchySettings.java index 1ed7f7c3..89665261 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/config/AntarchySettings.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/config/AntarchySettings.java @@ -285,7 +285,7 @@ public final class AntarchySettings { private static int queenBlackHoleActiveTicks = 120; private static double queenBlackHolePullStrength = 0.16D; private static int queenBlackHoleBlockSuctionCap = 160; - private static double kingFireballDamage = 32.0D; + private static double kingFireballDamage = 48.0D; private static double kingFireballRadius = 4.5D; private static int kingFireballCooldownTicks = 150; private static double kingIceballDamage = 18.0D; diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/CloudBlock.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/CloudBlock.java index c7d54bbe..a471287c 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/CloudBlock.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/CloudBlock.java @@ -1,11 +1,11 @@ package com.craisinlord.antarchy.content.block; +import com.craisinlord.antarchy.content.entity.royal.KingEntity; import java.util.Optional; import java.util.function.Supplier; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; @@ -40,7 +40,8 @@ public final class CloudBlock extends Block implements BucketPickup { protected VoxelShape getCollisionShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) { if (context instanceof EntityCollisionContext ecc) { Entity entity = ecc.getEntity(); - if (entity instanceof net.minecraft.world.entity.LivingEntity le && le.isShiftKeyDown()) { + if (entity instanceof KingEntity + || entity instanceof net.minecraft.world.entity.LivingEntity le && le.isShiftKeyDown()) { return EMPTY; } } @@ -73,6 +74,9 @@ public final class CloudBlock extends Block implements BucketPickup { } public void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { + if (entity instanceof KingEntity) { + return; + } Vec3 motion = entity.getDeltaMovement(); double slowedY = motion.y < 0.0D ? Math.max(motion.y * 0.4D, -0.08D) : motion.y; entity.setDeltaMovement(motion.x * 0.92D, slowedY, motion.z * 0.92D); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/UndertrialSpawnContext.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/UndertrialSpawnContext.java new file mode 100644 index 00000000..2f03fa6b --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/UndertrialSpawnContext.java @@ -0,0 +1,37 @@ +package com.craisinlord.antarchy.content.block.entity; + +/** + * Identifies spawn-rule checks made by an Undertrial spawner's vanilla + * TrialSpawner tick. The context is scoped to the current server-thread call + * so ordinary trial spawners and all other spawn paths retain vanilla rules. + */ +public final class UndertrialSpawnContext implements AutoCloseable { + private static final ThreadLocal DEPTH = ThreadLocal.withInitial(() -> 0); + + private boolean closed; + + private UndertrialSpawnContext() { + DEPTH.set(DEPTH.get() + 1); + } + + public static UndertrialSpawnContext enter() { + return new UndertrialSpawnContext(); + } + + public static boolean isActive() { + return DEPTH.get() > 0; + } + + @Override + public void close() { + if (!closed) { + closed = true; + int depth = DEPTH.get() - 1; + if (depth <= 0) { + DEPTH.remove(); + } else { + DEPTH.set(depth); + } + } + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/UndertrialSpawnerBlockEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/UndertrialSpawnerBlockEntity.java index db0965e7..1ded37c0 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/UndertrialSpawnerBlockEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/block/entity/UndertrialSpawnerBlockEntity.java @@ -69,7 +69,9 @@ public final class UndertrialSpawnerBlockEntity extends BlockEntity implements T boolean ominous = state.getValue(UndertrialSpawnerBlock.OMINOUS); boolean rewardReady = previousState == TrialSpawnerState.EJECTING_REWARD && blockEntity.trialSpawner.getData().isReadyToEjectItems(level, 30.0F, blockEntity.trialSpawner.getTargetCooldownLength()); - blockEntity.trialSpawner.tickServer(level, pos, ominous); + try (UndertrialSpawnContext ignored = UndertrialSpawnContext.enter()) { + blockEntity.trialSpawner.tickServer(level, pos, ominous); + } if (rewardReady && blockEntity.getState() == TrialSpawnerState.EJECTING_REWARD) { blockEntity.ejectReward(level, pos, ominous); } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/QueenMusicHandler.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/QueenMusicHandler.java new file mode 100644 index 00000000..3ddb1729 --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/QueenMusicHandler.java @@ -0,0 +1,112 @@ +package com.craisinlord.antarchy.content.client; + +import com.craisinlord.antarchy.content.entity.royal.QueenEntity; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.DeathScreen; +import net.minecraft.client.resources.sounds.AbstractTickableSoundInstance; +import net.minecraft.client.resources.sounds.SoundInstance; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundSource; +import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; + +import java.util.Comparator; + +public final class QueenMusicHandler { + private static final double START_RADIUS = 128.0D; + private static final double STOP_RADIUS = 160.0D; + private static final int RESTART_COOLDOWN_TICKS = 100; + private static QueenMusicSound music; + private static int cooldownTicks; + private static boolean wasInEncounter; + + private QueenMusicHandler() { + } + + public static void tick(Minecraft minecraft, SoundEvent soundEvent) { + if (minecraft.level == null || minecraft.player == null || minecraft.isPaused() + || !minecraft.player.isAlive() || minecraft.player.isRemoved() + || minecraft.player.isDeadOrDying() || minecraft.screen instanceof DeathScreen) { + reset(minecraft); + return; + } + + if (cooldownTicks > 0) { + cooldownTicks--; + } + + QueenEntity queen = minecraft.level.getEntitiesOfClass( + QueenEntity.class, + minecraft.player.getBoundingBox().inflate(STOP_RADIUS), + QueenEntity::shouldPlayQueenMusic + ).stream() + .min(Comparator.comparingDouble(entity -> entity.distanceToSqr(minecraft.player))) + .orElse(null); + + if (queen == null) { + stop(minecraft); + if (wasInEncounter) { + cooldownTicks = Math.max(cooldownTicks, RESTART_COOLDOWN_TICKS); + } + wasInEncounter = false; + return; + } + + wasInEncounter = true; + if (music != null && !minecraft.getSoundManager().isActive(music)) { + music = null; + cooldownTicks = Math.max(cooldownTicks, RESTART_COOLDOWN_TICKS); + } + + if (music == null && cooldownTicks <= 0) { + music = new QueenMusicSound(soundEvent); + minecraft.getSoundManager().play(music); + } + + if (music != null) { + double distance = Math.sqrt(queen.distanceToSqr(minecraft.player)); + float volume = distance <= START_RADIUS + ? 1.0F + : (float) Mth.clamp(1.0D - (distance - START_RADIUS) / (STOP_RADIUS - START_RADIUS), 0.0D, 1.0D); + music.setVolume(volume); + } + } + + private static void stop(Minecraft minecraft) { + if (music != null) { + minecraft.getSoundManager().stop(music); + music = null; + } + } + + private static void reset(Minecraft minecraft) { + stop(minecraft); + cooldownTicks = 0; + wasInEncounter = false; + } + + private static final class QueenMusicSound extends AbstractTickableSoundInstance { + private QueenMusicSound(SoundEvent soundEvent) { + super(soundEvent, SoundSource.MUSIC, RandomSource.create()); + this.looping = false; + this.delay = 0; + this.relative = true; + this.attenuation = SoundInstance.Attenuation.NONE; + this.volume = 1.0F; + this.pitch = 1.0F; + } + + private void setVolume(float volume) { + this.volume = volume; + } + + @Override + public void tick() { + } + + @Override + public boolean canStartSilent() { + return true; + } + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/creative/CreativeTabContents.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/creative/CreativeTabContents.java index e8093994..2f8f2274 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/creative/CreativeTabContents.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/creative/CreativeTabContents.java @@ -386,6 +386,7 @@ public final class CreativeTabContents { entry("duct_tape", "tools_and_utilities", "shears"), entry("bug_spray", "tools_and_utilities"), entry("music_disc_underside", "tools_and_utilities"), + entry("music_disc_the_queen", "tools_and_utilities"), entry("diamond_minecart", "tools_and_utilities", "minecart"), entry("bile_bucket", "tools_and_utilities"), entry("ichor_bucket", "tools_and_utilities"), diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/KingEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/KingEntity.java index 9b92ef8b..44f9abc5 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/KingEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/KingEntity.java @@ -252,17 +252,7 @@ public class KingEntity extends RoyalBossEntity { @Override protected boolean blocksRoyalBeamScheduling() { - if (this.royalChargeActive) { - return true; - } - LivingEntity target = this.getTarget(); - if (target == null || this.royalChargeOpeningDelayTicks > 0 - || this.kingLandingStage != KingLandingStage.AERIAL - || !this.attackScheduler.ready("royal_charge", RoyalAttackLane.MOVEMENT)) { - return false; - } - double distance = this.distanceTo(target); - return distance >= ROYAL_CHARGE_MIN_RANGE && distance <= ROYAL_CHARGE_MAX_RANGE; + return this.royalChargeActive; } @Override @@ -423,7 +413,12 @@ public class KingEntity extends RoyalBossEntity { @Override protected double royalBeamMinimumRange() { - return AntarchySettings.kingBeamMinimumRange(); + return Math.min(AntarchySettings.kingBeamMinimumRange(), 28.0D); + } + + @Override + protected boolean royalBeamUsesTrackedAim() { + return false; } @Override @@ -758,10 +753,12 @@ public class KingEntity extends RoyalBossEntity { private boolean clearTreePatrolPath(Vec3 destination) { Vec3 start = this.position(); - for (int sample = 1; sample <= TREE_ORBIT_PATH_SAMPLES; sample++) { + AABB bounds = this.getBoundingBox(); + for (int check = 0; check < TREE_ORBIT_PATH_SAMPLES; check++) { + int sample = check == 0 ? TREE_ORBIT_PATH_SAMPLES : check; double progress = sample / (double) TREE_ORBIT_PATH_SAMPLES; Vec3 point = start.lerp(destination, progress); - AABB box = this.getBoundingBox().move(point.x - this.getX(), point.y - this.getY(), point.z - this.getZ()); + AABB box = bounds.move(point.x - this.getX(), point.y - this.getY(), point.z - this.getZ()); if (!this.level().noCollision(this, box)) { return false; } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/QueenEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/QueenEntity.java index edc90409..7d4b22a7 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/QueenEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/QueenEntity.java @@ -24,15 +24,12 @@ import net.minecraft.core.particles.DustParticleOptions; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; -import net.minecraft.network.protocol.game.ClientboundSetTitleTextPacket; -import net.minecraft.network.protocol.game.ClientboundSetTitlesAnimationPacket; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; -import net.minecraft.ChatFormatting; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; import net.minecraft.world.BossEvent; @@ -74,16 +71,17 @@ public class QueenEntity extends RoyalBossEntity { private static final int GRAVITY_STOMP_COOLDOWN = 180; private static final int MOMENTUM_LOCK_COOLDOWN = 420; private static final int MOMENTUM_LOCK_DURATION = 90; - private static final double MOMENTUM_LOCK_RADIUS = 26.0D; + private static final double MOMENTUM_LOCK_RADIUS = 40.0D; private static final int CRUSHING_GRAVITY_COOLDOWN = 360; private static final int CRUSHING_GRAVITY_DURATION = 120; - private static final double CRUSHING_GRAVITY_RADIUS = 18.0D; + private static final double CRUSHING_GRAVITY_RADIUS = 36.0D; private static final double CRUSHING_GRAVITY_STRENGTH = 0.12D; private static final int ACCELERATION_COOLDOWN = 500; - private static final int QUEEN_CHRONOSPHERE_COOLDOWN = 700; + private static final int QUEEN_CHRONOSPHERE_COOLDOWN = 500; private static final int QUEEN_CHRONOSPHERE_DURATION = 200; - private static final double QUEEN_CHRONOSPHERE_RADIUS = 20.0D; - private static final int ACCELERATION_DURATION = 140; + private static final double QUEEN_CHRONOSPHERE_RADIUS = 40.0D; + private static final double QUEEN_CHRONOSPHERE_RATE = 0.14D; + private static final int ACCELERATION_DURATION = 360; private static final int BLACK_HOLE_COOLDOWN = 340; private static final double QUEEN_BITE_COOLDOWN_MULTIPLIER = 1.5D; private static final int GRAVITY_STOMP_TELEGRAPH_TICKS = 22; @@ -108,11 +106,17 @@ public class QueenEntity extends RoyalBossEntity { private static final int GRAVITIC_UPHEAVAL_DURATION = GRAVITIC_UPHEAVAL_RISE_TICKS + GRAVITIC_UPHEAVAL_HANG_TICKS; private static final double GRAVITIC_UPHEAVAL_RISE_SPEED = 0.55D; private static final int LANDING_TELEGRAPH_TICKS = 30; + private static final int LANDING_DESCENT_TIMEOUT_TICKS = 120; private static final int LANDING_IMPACT_TICKS = 18; - private static final int GROUND_COMBAT_TICKS = 160; + private static final int GROUND_COMBAT_TICKS = 240; + private static final int GROUND_CHARGE_WINDUP_TICKS = 10; + private static final int GROUND_CHARGE_DURATION_TICKS = 14; + private static final int GROUND_CHARGE_COOLDOWN_MIN = 45; + private static final int GROUND_CHARGE_COOLDOWN_VARIANCE = 25; + private static final double GROUND_CHARGE_SPEED = 1.45D; private static final int TAKEOFF_TICKS = 30; - private static final int LANDING_COOLDOWN_MIN = 300; - private static final int LANDING_COOLDOWN_VARIANCE = 120; + private static final int LANDING_COOLDOWN_MIN = 220; + private static final int LANDING_COOLDOWN_VARIANCE = 80; private static final int BLACK_HOLE_FOLLOW_UP_DELAY = 22; private static final int CRUSHING_LANDING_DELAY = 40; private static final int MOMENTUM_VOLLEY_DELAY = MOMENTUM_LOCK_DURATION + 5; @@ -142,13 +146,20 @@ public class QueenEntity extends RoyalBossEntity { private final List graviticUpheavalBlocks = new ArrayList<>(); @Nullable private Vec3 pendingBlackHoleAnchor; - private int queenLandingCooldownTicks = 300; + private int queenLandingCooldownTicks = 200; private int queenLandingStageTicks; + private int queenGroundChargeCooldownTicks; + private int queenGroundChargeWindupTicks; + private int queenGroundChargeTicks; private QueenLandingStage queenLandingStage = QueenLandingStage.AERIAL; @Nullable private Vec3 queenLandingWaypoint; @Nullable + private Vec3 queenGroundChargeDirection; + @Nullable private Phase pendingPhaseSignature; + private boolean pendingPhaseTwoCrushingGravity; + private boolean pendingPhaseThreeChronosphere; private QueenFollowUp queuedQueenFollowUp = QueenFollowUp.NONE; private int queuedQueenFollowUpTicks; private int queuedQueenLandingRetryTicks; @@ -160,6 +171,7 @@ public class QueenEntity extends RoyalBossEntity { private boolean manticoreAnimationPending; private final RoyalEffectController royalEffects = new RoyalEffectController(); private final Map frozenVelocities = new HashMap<>(); + private final Map frozenPositions = new HashMap<>(); private long naturalTrailSiteId = Long.MIN_VALUE; @Nullable private BlockPos naturalTrailHome; @@ -214,6 +226,8 @@ public class QueenEntity extends RoyalBossEntity { || this.queenLandingStage == QueenLandingStage.DESCENT || this.queenLandingStage == QueenLandingStage.IMPACT || this.queenLandingStage == QueenLandingStage.TAKEOFF + || this.queenGroundChargeWindupTicks > 0 + || this.queenGroundChargeTicks > 0 || this.isQueenAbilityTelegraphActive(); } @@ -231,16 +245,6 @@ public class QueenEntity extends RoyalBossEntity { this.getNavigation().stop(); this.setDeltaMovement(this.getDeltaMovement().scale(0.35D)); this.playRoyalSound(AntarchySoundEvents.QUEEN_ROAR.get(), nextPhase == Phase.THREE ? 0.66F : 0.82F); - if (this.level() instanceof ServerLevel level) { - Component title = Component.translatable(nextPhase == Phase.TWO - ? "boss.antarchy.queen.phase_two" : "boss.antarchy.queen.phase_three") - .withStyle(style -> style.withColor(nextPhase == Phase.TWO - ? ChatFormatting.DARK_PURPLE : ChatFormatting.RED).withBold(true)); - for (ServerPlayer player : this.royalEncounterPlayers(level)) { - player.connection.send(new ClientboundSetTitlesAnimationPacket(5, 45, 10)); - player.connection.send(new ClientboundSetTitleTextPacket(title)); - } - } } @Override @@ -260,22 +264,34 @@ public class QueenEntity extends RoyalBossEntity { if (nextPhase == Phase.TWO) { this.momentumLockCooldownTicks = 0; this.pendingPhaseSignature = Phase.TWO; + this.pendingPhaseTwoCrushingGravity = true; this.queenLandingCooldownTicks = Math.min(this.queenLandingCooldownTicks, 100); } else if (nextPhase == Phase.THREE) { this.accelerationCooldownTicks = 0; + this.queenChronosphereCooldownTicks = 0; this.pendingPhaseSignature = Phase.THREE; + this.pendingPhaseThreeChronosphere = true; this.queenLandingCooldownTicks = 0; } } @Override protected double biteApproachSpeed() { - return 1.55D; + return this.queenLandingStage == QueenLandingStage.GROUND_COMBAT && !this.isRoyalFlying() + ? 1.9D : 1.55D; } @Override protected double combatStandoffDistance() { - return Math.min(super.combatStandoffDistance(), 14.0D); + if (this.queenLandingStage == QueenLandingStage.GROUND_COMBAT && !this.isRoyalFlying()) { + return 0.0D; + } + return Math.max(super.combatStandoffDistance(), AntarchySettings.queenBeamMinimumRange() + 6.0D); + } + + @Override + protected double biteDamageMultiplier() { + return super.biteDamageMultiplier() * 1.5D; } @Override @@ -327,6 +343,11 @@ public class QueenEntity extends RoyalBossEntity { && !this.isAlliedTo(target); } + public boolean shouldPlayQueenMusic() { + LivingEntity target = this.getTarget(); + return !this.isDeadOrDying() && target != null && target.isAlive() && this.canAttack(target); + } + @Override protected SoundEvent royalFlyLoopSound() { return AntarchySoundEvents.QUEEN_FLY_LOOP.get(); @@ -395,10 +416,29 @@ public class QueenEntity extends RoyalBossEntity { }; } + @Override + protected boolean royalBeamUsesTrackedAim() { + return false; + } + public static boolean isFieldImmune(Entity entity) { return entity.getType().is(AntarchyTags.Entities.QUEEN_DOES_NOT_ATTACK); } + private AABB queenEffectBounds(double radius) { + double centerY = this.getY() + this.getBbHeight() * 0.5D; + return new AABB(this.getX() - radius, centerY - radius, this.getZ() - radius, + this.getX() + radius, centerY + radius, this.getZ() + radius); + } + + private boolean withinQueenEffectRange(Entity entity, double radius) { + double dx = entity.getX() - this.getX(); + double dz = entity.getZ() - this.getZ(); + double centerY = this.getY() + this.getBbHeight() * 0.5D; + double entityY = entity.getY() + entity.getBbHeight() * 0.5D; + return dx * dx + dz * dz <= radius * radius && Math.abs(entityY - centerY) <= radius; + } + @Override public void tick() { super.tick(); @@ -439,7 +479,7 @@ public class QueenEntity extends RoyalBossEntity { private void tickQueenLandingSequence(LivingEntity target) { if (this.queenLandingStage == QueenLandingStage.AERIAL && this.isRoyalFlying() && !this.isQueenAbilityTelegraphActive() - && this.queenLandingCooldownTicks-- <= 0 && target.onGround()) { + && this.queenLandingCooldownTicks-- <= 0) { this.beginQueenLanding(target); } @@ -450,6 +490,7 @@ public class QueenEntity extends RoyalBossEntity { this.tickQueenLandingIndicator(); if (--this.queenLandingStageTicks <= 0) { this.queenLandingStage = QueenLandingStage.DESCENT; + this.queenLandingStageTicks = LANDING_DESCENT_TIMEOUT_TICKS; this.playRoyalSound(AntarchySoundEvents.QUEEN_FLY_LOOP.get(), 0.72F); } } @@ -468,6 +509,9 @@ public class QueenEntity extends RoyalBossEntity { this.queenLandingStage = QueenLandingStage.IMPACT; this.queenLandingStageTicks = LANDING_IMPACT_TICKS; this.performGravityStomp((ServerLevel) this.level(), target); + } else if (--this.queenLandingStageTicks <= 0) { + this.resetQueenLandingSequence(); + this.queenLandingCooldownTicks = 40; } } case IMPACT -> { @@ -476,10 +520,12 @@ public class QueenEntity extends RoyalBossEntity { if (--this.queenLandingStageTicks <= 0) { this.queenLandingStage = QueenLandingStage.GROUND_COMBAT; this.queenLandingStageTicks = GROUND_COMBAT_TICKS; + this.queenGroundChargeCooldownTicks = 20; this.queenLandingWaypoint = null; } } case GROUND_COMBAT -> { + this.tickQueenGroundCharge(target); if (--this.queenLandingStageTicks <= 0) { this.beginQueenTakeoff(); } @@ -563,6 +609,7 @@ public class QueenEntity extends RoyalBossEntity { } private void beginQueenTakeoff() { + this.clearQueenGroundCharge(); this.queenLandingStage = QueenLandingStage.TAKEOFF; this.queenLandingStageTicks = TAKEOFF_TICKS; this.triggerAnim("wing_action", "wing_gust"); @@ -580,6 +627,7 @@ public class QueenEntity extends RoyalBossEntity { } private void resetQueenLandingSequence() { + this.clearQueenGroundCharge(); if (this.queenLandingStage != QueenLandingStage.AERIAL) { this.setRoyalFlying(true); } @@ -591,6 +639,65 @@ public class QueenEntity extends RoyalBossEntity { } } + private void tickQueenGroundCharge(LivingEntity target) { + if (this.queenGroundChargeWindupTicks > 0) { + this.getNavigation().stop(); + this.setDeltaMovement(this.getDeltaMovement().scale(0.45D)); + this.getLookControl().setLookAt(target, 90.0F, 90.0F); + if (--this.queenGroundChargeWindupTicks <= 0) { + Vec3 direction = target.position().subtract(this.position()).multiply(1.0D, 0.0D, 1.0D); + if (direction.lengthSqr() > 1.0E-4D) { + this.queenGroundChargeDirection = direction.normalize(); + this.queenGroundChargeTicks = GROUND_CHARGE_DURATION_TICKS; + } else { + this.finishQueenGroundCharge(); + } + } + return; + } + if (this.queenGroundChargeTicks > 0 && this.queenGroundChargeDirection != null) { + Vec3 direction = this.queenGroundChargeDirection; + Vec3 movement = this.getDeltaMovement(); + this.setDeltaMovement(direction.x * GROUND_CHARGE_SPEED, movement.y, + direction.z * GROUND_CHARGE_SPEED); + this.setYRot((float) (Mth.atan2(-direction.x, direction.z) * Mth.RAD_TO_DEG)); + this.yBodyRot = this.getYRot(); + this.hasImpulse = true; + if (--this.queenGroundChargeTicks <= 0) { + this.finishQueenGroundCharge(); + } + return; + } + if (this.queenGroundChargeCooldownTicks-- > 0 + || target.position().multiply(1.0D, 0.0D, 1.0D) + .distanceToSqr(this.position().multiply(1.0D, 0.0D, 1.0D)) < 36.0D) { + return; + } + this.queenGroundChargeDirection = target.position().subtract(this.position()) + .multiply(1.0D, 0.0D, 1.0D).normalize(); + this.queenGroundChargeWindupTicks = GROUND_CHARGE_WINDUP_TICKS; + this.playRoyalSound(AntarchySoundEvents.QUEEN_ROAR.get(), 1.12F); + if (this.level() instanceof ServerLevel level) { + level.sendParticles(ACCEL_DUST, this.getX(), this.getY() + this.getBbHeight() * 0.35D, this.getZ(), + 32, this.getBbWidth() * 0.2D, 0.6D, this.getBbWidth() * 0.2D, 0.04D); + } + } + + private void finishQueenGroundCharge() { + this.queenGroundChargeTicks = 0; + this.queenGroundChargeWindupTicks = 0; + this.queenGroundChargeDirection = null; + this.queenGroundChargeCooldownTicks = GROUND_CHARGE_COOLDOWN_MIN + + this.random.nextInt(GROUND_CHARGE_COOLDOWN_VARIANCE + 1); + } + + private void clearQueenGroundCharge() { + this.queenGroundChargeCooldownTicks = 0; + this.queenGroundChargeWindupTicks = 0; + this.queenGroundChargeTicks = 0; + this.queenGroundChargeDirection = null; + } + private void tickDreamFireballs() { if (this.isRoyalRecoveryActive()) return; if (!(this.level() instanceof ServerLevel level)) return; @@ -654,7 +761,7 @@ public class QueenEntity extends RoyalBossEntity { } case LANDING -> { if (this.queenLandingStage == QueenLandingStage.AERIAL - && this.isRoyalFlying() && target.onGround()) { + && this.isRoyalFlying()) { this.clearQueuedQueenFollowUp(); this.queenLandingCooldownTicks = 0; } else if (--this.queuedQueenLandingRetryTicks <= 0) { @@ -908,9 +1015,11 @@ public class QueenEntity extends RoyalBossEntity { } Phase phase = this.phase(); + boolean accelerationBlocksMajor = this.royalEffects.active("acceleration") + && !this.pendingPhaseThreeChronosphere; boolean majorBusy = this.royalEffects.active("momentum_lock") || this.royalEffects.active("crushing_gravity") - || this.royalEffects.active("acceleration") + || accelerationBlocksMajor || this.royalEffects.active("gravitic_upheaval"); String[] candidates = switch (phase) { case ONE -> new String[] {"gravity_stomp", "black_hole"}; @@ -918,7 +1027,9 @@ public class QueenEntity extends RoyalBossEntity { case THREE -> new String[] {"gravity_stomp", "black_hole", "momentum_lock", "crushing_gravity", "acceleration", "queen_chronosphere", "debris_cyclone", "gravitic_upheaval"}; }; String forcedAttack = this.pendingPhaseSignature == Phase.TWO ? "momentum_lock" - : this.pendingPhaseSignature == Phase.THREE ? "acceleration" : null; + : this.pendingPhaseSignature == Phase.THREE ? "acceleration" + : phase == Phase.TWO && this.pendingPhaseTwoCrushingGravity ? "crushing_gravity" + : phase == Phase.THREE && this.pendingPhaseThreeChronosphere ? "queen_chronosphere" : null; String selected = forcedAttack != null && this.queenAttackReady(forcedAttack, phase, majorBusy) ? forcedAttack : this.attackScheduler.chooseWeighted(candidates, id -> { @@ -978,7 +1089,13 @@ public class QueenEntity extends RoyalBossEntity { })) return; this.lastQueenMajorAttack = selected; if (selected.equals(forcedAttack)) { - this.pendingPhaseSignature = null; + if ("momentum_lock".equals(selected) || "acceleration".equals(selected)) { + this.pendingPhaseSignature = null; + } else if ("crushing_gravity".equals(selected)) { + this.pendingPhaseTwoCrushingGravity = false; + } else if ("queen_chronosphere".equals(selected)) { + this.pendingPhaseThreeChronosphere = false; + } } } @@ -1020,7 +1137,8 @@ public class QueenEntity extends RoyalBossEntity { case "queen_chronosphere" -> { this.queenChronosphereCooldownTicks = cooldown; TimeDilationFieldEntity field = TimeDilationApi.createField(level, this.position(), - QUEEN_CHRONOSPHERE_RADIUS, 0.08D, QUEEN_CHRONOSPHERE_DURATION, this.getUUID()); + QUEEN_CHRONOSPHERE_RADIUS, QUEEN_CHRONOSPHERE_RATE, + QUEEN_CHRONOSPHERE_DURATION, this.getUUID()); field.configureQueenChronosphere(this); this.startRoyalRecovery(35); } @@ -1078,7 +1196,8 @@ public class QueenEntity extends RoyalBossEntity { return switch (phase) { case ONE -> "black_hole".equals(id) ? 6 : 3; case TWO -> switch (id) { - case "momentum_lock", "crushing_gravity" -> 6; + case "crushing_gravity" -> 12; + case "momentum_lock" -> 7; case "debris_cyclone" -> 5; case "gravitic_upheaval" -> 4; case "gravity_stomp" -> 3; @@ -1087,11 +1206,11 @@ public class QueenEntity extends RoyalBossEntity { }; case THREE -> switch (id) { case "acceleration" -> 7; - case "queen_chronosphere" -> 6; - case "black_hole", "crushing_gravity" -> 5; + case "queen_chronosphere", "crushing_gravity" -> 10; + case "black_hole" -> 5; case "debris_cyclone", "gravitic_upheaval" -> 5; case "gravity_stomp" -> 4; - case "momentum_lock" -> 2; + case "momentum_lock" -> 7; default -> 0; }; }; @@ -1296,7 +1415,9 @@ public class QueenEntity extends RoyalBossEntity { } if (this.momentumLockTelegraphTicks <= 14) { for (LivingEntity living : level.getEntitiesOfClass(LivingEntity.class, - this.getBoundingBox().inflate(MOMENTUM_LOCK_RADIUS), this::canDamageWithRoyalAttack)) { + this.queenEffectBounds(MOMENTUM_LOCK_RADIUS), + living -> this.canDamageWithRoyalAttack(living) + && this.withinQueenEffectRange(living, MOMENTUM_LOCK_RADIUS))) { this.spawnMomentumTargetCage(level, living); if (this.momentumLockTelegraphTicks == 12) { NightmareBiteEntity.spawnTelegraphAt(level, living, true); @@ -1318,7 +1439,9 @@ public class QueenEntity extends RoyalBossEntity { double progress = elapsed / (double) CRUSHING_GRAVITY_TELEGRAPH_TICKS; if (this.tickCount % 2 == 0) { for (LivingEntity living : level.getEntitiesOfClass(LivingEntity.class, - this.getBoundingBox().inflate(CRUSHING_GRAVITY_RADIUS), this::canDamageWithRoyalAttack)) { + this.queenEffectBounds(CRUSHING_GRAVITY_RADIUS), + living -> this.canDamageWithRoyalAttack(living) + && this.withinQueenEffectRange(living, CRUSHING_GRAVITY_RADIUS))) { double downSign = AntarchyGravityApi.isGravityInverted(living) ? 1.0D : -1.0D; this.spawnCrushingGravityArrow(level, living, downSign, progress); } @@ -1644,12 +1767,15 @@ public class QueenEntity extends RoyalBossEntity { this.momentumLockCooldownTicks = MOMENTUM_LOCK_COOLDOWN; this.royalEffects.start("momentum_lock", MOMENTUM_LOCK_DURATION, () -> { this.frozenVelocities.clear(); + this.frozenPositions.clear(); for (Entity entity : level.getEntitiesOfClass(Entity.class, - this.getBoundingBox().inflate(MOMENTUM_LOCK_RADIUS))) { + this.queenEffectBounds(MOMENTUM_LOCK_RADIUS), + entity -> this.withinQueenEffectRange(entity, MOMENTUM_LOCK_RADIUS))) { if (entity == this || isFieldImmune(entity) || entity instanceof Player player && player.isCreative()) { continue; } this.frozenVelocities.put(entity.getUUID(), entity.getDeltaMovement()); + this.frozenPositions.put(entity.getUUID(), entity.position()); } }, this::tickMomentumLockEffect, () -> { for (Map.Entry entry : this.frozenVelocities.entrySet()) { @@ -1660,6 +1786,7 @@ public class QueenEntity extends RoyalBossEntity { } } this.frozenVelocities.clear(); + this.frozenPositions.clear(); this.startRoyalRecovery(35); }); this.playRoyalSound(AntarchySoundEvents.QUEEN_ROAR.get(), 0.5F); @@ -1674,8 +1801,13 @@ public class QueenEntity extends RoyalBossEntity { Entity entity = level.getEntity(entry.getKey()); if (entity == null || !entity.isAlive()) { iterator.remove(); + this.frozenPositions.remove(entry.getKey()); continue; } + Vec3 lockedPosition = this.frozenPositions.get(entry.getKey()); + if (lockedPosition != null && entity.position().distanceToSqr(lockedPosition) > 1.0E-6D) { + entity.teleportTo(lockedPosition.x, lockedPosition.y, lockedPosition.z); + } entity.setDeltaMovement(Vec3.ZERO); entity.fallDistance = 0.0F; entity.hasImpulse = true; @@ -1694,13 +1826,17 @@ public class QueenEntity extends RoyalBossEntity { return; } for (Entity entity : level.getEntitiesOfClass(Entity.class, - this.getBoundingBox().inflate(CRUSHING_GRAVITY_RADIUS))) { + this.queenEffectBounds(CRUSHING_GRAVITY_RADIUS), + entity -> this.withinQueenEffectRange(entity, CRUSHING_GRAVITY_RADIUS))) { if (entity == this || isFieldImmune(entity) || entity instanceof Player player && player.isCreative()) { continue; } double downSign = AntarchyGravityApi.isGravityInverted(entity) ? 1.0D : -1.0D; entity.setDeltaMovement(entity.getDeltaMovement().add(0.0D, downSign * CRUSHING_GRAVITY_STRENGTH, 0.0D)); entity.hasImpulse = true; + if (entity instanceof LivingEntity living && this.tickCount % 8 == 0) { + this.spawnCrushingGravityArrow(level, living, downSign, 1.0D); + } } if (this.tickCount % 8 == 0) { level.sendParticles(ACCEL_DUST, this.getX(), this.getY() + 1.0D, this.getZ(), 20, @@ -1756,6 +1892,7 @@ public class QueenEntity extends RoyalBossEntity { } this.royalEffects.clear(); this.frozenVelocities.clear(); + this.frozenPositions.clear(); removeAccelModifier(this.getAttribute(Attributes.MOVEMENT_SPEED), ACCEL_SPEED_ID); removeAccelModifier(this.getAttribute(Attributes.FLYING_SPEED), ACCEL_FLY_ID); super.die(damageSource); @@ -1804,6 +1941,8 @@ public class QueenEntity extends RoyalBossEntity { tag.putInt("DebrisCycloneCooldownTicks", this.debrisCycloneCooldownTicks); tag.putInt("GraviticUpheavalCooldownTicks", this.graviticUpheavalCooldownTicks); tag.putInt("QueenLandingCooldownTicks", this.queenLandingCooldownTicks); + tag.putBoolean("PendingPhaseTwoCrushingGravity", this.pendingPhaseTwoCrushingGravity); + tag.putBoolean("PendingPhaseThreeChronosphere", this.pendingPhaseThreeChronosphere); tag.putString("QueuedQueenFollowUp", this.queuedQueenFollowUp.name()); tag.putInt("QueuedQueenFollowUpTicks", this.queuedQueenFollowUpTicks); tag.putInt("QueuedQueenLandingRetryTicks", this.queuedQueenLandingRetryTicks); @@ -1830,7 +1969,9 @@ public class QueenEntity extends RoyalBossEntity { this.debrisCycloneCooldownTicks = Math.max(0, tag.getInt("DebrisCycloneCooldownTicks")); this.graviticUpheavalCooldownTicks = Math.max(0, tag.getInt("GraviticUpheavalCooldownTicks")); this.queenLandingCooldownTicks = tag.contains("QueenLandingCooldownTicks") - ? Math.max(0, tag.getInt("QueenLandingCooldownTicks")) : 300; + ? Math.max(0, tag.getInt("QueenLandingCooldownTicks")) : 200; + this.pendingPhaseTwoCrushingGravity = tag.getBoolean("PendingPhaseTwoCrushingGravity"); + this.pendingPhaseThreeChronosphere = tag.getBoolean("PendingPhaseThreeChronosphere"); if (tag.contains("QueuedQueenFollowUp")) { try { this.queuedQueenFollowUp = QueenFollowUp.valueOf(tag.getString("QueuedQueenFollowUp")); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalAssailantBlackHoleEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalAssailantBlackHoleEntity.java index 364e41c8..790c49e7 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalAssailantBlackHoleEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalAssailantBlackHoleEntity.java @@ -32,6 +32,16 @@ public final class RoyalAssailantBlackHoleEntity extends RoyalBlackHoleEntity { return Math.max(2.0D, this.radius() * 0.55D); } + @Override + protected double effectGrowthStart() { + return 0.45D; + } + + @Override + protected double pullRadius() { + return this.effectRadius(); + } + @Override protected boolean hasVisibleTimeDilationField() { return false; diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBlackHoleEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBlackHoleEntity.java index b6cf65f5..45309fa4 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBlackHoleEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBlackHoleEntity.java @@ -67,6 +67,8 @@ public class RoyalBlackHoleEntity extends Entity implements GeoEntity { private static final double EFFECT_GROWTH_START = 0.45D; private static final double EFFECT_GROWTH_END = 1.6D; private static final double EFFECT_GROWTH_FRACTION = 0.6D; + private static final double QUEEN_EFFECT_GROWTH_START = EFFECT_GROWTH_START * 1.5D; + private static final double QUEEN_PULL_RADIUS_SCALE = 2.0D; private static final double MODEL_BASELINE_Y = 24.0D; private static final double CORE_CUBE_CENTER_Y = 146.0D; private static final double CORE_START_OFFSET_Y = -100.0D; @@ -143,7 +145,11 @@ public class RoyalBlackHoleEntity extends Entity implements GeoEntity { double progress = this.activeTicks <= 0 ? 1.0D : Mth.clamp(this.age / (this.activeTicks * EFFECT_GROWTH_FRACTION), 0.0D, 1.0D); - return this.radius() * Mth.lerp(progress, EFFECT_GROWTH_START, EFFECT_GROWTH_END); + return this.radius() * Mth.lerp(progress, this.effectGrowthStart(), EFFECT_GROWTH_END); + } + + protected double effectGrowthStart() { + return QUEEN_EFFECT_GROWTH_START; } public boolean isCollapsing() { @@ -228,6 +234,10 @@ public class RoyalBlackHoleEntity extends Entity implements GeoEntity { return true; } + protected double pullRadius() { + return this.effectRadius() * QUEEN_PULL_RADIUS_SCALE; + } + /** Returns the center of the animated black-hole cube in world coordinates. */ public Vec3 effectCenter() { double animationSeconds = Math.min(CORE_RISE_END_SECONDS, this.animationAge / 20.0D); @@ -269,7 +279,7 @@ public class RoyalBlackHoleEntity extends Entity implements GeoEntity { private void applyPull() { Vec3 center = this.effectCenter(); - double radius = this.effectRadius(); + double radius = this.pullRadius(); for (Entity entity : this.level().getEntitiesOfClass(Entity.class, new AABB(center, center).inflate(radius))) { if (entity == this || entity instanceof TimeDilationFieldEntity || this.isImmune(entity)) { continue; @@ -302,9 +312,10 @@ public class RoyalBlackHoleEntity extends Entity implements GeoEntity { Vec3 center = this.effectCenter(); Vec3 terrainOrigin = center; - double radius = this.effectRadius(); + double radius = this.pullRadius(); int pulledThisTick = 0; - for (int attempt = 0; attempt < BLOCK_SUCTION_ATTEMPTS && pulledThisTick < BLOCKS_PER_SUCTION + int suctionAttempts = BLOCK_SUCTION_ATTEMPTS * 4; + for (int attempt = 0; attempt < suctionAttempts && pulledThisTick < BLOCKS_PER_SUCTION && this.suckedBlocks < cap; attempt++) { BlockPos pos = BlockPos.containing( terrainOrigin.x + (this.random.nextDouble() * 2.0D - 1.0D) * radius, diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBossEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBossEntity.java index a592a18a..301882cd 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBossEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBossEntity.java @@ -339,6 +339,11 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult return Math.max(10, Mth.floor(AntarchySettings.royalBossBiteCooldownTicks() * phase.cooldownScale())); } + /** Allows either royal boss to tune bite damage without changing the other. */ + protected double biteDamageMultiplier() { + return AntarchySettings.royalBossBiteDamageMultiplier(); + } + public String geoNameForRender() { return this.geoName(); } @@ -543,19 +548,21 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult } this.initializeMultiplayerScaling(primaryTarget); + this.assignHeadTargets(primaryTarget); this.tickCombatLocomotionMode(primaryTarget); - if (this.blocksRoyalAttacksForMovement()) { + boolean movementBlocksAttacks = this.blocksRoyalAttacksForMovement(); + if (!movementBlocksAttacks) { + boolean aeriallyStabilized = this.steerTowardTarget(primaryTarget); + if (!aeriallyStabilized) { + this.getLookControl().setLookAt(primaryTarget, 30.0F, 30.0F); + } + } + this.tickRoyalBeam(primaryTarget, + !movementBlocksAttacks && !this.blocksRoyalBeamScheduling()); + if (movementBlocksAttacks) { return; } - boolean aeriallyStabilized = this.steerTowardTarget(primaryTarget); - if (!aeriallyStabilized) { - this.getLookControl().setLookAt(primaryTarget, 30.0F, 30.0F); - } - this.assignHeadTargets(primaryTarget); - if (!this.blocksRoyalBeamScheduling()) { - this.tickRoyalBeam(primaryTarget); - } this.tickBodyCrush(); Phase phase = this.phase(); @@ -590,10 +597,7 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult || super.isInvulnerableTo(source); } - private void tickRoyalBeam(LivingEntity primaryTarget) { - if (this.recoveryWindowTicks > 0) { - return; - } + private void tickRoyalBeam(LivingEntity primaryTarget, boolean allowScheduling) { Phase phase = this.phase(); int activeBeams = 0; for (RoyalHead head : this.heads) { @@ -625,7 +629,8 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult beamTarget, this.royalBeamSettings(), this.royalBeamTerrainMode(head), - end -> this.setRoyalBeamEndPosition(head.slot(), end)); + end -> this.setRoyalBeamEndPosition(head.slot(), end), + this.royalBeamUsesTrackedAim()); Vec3 beamEnd = controller.beamEndPosition(); if (beamEnd != null) { this.tickRoyalBeamEffects(head, this.beamAnchor(head), beamEnd); @@ -635,6 +640,12 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult } continue; } + } + if (!allowScheduling || this.recoveryWindowTicks > 0) { + return; + } + for (RoyalHead head : this.heads) { + int index = head.slot().ordinal(); if (activeBeams >= this.beamVolleyLimit) { continue; } @@ -694,6 +705,11 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult return phase.maxConcurrentHeadAttacks(); } + /** Uses the beam controller's smoothed target point instead of the boss body's forward axis. */ + protected boolean royalBeamUsesTrackedAim() { + return false; + } + protected boolean isRoyalRecoveryActive() { return this.recoveryWindowTicks > 0; } @@ -786,6 +802,7 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult protected final void stopRoyalBeamsForDirectedAttack() { for (RoyalHead head : this.heads) { if (head.beamActive() || head.shooting()) { + this.attackScheduler.cancel(this.headLane(head)); this.stopRoyalBeam(head); } } @@ -1059,7 +1076,7 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult } Vec3 anchor = this.headAnchor(head); double reach = this.biteReach(); - float damage = (float) (this.getAttributeValue(Attributes.ATTACK_DAMAGE) * AntarchySettings.royalBossBiteDamageMultiplier()); + float damage = (float) (this.getAttributeValue(Attributes.ATTACK_DAMAGE) * this.biteDamageMultiplier()); DamageSource damageSource = this.damageSources().mobAttack(this); AABB box = new AABB(anchor, anchor).inflate(reach); for (LivingEntity living : this.level().getEntitiesOfClass(LivingEntity.class, box, entity -> entity.isAlive() && entity != this)) { @@ -1122,7 +1139,7 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult AntarchyGravityApi.getGravityDirection(this)).normalize(); } - private boolean targetInBeamLine(RoyalHead head, LivingEntity target) { + protected boolean targetInBeamLine(RoyalHead head, LivingEntity target) { Vec3 origin = this.beamAnchor(head); Vec3 direction = this.beamDirection(head); Vec3 toTarget = target.getEyePosition().subtract(origin); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/beam/RoyalBeamController.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/beam/RoyalBeamController.java index 2825384f..3aa28a7e 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/beam/RoyalBeamController.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/beam/RoyalBeamController.java @@ -88,6 +88,18 @@ public final class RoyalBeamController { RoyalBeamSettings settings, RoyalBeamTerrainMode terrainMode, Consumer<@Nullable Vec3> syncedEndPosition + ) { + this.tick(shootFrom, shootDirection, target, settings, terrainMode, syncedEndPosition, false); + } + + public void tick( + Vec3 shootFrom, + Vec3 shootDirection, + @Nullable LivingEntity target, + RoyalBeamSettings settings, + RoyalBeamTerrainMode terrainMode, + Consumer<@Nullable Vec3> syncedEndPosition, + boolean useTrackedTargetAim ) { if (this.beamTicks <= 0) { syncedEndPosition.accept(null); @@ -111,7 +123,10 @@ public final class RoyalBeamController { return; } - Vec3 direction = shootDirection.lengthSqr() < 1.0E-7D + Vec3 trackedDirection = this.serverTarget.subtract(shootFrom); + Vec3 direction = useTrackedTargetAim && trackedDirection.lengthSqr() >= 1.0E-7D + ? trackedDirection.normalize() + : shootDirection.lengthSqr() < 1.0E-7D ? this.owner.getLookAngle().normalize() : shootDirection.normalize(); double committedDistance = Math.min(settings.range(), Math.max(settings.pathStep(), diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/fluid/AntiwaterBubbleColumnUtil.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/fluid/AntiwaterBubbleColumnUtil.java deleted file mode 100644 index 4afa42da..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/fluid/AntiwaterBubbleColumnUtil.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.craisinlord.antarchy.content.fluid; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.BubbleColumnBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.FluidState; - -/** Converts a full Antiwater cell next to a vanilla bubble-column source. */ -public final class AntiwaterBubbleColumnUtil { - private AntiwaterBubbleColumnUtil() { - } - - public static void update(LevelAccessor level, BlockPos pos, FluidState fluidState) { - if (!AntarchyFluidChecks.isAntiwater(fluidState) - || (!fluidState.isSource() && fluidState.getAmount() < 7)) { - return; - } - - BlockState below = level.getBlockState(pos.below()); - if (isBubbleSource(below)) { - replaceColumn(level, pos, Direction.UP, below.is(Blocks.MAGMA_BLOCK)); - return; - } - - BlockState above = level.getBlockState(pos.above()); - if (isBubbleSource(above)) { - replaceColumn(level, pos, Direction.DOWN, above.is(Blocks.MAGMA_BLOCK)); - } - } - - private static boolean isBubbleSource(BlockState state) { - return state.is(Blocks.MAGMA_BLOCK) || state.is(Blocks.SOUL_SAND); - } - - private static void replaceColumn(LevelAccessor level, BlockPos start, Direction direction, boolean dragDown) { - BlockPos.MutableBlockPos cursor = start.mutable(); - BlockState columnState = Blocks.BUBBLE_COLUMN.defaultBlockState() - .setValue(BubbleColumnBlock.DRAG_DOWN, dragDown); - - while (true) { - BlockState state = level.getBlockState(cursor); - FluidState fluidState = state.getFluidState(); - if (!AntarchyFluidChecks.isAntiwater(fluidState) - && !state.is(Blocks.BUBBLE_COLUMN)) { - return; - } - - level.setBlock(cursor, columnState, 3); - cursor.move(direction); - } - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/thoraxis/ThoraxisUndersideManager.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/thoraxis/ThoraxisUndersideManager.java index 8267bc80..2d0ad520 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/thoraxis/ThoraxisUndersideManager.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/worldgen/thoraxis/ThoraxisUndersideManager.java @@ -47,6 +47,7 @@ public final class ThoraxisUndersideManager { private static final int CROSSING_TIMEOUT_TICKS = 100; private static final int SETTLE_TIMEOUT_TICKS = 70; private static final double MIN_CROSSING_SPEED = 0.48D; + private static final double MIN_ENTRY_CROSSING_SPEED = 0.02D; private static final int RECENT_UNDERSIDE_WINDOW_TICKS = 40; private static final int UNDERSIDE_ENTRY_BORDER_Y = GRAVITY_FLIP_Y - 7; private static final int FRESH_ENTRY_DELAY_TICKS = 20; @@ -225,6 +226,16 @@ public final class ThoraxisUndersideManager { continue; } + if (AntarchyGravityApi.getGravityDirection(player) == AntarchyGravityDirection.DOWN + && player.getY() < UNDERSIDE_ENTRY_BORDER_Y + && flipReady(tracking, player.getUUID(), now)) { + AntarchyGravityApi.setAirborneGravityDirection(player, AntarchyGravityDirection.UP, true, THROAT_TRANSITION); + player.resetFallDistance(); + tracking.lastFlipTick.put(player.getUUID(), now); + refreshInvertedEffect(player); + continue; + } + if (AntarchyGravityApi.isGravityInverted(player) && player.getY() < EXIT_UNDERSIDE_Y) { refreshInvertedEffect(player); } @@ -297,7 +308,7 @@ public final class ThoraxisUndersideManager { AABB swept = player.getBoundingBox().expandTowards(velocity.scale(-1.0D)).inflate(0.08D); AntarchyGravityDirection direction = AntarchyGravityApi.getGravityDirection(player); return direction == AntarchyGravityDirection.DOWN - ? swept.minY < UNDERSIDE_ENTRY_BORDER_Y && swept.maxY >= UNDERSIDE_ENTRY_BORDER_Y && velocity.y <= -MIN_CROSSING_SPEED + ? swept.minY < UNDERSIDE_ENTRY_BORDER_Y && swept.maxY >= UNDERSIDE_ENTRY_BORDER_Y && velocity.y <= -MIN_ENTRY_CROSSING_SPEED : swept.minY <= GRAVITY_FLIP_Y && swept.maxY > GRAVITY_FLIP_Y && velocity.y >= MIN_CROSSING_SPEED; } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/UndertrialSpawnPlacementsMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/UndertrialSpawnPlacementsMixin.java new file mode 100644 index 00000000..e7d9235f --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/UndertrialSpawnPlacementsMixin.java @@ -0,0 +1,32 @@ +package com.craisinlord.antarchy.mixins; + +import com.craisinlord.antarchy.content.block.entity.UndertrialSpawnContext; +import net.minecraft.world.entity.MobSpawnType; +import net.minecraft.world.entity.SpawnPlacements; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +/** + * Lets the Undertrial's vanilla TrialSpawner path spawn entities whose normal + * placement predicate assumes floor support. TrialSpawner already performs + * its own no-collision and obstruction checks before this method is reached. + */ +@Mixin(SpawnPlacements.class) +public abstract class UndertrialSpawnPlacementsMixin { + @Inject(method = "checkSpawnRules", at = @At("RETURN"), cancellable = true) + private static void antarchy$allowUndertrialSpawn( + net.minecraft.world.entity.EntityType entityType, + net.minecraft.world.level.ServerLevelAccessor level, + MobSpawnType spawnReason, + net.minecraft.core.BlockPos pos, + net.minecraft.util.RandomSource random, + CallbackInfoReturnable cir) { + if (!cir.getReturnValueZ() + && spawnReason == MobSpawnType.TRIAL_SPAWNER + && UndertrialSpawnContext.isActive()) { + cir.setReturnValue(true); + } + } +} diff --git a/common-1.21.1/src/main/resources/antarchy-common.mixins.json b/common-1.21.1/src/main/resources/antarchy-common.mixins.json index 78bc2893..6add0a5f 100644 --- a/common-1.21.1/src/main/resources/antarchy-common.mixins.json +++ b/common-1.21.1/src/main/resources/antarchy-common.mixins.json @@ -30,6 +30,7 @@ "KingsTreeLocateCommandMixin", "LivingEntityJumpingAccessor", "CommandedMobMixin", + "UndertrialSpawnPlacementsMixin", "LivingEntityRoyalEffectsMixin", "JudgmentMarkEntityMixin", "RoyalJudgmentCombatMixin", diff --git a/common-1.21.1/src/main/resources/assets/antarchy/lang/en_us.json b/common-1.21.1/src/main/resources/assets/antarchy/lang/en_us.json index 8f08e181..2870db70 100644 --- a/common-1.21.1/src/main/resources/assets/antarchy/lang/en_us.json +++ b/common-1.21.1/src/main/resources/assets/antarchy/lang/en_us.json @@ -388,6 +388,8 @@ "item.antarchy.nightmare_scale": "Nightmare Scale", "item.antarchy.music_disc_underside": "Music Disc", "jukebox_song.antarchy.underside": "docshrekbot - underside", + "item.antarchy.music_disc_the_queen": "Music Disc", + "jukebox_song.antarchy.the_queen": "The Queen", "item.antarchy.nightmare_helmet": "Nightmare Helmet", "item.antarchy.nightmare_chestplate": "Nightmare Chestplate", "item.antarchy.nightmare_leggings": "Nightmare Leggings", @@ -543,7 +545,7 @@ "item.antarchy.royal_guardian_boots": "Royal Guardian Boots", "item.antarchy.royal_guardian_sword": "Royal Guardian Sword", "item.antarchy.royal_guardian_shield": "Royal Guardian Shield", - "tooltip.antarchy.royal_guardian_sword.mode": "Attunement: %s", + "tooltip.antarchy.royal_guardian_sword.mode": "Mode: %s", "tooltip.antarchy.royal_guardian_sword.mode.fire": "Fire", "tooltip.antarchy.royal_guardian_sword.mode.frost": "Frost", "tooltip.antarchy.royal_guardian_sword.mode.storm": "Storm", @@ -551,7 +553,7 @@ "tooltip.antarchy.royal_guardian_sword.frost": "Fully charged hits freeze the target and raise a fan of royal ice spikes.", "tooltip.antarchy.royal_guardian_sword.storm": "Fully charged hits call royal lightning that chains between nearby enemies.", "tooltip.antarchy.royal_guardian_sword.controls": "Sneak-use to cycle modes. Fully charged hits unleash the selected element (%s-second cooldown).", - "message.antarchy.royal_guardian_sword.mode": "Royal Guardian attuned to %s", + "message.antarchy.royal_guardian_sword.mode": "Royal Guardian Mode: %s", "item.antarchy.royal_assailant_helmet": "Royal Assailant Helmet", "item.antarchy.royal_assailant_chestplate": "Royal Assailant Chestplate", "item.antarchy.royal_assailant_leggings": "Royal Assailant Leggings", @@ -561,10 +563,10 @@ "tooltip.antarchy.royal_assailant_staff": "Opens paired tears that summon four allied Manticores for 30 seconds.", "tooltip.antarchy.royal_assailant_battleaxe.black_hole": "Use to create a Black Hole", "tooltip.antarchy.royal_assailant_battleaxe.dilation": "Hits apply Temporal Dilation", - "tooltip.antarchy.royal_guardian_shield.command": "Sneak-use to muster nearby mobs. Royal Investiture empowers their offense, speed, and resilience.", + "tooltip.antarchy.royal_guardian_shield.command": "Sneak-use to command nearby mobs to fight for you, empowering their offense, speed, and resilience.", "tooltip.antarchy.royal_guardian_helmet.judgment": "Marked for Judgment: +%s%% damage against marked targets", "tooltip.antarchy.royal_guardian_chestplate.judgment": "Marked for Judgment: +%s%% damage against marked targets", - "tooltip.antarchy.royal_guardian_chestplate.boundary": "Royal Boundary (B by default): Freezes incoming hostile projectiles and grants Strength to allies.", + "tooltip.antarchy.royal_guardian_chestplate.boundary": "Royal Boundary Key: Freezes incoming hostile projectiles and grants Strength to allies.", "tooltip.antarchy.royal_guardian_leggings.judgment": "Marked for Judgment: +%s%% damage against marked targets", "tooltip.antarchy.royal_guardian_boots.judgment": "Marked for Judgment: +%s%% damage against marked targets", "tooltip.antarchy.royal_assailant_chestplate.invert": "Press the inversion key to toggle inverted gravity on and off.", diff --git a/common-1.21.1/src/main/resources/assets/antarchy/models/item/music_disc_the_queen.json b/common-1.21.1/src/main/resources/assets/antarchy/models/item/music_disc_the_queen.json new file mode 100644 index 00000000..f6043afb --- /dev/null +++ b/common-1.21.1/src/main/resources/assets/antarchy/models/item/music_disc_the_queen.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "antarchy:item/music_disc_the_queen" + } +} diff --git a/common-1.21.1/src/main/resources/assets/antarchy/sounds.json b/common-1.21.1/src/main/resources/assets/antarchy/sounds.json index 5ceebe06..c583c64b 100644 --- a/common-1.21.1/src/main/resources/assets/antarchy/sounds.json +++ b/common-1.21.1/src/main/resources/assets/antarchy/sounds.json @@ -1065,6 +1065,14 @@ } ] }, + "the_queen": { + "sounds": [ + { + "name": "antarchy:music/game/thoraxis/the_queen", + "stream": true + } + ] + }, "lucid_lullaby": { "sounds": [ { diff --git a/common-1.21.1/src/main/resources/assets/antarchy/sounds/music/game/thoraxis/the_queen.ogg b/common-1.21.1/src/main/resources/assets/antarchy/sounds/music/game/thoraxis/the_queen.ogg new file mode 100644 index 00000000..ffdcf8b5 Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/sounds/music/game/thoraxis/the_queen.ogg differ diff --git a/common-1.21.1/src/main/resources/assets/antarchy/textures/item/music_disc_the_queen.png b/common-1.21.1/src/main/resources/assets/antarchy/textures/item/music_disc_the_queen.png new file mode 100644 index 00000000..b6c6f083 Binary files /dev/null and b/common-1.21.1/src/main/resources/assets/antarchy/textures/item/music_disc_the_queen.png differ diff --git a/common-1.21.1/src/main/resources/data/antarchy/jukebox_song/the_queen.json b/common-1.21.1/src/main/resources/data/antarchy/jukebox_song/the_queen.json new file mode 100644 index 00000000..6ffdc358 --- /dev/null +++ b/common-1.21.1/src/main/resources/data/antarchy/jukebox_song/the_queen.json @@ -0,0 +1,8 @@ +{ + "sound_event": "antarchy:the_queen", + "description": { + "translate": "jukebox_song.antarchy.the_queen" + }, + "length_in_seconds": 180.0, + "comparator_output": 13 +} diff --git a/common-1.21.1/src/main/resources/data/antarchy/loot_table/entities/queen.json b/common-1.21.1/src/main/resources/data/antarchy/loot_table/entities/queen.json index 39697c66..a5fc0b2c 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/loot_table/entities/queen.json +++ b/common-1.21.1/src/main/resources/data/antarchy/loot_table/entities/queen.json @@ -2,6 +2,21 @@ "type": "minecraft:entity", "random_sequence": "antarchy:entities/queen", "pools": [ + { + "rolls": 1.0, + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:killed_by_player" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "antarchy:music_disc_the_queen" + } + ] + }, { "rolls": 1.0, "bonus_rolls": 0.0, diff --git a/common-1.21.1/src/main/resources/data/c/tags/item/music_discs.json b/common-1.21.1/src/main/resources/data/c/tags/item/music_discs.json new file mode 100644 index 00000000..19c6f1f6 --- /dev/null +++ b/common-1.21.1/src/main/resources/data/c/tags/item/music_discs.json @@ -0,0 +1,7 @@ +{ + "replace": false, + "values": [ + "antarchy:music_disc_underside", + "antarchy:music_disc_the_queen" + ] +} diff --git a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClient.java b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClient.java index 8f996371..69778d05 100644 --- a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClient.java +++ b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClient.java @@ -1,9 +1,12 @@ package com.craisinlord.antarchy.fabric.client; import com.craisinlord.antarchy.Antarchy; +import com.craisinlord.antarchy.content.client.QueenMusicHandler; import com.craisinlord.antarchy.content.client.game.AntarchyComputerGames; import com.craisinlord.antarchy.fabric.network.AntarchyFabricClientNetworking; +import com.craisinlord.antarchy.fabric.registry.AntarchyFabricSounds; import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener; import net.fabricmc.fabric.api.resource.ResourceManagerHelper; import net.minecraft.resources.ResourceLocation; @@ -18,6 +21,7 @@ import java.util.concurrent.Executor; public final class AntarchyFabricClient implements ClientModInitializer { @Override public void onInitializeClient() { + ClientTickEvents.END_CLIENT_TICK.register(client -> QueenMusicHandler.tick(client, AntarchyFabricSounds.THE_QUEEN.get())); AntarchyFabricClientNetworking.register(); AntarchyFabricClientNetworking.bootstrapMultipartClient(); AntarchyFabricClientBootstrap.register(); diff --git a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/content/fluid/AntiwaterFluid.java b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/content/fluid/AntiwaterFluid.java index 06ff2046..9b32a774 100644 --- a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/content/fluid/AntiwaterFluid.java +++ b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/content/fluid/AntiwaterFluid.java @@ -1,5 +1,4 @@ package com.craisinlord.antarchy.fabric.content.fluid; -import com.craisinlord.antarchy.content.fluid.AntiwaterBubbleColumnUtil; import com.craisinlord.antarchy.fabric.registry.AntarchyFabricBlocks; import com.craisinlord.antarchy.fabric.registry.AntarchyFabricItems; import com.craisinlord.antarchy.fabric.registry.AntarchyFabricMisc; @@ -170,8 +169,6 @@ public abstract class AntiwaterFluid extends FlowingFluid { return; } - AntiwaterBubbleColumnUtil.update(level, pos, state); - if (!state.isSource() && !this.isFlowingStateValid(level, pos, state)) { level.setBlockAndUpdate(pos, net.minecraft.world.level.block.Blocks.AIR.defaultBlockState()); this.scheduleCleanup(level, pos); diff --git a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricItems.java b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricItems.java index 5f7090aa..12eebf96 100644 --- a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricItems.java +++ b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricItems.java @@ -92,6 +92,11 @@ public final class AntarchyFabricItems { .jukeboxPlayable(ResourceKey.create(Registries.JUKEBOX_SONG, ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "underside")))); + public static final DeferredItem MUSIC_DISC_THE_QUEEN = ITEMS.registerSimpleItem("music_disc_the_queen", + new Item.Properties().stacksTo(1).rarity(Rarity.RARE) + .jukeboxPlayable(ResourceKey.create(Registries.JUKEBOX_SONG, + ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "the_queen")))); + public static final DeferredItem PRIMORDIAL_SCUTE = ITEMS.registerSimpleItem("primordial_scute", new Item.Properties().rarity(Rarity.UNCOMMON)); diff --git a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricSounds.java b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricSounds.java index dfdc91bb..4a7dccd4 100644 --- a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricSounds.java +++ b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/registry/AntarchyFabricSounds.java @@ -528,6 +528,7 @@ public final class AntarchyFabricSounds { public static final DeferredHolder POTENT_NYXITE_GEYSER_CONTINUOUS_ACTIVE = registerSoundEvent("potent_nyxite_geyser_continuous_active"); public static final DeferredHolder MUSIC_DISC_UNDERSIDE = registerSoundEvent("music_disc_underside"); + public static final DeferredHolder THE_QUEEN = registerSoundEvent("the_queen"); public static final DeferredHolder WORM_HOOK_FLYING = registerSoundEvent("worm_hook_flying"); public static final DeferredHolder BLOOD_CRYSTAL_KATANA_DASH = registerSoundEvent("blood_crystal_katana_dash"); public static final DeferredHolder BLOOD_CRYSTAL_ARMOR_EQUIP = registerSoundEvent("blood_crystal_armor_equip"); diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyMobsConfig.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyMobsConfig.java index 66422232..2d63eac4 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyMobsConfig.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyMobsConfig.java @@ -686,7 +686,7 @@ public final class AntarchyMobsConfig { QUEEN_BLACK_HOLE_ACTIVE_TICKS = b.comment("Active duration for Royal Assailant axe black holes. Queen black holes always follow their 20.125-second animation.").defineInRange("queenBlackHoleActiveTicks", 120, 20, 1200); QUEEN_BLACK_HOLE_PULL_STRENGTH = b.defineInRange("queenBlackHolePullStrength", 0.16D, 0.0D, 2.0D); QUEEN_BLACK_HOLE_BLOCK_SUCTION_CAP = b.comment("Maximum terrain blocks a single Queen black hole may pull into itself.").defineInRange("queenBlackHoleBlockSuctionCap", 160, 0, 4096); - KING_FIREBALL_DAMAGE = b.defineInRange("kingFireballDamage", 32.0D, 0.0D, 1024.0D); + KING_FIREBALL_DAMAGE = b.defineInRange("kingFireballDamage", 48.0D, 0.0D, 1024.0D); KING_FIREBALL_RADIUS = b.defineInRange("kingFireballRadius", 4.5D, 0.5D, 32.0D); KING_FIREBALL_COOLDOWN_TICKS = b.defineInRange("kingFireballCooldownTicks", 150, 1, 2400); KING_ICEBALL_DAMAGE = b.defineInRange("kingIceballDamage", 18.0D, 0.0D, 1024.0D); diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/client/QueenMusicClientHandler.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/client/QueenMusicClientHandler.java new file mode 100644 index 00000000..f03588bd --- /dev/null +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/client/QueenMusicClientHandler.java @@ -0,0 +1,22 @@ +package com.craisinlord.antarchy.neoforge.client; + +import com.craisinlord.antarchy.Antarchy; +import com.craisinlord.antarchy.content.client.QueenMusicHandler; +import com.craisinlord.antarchy.neoforge.registry.AntarchyNeoforgeSounds; +import net.minecraft.client.Minecraft; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.client.event.ClientTickEvent; + +@EventBusSubscriber(modid = Antarchy.MODID, value = Dist.CLIENT) +public final class QueenMusicClientHandler { + private QueenMusicClientHandler() { + } + + @SubscribeEvent + public static void onClientTick(ClientTickEvent.Post event) { + Minecraft minecraft = Minecraft.getInstance(); + QueenMusicHandler.tick(minecraft, AntarchyNeoforgeSounds.THE_QUEEN.get()); + } +} diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/content/fluid/AntiwaterFluid.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/content/fluid/AntiwaterFluid.java index c685a1e8..61d1829a 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/content/fluid/AntiwaterFluid.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/content/fluid/AntiwaterFluid.java @@ -1,6 +1,5 @@ package com.craisinlord.antarchy.neoforge.content.fluid; -import com.craisinlord.antarchy.content.fluid.AntiwaterBubbleColumnUtil; import com.craisinlord.antarchy.neoforge.registry.AntarchyNeoforgeBlocks; import java.util.HashSet; import java.util.Set; @@ -174,8 +173,6 @@ public abstract class AntiwaterFluid extends BaseFlowingFluid { return; } - AntiwaterBubbleColumnUtil.update(level, pos, state); - if (!state.isSource() && !this.isFlowingStateValid(level, pos, state)) { level.setBlockAndUpdate(pos, net.minecraft.world.level.block.Blocks.AIR.defaultBlockState()); this.scheduleCleanup(level, pos); diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeItems.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeItems.java index 1cf45b1c..cde6c6b5 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeItems.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeItems.java @@ -100,6 +100,11 @@ public final class AntarchyNeoforgeItems { .jukeboxPlayable(ResourceKey.create(Registries.JUKEBOX_SONG, ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "underside")))); + public static final DeferredItem MUSIC_DISC_THE_QUEEN = ITEMS.registerSimpleItem("music_disc_the_queen", + new Item.Properties().stacksTo(1).rarity(Rarity.RARE) + .jukeboxPlayable(ResourceKey.create(Registries.JUKEBOX_SONG, + ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "the_queen")))); + private static final DeferredHolder ULTIMATE_ARMOR_MATERIAL = ARMOR_MATERIALS.register("ultimate", () -> new ArmorMaterial( createUltimateArmorDefense(), diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeSounds.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeSounds.java index c0a128b3..c36b516a 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeSounds.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeSounds.java @@ -205,6 +205,7 @@ public final class AntarchyNeoforgeSounds { public static final DeferredHolder POTENT_NYXITE_GEYSER_CONTINUOUS_START = registerSoundEvent("potent_nyxite_geyser_continuous_start"); public static final DeferredHolder POTENT_NYXITE_GEYSER_CONTINUOUS_ACTIVE = registerSoundEvent("potent_nyxite_geyser_continuous_active"); public static final DeferredHolder MUSIC_DISC_UNDERSIDE = registerSoundEvent("music_disc_underside"); + public static final DeferredHolder THE_QUEEN = registerSoundEvent("the_queen"); public static final DeferredHolder WORM_HOOK_FLYING = registerSoundEvent("worm_hook_flying"); public static final DeferredHolder BLOOD_CRYSTAL_KATANA_DASH = registerSoundEvent("blood_crystal_katana_dash"); public static final DeferredHolder BLOOD_CRYSTAL_ARMOR_EQUIP = registerSoundEvent("blood_crystal_armor_equip");