final 2.0 release
This commit is contained in:
1 parent
c6b47b496a
commit
93e2adbe12
33 files changed
+559
-145
No files matched your search
@@ -285,7 +285,7 @@ public final class AntarchySettings {
|
|||||||
private static int queenBlackHoleActiveTicks = 120;
|
private static int queenBlackHoleActiveTicks = 120;
|
||||||
private static double queenBlackHolePullStrength = 0.16D;
|
private static double queenBlackHolePullStrength = 0.16D;
|
||||||
private static int queenBlackHoleBlockSuctionCap = 160;
|
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 double kingFireballRadius = 4.5D;
|
||||||
private static int kingFireballCooldownTicks = 150;
|
private static int kingFireballCooldownTicks = 150;
|
||||||
private static double kingIceballDamage = 18.0D;
|
private static double kingIceballDamage = 18.0D;
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.craisinlord.antarchy.content.block;
|
package com.craisinlord.antarchy.content.block;
|
||||||
|
|
||||||
|
import com.craisinlord.antarchy.content.entity.royal.KingEntity;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.Entity;
|
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.ItemStack;
|
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) {
|
protected VoxelShape getCollisionShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
|
||||||
if (context instanceof EntityCollisionContext ecc) {
|
if (context instanceof EntityCollisionContext ecc) {
|
||||||
Entity entity = ecc.getEntity();
|
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;
|
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) {
|
public void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) {
|
||||||
|
if (entity instanceof KingEntity) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Vec3 motion = entity.getDeltaMovement();
|
Vec3 motion = entity.getDeltaMovement();
|
||||||
double slowedY = motion.y < 0.0D ? Math.max(motion.y * 0.4D, -0.08D) : motion.y;
|
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);
|
entity.setDeltaMovement(motion.x * 0.92D, slowedY, motion.z * 0.92D);
|
||||||
|
|||||||
+37
@@ -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<Integer> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-1
@@ -69,7 +69,9 @@ public final class UndertrialSpawnerBlockEntity extends BlockEntity implements T
|
|||||||
boolean ominous = state.getValue(UndertrialSpawnerBlock.OMINOUS);
|
boolean ominous = state.getValue(UndertrialSpawnerBlock.OMINOUS);
|
||||||
boolean rewardReady = previousState == TrialSpawnerState.EJECTING_REWARD
|
boolean rewardReady = previousState == TrialSpawnerState.EJECTING_REWARD
|
||||||
&& blockEntity.trialSpawner.getData().isReadyToEjectItems(level, 30.0F, blockEntity.trialSpawner.getTargetCooldownLength());
|
&& 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) {
|
if (rewardReady && blockEntity.getState() == TrialSpawnerState.EJECTING_REWARD) {
|
||||||
blockEntity.ejectReward(level, pos, ominous);
|
blockEntity.ejectReward(level, pos, ominous);
|
||||||
}
|
}
|
||||||
|
|||||||
+112
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
@@ -386,6 +386,7 @@ public final class CreativeTabContents {
|
|||||||
entry("duct_tape", "tools_and_utilities", "shears"),
|
entry("duct_tape", "tools_and_utilities", "shears"),
|
||||||
entry("bug_spray", "tools_and_utilities"),
|
entry("bug_spray", "tools_and_utilities"),
|
||||||
entry("music_disc_underside", "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("diamond_minecart", "tools_and_utilities", "minecart"),
|
||||||
entry("bile_bucket", "tools_and_utilities"),
|
entry("bile_bucket", "tools_and_utilities"),
|
||||||
entry("ichor_bucket", "tools_and_utilities"),
|
entry("ichor_bucket", "tools_and_utilities"),
|
||||||
|
|||||||
+11
-14
@@ -252,17 +252,7 @@ public class KingEntity extends RoyalBossEntity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean blocksRoyalBeamScheduling() {
|
protected boolean blocksRoyalBeamScheduling() {
|
||||||
if (this.royalChargeActive) {
|
return 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -423,7 +413,12 @@ public class KingEntity extends RoyalBossEntity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double royalBeamMinimumRange() {
|
protected double royalBeamMinimumRange() {
|
||||||
return AntarchySettings.kingBeamMinimumRange();
|
return Math.min(AntarchySettings.kingBeamMinimumRange(), 28.0D);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean royalBeamUsesTrackedAim() {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -758,10 +753,12 @@ public class KingEntity extends RoyalBossEntity {
|
|||||||
|
|
||||||
private boolean clearTreePatrolPath(Vec3 destination) {
|
private boolean clearTreePatrolPath(Vec3 destination) {
|
||||||
Vec3 start = this.position();
|
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;
|
double progress = sample / (double) TREE_ORBIT_PATH_SAMPLES;
|
||||||
Vec3 point = start.lerp(destination, progress);
|
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)) {
|
if (!this.level().noCollision(this, box)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
+180
-39
@@ -24,15 +24,12 @@ import net.minecraft.core.particles.DustParticleOptions;
|
|||||||
import net.minecraft.core.particles.ParticleTypes;
|
import net.minecraft.core.particles.ParticleTypes;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.network.chat.Component;
|
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.resources.ResourceLocation;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.sounds.SoundEvent;
|
import net.minecraft.sounds.SoundEvent;
|
||||||
import net.minecraft.sounds.SoundEvents;
|
import net.minecraft.sounds.SoundEvents;
|
||||||
import net.minecraft.sounds.SoundSource;
|
import net.minecraft.sounds.SoundSource;
|
||||||
import net.minecraft.ChatFormatting;
|
|
||||||
import net.minecraft.util.Mth;
|
import net.minecraft.util.Mth;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.BossEvent;
|
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 GRAVITY_STOMP_COOLDOWN = 180;
|
||||||
private static final int MOMENTUM_LOCK_COOLDOWN = 420;
|
private static final int MOMENTUM_LOCK_COOLDOWN = 420;
|
||||||
private static final int MOMENTUM_LOCK_DURATION = 90;
|
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_COOLDOWN = 360;
|
||||||
private static final int CRUSHING_GRAVITY_DURATION = 120;
|
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 double CRUSHING_GRAVITY_STRENGTH = 0.12D;
|
||||||
private static final int ACCELERATION_COOLDOWN = 500;
|
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 int QUEEN_CHRONOSPHERE_DURATION = 200;
|
||||||
private static final double QUEEN_CHRONOSPHERE_RADIUS = 20.0D;
|
private static final double QUEEN_CHRONOSPHERE_RADIUS = 40.0D;
|
||||||
private static final int ACCELERATION_DURATION = 140;
|
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 int BLACK_HOLE_COOLDOWN = 340;
|
||||||
private static final double QUEEN_BITE_COOLDOWN_MULTIPLIER = 1.5D;
|
private static final double QUEEN_BITE_COOLDOWN_MULTIPLIER = 1.5D;
|
||||||
private static final int GRAVITY_STOMP_TELEGRAPH_TICKS = 22;
|
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 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 double GRAVITIC_UPHEAVAL_RISE_SPEED = 0.55D;
|
||||||
private static final int LANDING_TELEGRAPH_TICKS = 30;
|
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 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 TAKEOFF_TICKS = 30;
|
||||||
private static final int LANDING_COOLDOWN_MIN = 300;
|
private static final int LANDING_COOLDOWN_MIN = 220;
|
||||||
private static final int LANDING_COOLDOWN_VARIANCE = 120;
|
private static final int LANDING_COOLDOWN_VARIANCE = 80;
|
||||||
private static final int BLACK_HOLE_FOLLOW_UP_DELAY = 22;
|
private static final int BLACK_HOLE_FOLLOW_UP_DELAY = 22;
|
||||||
private static final int CRUSHING_LANDING_DELAY = 40;
|
private static final int CRUSHING_LANDING_DELAY = 40;
|
||||||
private static final int MOMENTUM_VOLLEY_DELAY = MOMENTUM_LOCK_DURATION + 5;
|
private static final int MOMENTUM_VOLLEY_DELAY = MOMENTUM_LOCK_DURATION + 5;
|
||||||
@@ -142,13 +146,20 @@ public class QueenEntity extends RoyalBossEntity {
|
|||||||
private final List<FallingBlockEntity> graviticUpheavalBlocks = new ArrayList<>();
|
private final List<FallingBlockEntity> graviticUpheavalBlocks = new ArrayList<>();
|
||||||
@Nullable
|
@Nullable
|
||||||
private Vec3 pendingBlackHoleAnchor;
|
private Vec3 pendingBlackHoleAnchor;
|
||||||
private int queenLandingCooldownTicks = 300;
|
private int queenLandingCooldownTicks = 200;
|
||||||
private int queenLandingStageTicks;
|
private int queenLandingStageTicks;
|
||||||
|
private int queenGroundChargeCooldownTicks;
|
||||||
|
private int queenGroundChargeWindupTicks;
|
||||||
|
private int queenGroundChargeTicks;
|
||||||
private QueenLandingStage queenLandingStage = QueenLandingStage.AERIAL;
|
private QueenLandingStage queenLandingStage = QueenLandingStage.AERIAL;
|
||||||
@Nullable
|
@Nullable
|
||||||
private Vec3 queenLandingWaypoint;
|
private Vec3 queenLandingWaypoint;
|
||||||
@Nullable
|
@Nullable
|
||||||
|
private Vec3 queenGroundChargeDirection;
|
||||||
|
@Nullable
|
||||||
private Phase pendingPhaseSignature;
|
private Phase pendingPhaseSignature;
|
||||||
|
private boolean pendingPhaseTwoCrushingGravity;
|
||||||
|
private boolean pendingPhaseThreeChronosphere;
|
||||||
private QueenFollowUp queuedQueenFollowUp = QueenFollowUp.NONE;
|
private QueenFollowUp queuedQueenFollowUp = QueenFollowUp.NONE;
|
||||||
private int queuedQueenFollowUpTicks;
|
private int queuedQueenFollowUpTicks;
|
||||||
private int queuedQueenLandingRetryTicks;
|
private int queuedQueenLandingRetryTicks;
|
||||||
@@ -160,6 +171,7 @@ public class QueenEntity extends RoyalBossEntity {
|
|||||||
private boolean manticoreAnimationPending;
|
private boolean manticoreAnimationPending;
|
||||||
private final RoyalEffectController royalEffects = new RoyalEffectController();
|
private final RoyalEffectController royalEffects = new RoyalEffectController();
|
||||||
private final Map<UUID, Vec3> frozenVelocities = new HashMap<>();
|
private final Map<UUID, Vec3> frozenVelocities = new HashMap<>();
|
||||||
|
private final Map<UUID, Vec3> frozenPositions = new HashMap<>();
|
||||||
private long naturalTrailSiteId = Long.MIN_VALUE;
|
private long naturalTrailSiteId = Long.MIN_VALUE;
|
||||||
@Nullable
|
@Nullable
|
||||||
private BlockPos naturalTrailHome;
|
private BlockPos naturalTrailHome;
|
||||||
@@ -214,6 +226,8 @@ public class QueenEntity extends RoyalBossEntity {
|
|||||||
|| this.queenLandingStage == QueenLandingStage.DESCENT
|
|| this.queenLandingStage == QueenLandingStage.DESCENT
|
||||||
|| this.queenLandingStage == QueenLandingStage.IMPACT
|
|| this.queenLandingStage == QueenLandingStage.IMPACT
|
||||||
|| this.queenLandingStage == QueenLandingStage.TAKEOFF
|
|| this.queenLandingStage == QueenLandingStage.TAKEOFF
|
||||||
|
|| this.queenGroundChargeWindupTicks > 0
|
||||||
|
|| this.queenGroundChargeTicks > 0
|
||||||
|| this.isQueenAbilityTelegraphActive();
|
|| this.isQueenAbilityTelegraphActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,16 +245,6 @@ public class QueenEntity extends RoyalBossEntity {
|
|||||||
this.getNavigation().stop();
|
this.getNavigation().stop();
|
||||||
this.setDeltaMovement(this.getDeltaMovement().scale(0.35D));
|
this.setDeltaMovement(this.getDeltaMovement().scale(0.35D));
|
||||||
this.playRoyalSound(AntarchySoundEvents.QUEEN_ROAR.get(), nextPhase == Phase.THREE ? 0.66F : 0.82F);
|
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
|
@Override
|
||||||
@@ -260,22 +264,34 @@ public class QueenEntity extends RoyalBossEntity {
|
|||||||
if (nextPhase == Phase.TWO) {
|
if (nextPhase == Phase.TWO) {
|
||||||
this.momentumLockCooldownTicks = 0;
|
this.momentumLockCooldownTicks = 0;
|
||||||
this.pendingPhaseSignature = Phase.TWO;
|
this.pendingPhaseSignature = Phase.TWO;
|
||||||
|
this.pendingPhaseTwoCrushingGravity = true;
|
||||||
this.queenLandingCooldownTicks = Math.min(this.queenLandingCooldownTicks, 100);
|
this.queenLandingCooldownTicks = Math.min(this.queenLandingCooldownTicks, 100);
|
||||||
} else if (nextPhase == Phase.THREE) {
|
} else if (nextPhase == Phase.THREE) {
|
||||||
this.accelerationCooldownTicks = 0;
|
this.accelerationCooldownTicks = 0;
|
||||||
|
this.queenChronosphereCooldownTicks = 0;
|
||||||
this.pendingPhaseSignature = Phase.THREE;
|
this.pendingPhaseSignature = Phase.THREE;
|
||||||
|
this.pendingPhaseThreeChronosphere = true;
|
||||||
this.queenLandingCooldownTicks = 0;
|
this.queenLandingCooldownTicks = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double biteApproachSpeed() {
|
protected double biteApproachSpeed() {
|
||||||
return 1.55D;
|
return this.queenLandingStage == QueenLandingStage.GROUND_COMBAT && !this.isRoyalFlying()
|
||||||
|
? 1.9D : 1.55D;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double combatStandoffDistance() {
|
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
|
@Override
|
||||||
@@ -327,6 +343,11 @@ public class QueenEntity extends RoyalBossEntity {
|
|||||||
&& !this.isAlliedTo(target);
|
&& !this.isAlliedTo(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean shouldPlayQueenMusic() {
|
||||||
|
LivingEntity target = this.getTarget();
|
||||||
|
return !this.isDeadOrDying() && target != null && target.isAlive() && this.canAttack(target);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected SoundEvent royalFlyLoopSound() {
|
protected SoundEvent royalFlyLoopSound() {
|
||||||
return AntarchySoundEvents.QUEEN_FLY_LOOP.get();
|
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) {
|
public static boolean isFieldImmune(Entity entity) {
|
||||||
return entity.getType().is(AntarchyTags.Entities.QUEEN_DOES_NOT_ATTACK);
|
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
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
super.tick();
|
super.tick();
|
||||||
@@ -439,7 +479,7 @@ public class QueenEntity extends RoyalBossEntity {
|
|||||||
private void tickQueenLandingSequence(LivingEntity target) {
|
private void tickQueenLandingSequence(LivingEntity target) {
|
||||||
if (this.queenLandingStage == QueenLandingStage.AERIAL && this.isRoyalFlying()
|
if (this.queenLandingStage == QueenLandingStage.AERIAL && this.isRoyalFlying()
|
||||||
&& !this.isQueenAbilityTelegraphActive()
|
&& !this.isQueenAbilityTelegraphActive()
|
||||||
&& this.queenLandingCooldownTicks-- <= 0 && target.onGround()) {
|
&& this.queenLandingCooldownTicks-- <= 0) {
|
||||||
this.beginQueenLanding(target);
|
this.beginQueenLanding(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -450,6 +490,7 @@ public class QueenEntity extends RoyalBossEntity {
|
|||||||
this.tickQueenLandingIndicator();
|
this.tickQueenLandingIndicator();
|
||||||
if (--this.queenLandingStageTicks <= 0) {
|
if (--this.queenLandingStageTicks <= 0) {
|
||||||
this.queenLandingStage = QueenLandingStage.DESCENT;
|
this.queenLandingStage = QueenLandingStage.DESCENT;
|
||||||
|
this.queenLandingStageTicks = LANDING_DESCENT_TIMEOUT_TICKS;
|
||||||
this.playRoyalSound(AntarchySoundEvents.QUEEN_FLY_LOOP.get(), 0.72F);
|
this.playRoyalSound(AntarchySoundEvents.QUEEN_FLY_LOOP.get(), 0.72F);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -468,6 +509,9 @@ public class QueenEntity extends RoyalBossEntity {
|
|||||||
this.queenLandingStage = QueenLandingStage.IMPACT;
|
this.queenLandingStage = QueenLandingStage.IMPACT;
|
||||||
this.queenLandingStageTicks = LANDING_IMPACT_TICKS;
|
this.queenLandingStageTicks = LANDING_IMPACT_TICKS;
|
||||||
this.performGravityStomp((ServerLevel) this.level(), target);
|
this.performGravityStomp((ServerLevel) this.level(), target);
|
||||||
|
} else if (--this.queenLandingStageTicks <= 0) {
|
||||||
|
this.resetQueenLandingSequence();
|
||||||
|
this.queenLandingCooldownTicks = 40;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case IMPACT -> {
|
case IMPACT -> {
|
||||||
@@ -476,10 +520,12 @@ public class QueenEntity extends RoyalBossEntity {
|
|||||||
if (--this.queenLandingStageTicks <= 0) {
|
if (--this.queenLandingStageTicks <= 0) {
|
||||||
this.queenLandingStage = QueenLandingStage.GROUND_COMBAT;
|
this.queenLandingStage = QueenLandingStage.GROUND_COMBAT;
|
||||||
this.queenLandingStageTicks = GROUND_COMBAT_TICKS;
|
this.queenLandingStageTicks = GROUND_COMBAT_TICKS;
|
||||||
|
this.queenGroundChargeCooldownTicks = 20;
|
||||||
this.queenLandingWaypoint = null;
|
this.queenLandingWaypoint = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case GROUND_COMBAT -> {
|
case GROUND_COMBAT -> {
|
||||||
|
this.tickQueenGroundCharge(target);
|
||||||
if (--this.queenLandingStageTicks <= 0) {
|
if (--this.queenLandingStageTicks <= 0) {
|
||||||
this.beginQueenTakeoff();
|
this.beginQueenTakeoff();
|
||||||
}
|
}
|
||||||
@@ -563,6 +609,7 @@ public class QueenEntity extends RoyalBossEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void beginQueenTakeoff() {
|
private void beginQueenTakeoff() {
|
||||||
|
this.clearQueenGroundCharge();
|
||||||
this.queenLandingStage = QueenLandingStage.TAKEOFF;
|
this.queenLandingStage = QueenLandingStage.TAKEOFF;
|
||||||
this.queenLandingStageTicks = TAKEOFF_TICKS;
|
this.queenLandingStageTicks = TAKEOFF_TICKS;
|
||||||
this.triggerAnim("wing_action", "wing_gust");
|
this.triggerAnim("wing_action", "wing_gust");
|
||||||
@@ -580,6 +627,7 @@ public class QueenEntity extends RoyalBossEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void resetQueenLandingSequence() {
|
private void resetQueenLandingSequence() {
|
||||||
|
this.clearQueenGroundCharge();
|
||||||
if (this.queenLandingStage != QueenLandingStage.AERIAL) {
|
if (this.queenLandingStage != QueenLandingStage.AERIAL) {
|
||||||
this.setRoyalFlying(true);
|
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() {
|
private void tickDreamFireballs() {
|
||||||
if (this.isRoyalRecoveryActive()) return;
|
if (this.isRoyalRecoveryActive()) return;
|
||||||
if (!(this.level() instanceof ServerLevel level)) return;
|
if (!(this.level() instanceof ServerLevel level)) return;
|
||||||
@@ -654,7 +761,7 @@ public class QueenEntity extends RoyalBossEntity {
|
|||||||
}
|
}
|
||||||
case LANDING -> {
|
case LANDING -> {
|
||||||
if (this.queenLandingStage == QueenLandingStage.AERIAL
|
if (this.queenLandingStage == QueenLandingStage.AERIAL
|
||||||
&& this.isRoyalFlying() && target.onGround()) {
|
&& this.isRoyalFlying()) {
|
||||||
this.clearQueuedQueenFollowUp();
|
this.clearQueuedQueenFollowUp();
|
||||||
this.queenLandingCooldownTicks = 0;
|
this.queenLandingCooldownTicks = 0;
|
||||||
} else if (--this.queuedQueenLandingRetryTicks <= 0) {
|
} else if (--this.queuedQueenLandingRetryTicks <= 0) {
|
||||||
@@ -908,9 +1015,11 @@ public class QueenEntity extends RoyalBossEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Phase phase = this.phase();
|
Phase phase = this.phase();
|
||||||
|
boolean accelerationBlocksMajor = this.royalEffects.active("acceleration")
|
||||||
|
&& !this.pendingPhaseThreeChronosphere;
|
||||||
boolean majorBusy = this.royalEffects.active("momentum_lock")
|
boolean majorBusy = this.royalEffects.active("momentum_lock")
|
||||||
|| this.royalEffects.active("crushing_gravity")
|
|| this.royalEffects.active("crushing_gravity")
|
||||||
|| this.royalEffects.active("acceleration")
|
|| accelerationBlocksMajor
|
||||||
|| this.royalEffects.active("gravitic_upheaval");
|
|| this.royalEffects.active("gravitic_upheaval");
|
||||||
String[] candidates = switch (phase) {
|
String[] candidates = switch (phase) {
|
||||||
case ONE -> new String[] {"gravity_stomp", "black_hole"};
|
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"};
|
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"
|
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
|
String selected = forcedAttack != null
|
||||||
&& this.queenAttackReady(forcedAttack, phase, majorBusy)
|
&& this.queenAttackReady(forcedAttack, phase, majorBusy)
|
||||||
? forcedAttack : this.attackScheduler.chooseWeighted(candidates, id -> {
|
? forcedAttack : this.attackScheduler.chooseWeighted(candidates, id -> {
|
||||||
@@ -978,7 +1089,13 @@ public class QueenEntity extends RoyalBossEntity {
|
|||||||
})) return;
|
})) return;
|
||||||
this.lastQueenMajorAttack = selected;
|
this.lastQueenMajorAttack = selected;
|
||||||
if (selected.equals(forcedAttack)) {
|
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" -> {
|
case "queen_chronosphere" -> {
|
||||||
this.queenChronosphereCooldownTicks = cooldown;
|
this.queenChronosphereCooldownTicks = cooldown;
|
||||||
TimeDilationFieldEntity field = TimeDilationApi.createField(level, this.position(),
|
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);
|
field.configureQueenChronosphere(this);
|
||||||
this.startRoyalRecovery(35);
|
this.startRoyalRecovery(35);
|
||||||
}
|
}
|
||||||
@@ -1078,7 +1196,8 @@ public class QueenEntity extends RoyalBossEntity {
|
|||||||
return switch (phase) {
|
return switch (phase) {
|
||||||
case ONE -> "black_hole".equals(id) ? 6 : 3;
|
case ONE -> "black_hole".equals(id) ? 6 : 3;
|
||||||
case TWO -> switch (id) {
|
case TWO -> switch (id) {
|
||||||
case "momentum_lock", "crushing_gravity" -> 6;
|
case "crushing_gravity" -> 12;
|
||||||
|
case "momentum_lock" -> 7;
|
||||||
case "debris_cyclone" -> 5;
|
case "debris_cyclone" -> 5;
|
||||||
case "gravitic_upheaval" -> 4;
|
case "gravitic_upheaval" -> 4;
|
||||||
case "gravity_stomp" -> 3;
|
case "gravity_stomp" -> 3;
|
||||||
@@ -1087,11 +1206,11 @@ public class QueenEntity extends RoyalBossEntity {
|
|||||||
};
|
};
|
||||||
case THREE -> switch (id) {
|
case THREE -> switch (id) {
|
||||||
case "acceleration" -> 7;
|
case "acceleration" -> 7;
|
||||||
case "queen_chronosphere" -> 6;
|
case "queen_chronosphere", "crushing_gravity" -> 10;
|
||||||
case "black_hole", "crushing_gravity" -> 5;
|
case "black_hole" -> 5;
|
||||||
case "debris_cyclone", "gravitic_upheaval" -> 5;
|
case "debris_cyclone", "gravitic_upheaval" -> 5;
|
||||||
case "gravity_stomp" -> 4;
|
case "gravity_stomp" -> 4;
|
||||||
case "momentum_lock" -> 2;
|
case "momentum_lock" -> 7;
|
||||||
default -> 0;
|
default -> 0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -1296,7 +1415,9 @@ public class QueenEntity extends RoyalBossEntity {
|
|||||||
}
|
}
|
||||||
if (this.momentumLockTelegraphTicks <= 14) {
|
if (this.momentumLockTelegraphTicks <= 14) {
|
||||||
for (LivingEntity living : level.getEntitiesOfClass(LivingEntity.class,
|
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);
|
this.spawnMomentumTargetCage(level, living);
|
||||||
if (this.momentumLockTelegraphTicks == 12) {
|
if (this.momentumLockTelegraphTicks == 12) {
|
||||||
NightmareBiteEntity.spawnTelegraphAt(level, living, true);
|
NightmareBiteEntity.spawnTelegraphAt(level, living, true);
|
||||||
@@ -1318,7 +1439,9 @@ public class QueenEntity extends RoyalBossEntity {
|
|||||||
double progress = elapsed / (double) CRUSHING_GRAVITY_TELEGRAPH_TICKS;
|
double progress = elapsed / (double) CRUSHING_GRAVITY_TELEGRAPH_TICKS;
|
||||||
if (this.tickCount % 2 == 0) {
|
if (this.tickCount % 2 == 0) {
|
||||||
for (LivingEntity living : level.getEntitiesOfClass(LivingEntity.class,
|
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;
|
double downSign = AntarchyGravityApi.isGravityInverted(living) ? 1.0D : -1.0D;
|
||||||
this.spawnCrushingGravityArrow(level, living, downSign, progress);
|
this.spawnCrushingGravityArrow(level, living, downSign, progress);
|
||||||
}
|
}
|
||||||
@@ -1644,12 +1767,15 @@ public class QueenEntity extends RoyalBossEntity {
|
|||||||
this.momentumLockCooldownTicks = MOMENTUM_LOCK_COOLDOWN;
|
this.momentumLockCooldownTicks = MOMENTUM_LOCK_COOLDOWN;
|
||||||
this.royalEffects.start("momentum_lock", MOMENTUM_LOCK_DURATION, () -> {
|
this.royalEffects.start("momentum_lock", MOMENTUM_LOCK_DURATION, () -> {
|
||||||
this.frozenVelocities.clear();
|
this.frozenVelocities.clear();
|
||||||
|
this.frozenPositions.clear();
|
||||||
for (Entity entity : level.getEntitiesOfClass(Entity.class,
|
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()) {
|
if (entity == this || isFieldImmune(entity) || entity instanceof Player player && player.isCreative()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
this.frozenVelocities.put(entity.getUUID(), entity.getDeltaMovement());
|
this.frozenVelocities.put(entity.getUUID(), entity.getDeltaMovement());
|
||||||
|
this.frozenPositions.put(entity.getUUID(), entity.position());
|
||||||
}
|
}
|
||||||
}, this::tickMomentumLockEffect, () -> {
|
}, this::tickMomentumLockEffect, () -> {
|
||||||
for (Map.Entry<UUID, Vec3> entry : this.frozenVelocities.entrySet()) {
|
for (Map.Entry<UUID, Vec3> entry : this.frozenVelocities.entrySet()) {
|
||||||
@@ -1660,6 +1786,7 @@ public class QueenEntity extends RoyalBossEntity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.frozenVelocities.clear();
|
this.frozenVelocities.clear();
|
||||||
|
this.frozenPositions.clear();
|
||||||
this.startRoyalRecovery(35);
|
this.startRoyalRecovery(35);
|
||||||
});
|
});
|
||||||
this.playRoyalSound(AntarchySoundEvents.QUEEN_ROAR.get(), 0.5F);
|
this.playRoyalSound(AntarchySoundEvents.QUEEN_ROAR.get(), 0.5F);
|
||||||
@@ -1674,8 +1801,13 @@ public class QueenEntity extends RoyalBossEntity {
|
|||||||
Entity entity = level.getEntity(entry.getKey());
|
Entity entity = level.getEntity(entry.getKey());
|
||||||
if (entity == null || !entity.isAlive()) {
|
if (entity == null || !entity.isAlive()) {
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
|
this.frozenPositions.remove(entry.getKey());
|
||||||
continue;
|
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.setDeltaMovement(Vec3.ZERO);
|
||||||
entity.fallDistance = 0.0F;
|
entity.fallDistance = 0.0F;
|
||||||
entity.hasImpulse = true;
|
entity.hasImpulse = true;
|
||||||
@@ -1694,13 +1826,17 @@ public class QueenEntity extends RoyalBossEntity {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (Entity entity : level.getEntitiesOfClass(Entity.class,
|
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()) {
|
if (entity == this || isFieldImmune(entity) || entity instanceof Player player && player.isCreative()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
double downSign = AntarchyGravityApi.isGravityInverted(entity) ? 1.0D : -1.0D;
|
double downSign = AntarchyGravityApi.isGravityInverted(entity) ? 1.0D : -1.0D;
|
||||||
entity.setDeltaMovement(entity.getDeltaMovement().add(0.0D, downSign * CRUSHING_GRAVITY_STRENGTH, 0.0D));
|
entity.setDeltaMovement(entity.getDeltaMovement().add(0.0D, downSign * CRUSHING_GRAVITY_STRENGTH, 0.0D));
|
||||||
entity.hasImpulse = true;
|
entity.hasImpulse = true;
|
||||||
|
if (entity instanceof LivingEntity living && this.tickCount % 8 == 0) {
|
||||||
|
this.spawnCrushingGravityArrow(level, living, downSign, 1.0D);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (this.tickCount % 8 == 0) {
|
if (this.tickCount % 8 == 0) {
|
||||||
level.sendParticles(ACCEL_DUST, this.getX(), this.getY() + 1.0D, this.getZ(), 20,
|
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.royalEffects.clear();
|
||||||
this.frozenVelocities.clear();
|
this.frozenVelocities.clear();
|
||||||
|
this.frozenPositions.clear();
|
||||||
removeAccelModifier(this.getAttribute(Attributes.MOVEMENT_SPEED), ACCEL_SPEED_ID);
|
removeAccelModifier(this.getAttribute(Attributes.MOVEMENT_SPEED), ACCEL_SPEED_ID);
|
||||||
removeAccelModifier(this.getAttribute(Attributes.FLYING_SPEED), ACCEL_FLY_ID);
|
removeAccelModifier(this.getAttribute(Attributes.FLYING_SPEED), ACCEL_FLY_ID);
|
||||||
super.die(damageSource);
|
super.die(damageSource);
|
||||||
@@ -1804,6 +1941,8 @@ public class QueenEntity extends RoyalBossEntity {
|
|||||||
tag.putInt("DebrisCycloneCooldownTicks", this.debrisCycloneCooldownTicks);
|
tag.putInt("DebrisCycloneCooldownTicks", this.debrisCycloneCooldownTicks);
|
||||||
tag.putInt("GraviticUpheavalCooldownTicks", this.graviticUpheavalCooldownTicks);
|
tag.putInt("GraviticUpheavalCooldownTicks", this.graviticUpheavalCooldownTicks);
|
||||||
tag.putInt("QueenLandingCooldownTicks", this.queenLandingCooldownTicks);
|
tag.putInt("QueenLandingCooldownTicks", this.queenLandingCooldownTicks);
|
||||||
|
tag.putBoolean("PendingPhaseTwoCrushingGravity", this.pendingPhaseTwoCrushingGravity);
|
||||||
|
tag.putBoolean("PendingPhaseThreeChronosphere", this.pendingPhaseThreeChronosphere);
|
||||||
tag.putString("QueuedQueenFollowUp", this.queuedQueenFollowUp.name());
|
tag.putString("QueuedQueenFollowUp", this.queuedQueenFollowUp.name());
|
||||||
tag.putInt("QueuedQueenFollowUpTicks", this.queuedQueenFollowUpTicks);
|
tag.putInt("QueuedQueenFollowUpTicks", this.queuedQueenFollowUpTicks);
|
||||||
tag.putInt("QueuedQueenLandingRetryTicks", this.queuedQueenLandingRetryTicks);
|
tag.putInt("QueuedQueenLandingRetryTicks", this.queuedQueenLandingRetryTicks);
|
||||||
@@ -1830,7 +1969,9 @@ public class QueenEntity extends RoyalBossEntity {
|
|||||||
this.debrisCycloneCooldownTicks = Math.max(0, tag.getInt("DebrisCycloneCooldownTicks"));
|
this.debrisCycloneCooldownTicks = Math.max(0, tag.getInt("DebrisCycloneCooldownTicks"));
|
||||||
this.graviticUpheavalCooldownTicks = Math.max(0, tag.getInt("GraviticUpheavalCooldownTicks"));
|
this.graviticUpheavalCooldownTicks = Math.max(0, tag.getInt("GraviticUpheavalCooldownTicks"));
|
||||||
this.queenLandingCooldownTicks = tag.contains("QueenLandingCooldownTicks")
|
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")) {
|
if (tag.contains("QueuedQueenFollowUp")) {
|
||||||
try {
|
try {
|
||||||
this.queuedQueenFollowUp = QueenFollowUp.valueOf(tag.getString("QueuedQueenFollowUp"));
|
this.queuedQueenFollowUp = QueenFollowUp.valueOf(tag.getString("QueuedQueenFollowUp"));
|
||||||
|
|||||||
+10
@@ -32,6 +32,16 @@ public final class RoyalAssailantBlackHoleEntity extends RoyalBlackHoleEntity {
|
|||||||
return Math.max(2.0D, this.radius() * 0.55D);
|
return Math.max(2.0D, this.radius() * 0.55D);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected double effectGrowthStart() {
|
||||||
|
return 0.45D;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected double pullRadius() {
|
||||||
|
return this.effectRadius();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean hasVisibleTimeDilationField() {
|
protected boolean hasVisibleTimeDilationField() {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
+15
-4
@@ -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_START = 0.45D;
|
||||||
private static final double EFFECT_GROWTH_END = 1.6D;
|
private static final double EFFECT_GROWTH_END = 1.6D;
|
||||||
private static final double EFFECT_GROWTH_FRACTION = 0.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 MODEL_BASELINE_Y = 24.0D;
|
||||||
private static final double CORE_CUBE_CENTER_Y = 146.0D;
|
private static final double CORE_CUBE_CENTER_Y = 146.0D;
|
||||||
private static final double CORE_START_OFFSET_Y = -100.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
|
double progress = this.activeTicks <= 0
|
||||||
? 1.0D
|
? 1.0D
|
||||||
: Mth.clamp(this.age / (this.activeTicks * EFFECT_GROWTH_FRACTION), 0.0D, 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() {
|
public boolean isCollapsing() {
|
||||||
@@ -228,6 +234,10 @@ public class RoyalBlackHoleEntity extends Entity implements GeoEntity {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected double pullRadius() {
|
||||||
|
return this.effectRadius() * QUEEN_PULL_RADIUS_SCALE;
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns the center of the animated black-hole cube in world coordinates. */
|
/** Returns the center of the animated black-hole cube in world coordinates. */
|
||||||
public Vec3 effectCenter() {
|
public Vec3 effectCenter() {
|
||||||
double animationSeconds = Math.min(CORE_RISE_END_SECONDS, this.animationAge / 20.0D);
|
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() {
|
private void applyPull() {
|
||||||
Vec3 center = this.effectCenter();
|
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))) {
|
for (Entity entity : this.level().getEntitiesOfClass(Entity.class, new AABB(center, center).inflate(radius))) {
|
||||||
if (entity == this || entity instanceof TimeDilationFieldEntity || this.isImmune(entity)) {
|
if (entity == this || entity instanceof TimeDilationFieldEntity || this.isImmune(entity)) {
|
||||||
continue;
|
continue;
|
||||||
@@ -302,9 +312,10 @@ public class RoyalBlackHoleEntity extends Entity implements GeoEntity {
|
|||||||
|
|
||||||
Vec3 center = this.effectCenter();
|
Vec3 center = this.effectCenter();
|
||||||
Vec3 terrainOrigin = center;
|
Vec3 terrainOrigin = center;
|
||||||
double radius = this.effectRadius();
|
double radius = this.pullRadius();
|
||||||
int pulledThisTick = 0;
|
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++) {
|
&& this.suckedBlocks < cap; attempt++) {
|
||||||
BlockPos pos = BlockPos.containing(
|
BlockPos pos = BlockPos.containing(
|
||||||
terrainOrigin.x + (this.random.nextDouble() * 2.0D - 1.0D) * radius,
|
terrainOrigin.x + (this.random.nextDouble() * 2.0D - 1.0D) * radius,
|
||||||
|
|||||||
+33
-16
@@ -339,6 +339,11 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult
|
|||||||
return Math.max(10, Mth.floor(AntarchySettings.royalBossBiteCooldownTicks() * phase.cooldownScale()));
|
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() {
|
public String geoNameForRender() {
|
||||||
return this.geoName();
|
return this.geoName();
|
||||||
}
|
}
|
||||||
@@ -543,19 +548,21 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.initializeMultiplayerScaling(primaryTarget);
|
this.initializeMultiplayerScaling(primaryTarget);
|
||||||
|
this.assignHeadTargets(primaryTarget);
|
||||||
|
|
||||||
this.tickCombatLocomotionMode(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;
|
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();
|
this.tickBodyCrush();
|
||||||
|
|
||||||
Phase phase = this.phase();
|
Phase phase = this.phase();
|
||||||
@@ -590,10 +597,7 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult
|
|||||||
|| super.isInvulnerableTo(source);
|
|| super.isInvulnerableTo(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tickRoyalBeam(LivingEntity primaryTarget) {
|
private void tickRoyalBeam(LivingEntity primaryTarget, boolean allowScheduling) {
|
||||||
if (this.recoveryWindowTicks > 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Phase phase = this.phase();
|
Phase phase = this.phase();
|
||||||
int activeBeams = 0;
|
int activeBeams = 0;
|
||||||
for (RoyalHead head : this.heads) {
|
for (RoyalHead head : this.heads) {
|
||||||
@@ -625,7 +629,8 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult
|
|||||||
beamTarget,
|
beamTarget,
|
||||||
this.royalBeamSettings(),
|
this.royalBeamSettings(),
|
||||||
this.royalBeamTerrainMode(head),
|
this.royalBeamTerrainMode(head),
|
||||||
end -> this.setRoyalBeamEndPosition(head.slot(), end));
|
end -> this.setRoyalBeamEndPosition(head.slot(), end),
|
||||||
|
this.royalBeamUsesTrackedAim());
|
||||||
Vec3 beamEnd = controller.beamEndPosition();
|
Vec3 beamEnd = controller.beamEndPosition();
|
||||||
if (beamEnd != null) {
|
if (beamEnd != null) {
|
||||||
this.tickRoyalBeamEffects(head, this.beamAnchor(head), beamEnd);
|
this.tickRoyalBeamEffects(head, this.beamAnchor(head), beamEnd);
|
||||||
@@ -635,6 +640,12 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (!allowScheduling || this.recoveryWindowTicks > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (RoyalHead head : this.heads) {
|
||||||
|
int index = head.slot().ordinal();
|
||||||
if (activeBeams >= this.beamVolleyLimit) {
|
if (activeBeams >= this.beamVolleyLimit) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -694,6 +705,11 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult
|
|||||||
return phase.maxConcurrentHeadAttacks();
|
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() {
|
protected boolean isRoyalRecoveryActive() {
|
||||||
return this.recoveryWindowTicks > 0;
|
return this.recoveryWindowTicks > 0;
|
||||||
}
|
}
|
||||||
@@ -786,6 +802,7 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult
|
|||||||
protected final void stopRoyalBeamsForDirectedAttack() {
|
protected final void stopRoyalBeamsForDirectedAttack() {
|
||||||
for (RoyalHead head : this.heads) {
|
for (RoyalHead head : this.heads) {
|
||||||
if (head.beamActive() || head.shooting()) {
|
if (head.beamActive() || head.shooting()) {
|
||||||
|
this.attackScheduler.cancel(this.headLane(head));
|
||||||
this.stopRoyalBeam(head);
|
this.stopRoyalBeam(head);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1059,7 +1076,7 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult
|
|||||||
}
|
}
|
||||||
Vec3 anchor = this.headAnchor(head);
|
Vec3 anchor = this.headAnchor(head);
|
||||||
double reach = this.biteReach();
|
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);
|
DamageSource damageSource = this.damageSources().mobAttack(this);
|
||||||
AABB box = new AABB(anchor, anchor).inflate(reach);
|
AABB box = new AABB(anchor, anchor).inflate(reach);
|
||||||
for (LivingEntity living : this.level().getEntitiesOfClass(LivingEntity.class, box, entity -> entity.isAlive() && entity != this)) {
|
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();
|
AntarchyGravityApi.getGravityDirection(this)).normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean targetInBeamLine(RoyalHead head, LivingEntity target) {
|
protected boolean targetInBeamLine(RoyalHead head, LivingEntity target) {
|
||||||
Vec3 origin = this.beamAnchor(head);
|
Vec3 origin = this.beamAnchor(head);
|
||||||
Vec3 direction = this.beamDirection(head);
|
Vec3 direction = this.beamDirection(head);
|
||||||
Vec3 toTarget = target.getEyePosition().subtract(origin);
|
Vec3 toTarget = target.getEyePosition().subtract(origin);
|
||||||
|
|||||||
+16
-1
@@ -88,6 +88,18 @@ public final class RoyalBeamController {
|
|||||||
RoyalBeamSettings settings,
|
RoyalBeamSettings settings,
|
||||||
RoyalBeamTerrainMode terrainMode,
|
RoyalBeamTerrainMode terrainMode,
|
||||||
Consumer<@Nullable Vec3> syncedEndPosition
|
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) {
|
if (this.beamTicks <= 0) {
|
||||||
syncedEndPosition.accept(null);
|
syncedEndPosition.accept(null);
|
||||||
@@ -111,7 +123,10 @@ public final class RoyalBeamController {
|
|||||||
return;
|
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()
|
? this.owner.getLookAngle().normalize()
|
||||||
: shootDirection.normalize();
|
: shootDirection.normalize();
|
||||||
double committedDistance = Math.min(settings.range(), Math.max(settings.pathStep(),
|
double committedDistance = Math.min(settings.range(), Math.max(settings.pathStep(),
|
||||||
|
|||||||
-55
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+12
-1
@@ -47,6 +47,7 @@ public final class ThoraxisUndersideManager {
|
|||||||
private static final int CROSSING_TIMEOUT_TICKS = 100;
|
private static final int CROSSING_TIMEOUT_TICKS = 100;
|
||||||
private static final int SETTLE_TIMEOUT_TICKS = 70;
|
private static final int SETTLE_TIMEOUT_TICKS = 70;
|
||||||
private static final double MIN_CROSSING_SPEED = 0.48D;
|
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 RECENT_UNDERSIDE_WINDOW_TICKS = 40;
|
||||||
private static final int UNDERSIDE_ENTRY_BORDER_Y = GRAVITY_FLIP_Y - 7;
|
private static final int UNDERSIDE_ENTRY_BORDER_Y = GRAVITY_FLIP_Y - 7;
|
||||||
private static final int FRESH_ENTRY_DELAY_TICKS = 20;
|
private static final int FRESH_ENTRY_DELAY_TICKS = 20;
|
||||||
@@ -225,6 +226,16 @@ public final class ThoraxisUndersideManager {
|
|||||||
continue;
|
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) {
|
if (AntarchyGravityApi.isGravityInverted(player) && player.getY() < EXIT_UNDERSIDE_Y) {
|
||||||
refreshInvertedEffect(player);
|
refreshInvertedEffect(player);
|
||||||
}
|
}
|
||||||
@@ -297,7 +308,7 @@ public final class ThoraxisUndersideManager {
|
|||||||
AABB swept = player.getBoundingBox().expandTowards(velocity.scale(-1.0D)).inflate(0.08D);
|
AABB swept = player.getBoundingBox().expandTowards(velocity.scale(-1.0D)).inflate(0.08D);
|
||||||
AntarchyGravityDirection direction = AntarchyGravityApi.getGravityDirection(player);
|
AntarchyGravityDirection direction = AntarchyGravityApi.getGravityDirection(player);
|
||||||
return direction == AntarchyGravityDirection.DOWN
|
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;
|
: swept.minY <= GRAVITY_FLIP_Y && swept.maxY > GRAVITY_FLIP_Y && velocity.y >= MIN_CROSSING_SPEED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+32
@@ -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 <T extends net.minecraft.world.entity.Entity> void antarchy$allowUndertrialSpawn(
|
||||||
|
net.minecraft.world.entity.EntityType<T> entityType,
|
||||||
|
net.minecraft.world.level.ServerLevelAccessor level,
|
||||||
|
MobSpawnType spawnReason,
|
||||||
|
net.minecraft.core.BlockPos pos,
|
||||||
|
net.minecraft.util.RandomSource random,
|
||||||
|
CallbackInfoReturnable<Boolean> cir) {
|
||||||
|
if (!cir.getReturnValueZ()
|
||||||
|
&& spawnReason == MobSpawnType.TRIAL_SPAWNER
|
||||||
|
&& UndertrialSpawnContext.isActive()) {
|
||||||
|
cir.setReturnValue(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,6 +30,7 @@
|
|||||||
"KingsTreeLocateCommandMixin",
|
"KingsTreeLocateCommandMixin",
|
||||||
"LivingEntityJumpingAccessor",
|
"LivingEntityJumpingAccessor",
|
||||||
"CommandedMobMixin",
|
"CommandedMobMixin",
|
||||||
|
"UndertrialSpawnPlacementsMixin",
|
||||||
"LivingEntityRoyalEffectsMixin",
|
"LivingEntityRoyalEffectsMixin",
|
||||||
"JudgmentMarkEntityMixin",
|
"JudgmentMarkEntityMixin",
|
||||||
"RoyalJudgmentCombatMixin",
|
"RoyalJudgmentCombatMixin",
|
||||||
|
|||||||
@@ -388,6 +388,8 @@
|
|||||||
"item.antarchy.nightmare_scale": "Nightmare Scale",
|
"item.antarchy.nightmare_scale": "Nightmare Scale",
|
||||||
"item.antarchy.music_disc_underside": "Music Disc",
|
"item.antarchy.music_disc_underside": "Music Disc",
|
||||||
"jukebox_song.antarchy.underside": "docshrekbot - underside",
|
"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_helmet": "Nightmare Helmet",
|
||||||
"item.antarchy.nightmare_chestplate": "Nightmare Chestplate",
|
"item.antarchy.nightmare_chestplate": "Nightmare Chestplate",
|
||||||
"item.antarchy.nightmare_leggings": "Nightmare Leggings",
|
"item.antarchy.nightmare_leggings": "Nightmare Leggings",
|
||||||
@@ -543,7 +545,7 @@
|
|||||||
"item.antarchy.royal_guardian_boots": "Royal Guardian Boots",
|
"item.antarchy.royal_guardian_boots": "Royal Guardian Boots",
|
||||||
"item.antarchy.royal_guardian_sword": "Royal Guardian Sword",
|
"item.antarchy.royal_guardian_sword": "Royal Guardian Sword",
|
||||||
"item.antarchy.royal_guardian_shield": "Royal Guardian Shield",
|
"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.fire": "Fire",
|
||||||
"tooltip.antarchy.royal_guardian_sword.mode.frost": "Frost",
|
"tooltip.antarchy.royal_guardian_sword.mode.frost": "Frost",
|
||||||
"tooltip.antarchy.royal_guardian_sword.mode.storm": "Storm",
|
"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.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.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).",
|
"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_helmet": "Royal Assailant Helmet",
|
||||||
"item.antarchy.royal_assailant_chestplate": "Royal Assailant Chestplate",
|
"item.antarchy.royal_assailant_chestplate": "Royal Assailant Chestplate",
|
||||||
"item.antarchy.royal_assailant_leggings": "Royal Assailant Leggings",
|
"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_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.black_hole": "Use to create a Black Hole",
|
||||||
"tooltip.antarchy.royal_assailant_battleaxe.dilation": "Hits apply Temporal Dilation",
|
"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_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.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_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_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.",
|
"tooltip.antarchy.royal_assailant_chestplate.invert": "Press the inversion key to toggle inverted gravity on and off.",
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"parent": "minecraft:item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "antarchy:item/music_disc_the_queen"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1065,6 +1065,14 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"the_queen": {
|
||||||
|
"sounds": [
|
||||||
|
{
|
||||||
|
"name": "antarchy:music/game/thoraxis/the_queen",
|
||||||
|
"stream": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"lucid_lullaby": {
|
"lucid_lullaby": {
|
||||||
"sounds": [
|
"sounds": [
|
||||||
{
|
{
|
||||||
|
|||||||
BIN
Binary file not shown.
BIN
Binary file not shown.
|
After Width: | Height: | Size: 412 B |
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"sound_event": "antarchy:the_queen",
|
||||||
|
"description": {
|
||||||
|
"translate": "jukebox_song.antarchy.the_queen"
|
||||||
|
},
|
||||||
|
"length_in_seconds": 180.0,
|
||||||
|
"comparator_output": 13
|
||||||
|
}
|
||||||
@@ -2,6 +2,21 @@
|
|||||||
"type": "minecraft:entity",
|
"type": "minecraft:entity",
|
||||||
"random_sequence": "antarchy:entities/queen",
|
"random_sequence": "antarchy:entities/queen",
|
||||||
"pools": [
|
"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,
|
"rolls": 1.0,
|
||||||
"bonus_rolls": 0.0,
|
"bonus_rolls": 0.0,
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"replace": false,
|
||||||
|
"values": [
|
||||||
|
"antarchy:music_disc_underside",
|
||||||
|
"antarchy:music_disc_the_queen"
|
||||||
|
]
|
||||||
|
}
|
||||||
+4
@@ -1,9 +1,12 @@
|
|||||||
package com.craisinlord.antarchy.fabric.client;
|
package com.craisinlord.antarchy.fabric.client;
|
||||||
|
|
||||||
import com.craisinlord.antarchy.Antarchy;
|
import com.craisinlord.antarchy.Antarchy;
|
||||||
|
import com.craisinlord.antarchy.content.client.QueenMusicHandler;
|
||||||
import com.craisinlord.antarchy.content.client.game.AntarchyComputerGames;
|
import com.craisinlord.antarchy.content.client.game.AntarchyComputerGames;
|
||||||
import com.craisinlord.antarchy.fabric.network.AntarchyFabricClientNetworking;
|
import com.craisinlord.antarchy.fabric.network.AntarchyFabricClientNetworking;
|
||||||
|
import com.craisinlord.antarchy.fabric.registry.AntarchyFabricSounds;
|
||||||
import net.fabricmc.api.ClientModInitializer;
|
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.IdentifiableResourceReloadListener;
|
||||||
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
|
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
@@ -18,6 +21,7 @@ import java.util.concurrent.Executor;
|
|||||||
public final class AntarchyFabricClient implements ClientModInitializer {
|
public final class AntarchyFabricClient implements ClientModInitializer {
|
||||||
@Override
|
@Override
|
||||||
public void onInitializeClient() {
|
public void onInitializeClient() {
|
||||||
|
ClientTickEvents.END_CLIENT_TICK.register(client -> QueenMusicHandler.tick(client, AntarchyFabricSounds.THE_QUEEN.get()));
|
||||||
AntarchyFabricClientNetworking.register();
|
AntarchyFabricClientNetworking.register();
|
||||||
AntarchyFabricClientNetworking.bootstrapMultipartClient();
|
AntarchyFabricClientNetworking.bootstrapMultipartClient();
|
||||||
AntarchyFabricClientBootstrap.register();
|
AntarchyFabricClientBootstrap.register();
|
||||||
|
|||||||
-3
@@ -1,5 +1,4 @@
|
|||||||
package com.craisinlord.antarchy.fabric.content.fluid;
|
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.AntarchyFabricBlocks;
|
||||||
import com.craisinlord.antarchy.fabric.registry.AntarchyFabricItems;
|
import com.craisinlord.antarchy.fabric.registry.AntarchyFabricItems;
|
||||||
import com.craisinlord.antarchy.fabric.registry.AntarchyFabricMisc;
|
import com.craisinlord.antarchy.fabric.registry.AntarchyFabricMisc;
|
||||||
@@ -170,8 +169,6 @@ public abstract class AntiwaterFluid extends FlowingFluid {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AntiwaterBubbleColumnUtil.update(level, pos, state);
|
|
||||||
|
|
||||||
if (!state.isSource() && !this.isFlowingStateValid(level, pos, state)) {
|
if (!state.isSource() && !this.isFlowingStateValid(level, pos, state)) {
|
||||||
level.setBlockAndUpdate(pos, net.minecraft.world.level.block.Blocks.AIR.defaultBlockState());
|
level.setBlockAndUpdate(pos, net.minecraft.world.level.block.Blocks.AIR.defaultBlockState());
|
||||||
this.scheduleCleanup(level, pos);
|
this.scheduleCleanup(level, pos);
|
||||||
|
|||||||
+5
@@ -92,6 +92,11 @@ public final class AntarchyFabricItems {
|
|||||||
.jukeboxPlayable(ResourceKey.create(Registries.JUKEBOX_SONG,
|
.jukeboxPlayable(ResourceKey.create(Registries.JUKEBOX_SONG,
|
||||||
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "underside"))));
|
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "underside"))));
|
||||||
|
|
||||||
|
public static final DeferredItem<Item> 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<Item> PRIMORDIAL_SCUTE = ITEMS.registerSimpleItem("primordial_scute",
|
public static final DeferredItem<Item> PRIMORDIAL_SCUTE = ITEMS.registerSimpleItem("primordial_scute",
|
||||||
new Item.Properties().rarity(Rarity.UNCOMMON));
|
new Item.Properties().rarity(Rarity.UNCOMMON));
|
||||||
|
|||||||
+1
@@ -528,6 +528,7 @@ public final class AntarchyFabricSounds {
|
|||||||
|
|
||||||
public static final DeferredHolder<SoundEvent, SoundEvent> POTENT_NYXITE_GEYSER_CONTINUOUS_ACTIVE = registerSoundEvent("potent_nyxite_geyser_continuous_active");
|
public static final DeferredHolder<SoundEvent, SoundEvent> POTENT_NYXITE_GEYSER_CONTINUOUS_ACTIVE = registerSoundEvent("potent_nyxite_geyser_continuous_active");
|
||||||
public static final DeferredHolder<SoundEvent, SoundEvent> MUSIC_DISC_UNDERSIDE = registerSoundEvent("music_disc_underside");
|
public static final DeferredHolder<SoundEvent, SoundEvent> MUSIC_DISC_UNDERSIDE = registerSoundEvent("music_disc_underside");
|
||||||
|
public static final DeferredHolder<SoundEvent, SoundEvent> THE_QUEEN = registerSoundEvent("the_queen");
|
||||||
public static final DeferredHolder<SoundEvent, SoundEvent> WORM_HOOK_FLYING = registerSoundEvent("worm_hook_flying");
|
public static final DeferredHolder<SoundEvent, SoundEvent> WORM_HOOK_FLYING = registerSoundEvent("worm_hook_flying");
|
||||||
public static final DeferredHolder<SoundEvent, SoundEvent> BLOOD_CRYSTAL_KATANA_DASH = registerSoundEvent("blood_crystal_katana_dash");
|
public static final DeferredHolder<SoundEvent, SoundEvent> BLOOD_CRYSTAL_KATANA_DASH = registerSoundEvent("blood_crystal_katana_dash");
|
||||||
public static final DeferredHolder<SoundEvent, SoundEvent> BLOOD_CRYSTAL_ARMOR_EQUIP = registerSoundEvent("blood_crystal_armor_equip");
|
public static final DeferredHolder<SoundEvent, SoundEvent> BLOOD_CRYSTAL_ARMOR_EQUIP = registerSoundEvent("blood_crystal_armor_equip");
|
||||||
|
|||||||
+1
-1
@@ -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_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_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);
|
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_RADIUS = b.defineInRange("kingFireballRadius", 4.5D, 0.5D, 32.0D);
|
||||||
KING_FIREBALL_COOLDOWN_TICKS = b.defineInRange("kingFireballCooldownTicks", 150, 1, 2400);
|
KING_FIREBALL_COOLDOWN_TICKS = b.defineInRange("kingFireballCooldownTicks", 150, 1, 2400);
|
||||||
KING_ICEBALL_DAMAGE = b.defineInRange("kingIceballDamage", 18.0D, 0.0D, 1024.0D);
|
KING_ICEBALL_DAMAGE = b.defineInRange("kingIceballDamage", 18.0D, 0.0D, 1024.0D);
|
||||||
|
|||||||
+22
@@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
-3
@@ -1,6 +1,5 @@
|
|||||||
package com.craisinlord.antarchy.neoforge.content.fluid;
|
package com.craisinlord.antarchy.neoforge.content.fluid;
|
||||||
|
|
||||||
import com.craisinlord.antarchy.content.fluid.AntiwaterBubbleColumnUtil;
|
|
||||||
import com.craisinlord.antarchy.neoforge.registry.AntarchyNeoforgeBlocks;
|
import com.craisinlord.antarchy.neoforge.registry.AntarchyNeoforgeBlocks;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -174,8 +173,6 @@ public abstract class AntiwaterFluid extends BaseFlowingFluid {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AntiwaterBubbleColumnUtil.update(level, pos, state);
|
|
||||||
|
|
||||||
if (!state.isSource() && !this.isFlowingStateValid(level, pos, state)) {
|
if (!state.isSource() && !this.isFlowingStateValid(level, pos, state)) {
|
||||||
level.setBlockAndUpdate(pos, net.minecraft.world.level.block.Blocks.AIR.defaultBlockState());
|
level.setBlockAndUpdate(pos, net.minecraft.world.level.block.Blocks.AIR.defaultBlockState());
|
||||||
this.scheduleCleanup(level, pos);
|
this.scheduleCleanup(level, pos);
|
||||||
|
|||||||
+5
@@ -100,6 +100,11 @@ public final class AntarchyNeoforgeItems {
|
|||||||
.jukeboxPlayable(ResourceKey.create(Registries.JUKEBOX_SONG,
|
.jukeboxPlayable(ResourceKey.create(Registries.JUKEBOX_SONG,
|
||||||
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "underside"))));
|
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "underside"))));
|
||||||
|
|
||||||
|
public static final DeferredItem<Item> 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<ArmorMaterial, ArmorMaterial> ULTIMATE_ARMOR_MATERIAL = ARMOR_MATERIALS.register("ultimate",
|
private static final DeferredHolder<ArmorMaterial, ArmorMaterial> ULTIMATE_ARMOR_MATERIAL = ARMOR_MATERIALS.register("ultimate",
|
||||||
() -> new ArmorMaterial(
|
() -> new ArmorMaterial(
|
||||||
createUltimateArmorDefense(),
|
createUltimateArmorDefense(),
|
||||||
|
|||||||
+1
@@ -205,6 +205,7 @@ public final class AntarchyNeoforgeSounds {
|
|||||||
public static final DeferredHolder<SoundEvent, SoundEvent> POTENT_NYXITE_GEYSER_CONTINUOUS_START = registerSoundEvent("potent_nyxite_geyser_continuous_start");
|
public static final DeferredHolder<SoundEvent, SoundEvent> POTENT_NYXITE_GEYSER_CONTINUOUS_START = registerSoundEvent("potent_nyxite_geyser_continuous_start");
|
||||||
public static final DeferredHolder<SoundEvent, SoundEvent> POTENT_NYXITE_GEYSER_CONTINUOUS_ACTIVE = registerSoundEvent("potent_nyxite_geyser_continuous_active");
|
public static final DeferredHolder<SoundEvent, SoundEvent> POTENT_NYXITE_GEYSER_CONTINUOUS_ACTIVE = registerSoundEvent("potent_nyxite_geyser_continuous_active");
|
||||||
public static final DeferredHolder<SoundEvent, SoundEvent> MUSIC_DISC_UNDERSIDE = registerSoundEvent("music_disc_underside");
|
public static final DeferredHolder<SoundEvent, SoundEvent> MUSIC_DISC_UNDERSIDE = registerSoundEvent("music_disc_underside");
|
||||||
|
public static final DeferredHolder<SoundEvent, SoundEvent> THE_QUEEN = registerSoundEvent("the_queen");
|
||||||
public static final DeferredHolder<SoundEvent, SoundEvent> WORM_HOOK_FLYING = registerSoundEvent("worm_hook_flying");
|
public static final DeferredHolder<SoundEvent, SoundEvent> WORM_HOOK_FLYING = registerSoundEvent("worm_hook_flying");
|
||||||
public static final DeferredHolder<SoundEvent, SoundEvent> BLOOD_CRYSTAL_KATANA_DASH = registerSoundEvent("blood_crystal_katana_dash");
|
public static final DeferredHolder<SoundEvent, SoundEvent> BLOOD_CRYSTAL_KATANA_DASH = registerSoundEvent("blood_crystal_katana_dash");
|
||||||
public static final DeferredHolder<SoundEvent, SoundEvent> BLOOD_CRYSTAL_ARMOR_EQUIP = registerSoundEvent("blood_crystal_armor_equip");
|
public static final DeferredHolder<SoundEvent, SoundEvent> BLOOD_CRYSTAL_ARMOR_EQUIP = registerSoundEvent("blood_crystal_armor_equip");
|
||||||
|
|||||||
Reference in new issue
Block a user