diff --git a/common-1.20.1/src/main/java/com/craisinlord/antarchy/compat/infinity/InfinityConfigRefresh.java b/common-1.20.1/src/main/java/com/craisinlord/antarchy/compat/infinity/InfinityConfigRefresh.java index c0f91f7b..d6fe5125 100644 --- a/common-1.20.1/src/main/java/com/craisinlord/antarchy/compat/infinity/InfinityConfigRefresh.java +++ b/common-1.20.1/src/main/java/com/craisinlord/antarchy/compat/infinity/InfinityConfigRefresh.java @@ -15,6 +15,7 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; public final class InfinityConfigRefresh { private static final Map> CHECKED_FILES = Map.of( @@ -22,6 +23,7 @@ public final class InfinityConfigRefresh { "items.json", BuiltInRegistries.ITEM, "effects.json", BuiltInRegistries.MOB_EFFECT ); + private static final Set DISABLED_IDS = Set.of("antarchy:paralyzed"); private InfinityConfigRefresh() { } @@ -43,7 +45,7 @@ public final class InfinityConfigRefresh { try { Files.delete(invocationLock); Antarchy.LOGGER.info( - "[Antarchy] Infinite Dimensions config lists unregistered Antarchy content {}; its config will regenerate on next world join", + "[Antarchy] Infinite Dimensions config lists unregistered or disabled Antarchy content {}; its config will regenerate on next world join", staleIds ); } catch (Exception exception) { @@ -73,6 +75,8 @@ public final class InfinityConfigRefresh { ResourceLocation id = ResourceLocation.tryParse(key); if (id != null && Antarchy.MODID.equals(id.getNamespace()) && !registry.containsKey(id)) { staleIds.add(key); + } else if (DISABLED_IDS.contains(key) && (!entry.has("weight") || entry.get("weight").getAsDouble() > 0.0D)) { + staleIds.add(key); } } } catch (Exception exception) { diff --git a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/client/QueenMusicHandler.java b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/client/QueenMusicHandler.java index 69d71742..f854867f 100644 --- a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/client/QueenMusicHandler.java +++ b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/client/QueenMusicHandler.java @@ -11,6 +11,7 @@ import net.minecraft.util.Mth; import net.minecraft.util.RandomSource; import java.util.Comparator; +import java.util.function.Supplier; public final class QueenMusicHandler { private static final double START_RADIUS = 256.0D; @@ -25,7 +26,7 @@ public final class QueenMusicHandler { return music != null; } - public static void tick(Minecraft minecraft, SoundEvent soundEvent) { + public static void tick(Minecraft minecraft, Supplier soundEventSupplier) { if (minecraft.level == null || minecraft.player == null || minecraft.isPaused() || !minecraft.player.isAlive() || minecraft.player.isRemoved() || minecraft.player.isDeadOrDying() || minecraft.screen instanceof DeathScreen) { @@ -51,6 +52,15 @@ public final class QueenMusicHandler { } if (music == null) { + SoundEvent soundEvent; + try { + soundEvent = soundEventSupplier.get(); + } catch (RuntimeException exception) { + return; + } + if (soundEvent == null) { + return; + } minecraft.getMusicManager().stopPlaying(); music = new QueenMusicSound(soundEvent); minecraft.getSoundManager().play(music); diff --git a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/HerculesBeetleEntity.java b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/HerculesBeetleEntity.java index 5d604e52..f5901571 100644 --- a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/HerculesBeetleEntity.java +++ b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/HerculesBeetleEntity.java @@ -759,10 +759,6 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl } } - private boolean isMountedFlightPoseActive() { - return this.isFlying() && (!this.onGround() || this.toLocal(this.getDeltaMovement()).y > 0.08D); - } - private void startMountedFlight() { this.pendingChargeStart = false; this.setFlying(true); @@ -1169,6 +1165,19 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl && this.getControllingPassenger() == player; } + @Override + public boolean isControlledByLocalInstance() { + if (this.level().isClientSide && this.isChargeAnimationActive()) { + return false; + } + return super.isControlledByLocalInstance(); + } + + private boolean isChargeAnimationActive() { + int state = this.getAnimationState(); + return state == ANIM_CHARGE_START || state == ANIM_CHARGE; + } + @Override @Nullable public LivingEntity getControllingPassenger() { @@ -1184,7 +1193,7 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl if (this.hasPassenger(passenger)) { Vec3 localForward = this.toLocalPlane(this.getLookAngle()); Vec3 forward = localForward.lengthSqr() > 1.0E-4D ? this.toWorld(localForward.normalize()) : this.toWorld(0.0D, 0.0D, 1.0D); - boolean mountedFlightPose = this.isMountedFlightPoseActive(); + boolean mountedFlightPose = this.isFlying(); double yOffset = mountedFlightPose ? 5.3D : 3.0D; double forwardOffset = mountedFlightPose ? 2.2D : 1.25D; if (!this.isFlying()) { diff --git a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/AntTeleportHelper.java b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/AntTeleportHelper.java index 1d09e24c..33982ce1 100644 --- a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/AntTeleportHelper.java +++ b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/AntTeleportHelper.java @@ -63,7 +63,7 @@ public final class AntTeleportHelper { } } - private static List collectCompanions(ServerPlayer player) { + public static List collectCompanions(ServerPlayer player) { List companions = new ArrayList<>(); if (player.getVehicle() instanceof Mob vehicle) { companions.add(vehicle); @@ -95,7 +95,7 @@ public final class AntTeleportHelper { } @Nullable - private static Mob moveCompanion(Mob companion, ServerLevel destination, Vec3 destinationPos) { + public static Mob moveCompanion(Mob companion, ServerLevel destination, Vec3 destinationPos) { companion.stopRiding(); companion.ejectPassengers(); companion.getNavigation().stop(); @@ -400,7 +400,7 @@ public final class AntTeleportHelper { return null; } - private static void loadArrivalSearchArea(ServerLevel destination, BlockPos preferredPos, int searchRadius) { + public static void loadArrivalSearchArea(ServerLevel destination, BlockPos preferredPos, int searchRadius) { ChunkPos center = new ChunkPos(preferredPos); int chunkRadius = (searchRadius >> 4) + 1; for (int chunkX = center.x - chunkRadius; chunkX <= center.x + chunkRadius; chunkX++) { diff --git a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/KingEntity.java b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/KingEntity.java index 571f511f..90ea7343 100644 --- a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/KingEntity.java +++ b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/KingEntity.java @@ -131,7 +131,13 @@ public class KingEntity extends RoyalBossEntity { private static final int COMBAT_WAYPOINT_VARIANCE = 35; private static final int GROUND_COMBAT_WAYPOINT_MIN_TICKS = 18; private static final int GROUND_COMBAT_WAYPOINT_VARIANCE = 12; - + private static final int LANDING_DESCENT_TIMEOUT_TICKS = 120; + private static final int LANDING_RETRY_TICKS = 40; + private static final int LANDING_ROUTE_SAMPLES = 6; + private static final int LANDING_ROUTE_CHECK_LIMIT = 4; + private static final double GROUND_COMBAT_BITE_DISTANCE = 19.0D; + private static final double GROUND_COMBAT_BITE_VARIANCE = 4.0D; + private static final int ELEVATED_TARGET_TAKEOFF_TICKS = 40; @Nullable private Vec3 patrolCenter; @Nullable @@ -182,6 +188,7 @@ public class KingEntity extends RoyalBossEntity { @Nullable private Vec3 kingGroundCombatWaypoint; private int kingStrafeDirection = 1; + private int kingLandingRetryTicks; private int royalBoundaryGraceTicks; @Nullable private ServerPlayer exileTarget; @@ -254,6 +261,35 @@ public class KingEntity extends RoyalBossEntity { return this.royalChargeActive; } + @Override + protected SoundEvent royalWingBuffetSound() { + return AntarchySoundEvents.KING_WING_FLAP.get(); + } + + @Override + protected boolean royalShouldFaceTarget(LivingEntity target) { + return !this.royalChargeActive; + } + + @Override + protected void onRoyalStuck(LivingEntity target) { + switch (this.kingLandingStage) { + case GROUND_COMBAT -> this.beginKingTakeoff(target); + case TELEGRAPH, DESCENT -> { + this.resetKingCombatMovement(); + this.kingLandingRetryTicks = LANDING_RETRY_TICKS; + this.groundAssaultCooldownTicks = Math.max(this.groundAssaultCooldownTicks, 160); + this.setRoyalFlying(true); + } + case AERIAL -> { + this.kingCombatWaypoint = null; + this.kingStrafeDirection *= -1; + } + default -> { + } + } + } + @Override protected void onRoyalPhaseTransitionStarted(Phase previousPhase, Phase nextPhase) { this.attackScheduler.cancel(RoyalAttackLane.MOVEMENT); @@ -476,6 +512,14 @@ public class KingEntity extends RoyalBossEntity { } } + @Override + public boolean canDamageWithRoyalAttack(LivingEntity target) { + if (target instanceof QueenEntity) { + return target.isAlive() && !this.isAlliedTo(target); + } + return super.canDamageWithRoyalAttack(target); + } + private void chainLightning(ServerLevel level, Vec3 origin) { java.util.Set struck = new java.util.HashSet<>(); Vec3 from = origin; @@ -485,7 +529,7 @@ public class KingEntity extends RoyalBossEntity { double bestScore = Double.MAX_VALUE; for (LivingEntity candidate : level.getEntitiesOfClass(LivingEntity.class, new AABB(from, from).inflate(CHAIN_LIGHTNING_JUMP_RANGE), - e -> e.isAlive() && !(e instanceof RoyalBossEntity) && e.getType() != this.getType())) { + e -> e.isAlive() && (e instanceof QueenEntity || !(e instanceof RoyalBossEntity)) && e.getType() != this.getType())) { if (struck.contains(candidate.getUUID())) { continue; } @@ -565,17 +609,26 @@ public class KingEntity extends RoyalBossEntity { if (this.royalChargeOpeningDelayTicks > 0) { this.royalChargeOpeningDelayTicks--; } + if (this.kingLandingRetryTicks > 0) { + this.kingLandingRetryTicks--; + } + if (!this.isDeadOrDying()) { + if (this.fireballCooldownTicks > 0) this.fireballCooldownTicks--; + if (this.iceballCooldownTicks > 0) this.iceballCooldownTicks--; + if (this.iceSpikeCooldownTicks > 0) this.iceSpikeCooldownTicks--; + } if (this.isRoyalPhaseTransitionActive()) { return; } LivingEntity target = this.getTarget(); - if (target != null && !this.isDeadOrDying() && this.level() instanceof ServerLevel level) { + if (target != null && target.isAlive() && !this.isDeadOrDying() && this.level() instanceof ServerLevel level) { this.trackBehavior(target); this.tickDecree(level, target); this.tickKingCombatMovement(target); if (!this.blocksRoyalAttacksForMovement()) { this.tickKingWholeBody(level, target); } + this.applyRoyalBoundaryPull(); this.stabilizeKingRotation(); return; } @@ -583,11 +636,15 @@ public class KingEntity extends RoyalBossEntity { if (this.isDeadOrDying() || !(this.level() instanceof ServerLevel)) { return; } + if (this.activeDecree != null) { + this.endDecree(null); + } this.setRoyalFlying(true); this.resetKingCombatMovement(); this.decreeRetreatPressure = false; if (this.treePatrolBound && this.treePatrolCenter != null) { this.tickTreePatrol(); + this.applyRoyalBoundaryPull(); return; } if (this.patrolCenter == null || this.position().distanceToSqr(this.patrolCenter) > 64.0D * 64.0D) { @@ -667,17 +724,6 @@ public class KingEntity extends RoyalBossEntity { return; } double boundaryRadius = Math.max(32.0D, AntarchySettings.royalBoundaryRadius()); - double distance = Math.sqrt(this.horizontalDistanceToTreeSqr()); - if (distance > boundaryRadius) { - Vec3 towardCenter = this.treePatrolCenter.subtract(this.position()).multiply(1.0D, 0.0D, 1.0D); - if (towardCenter.lengthSqr() > 0.001D) { - towardCenter = towardCenter.normalize(); - this.getMoveControl().setWantedPosition(this.getX() + towardCenter.x * 12.0D, - this.groundYBelow(this.getX() + towardCenter.x * 12.0D, - this.getZ() + towardCenter.z * 12.0D) + FLYING_PREFERRED_HOVER, - this.getZ() + towardCenter.z * 12.0D, 1.4D); - } - } LivingEntity target = this.getTarget(); if (target == null || !target.isAlive()) { this.royalBoundaryGraceTicks = 0; @@ -702,6 +748,25 @@ public class KingEntity extends RoyalBossEntity { } } + private void applyRoyalBoundaryPull() { + if (!this.treePatrolBound || this.treePatrolCenter == null || this.royalChargeActive + || this.kingLandingStage != KingLandingStage.AERIAL) { + return; + } + double boundaryRadius = Math.max(32.0D, AntarchySettings.royalBoundaryRadius()); + if (this.horizontalDistanceToTreeSqr() <= boundaryRadius * boundaryRadius) { + return; + } + Vec3 towardCenter = this.treePatrolCenter.subtract(this.position()).multiply(1.0D, 0.0D, 1.0D); + if (towardCenter.lengthSqr() <= 0.001D) { + return; + } + towardCenter = towardCenter.normalize(); + double x = this.getX() + towardCenter.x * 12.0D; + double z = this.getZ() + towardCenter.z * 12.0D; + this.getMoveControl().setWantedPosition(x, this.groundYBelow(x, z) + FLYING_PREFERRED_HOVER, z, 1.4D); + } + private double horizontalDistanceToTreeSqr() { if (this.treePatrolCenter == null) { return 0.0D; @@ -793,9 +858,14 @@ public class KingEntity extends RoyalBossEntity { return; } boolean closeQuarters = this.activeDecree instanceof CloseQuartersDecree; - if (closeQuarters && this.isRoyalFlying() && this.kingLandingStage == KingLandingStage.AERIAL) { + if (!this.isRoyalFlying() && this.kingLandingStage == KingLandingStage.AERIAL) { + this.setRoyalFlying(true); + } + if (closeQuarters && this.isRoyalFlying() && this.kingLandingStage == KingLandingStage.AERIAL + && this.kingLandingRetryTicks <= 0) { this.beginKingLanding(target); } else if (!closeQuarters && this.isRoyalFlying() && this.kingLandingStage == KingLandingStage.AERIAL + && this.kingLandingRetryTicks <= 0 && this.groundAssaultCooldownTicks-- <= 0 && target.onGround()) { this.beginKingLanding(target); } @@ -807,6 +877,7 @@ public class KingEntity extends RoyalBossEntity { this.tickKingLandingIndicator(); if (--this.kingLandingStageTicks <= 0) { this.kingLandingStage = KingLandingStage.DESCENT; + this.kingLandingStageTicks = LANDING_DESCENT_TIMEOUT_TICKS; this.playRoyalSound(AntarchySoundEvents.KING_WING_FLAP.get(), 0.72F); } return; @@ -829,7 +900,10 @@ public class KingEntity extends RoyalBossEntity { || Math.abs(localLandingDelta.y) <= 1.25D && horizontalDistanceSquared <= 4.0D; if (reachedLanding) { this.setRoyalFlying(false); - this.setPos(this.getX(), landing.y, this.getZ()); + AABB snapped = this.getBoundingBox().move(0.0D, landing.y - this.getY(), 0.0D); + if (Math.abs(landing.y - this.getY()) > 1.0E-3D && this.level().noCollision(this, snapped)) { + this.setPos(this.getX(), landing.y, this.getZ()); + } this.kingLandingStage = KingLandingStage.IMPACT; this.kingLandingStageTicks = LANDING_IMPACT_TICKS; this.triggerAnim("body_action", "stomp"); @@ -837,6 +911,10 @@ public class KingEntity extends RoyalBossEntity { if (this.level() instanceof ServerLevel level) { this.performStomp(level, target); } + } else if (--this.kingLandingStageTicks <= 0) { + this.resetKingCombatMovement(); + this.kingLandingRetryTicks = LANDING_RETRY_TICKS; + this.groundAssaultCooldownTicks = Math.max(this.groundAssaultCooldownTicks, 160); } return; } @@ -864,8 +942,12 @@ public class KingEntity extends RoyalBossEntity { this.getMoveControl().setWantedPosition(this.kingGroundCombatWaypoint.x, this.kingGroundCombatWaypoint.y, this.kingGroundCombatWaypoint.z, 1.25D); } - if (--this.kingLandingStageTicks <= 0 && !closeQuarters) { + boolean targetOutOfReach = this.royalElevatedTargetTicks() >= ELEVATED_TARGET_TAKEOFF_TICKS; + if (--this.kingLandingStageTicks <= 0 && !closeQuarters || targetOutOfReach) { this.beginKingTakeoff(target); + if (targetOutOfReach) { + this.kingLandingRetryTicks = 100; + } } return; } @@ -913,6 +995,7 @@ public class KingEntity extends RoyalBossEntity { } else { this.kingLandingWaypoint = null; this.groundAssaultCooldownTicks = 100; + this.kingLandingRetryTicks = LANDING_RETRY_TICKS; } } @@ -954,7 +1037,9 @@ public class KingEntity extends RoyalBossEntity { private Vec3 findKingLandingPoint(LivingEntity target) { Vec3 away = this.position().subtract(target.position()).multiply(1.0D, 0.0D, 1.0D); double baseAngle = away.lengthSqr() > 1.0E-4D ? Math.atan2(away.z, away.x) : this.random.nextDouble() * Mth.TWO_PI; - double[] radii = {9.0D, 13.0D, 17.0D, 6.0D, 4.0D, 2.0D, 0.0D}; + double[] radii = {20.0D, 23.0D, 17.0D, 13.0D, 9.0D, 6.0D, 0.0D}; + int routeChecks = 0; + Vec3 unroutedCandidate = null; for (int angleIndex = 0; angleIndex < 16; angleIndex++) { double angle = baseAngle + angleIndex * Mth.TWO_PI / 16.0D; for (double radius : radii) { @@ -962,18 +1047,27 @@ public class KingEntity extends RoyalBossEntity { double z = target.getZ() + Math.sin(angle) * radius; double y = GravityApi.isGravityInverted(this) ? target.position().y - 0.1D - : this.groundYBelow(x, z) + 0.1D; + : this.groundYBelow(x, z, target.getY() + 1.0D) + 0.1D; Vec3 candidate = new Vec3(x, y, z); AABB box = this.getBoundingBox().move( candidate.x - this.getX(), candidate.y - this.getY(), candidate.z - this.getZ()); - if (this.level().noCollision(this, box)) { - return candidate; + if (!this.level().noCollision(this, box)) { + continue; + } + if (unroutedCandidate == null) { + unroutedCandidate = candidate; + } + if (this.clearKingLandingRoute(candidate) || ++routeChecks >= LANDING_ROUTE_CHECK_LIMIT) { + return routeChecks >= LANDING_ROUTE_CHECK_LIMIT ? unroutedCandidate : candidate; } } } + if (unroutedCandidate != null) { + return unroutedCandidate; + } double fallbackY = GravityApi.isGravityInverted(this) ? target.position().y - 0.1D - : this.groundYBelow(target.getX(), target.getZ()) + 0.1D; + : this.groundYBelow(target.getX(), target.getZ(), target.getY() + 1.0D) + 0.1D; Vec3 fallback = new Vec3(target.getX(), fallbackY, target.getZ()); AABB fallbackBox = this.getBoundingBox().move( fallback.x - this.getX(), fallback.y - this.getY(), fallback.z - this.getZ()); @@ -989,6 +1083,26 @@ public class KingEntity extends RoyalBossEntity { return this.level().noCollision(this, directBox) ? direct : null; } + private boolean clearKingLandingRoute(Vec3 destination) { + Vec3 start = this.position(); + AABB bounds = this.getBoundingBox(); + for (int sample = 1; sample < LANDING_ROUTE_SAMPLES; sample++) { + Vec3 point = start.lerp(destination, sample / (double) LANDING_ROUTE_SAMPLES); + AABB box = bounds.move(point.x - this.getX(), point.y - this.getY(), point.z - this.getZ()); + if (!this.level().noCollision(this, box)) { + return false; + } + } + return true; + } + + private double kingAerialWaypointY(double x, double z, LivingEntity target, double hoverOffset) { + double groundY = this.groundYBelow(x, z, target.getY() + 1.0D); + double desired = target.getY() + hoverOffset; + return Mth.clamp(desired, groundY + FLYING_MIN_HOVER, + Math.max(groundY + FLYING_MAX_HOVER_ABOVE_GROUND, desired)); + } + private void selectKingCombatWaypoint(LivingEntity target) { Vec3 radial = this.position().subtract(target.position()).multiply(1.0D, 0.0D, 1.0D); if (radial.lengthSqr() < 1.0E-4D) { @@ -1009,9 +1123,7 @@ public class KingEntity extends RoyalBossEntity { double candidateRange = range + (angleAttempt % 2 == 0 ? 0.0D : -6.0D); double x = target.getX() + Math.cos(angle) * candidateRange; double z = target.getZ() + Math.sin(angle) * candidateRange; - double groundY = this.groundYBelow(x, z); - double y = Mth.clamp(target.getY() + hoverOffset, - groundY + FLYING_MIN_HOVER, groundY + FLYING_MAX_HOVER_ABOVE_GROUND); + double y = this.kingAerialWaypointY(x, z, target, hoverOffset); Vec3 candidate = new Vec3(x, y, z); if (treeBoundCombat) { double dx = x - this.treePatrolCenter.x; @@ -1029,9 +1141,7 @@ public class KingEntity extends RoyalBossEntity { double angle = currentAngle + this.kingStrafeDirection * COMBAT_ORBIT_ANGLE_STEP; double x = target.getX() + Math.cos(angle) * range; double z = target.getZ() + Math.sin(angle) * range; - double groundY = this.groundYBelow(x, z); - double y = Mth.clamp(target.getY() + hoverOffset, - groundY + FLYING_MIN_HOVER, groundY + FLYING_MAX_HOVER_ABOVE_GROUND); + double y = this.kingAerialWaypointY(x, z, target, hoverOffset); Vec3 candidate = new Vec3(x, y, z); double dx = candidate.x - this.treePatrolCenter.x; double dz = candidate.z - this.treePatrolCenter.z; @@ -1044,9 +1154,7 @@ public class KingEntity extends RoyalBossEntity { double angle = currentAngle + this.kingStrafeDirection * COMBAT_ORBIT_ANGLE_STEP; double x = target.getX() + Math.cos(angle) * range; double z = target.getZ() + Math.sin(angle) * range; - double groundY = this.groundYBelow(x, z); - double y = Mth.clamp(target.getY() + hoverOffset, - groundY + FLYING_MIN_HOVER, groundY + FLYING_MAX_HOVER_ABOVE_GROUND); + double y = this.kingAerialWaypointY(x, z, target, hoverOffset); orbitWaypoint = new Vec3(x, y, z); if (treeBoundCombat) { orbitWaypoint = this.findTreePatrolWaypoint(this.treePatrolCenter, this.treePatrolAngle); @@ -1060,6 +1168,9 @@ public class KingEntity extends RoyalBossEntity { } private void stabilizeKingRotation() { + if (this.royalFacingPoint() != null) { + return; + } Vec3 movement = this.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D); if (movement.lengthSqr() < 0.0025D) { return; @@ -1093,16 +1204,16 @@ public class KingEntity extends RoyalBossEntity { radial = radial.normalize(); Vec3 tangent = new Vec3(-radial.z * this.kingStrafeDirection, 0.0D, radial.x * this.kingStrafeDirection); - double distance = 4.0D + this.random.nextDouble() * 3.0D; - Vec3 candidate = target.position().add(radial.scale(distance)).add(tangent.scale(2.5D)); - Vec3 waypoint = new Vec3(candidate.x, target.getY(), candidate.z); + double distance = GROUND_COMBAT_BITE_DISTANCE + this.random.nextDouble() * GROUND_COMBAT_BITE_VARIANCE; + Vec3 candidate = target.position().add(radial.scale(distance)).add(tangent.scale(4.0D)); + Vec3 waypoint = this.kingGroundPoint(candidate.x, candidate.z, target); AABB box = this.getBoundingBox().move(waypoint.x - this.getX(), waypoint.y - this.getY(), waypoint.z - this.getZ()); if (!this.level().noCollision(this, box)) { - waypoint = target.position().add(radial.scale(distance)); - waypoint = new Vec3(waypoint.x, target.getY(), waypoint.z); + Vec3 radialOnly = target.position().add(radial.scale(distance)); + waypoint = this.kingGroundPoint(radialOnly.x, radialOnly.z, target); box = this.getBoundingBox().move(waypoint.x - this.getX(), waypoint.y - this.getY(), waypoint.z - this.getZ()); } - this.kingGroundCombatWaypoint = this.level().noCollision(this, box) ? waypoint : target.position(); + this.kingGroundCombatWaypoint = this.level().noCollision(this, box) ? waypoint : this.position(); this.kingGroundCombatWaypointTicks = GROUND_COMBAT_WAYPOINT_MIN_TICKS + this.random.nextInt(GROUND_COMBAT_WAYPOINT_VARIANCE + 1); if (this.random.nextInt(4) == 0) { @@ -1110,6 +1221,13 @@ public class KingEntity extends RoyalBossEntity { } } + private Vec3 kingGroundPoint(double x, double z, LivingEntity target) { + double y = GravityApi.isGravityInverted(this) + ? target.getY() + : this.groundYBelow(x, z, Math.max(this.getY(), target.getY()) + 1.0D); + return new Vec3(x, y, z); + } + public void requestCloseQuartersAssault(LivingEntity target) { if (target != null && target.isAlive() && this.isRoyalFlying() && this.kingLandingStage == KingLandingStage.AERIAL) { @@ -1433,10 +1551,8 @@ public class KingEntity extends RoyalBossEntity { this.bumpBehavior(Behavior.SPRINTING, target.isSprinting() ? 1 : -1); this.bumpBehavior(Behavior.HUGGING, distance <= 10.0D ? 1 : -1); this.bumpBehavior(Behavior.KEEPING_FAR, distance >= 22.0D ? 1 : -1); - if (this.patrolCenter != null) { - this.bumpBehavior(Behavior.RETREATING, distance > 20.0D && target.getDeltaMovement().horizontalDistanceSqr() > 0.02D - && target.position().subtract(this.position()).dot(target.getDeltaMovement()) > 0.0D ? 1 : -1); - } + this.bumpBehavior(Behavior.RETREATING, distance > 20.0D && target.getDeltaMovement().horizontalDistanceSqr() > 0.02D + && target.position().subtract(this.position()).dot(target.getDeltaMovement()) > 0.0D ? 1 : -1); } private void bumpBehavior(Behavior behavior, int delta) { @@ -1708,10 +1824,6 @@ public class KingEntity extends RoyalBossEntity { } private void tickKingElementalProjectiles(ServerLevel level, LivingEntity target) { - if (this.fireballCooldownTicks > 0) this.fireballCooldownTicks--; - if (this.iceballCooldownTicks > 0) this.iceballCooldownTicks--; - if (this.iceSpikeCooldownTicks > 0) this.iceSpikeCooldownTicks--; - double distance = this.distanceTo(target); String[] candidates = {"fireball", "iceball", "ice_spikes"}; String selected = this.attackScheduler.chooseWeighted(candidates, id -> { @@ -1789,14 +1901,25 @@ public class KingEntity extends RoyalBossEntity { Vec3 start = this.position(); Vec3 end = target.position(); Vec3 line = end.subtract(start).multiply(1.0D, 0.0D, 1.0D); - if (line.lengthSqr() < 1.0E-4D) return; - line = line.normalize(); + double reach = line.length(); + if (reach < 6.0D) { + for (int index = 0; index < 8; index++) { + double angle = Mth.TWO_PI * index / 8.0D; + double x = end.x + Math.cos(angle) * 2.5D; + double z = end.z + Math.sin(angle) * 2.5D; + double y = this.groundYBelow(x, z, end.y + 1.0D) + 0.1D; + level.addFreshEntity(RoyalIceSpikeEntity.create(level, new Vec3(x, y, z), this)); + } + return; + } + line = line.scale(1.0D / reach); Vec3 side = new Vec3(-line.z, 0.0D, line.x); - for (int i = 1; i <= 5; i++) { - double distance = i * 4.0D; + double firstDistance = Math.max(4.0D, reach - 16.0D); + for (int i = 0; i < 5; i++) { + double distance = firstDistance + i * 4.0D; for (int lane = -1; lane <= 1; lane++) { - Vec3 point = start.add(line.scale(distance)).add(side.scale(lane * (i % 2 == 0 ? 2.0D : 0.0D))); - double y = this.groundYBelow(point.x, point.z) + 0.1D; + Vec3 point = start.add(line.scale(distance)).add(side.scale(lane * (i % 2 == 1 ? 2.0D : 0.0D))); + double y = this.groundYBelow(point.x, point.z, end.y + 1.0D) + 0.1D; RoyalIceSpikeEntity spike = RoyalIceSpikeEntity.create(level, new Vec3(point.x, y, point.z), this); level.addFreshEntity(spike); } diff --git a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/QueenEntity.java b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/QueenEntity.java index 6a11dbda..a8b497ef 100644 --- a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/QueenEntity.java +++ b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/QueenEntity.java @@ -44,7 +44,10 @@ import net.minecraft.world.entity.ai.attributes.AttributeInstance; import net.minecraft.world.entity.ai.attributes.AttributeModifier; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal; import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal; +import net.minecraft.world.entity.ambient.AmbientCreature; +import net.minecraft.world.entity.animal.WaterAnimal; import net.minecraft.world.entity.MobSpawnType; import net.minecraft.world.level.GameRules; import net.minecraft.world.level.Level; @@ -128,6 +131,12 @@ public class QueenEntity extends RoyalBossEntity { private static final int ACCELERATION_VOLLEY_DELAY = 18; private static final int ACCELERATION_LANDING_DELAY = 55; private static final int DIRECTED_LANDING_RETRY_TICKS = 60; + private static final int LANDING_TIMEOUT_COOLDOWN_TICKS = 160; + private static final double GROUND_CHARGE_MIN_DISTANCE = 16.0D; + private static final double GROUND_CHARGE_HIT_INFLATE = 1.5D; + private static final double GROUND_CHARGE_DAMAGE_SCALE = 1.1D; + private static final double GROUND_CHARGE_KNOCKBACK = 2.2D; + private static final int ELEVATED_TARGET_TAKEOFF_TICKS = 40; private int manticoreSummonCooldownTicks; private int gravityStompCooldownTicks; @@ -161,6 +170,7 @@ public class QueenEntity extends RoyalBossEntity { private Vec3 queenLandingWaypoint; @Nullable private Vec3 queenGroundChargeDirection; + private final java.util.Set queenGroundChargeHits = new java.util.HashSet<>(); @Nullable private Phase pendingPhaseSignature; private boolean pendingPhaseTwoCrushingGravity; @@ -295,11 +305,34 @@ public class QueenEntity extends RoyalBossEntity { @Override protected double combatStandoffDistance() { if (this.queenLandingStage == QueenLandingStage.GROUND_COMBAT && !this.isRoyalFlying()) { - return 0.0D; + return super.combatStandoffDistance(); } return Math.max(super.combatStandoffDistance(), AntarchySettings.queenBeamMinimumRange() + 6.0D); } + @Override + protected SoundEvent royalWingBuffetSound() { + return AntarchySoundEvents.QUEEN_FLY_LOOP.get(); + } + + @Override + protected boolean royalShouldFaceTarget(LivingEntity target) { + return this.queenGroundChargeWindupTicks <= 0 && this.queenGroundChargeTicks <= 0; + } + + @Override + protected void onRoyalStuck(LivingEntity target) { + switch (this.queenLandingStage) { + case GROUND_COMBAT -> this.beginQueenTakeoff(); + case TELEGRAPH, DESCENT -> { + this.resetQueenLandingSequence(); + this.queenLandingCooldownTicks = LANDING_TIMEOUT_COOLDOWN_TICKS; + } + default -> { + } + } + } + @Override protected double biteDamageMultiplier() { return super.biteDamageMultiplier() * 1.5D; @@ -320,9 +353,13 @@ public class QueenEntity extends RoyalBossEntity { protected void registerRoyalTargetGoals() { this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, KingEntity.class, true)); - this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true)); - this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>( - this, Mob.class, 10, true, false, this::canAttack)); + this.targetSelector.addGoal(2, new HurtByTargetGoal(this).setUnseenMemoryTicks(ROYAL_UNSEEN_MEMORY_TICKS)); + this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Player.class, true) + .setUnseenMemoryTicks(ROYAL_UNSEEN_MEMORY_TICKS)); + this.targetSelector.addGoal(4, new NearestAttackableTargetGoal<>( + this, Mob.class, 10, true, false, + living -> !(living instanceof AmbientCreature) && !(living instanceof WaterAnimal) + && this.canAttack(living))); } @Override @@ -495,6 +532,9 @@ public class QueenEntity extends RoyalBossEntity { } private void tickQueenLandingSequence(LivingEntity target) { + if (this.queenLandingStage == QueenLandingStage.AERIAL && !this.isRoyalFlying()) { + this.setRoyalFlying(true); + } if (this.queenLandingStage == QueenLandingStage.AERIAL && this.isRoyalFlying() && !this.isQueenAbilityTelegraphActive() && this.queenLandingCooldownTicks-- <= 0) { @@ -529,7 +569,7 @@ public class QueenEntity extends RoyalBossEntity { this.performGravityStomp((ServerLevel) this.level(), target); } else if (--this.queenLandingStageTicks <= 0) { this.resetQueenLandingSequence(); - this.queenLandingCooldownTicks = 40; + this.queenLandingCooldownTicks = LANDING_TIMEOUT_COOLDOWN_TICKS; } } case IMPACT -> { @@ -544,7 +584,8 @@ public class QueenEntity extends RoyalBossEntity { } case GROUND_COMBAT -> { this.tickQueenGroundCharge(target); - if (--this.queenLandingStageTicks <= 0) { + if (--this.queenLandingStageTicks <= 0 + || this.royalElevatedTargetTicks() >= ELEVATED_TARGET_TAKEOFF_TICKS) { this.beginQueenTakeoff(); } } @@ -577,7 +618,7 @@ public class QueenEntity extends RoyalBossEntity { double baseAngle = away.lengthSqr() > 1.0E-4D ? Math.atan2(away.z, away.x) : this.random.nextDouble() * Mth.TWO_PI; boolean inverted = GravityApi.isGravityInverted(this); - double[] radii = {10.0D, 14.0D, 18.0D, 7.0D}; + double[] radii = {20.0D, 23.0D, 17.0D, 14.0D, 10.0D}; for (int angleIndex = 0; angleIndex < 12; angleIndex++) { double angle = baseAngle + angleIndex * Mth.TWO_PI / 12.0D; for (double radius : radii) { @@ -585,7 +626,7 @@ public class QueenEntity extends RoyalBossEntity { double z = target.getZ() + Math.sin(angle) * radius; double y = inverted ? target.position().y - 0.1D - : this.groundYBelow(x, z) + 0.1D; + : this.groundYBelow(x, z, target.getY() + 1.0D) + 0.1D; Vec3 candidate = new Vec3(x, y, z); AABB box = this.getBoundingBox().move( candidate.x - this.getX(), candidate.y - this.getY(), candidate.z - this.getZ()); @@ -596,7 +637,7 @@ public class QueenEntity extends RoyalBossEntity { } double fallbackY = inverted ? target.position().y - 0.1D - : this.groundYBelow(target.getX(), target.getZ()) + 0.1D; + : this.groundYBelow(target.getX(), target.getZ(), target.getY() + 1.0D) + 0.1D; Vec3 fallback = new Vec3(target.getX(), fallbackY, target.getZ()); AABB fallbackBox = this.getBoundingBox().move( fallback.x - this.getX(), fallback.y - this.getY(), fallback.z - this.getZ()); @@ -667,6 +708,7 @@ public class QueenEntity extends RoyalBossEntity { if (direction.lengthSqr() > 1.0E-4D) { this.queenGroundChargeDirection = direction.normalize(); this.queenGroundChargeTicks = GROUND_CHARGE_DURATION_TICKS; + this.queenGroundChargeHits.clear(); } else { this.finishQueenGroundCharge(); } @@ -681,6 +723,9 @@ public class QueenEntity extends RoyalBossEntity { this.setYRot((float) (Mth.atan2(-direction.x, direction.z) * Mth.RAD_TO_DEG)); this.yBodyRot = this.getYRot(); this.hasImpulse = true; + if (this.level() instanceof ServerLevel level) { + this.applyQueenGroundChargeHits(level, direction); + } if (--this.queenGroundChargeTicks <= 0) { this.finishQueenGroundCharge(); } @@ -688,7 +733,8 @@ public class QueenEntity extends RoyalBossEntity { } 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) { + .distanceToSqr(this.position().multiply(1.0D, 0.0D, 1.0D)) + < GROUND_CHARGE_MIN_DISTANCE * GROUND_CHARGE_MIN_DISTANCE) { return; } this.queenGroundChargeDirection = target.position().subtract(this.position()) @@ -701,6 +747,34 @@ public class QueenEntity extends RoyalBossEntity { } } + private void applyQueenGroundChargeHits(ServerLevel level, Vec3 direction) { + float damage = (float) (this.getAttributeValue(Attributes.ATTACK_DAMAGE) * GROUND_CHARGE_DAMAGE_SCALE); + DamageSource source = this.damageSources().mobAttack(this); + AABB hitBox = this.getBoundingBox().inflate(GROUND_CHARGE_HIT_INFLATE); + for (LivingEntity living : level.getEntitiesOfClass(LivingEntity.class, hitBox, + entity -> entity.isAlive() && entity != this && this.canDamageWithRoyalAttack(entity))) { + Vec3 offset = living.position().subtract(this.position()).multiply(1.0D, 0.0D, 1.0D); + if (offset.dot(direction) < -this.getBbWidth() * 0.15D + || !this.queenGroundChargeHits.add(living.getUUID())) { + continue; + } + living.hurt(source, damage); + if (!(living instanceof RoyalBossEntity)) { + Vec3 lift = GravityRotationUtil.vecPlayerToWorld( + 0.0D, 0.55D, 0.0D, GravityApi.getGravityDirection(living)); + this.addGravityAwareImpulse(living, direction.scale(GROUND_CHARGE_KNOCKBACK).add(lift)); + living.hasImpulse = true; + living.hurtMarked = true; + } + level.sendParticles(ParticleTypes.CRIT, living.getX(), living.getY() + living.getBbHeight() * 0.5D, + living.getZ(), 16, 0.5D, 0.6D, 0.5D, 0.1D); + } + if (this.queenGroundChargeTicks % 4 == 0) { + Vec3 front = this.position().add(direction.scale(this.getBbWidth() * 0.5D + 1.0D)); + RoyalBlockDestruction.destroySphere(level, this, front.add(0.0D, 2.0D, 0.0D), 3.5D, 24, 60.0D, 0.1F); + } + } + private void finishQueenGroundCharge() { this.queenGroundChargeTicks = 0; this.queenGroundChargeWindupTicks = 0; @@ -710,6 +784,7 @@ public class QueenEntity extends RoyalBossEntity { } private void clearQueenGroundCharge() { + this.queenGroundChargeHits.clear(); this.queenGroundChargeCooldownTicks = 0; this.queenGroundChargeWindupTicks = 0; this.queenGroundChargeTicks = 0; @@ -1048,14 +1123,21 @@ public class QueenEntity extends RoyalBossEntity { : 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 chosen = forcedAttack != null && this.queenAttackReady(forcedAttack, phase, majorBusy) ? forcedAttack : this.attackScheduler.chooseWeighted(candidates, id -> { if (!this.queenAttackReady(id, phase, majorBusy) || id.equals(this.lastQueenMajorAttack)) return 0; return this.queenAttackWeight(id, phase); }, this.random); - if (selected == null) return; + if (chosen == null && this.lastQueenMajorAttack != null + && this.queenAttackReady(this.lastQueenMajorAttack, phase, majorBusy) + && java.util.Arrays.asList(candidates).contains(this.lastQueenMajorAttack) + && this.queenAttackWeight(this.lastQueenMajorAttack, phase) > 0) { + chosen = this.lastQueenMajorAttack; + } + if (chosen == null) return; + final String selected = chosen; int cooldown = switch (selected) { case "gravity_stomp" -> GRAVITY_STOMP_COOLDOWN; case "black_hole" -> BLACK_HOLE_COOLDOWN; @@ -1606,7 +1688,9 @@ public class QueenEntity extends RoyalBossEntity { double radius = this.random.nextDouble() * GRAVITIC_UPHEAVAL_RADIUS; double x = center.x + Math.cos(angle) * radius; double z = center.z + Math.sin(angle) * radius; - BlockPos pos = BlockPos.containing(x, this.groundYBelow(x, z), z); + BlockPos pos = inverted + ? BlockPos.containing(x, this.ceilingYAbove(x, z, this.getBoundingBox().minY + 0.5D) + 0.5D, z) + : BlockPos.containing(x, this.groundYBelow(x, z) - 0.5D, z); BlockState state = level.getBlockState(pos); if (!state.is(AntarchyTags.Blocks.QUEEN_GRABBABLE_BLOCKS) || level.getBlockEntity(pos) != null || state.getDestroySpeed(level, pos) < 0.0F || state.getCollisionShape(level, pos).isEmpty()) { diff --git a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBossEntity.java b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBossEntity.java index eda8bead..5545692a 100644 --- a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBossEntity.java +++ b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBossEntity.java @@ -57,8 +57,13 @@ import net.minecraft.world.entity.ai.navigation.GroundPathNavigation; import net.minecraft.world.entity.ai.navigation.PathNavigation; import net.minecraft.world.entity.monster.Monster; import net.minecraft.world.entity.player.Player; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.level.ClipContext; import net.minecraft.world.level.Level; import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.Nullable; import software.bernie.geckolib.animatable.GeoEntity; @@ -112,6 +117,9 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult private static final ResourceLocation MULTIPLAYER_DAMAGE_ID = new ResourceLocation("antarchy", "royal_multiplayer_damage"); private static final UUID MULTIPLAYER_DAMAGE_UUID = UUID.nameUUIDFromBytes(MULTIPLAYER_DAMAGE_ID.toString().getBytes()); private static final int OBSTRUCTION_CLEAR_INTERVAL_TICKS = 5; + private static final int RIVAL_OBSTRUCTION_CLEAR_INTERVAL_TICKS = 10; + private static final int BODY_CRUSH_INTERVAL_TICKS = 10; + private static final int RIVAL_BODY_CRUSH_INTERVAL_TICKS = 20; private static final double OBSTRUCTION_CLEAR_RADIUS = 3.5D; private static final int OBSTRUCTION_CLEAR_MAX_BLOCKS = 24; private static final double OBSTRUCTION_CLEAR_MAX_RESISTANCE = 60.0D; @@ -121,6 +129,36 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult private static final double BEAM_MUZZLE_SIDE_Y = 10.25D; private static final double BEAM_MUZZLE_LATERAL = 2.625D; private static final int HEAVY_BLOCK_CHECK_INTERVAL_TICKS = 4; + private static final String WING_BUFFET_ID = "royal_wing_buffet"; + private static final int WING_BUFFET_WINDUP_TICKS = 16; + private static final double WING_BUFFET_EXTRA_RADIUS = 5.0D; + private static final double WING_BUFFET_BELOW = 14.0D; + private static final double WING_BUFFET_ABOVE = 6.0D; + private static final double WING_BUFFET_DAMAGE_SCALE = 0.85D; + private static final double WING_BUFFET_PUSH = 2.6D; + private static final double WING_BUFFET_LIFT = 0.75D; + private static final String EXCAVATION_ID = "royal_excavation"; + private static final int EXCAVATION_TRIGGER_TICKS = 100; + private static final int EXCAVATION_WINDUP_TICKS = 24; + private static final int EXCAVATION_COOLDOWN_TICKS = 200; + private static final double EXCAVATION_RANGE = 72.0D; + private static final double EXCAVATION_RADIUS = 2.5D; + private static final double EXCAVATION_DEPTH = 10.0D; + private static final int EXCAVATION_MAX_BLOCKS = 20; + private static final double EXCAVATION_CONCEALED_DAMAGE = 5.0D; + private static final int STUCK_SAMPLE_TICKS = 40; + private static final double STUCK_MIN_PROGRESS_SQR = 1.0D; + private static final double STUCK_MIN_WANTED_DISTANCE_SQR = 36.0D; + private static final int STUCK_TAKEOFF_STRIKES = 2; + private static final int STUCK_TELEPORT_STRIKES = 4; + private static final int STUCK_TELEPORT_COOLDOWN_TICKS = 600; + private static final int STUCK_TELEPORT_ATTEMPTS = 16; + private static final int LANDING_FOR_COMBAT_TIMEOUT_TICKS = 120; + private static final int GROUND_SCAN_DEPTH = 48; + private static final int GROUND_SCAN_RISE = 24; + private static final double MAX_BEAM_PITCH = Math.toRadians(55.0D); + private static final int ELEVATED_TARGET_HEIGHT = 10; + private static final float FACING_TURN_RATE = 6.0F; protected static final double FLYING_MIN_HOVER = 2.5D; protected static final double FLYING_PREFERRED_HOVER = 6.0D; @@ -197,6 +235,16 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult private boolean multiplayerScalingInitialized; private final Set encounterParticipants = new HashSet<>(); private double royalDamageMultiplier = 1.0D; + private int landingForCombatTicks; + private int royalDeadZoneTicks; + private int royalConcealedTicks; + private int royalElevatedTargetTicks; + private int royalLastMoveRequestTick = Integer.MIN_VALUE; + @Nullable + private Vec3 royalStuckSamplePosition; + private int royalStuckSampleTicks; + private int royalStuckStrikes; + private int royalTeleportCooldownTicks; @Nullable private Entity[] multipartParts; @@ -207,8 +255,8 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult this.beamControllers[i] = new BeamController(this); } this.xpReward = 500; - this.groundMoveControl = new MoveControl(this); - this.flyingMoveControl = new FlyingMoveControl(this, 20, true); + this.groundMoveControl = new RoyalGroundMoveControl(this); + this.flyingMoveControl = new RoyalFlyingMoveControl(this, 20); this.groundNavigation = new GroundPathNavigation(this, level); FlyingPathNavigation flyingNavigation = new FlyingPathNavigation(this, level); flyingNavigation.setCanFloat(true); @@ -217,6 +265,7 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult this.moveControl = this.flyingMoveControl; this.navigation = this.flyingNavigation; } else { + this.moveControl = this.groundMoveControl; this.navigation = this.groundNavigation; } this.bossEvent = new com.craisinlord.antarchy.content.boss.EntityLinkedServerBossEvent( @@ -380,8 +429,42 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult } protected void registerRoyalTargetGoals() { - this.targetSelector.addGoal(1, new HurtByTargetGoal(this)); - this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true)); + this.targetSelector.addGoal(1, new HurtByTargetGoal(this).setUnseenMemoryTicks(ROYAL_UNSEEN_MEMORY_TICKS)); + this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true) + .setUnseenMemoryTicks(ROYAL_UNSEEN_MEMORY_TICKS)); + } + + protected static final int ROYAL_UNSEEN_MEMORY_TICKS = 400; + + protected SoundEvent royalWingBuffetSound() { + return this.royalBiteSound(); + } + + protected int royalWingBuffetCooldownTicks(Phase phase) { + return switch (phase) { + case ONE -> 110; + case TWO -> 90; + case THREE -> 70; + }; + } + + protected int royalDeadZoneTriggerTicks(Phase phase) { + return switch (phase) { + case ONE -> 40; + case TWO -> 32; + case THREE -> 24; + }; + } + + protected boolean royalShouldFaceTarget(LivingEntity target) { + return true; + } + + protected void onRoyalStuck(LivingEntity target) { + } + + protected final int royalElevatedTargetTicks() { + return this.royalElevatedTargetTicks; } public boolean canDamageWithRoyalAttack(LivingEntity target) { @@ -512,7 +595,7 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult if (this.shouldClearObstruction() && !this.level().isClientSide && !this.isDeadOrDying() - && this.tickCount % OBSTRUCTION_CLEAR_INTERVAL_TICKS == 0 + && this.tickCount % (this.isFightingRoyalRival() ? RIVAL_OBSTRUCTION_CLEAR_INTERVAL_TICKS : OBSTRUCTION_CLEAR_INTERVAL_TICKS) == 0 && this.isInWall()) { RoyalBlockDestruction.destroySphere( (ServerLevel) this.level(), @@ -575,13 +658,16 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult for (RoyalHead head : this.heads) { head.setTarget(null); } + this.resetRoyalCombatTracking(); return; } this.initializeMultiplayerScaling(primaryTarget); this.assignHeadTargets(primaryTarget); + this.tickRoyalTargetElevation(primaryTarget); this.tickCombatLocomotionMode(primaryTarget); + this.tickRoyalStuckRecovery(primaryTarget); boolean movementBlocksAttacks = this.blocksRoyalAttacksForMovement(); if (!movementBlocksAttacks) { boolean aeriallyStabilized = this.steerTowardTarget(primaryTarget); @@ -595,6 +681,8 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult return; } this.tickBodyCrush(); + this.tickRoyalCloseRangeAnswer(primaryTarget); + this.tickRoyalConcealedTarget(primaryTarget); Phase phase = this.phase(); int activeHeadAttacks = 0; @@ -917,15 +1005,18 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult double verticalDistance = Math.abs(target.getY() + target.getBbHeight() * 0.5D - (this.getY() + this.getBbHeight() * 0.5D)); + boolean inverted = GravityApi.isGravityInverted(this); + double groundBelowTarget = this.groundYBelow(wanted.x, wanted.z, target.getY() + 1.0D); + double wantedY = this.landingForCombat + ? (inverted ? target.getY() + target.getBbHeight() - this.getBbHeight() : groundBelowTarget) + : inverted + ? target.getY() - 3.0D + : Mth.clamp(target.getY() + 3.0D, + groundBelowTarget + FLYING_MIN_HOVER, + Math.max(groundBelowTarget + FLYING_MAX_HOVER_ABOVE_GROUND, target.getY() + 4.0D)); if (!this.landingForCombat && verticalDistance > 6.0D) { if (this.aerialCombatAnchor == null || this.aerialCombatAnchorTicks-- <= 0) { - double anchorX = this.getX(); - double anchorZ = this.getZ(); - if (horizontalDistance > 10.0D) { - anchorX = wanted.x; - anchorZ = wanted.z; - } - this.aerialCombatAnchor = new Vec3(anchorX, this.getY(), anchorZ); + this.aerialCombatAnchor = new Vec3(wanted.x, wantedY, wanted.z); this.aerialCombatAnchorTicks = 20; } Vec3 anchor = this.aerialCombatAnchor; @@ -935,15 +1026,6 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult this.aerialCombatAnchor = null; this.aerialCombatAnchorTicks = 0; - boolean inverted = GravityApi.isGravityInverted(this); - double groundBelowTarget = this.groundYBelow(wanted.x, wanted.z); - double wantedY = this.landingForCombat - ? (inverted ? target.getY() + target.getBbHeight() - this.getBbHeight() : groundBelowTarget) - : inverted - ? target.getY() - 3.0D - : Mth.clamp(target.getY() + 3.0D, - groundBelowTarget + FLYING_MIN_HOVER, - groundBelowTarget + FLYING_MAX_HOVER_ABOVE_GROUND); boolean closeVertically = Math.abs(wantedY - this.getY()) <= 2.5D; if (atStandoff && closeVertically) { this.getNavigation().stop(); @@ -953,6 +1035,536 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult return false; } + private void resetRoyalCombatTracking() { + this.royalDeadZoneTicks = 0; + this.royalConcealedTicks = 0; + this.royalElevatedTargetTicks = 0; + this.royalStuckSamplePosition = null; + this.royalStuckSampleTicks = 0; + this.royalStuckStrikes = 0; + } + + private void tickRoyalTargetElevation(LivingEntity target) { + Vec3 local = GravityRotationUtil.vecWorldToPlayer(target.position().subtract(this.position()), + GravityApi.getGravityDirection(this)); + if (local.y > ELEVATED_TARGET_HEIGHT) { + this.royalElevatedTargetTicks++; + } else { + this.royalElevatedTargetTicks = 0; + } + } + + final void markRoyalMoveRequested() { + this.royalLastMoveRequestTick = this.tickCount; + } + + private void tickRoyalStuckRecovery(LivingEntity target) { + if (this.royalTeleportCooldownTicks > 0) { + this.royalTeleportCooldownTicks--; + } + MoveControl control = this.getMoveControl(); + boolean requested = (long) this.tickCount - (long) this.royalLastMoveRequestTick <= 2L + && this.distanceToSqr(control.getWantedX(), control.getWantedY(), control.getWantedZ()) + > STUCK_MIN_WANTED_DISTANCE_SQR; + if (!requested) { + this.royalStuckSamplePosition = null; + this.royalStuckSampleTicks = 0; + this.royalStuckStrikes = 0; + return; + } + if (this.royalStuckSamplePosition == null) { + this.royalStuckSamplePosition = this.position(); + this.royalStuckSampleTicks = 0; + return; + } + if (++this.royalStuckSampleTicks < STUCK_SAMPLE_TICKS) { + return; + } + boolean progressed = this.position().distanceToSqr(this.royalStuckSamplePosition) >= STUCK_MIN_PROGRESS_SQR; + this.royalStuckSamplePosition = this.position(); + this.royalStuckSampleTicks = 0; + if (progressed) { + this.royalStuckStrikes = 0; + return; + } + this.royalStuckStrikes++; + this.onRoyalMovementObstructed(target); + } + + private void onRoyalMovementObstructed(LivingEntity target) { + if (this.level() instanceof ServerLevel serverLevel) { + this.clearRoyalPathTowardWanted(serverLevel); + } + if (this.royalStuckStrikes >= STUCK_TAKEOFF_STRIKES) { + this.onRoyalStuck(target); + if (this.isFlyingBoss()) { + this.addGravityAwareImpulse(this, GravityRotationUtil.vecPlayerToWorld( + 0.0D, 0.6D, 0.0D, GravityApi.getGravityDirection(this))); + this.hasImpulse = true; + } + } + if (this.royalStuckStrikes >= STUCK_TELEPORT_STRIKES && this.royalTeleportCooldownTicks <= 0 + && this.tryRoyalRecoveryTeleport(target)) { + this.royalStuckStrikes = 0; + this.royalStuckSamplePosition = null; + this.royalTeleportCooldownTicks = STUCK_TELEPORT_COOLDOWN_TICKS; + } + } + + private void clearRoyalPathTowardWanted(ServerLevel level) { + MoveControl control = this.getMoveControl(); + Vec3 toWanted = new Vec3(control.getWantedX() - this.getX(), control.getWantedY() - this.getY(), + control.getWantedZ() - this.getZ()); + Vec3 horizontal = toWanted.multiply(1.0D, 0.0D, 1.0D); + Vec3 direction; + if (horizontal.lengthSqr() > 1.0E-4D) { + direction = horizontal.normalize(); + } else { + double yaw = this.yBodyRot * Mth.DEG_TO_RAD; + direction = new Vec3(-Math.sin(yaw), 0.0D, Math.cos(yaw)); + } + Vec3 side = new Vec3(-direction.z, 0.0D, direction.x); + var gravity = GravityApi.getGravityDirection(this); + double reach = this.getBbWidth() * 0.5D + 1.0D; + double[] heights = {1.5D, this.getBbHeight() * 0.4D, this.getBbHeight() * 0.75D}; + double[] laterals = {-this.getBbWidth() * 0.3D, 0.0D, this.getBbWidth() * 0.3D}; + for (double height : heights) { + for (double lateral : laterals) { + Vec3 center = this.position().add(direction.scale(reach)).add(side.scale(lateral)) + .add(GravityRotationUtil.vecPlayerToWorld(0.0D, height, 0.0D, gravity)); + RoyalBlockDestruction.destroySphere(level, this, center, OBSTRUCTION_CLEAR_RADIUS, + OBSTRUCTION_CLEAR_MAX_BLOCKS, OBSTRUCTION_CLEAR_MAX_RESISTANCE, OBSTRUCTION_CLEAR_DROP_CHANCE); + } + } + if (toWanted.y > 3.0D) { + RoyalBlockDestruction.destroySphere(level, this, + this.position().add(GravityRotationUtil.vecPlayerToWorld(0.0D, this.getBbHeight() + 1.0D, 0.0D, gravity)), + OBSTRUCTION_CLEAR_RADIUS, OBSTRUCTION_CLEAR_MAX_BLOCKS, OBSTRUCTION_CLEAR_MAX_RESISTANCE, + OBSTRUCTION_CLEAR_DROP_CHANCE); + } + } + + private boolean tryRoyalRecoveryTeleport(LivingEntity target) { + if (!(this.level() instanceof ServerLevel level)) { + return false; + } + boolean inverted = GravityApi.isGravityInverted(this); + for (int attempt = 0; attempt < STUCK_TELEPORT_ATTEMPTS; attempt++) { + double angle = this.random.nextDouble() * Mth.TWO_PI; + double radius = 22.0D + this.random.nextDouble() * 14.0D; + double x = target.getX() + Math.cos(angle) * radius; + double z = target.getZ() + Math.sin(angle) * radius; + double y = inverted + ? target.getY() + target.getBbHeight() - this.getBbHeight() + : this.groundYBelow(x, z, target.getY() + 1.0D) + + (this.isRoyalFlying() ? FLYING_PREFERRED_HOVER : 0.1D); + AABB box = this.getBoundingBox().move(x - this.getX(), y - this.getY(), z - this.getZ()); + if (!level.noCollision(this, box) || level.containsAnyLiquid(box)) { + continue; + } + this.sendRoyalRelocationBurst(level); + this.getNavigation().stop(); + this.teleportTo(x, y, z); + this.setDeltaMovement(Vec3.ZERO); + this.sendRoyalRelocationBurst(level); + level.playSound(null, x, y, z, SoundEvents.ENDERMAN_TELEPORT, SoundSource.HOSTILE, 3.0F, 0.55F); + return true; + } + return false; + } + + private void sendRoyalRelocationBurst(ServerLevel level) { + level.sendParticles(ParticleTypes.REVERSE_PORTAL, + this.getX(), this.getY() + this.getBbHeight() * 0.5D, this.getZ(), + 80, this.getBbWidth() * 0.3D, this.getBbHeight() * 0.3D, this.getBbWidth() * 0.3D, 0.2D); + } + + private double royalDeadZoneRadius() { + return this.getBbWidth() * 0.5D + WING_BUFFET_EXTRA_RADIUS; + } + + private boolean isInRoyalDeadZone(LivingEntity living) { + Vec3 local = GravityRotationUtil.vecWorldToPlayer(living.position().subtract(this.position()), + GravityApi.getGravityDirection(this)); + double radius = this.royalDeadZoneRadius(); + if (local.x * local.x + local.z * local.z > radius * radius + || local.y < -WING_BUFFET_BELOW + || local.y > this.getBbHeight() + WING_BUFFET_ABOVE) { + return false; + } + for (RoyalHead head : this.heads) { + if (this.headWithinBiteReach(head, living)) { + return false; + } + } + return true; + } + + private boolean hasRoyalDeadZoneIntruder(ServerLevel level, LivingEntity primaryTarget) { + if (!(primaryTarget instanceof Player) && this.isInRoyalDeadZone(primaryTarget)) { + return true; + } + AABB area = this.getBoundingBox().inflate(WING_BUFFET_EXTRA_RADIUS + 1.0D, WING_BUFFET_BELOW, + WING_BUFFET_EXTRA_RADIUS + 1.0D); + for (Player player : level.getEntitiesOfClass(Player.class, area, + candidate -> candidate.isAlive() && !candidate.isSpectator() && !candidate.isCreative())) { + if (this.canDamageWithRoyalAttack(player) && this.isInRoyalDeadZone(player)) { + return true; + } + } + return false; + } + + private void tickRoyalCloseRangeAnswer(LivingEntity primaryTarget) { + if (!(this.level() instanceof ServerLevel level)) { + return; + } + boolean intruder = this.hasRoyalDeadZoneIntruder(level, primaryTarget); + this.royalDeadZoneTicks = intruder ? this.royalDeadZoneTicks + 1 : Math.max(0, this.royalDeadZoneTicks - 2); + Phase phase = this.phase(); + if (this.royalDeadZoneTicks < this.royalDeadZoneTriggerTicks(phase) + || this.recoveryWindowTicks > 0 + || !this.attackScheduler.ready(WING_BUFFET_ID, RoyalAttackLane.BODY)) { + return; + } + if (this.beginRoyalAttack(WING_BUFFET_ID, RoyalAttackLane.BODY, this.royalWingBuffetCooldownTicks(phase), + WING_BUFFET_WINDUP_TICKS, 1, this.animationRecovery(55, WING_BUFFET_WINDUP_TICKS, 1, 12), + new RoyalAttackScheduler.Action() { + @Override + public void onStart() { + RoyalBossEntity.this.triggerAnim("wing_action", "wing_gust"); + RoyalBossEntity.this.playRoyalSound(RoyalBossEntity.this.royalWingBuffetSound(), 0.75F); + } + + @Override + public void onWindup(int elapsedTicks, int remainingTicks) { + RoyalBossEntity.this.sendRoyalWingBuffetTelegraph(level, elapsedTicks); + } + + @Override + public void onActive(int elapsedTicks) { + RoyalBossEntity.this.performRoyalWingBuffet(level); + } + })) { + this.royalDeadZoneTicks = 0; + } + } + + private void sendRoyalWingBuffetTelegraph(ServerLevel level, int elapsedTicks) { + if (elapsedTicks % 2 != 0) { + return; + } + double progress = Math.min(1.0D, elapsedTicks / (double) WING_BUFFET_WINDUP_TICKS); + double radius = Mth.lerp(progress, this.getBbWidth() * 0.3D, this.royalDeadZoneRadius()); + var gravity = GravityApi.getGravityDirection(this); + for (int index = 0; index < 40; index++) { + double angle = Mth.TWO_PI * index / 40.0D; + Vec3 point = this.position().add(GravityRotationUtil.vecPlayerToWorld( + Math.cos(angle) * radius, 0.3D, Math.sin(angle) * radius, gravity)); + level.sendParticles(ParticleTypes.CLOUD, point.x, point.y, point.z, 1, 0.0D, 0.02D, 0.0D, 0.0D); + } + } + + private void performRoyalWingBuffet(ServerLevel level) { + float damage = (float) (this.getAttributeValue(Attributes.ATTACK_DAMAGE) * WING_BUFFET_DAMAGE_SCALE); + DamageSource source = this.damageSources().mobAttack(this); + var gravity = GravityApi.getGravityDirection(this); + double radius = this.royalDeadZoneRadius() + 2.0D; + AABB area = this.getBoundingBox().inflate(WING_BUFFET_EXTRA_RADIUS + 3.0D, WING_BUFFET_BELOW + 2.0D, + WING_BUFFET_EXTRA_RADIUS + 3.0D); + for (LivingEntity living : level.getEntitiesOfClass(LivingEntity.class, area, + entity -> entity.isAlive() && entity != this && this.canDamageWithRoyalAttack(entity))) { + if (living instanceof Player player && (player.isCreative() || player.isSpectator())) { + continue; + } + Vec3 local = GravityRotationUtil.vecWorldToPlayer(living.position().subtract(this.position()), gravity); + double horizontalSqr = local.x * local.x + local.z * local.z; + if (horizontalSqr > radius * radius + || local.y < -WING_BUFFET_BELOW - 2.0D + || local.y > this.getBbHeight() + WING_BUFFET_ABOVE + 2.0D) { + continue; + } + living.hurt(source, damage); + if (living instanceof RoyalBossEntity) { + continue; + } + Vec3 outwardLocal = horizontalSqr > 1.0E-4D + ? new Vec3(local.x, 0.0D, local.z).normalize() + : new Vec3(1.0D, 0.0D, 0.0D); + Vec3 outward = GravityRotationUtil.vecPlayerToWorld(outwardLocal, gravity); + Vec3 lift = GravityRotationUtil.vecPlayerToWorld(0.0D, WING_BUFFET_LIFT, 0.0D, + GravityApi.getGravityDirection(living)); + this.addGravityAwareImpulse(living, outward.scale(WING_BUFFET_PUSH).add(lift)); + living.hasImpulse = true; + living.hurtMarked = true; + } + for (int ring = 1; ring <= 3; ring++) { + double ringRadius = this.getBbWidth() * 0.22D * ring; + int samples = 16 + ring * 8; + for (int sample = 0; sample < samples; sample++) { + double angle = Mth.TWO_PI * sample / samples; + Vec3 point = this.position().add(GravityRotationUtil.vecPlayerToWorld( + Math.cos(angle) * ringRadius, 1.0D, Math.sin(angle) * ringRadius, gravity)); + Vec3 velocity = GravityRotationUtil.vecPlayerToWorld( + Math.cos(angle) * 0.45D, 0.04D, Math.sin(angle) * 0.45D, gravity); + level.sendParticles(ParticleTypes.CLOUD, point.x, point.y, point.z, + 0, velocity.x, velocity.y, velocity.z, 1.0D); + } + } + level.sendParticles(ParticleTypes.SWEEP_ATTACK, this.getX(), this.getY() + 2.0D, this.getZ(), + 16, this.getBbWidth() * 0.3D, 1.0D, this.getBbWidth() * 0.3D, 0.0D); + this.playRoyalSound(this.royalWingBuffetSound(), 0.6F); + } + + private void tickRoyalConcealedTarget(LivingEntity target) { + if (!(this.level() instanceof ServerLevel level) || this.tickCount % 10 != 0) { + return; + } + if (this.distanceToSqr(target) > EXCAVATION_RANGE * EXCAVATION_RANGE || this.royalCanSeeTarget(target)) { + this.royalConcealedTicks = 0; + return; + } + this.royalConcealedTicks += 10; + if (this.royalConcealedTicks < EXCAVATION_TRIGGER_TICKS + || this.recoveryWindowTicks > 0 + || !this.attackScheduler.ready(EXCAVATION_ID, RoyalAttackLane.SUMMON)) { + return; + } + RoyalHead head = this.heads[RoyalHead.Slot.CENTER.ordinal()]; + LivingEntity committedTarget = target; + if (this.beginRoyalAttack(EXCAVATION_ID, RoyalAttackLane.SUMMON, EXCAVATION_COOLDOWN_TICKS, + EXCAVATION_WINDUP_TICKS, 1, 10, new RoyalAttackScheduler.Action() { + @Override + public void onStart() { + if (head.readyToAttack()) { + RoyalBossEntity.this.triggerAnim(head.slot().controllerName(), "shoot"); + } + RoyalBossEntity.this.playRoyalSound(RoyalBossEntity.this.royalBeamStartSound(head), 0.8F); + } + + @Override + public void onWindup(int elapsedTicks, int remainingTicks) { + if (committedTarget.isAlive() && committedTarget.level() == level && elapsedTicks % 2 == 0) { + RoyalBossEntity.this.sendRoyalExcavationTelegraph(level, committedTarget); + } + } + + @Override + public void onActive(int elapsedTicks) { + RoyalBossEntity.this.performRoyalExcavation(level, committedTarget); + } + })) { + this.royalConcealedTicks = 0; + } + } + + private boolean royalCanSeeTarget(LivingEntity target) { + Vec3 targetEye = target.getEyePosition(); + if (this.clearRoyalSightLine(this.getEyePosition(), targetEye)) { + return true; + } + for (RoyalHead head : this.heads) { + if (this.clearRoyalSightLine(this.headAnchor(head), targetEye)) { + return true; + } + } + return false; + } + + private boolean clearRoyalSightLine(Vec3 from, Vec3 to) { + return this.level().clip(new ClipContext(from, to, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)) + .getType() == HitResult.Type.MISS; + } + + private void sendRoyalExcavationTelegraph(ServerLevel level, LivingEntity target) { + Vec3 origin = this.headAnchor(this.heads[RoyalHead.Slot.CENTER.ordinal()]); + Vec3 targetCenter = target.position().add(0.0D, target.getBbHeight() * 0.5D, 0.0D); + Vec3 line = targetCenter.subtract(origin); + double length = line.length(); + if (length > 1.0E-3D) { + Vec3 direction = line.scale(1.0D / length); + for (double walked = 0.0D; walked <= length; walked += 2.0D) { + Vec3 point = origin.add(direction.scale(walked)); + level.sendParticles(ParticleTypes.ELECTRIC_SPARK, point.x, point.y, point.z, 1, 0.05D, 0.05D, 0.05D, 0.0D); + } + } + for (int index = 0; index < 20; index++) { + double angle = Mth.TWO_PI * index / 20.0D; + level.sendParticles(ParticleTypes.END_ROD, + targetCenter.x + Math.cos(angle) * EXCAVATION_RADIUS, targetCenter.y, + targetCenter.z + Math.sin(angle) * EXCAVATION_RADIUS, + 1, 0.0D, 0.0D, 0.0D, 0.0D); + } + } + + private void performRoyalExcavation(ServerLevel level, LivingEntity target) { + if (!target.isAlive() || target.level() != level) { + return; + } + Vec3 targetCenter = target.position().add(0.0D, target.getBbHeight() * 0.5D, 0.0D); + Vec3 origin = this.headAnchor(this.heads[RoyalHead.Slot.CENTER.ordinal()]); + Vec3 toward = origin.subtract(targetCenter); + double length = toward.length(); + Vec3 direction = length > 1.0E-4D ? toward.scale(1.0D / length) : Vec3.ZERO; + double depth = Math.min(length, EXCAVATION_DEPTH); + for (double step = 1.5D; step <= depth; step += EXCAVATION_RADIUS) { + Vec3 center = targetCenter.add(direction.scale(step)); + RoyalBlockDestruction.destroySphere(level, this, center, EXCAVATION_RADIUS, EXCAVATION_MAX_BLOCKS, + OBSTRUCTION_CLEAR_MAX_RESISTANCE, OBSTRUCTION_CLEAR_DROP_CHANCE); + level.sendParticles(ParticleTypes.EXPLOSION, center.x, center.y, center.z, 1, 0.4D, 0.4D, 0.4D, 0.0D); + } + level.playSound(null, targetCenter.x, targetCenter.y, targetCenter.z, + SoundEvents.GENERIC_EXPLODE, SoundSource.HOSTILE, 2.0F, 0.7F); + if (!this.royalCanSeeTarget(target)) { + target.hurt(this.damageSources().indirectMagic(this, this), + this.scaleRoyalDamage(EXCAVATION_CONCEALED_DAMAGE)); + } + } + + @Nullable + final Vec3 royalFacingPoint() { + if (this.level().isClientSide || this.isDeadOrDying() || this.phaseTransitionTicks > 0 + || GravityApi.isGravityInverted(this)) { + return null; + } + LivingEntity target = this.getTarget(); + if (target == null || !target.isAlive() || !this.canAttack(target) || !this.royalShouldFaceTarget(target)) { + return null; + } + return target.position(); + } + + final void turnRoyalBodyToward(Vec3 point) { + double dx = point.x - this.getX(); + double dz = point.z - this.getZ(); + if (dx * dx + dz * dz < 1.0E-4D) { + return; + } + float desiredYaw = (float) (Mth.atan2(dz, dx) * Mth.RAD_TO_DEG) - 90.0F; + float turn = Mth.clamp(Mth.wrapDegrees(desiredYaw - this.getYRot()), -FACING_TURN_RATE, FACING_TURN_RATE); + this.setYRot(this.getYRot() + turn); + this.yBodyRot = this.getYRot(); + } + + private static void applyRelativeInput(Mob mob, double dx, double dz, float speed) { + double length = Math.sqrt(dx * dx + dz * dz); + double yaw = mob.getYRot() * Mth.DEG_TO_RAD; + double nx = dx / length; + double nz = dz / length; + float forward = (float) (-nx * Math.sin(yaw) + nz * Math.cos(yaw)); + float strafe = (float) (nx * Math.cos(yaw) + nz * Math.sin(yaw)); + mob.setSpeed(speed); + mob.setZza(forward * speed); + mob.setXxa(strafe * speed); + } + + private static final class RoyalGroundMoveControl extends MoveControl { + private final RoyalBossEntity boss; + + private RoyalGroundMoveControl(RoyalBossEntity boss) { + super(boss); + this.boss = boss; + } + + @Override + public void setWantedPosition(double x, double y, double z, double speed) { + super.setWantedPosition(x, y, z, speed); + this.boss.markRoyalMoveRequested(); + } + + @Override + public void tick() { + Vec3 facing = this.boss.royalFacingPoint(); + if (facing == null) { + super.tick(); + return; + } + if (this.operation != Operation.MOVE_TO) { + boolean waiting = this.operation == Operation.WAIT; + super.tick(); + if (waiting) { + this.mob.setXxa(0.0F); + } + this.boss.turnRoyalBodyToward(facing); + return; + } + this.operation = Operation.WAIT; + double dx = this.wantedX - this.mob.getX(); + double dy = this.wantedY - this.mob.getY(); + double dz = this.wantedZ - this.mob.getZ(); + double horizontalSqr = dx * dx + dz * dz; + this.boss.turnRoyalBodyToward(facing); + if (horizontalSqr < 2.5E-7D) { + this.mob.setZza(0.0F); + this.mob.setXxa(0.0F); + return; + } + float speed = (float) (this.speedModifier * this.mob.getAttributeValue(Attributes.MOVEMENT_SPEED)); + applyRelativeInput(this.mob, dx, dz, speed); + if (dy > this.mob.maxUpStep() && horizontalSqr < Math.max(1.0F, this.mob.getBbWidth())) { + this.mob.getJumpControl().jump(); + this.operation = Operation.JUMPING; + } + } + } + + private static final class RoyalFlyingMoveControl extends FlyingMoveControl { + private final RoyalBossEntity boss; + private final int maxPitchTurn; + + private RoyalFlyingMoveControl(RoyalBossEntity boss, int maxTurn) { + super(boss, maxTurn, true); + this.boss = boss; + this.maxPitchTurn = maxTurn; + } + + @Override + public void setWantedPosition(double x, double y, double z, double speed) { + super.setWantedPosition(x, y, z, speed); + this.boss.markRoyalMoveRequested(); + } + + @Override + public void tick() { + Vec3 facing = this.boss.royalFacingPoint(); + if (facing == null) { + super.tick(); + return; + } + if (this.operation != Operation.MOVE_TO) { + super.tick(); + this.mob.setXxa(0.0F); + this.boss.turnRoyalBodyToward(facing); + return; + } + this.operation = Operation.WAIT; + this.mob.setNoGravity(true); + double dx = this.wantedX - this.mob.getX(); + double dy = this.wantedY - this.mob.getY(); + double dz = this.wantedZ - this.mob.getZ(); + this.boss.turnRoyalBodyToward(facing); + if (dx * dx + dy * dy + dz * dz < 2.5E-7D) { + this.mob.setYya(0.0F); + this.mob.setZza(0.0F); + this.mob.setXxa(0.0F); + return; + } + float speed = (float) (this.speedModifier * this.mob.getAttributeValue( + this.mob.onGround() ? Attributes.MOVEMENT_SPEED : Attributes.FLYING_SPEED)); + double horizontal = Math.sqrt(dx * dx + dz * dz); + if (horizontal > 1.0E-5D) { + applyRelativeInput(this.mob, dx, dz, speed); + } else { + this.mob.setSpeed(speed); + this.mob.setZza(0.0F); + this.mob.setXxa(0.0F); + } + float pitch = (float) (-(Mth.atan2(dy, horizontal) * Mth.RAD_TO_DEG)); + this.mob.setXRot(this.rotlerp(this.mob.getXRot(), pitch, this.maxPitchTurn)); + this.mob.setYya(dy > 0.0D ? speed : -speed); + } + } + protected double combatStandoffDistance() { return Math.max(this.getBbWidth() * 0.55D, BEAM_MUZZLE_FORWARD - this.biteReach() * 0.65D + 1.0D); @@ -965,8 +1577,9 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult boolean inverted = GravityApi.isGravityInverted(this); double groundY = this.groundYBelow(this.getX(), this.getZ()); if (this.landingForCombat) { - if (!target.onGround()) { + if (!target.onGround() || ++this.landingForCombatTicks > LANDING_FOR_COMBAT_TIMEOUT_TICKS) { this.landingForCombat = false; + this.landingForCombatTicks = 0; this.locomotionDecisionTicks = 60; } else if (this.onGround() || !inverted && this.getY() <= groundY + 1.0D) { this.landingForCombat = false; @@ -983,6 +1596,7 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult this.locomotionDecisionTicks = 60 + this.random.nextInt(80); if (target.onGround() && this.random.nextDouble() < this.groundCombatBias()) { this.landingForCombat = true; + this.landingForCombatTicks = 0; } } else if (!target.onGround() || this.random.nextDouble() >= this.groundCombatBias()) { this.setRoyalFlying(true); @@ -1009,8 +1623,61 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult } protected double groundYBelow(double x, double z) { - return this.level().getHeight(net.minecraft.world.level.levelgen.Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, - Mth.floor(x), Mth.floor(z)); + return this.groundYBelow(x, z, this.getY() + 1.0D); + } + + protected double groundYBelow(double x, double z, double referenceY) { + Level level = this.level(); + int blockX = Mth.floor(x); + int blockZ = Mth.floor(z); + int surface = level.getHeight(net.minecraft.world.level.levelgen.Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, + blockX, blockZ); + int startY = Mth.floor(referenceY); + if (startY >= surface) { + return surface; + } + net.minecraft.core.BlockPos.MutableBlockPos cursor = new net.minecraft.core.BlockPos.MutableBlockPos(blockX, startY, blockZ); + if (this.isRoyalGroundBlock(level, cursor)) { + int top = Math.min(surface, startY + GROUND_SCAN_RISE); + for (int y = startY + 1; y <= top; y++) { + cursor.setY(y); + if (!this.isRoyalGroundBlock(level, cursor)) { + return y; + } + } + return surface; + } + int bottom = Math.max(level.getMinBuildHeight(), startY - GROUND_SCAN_DEPTH); + for (int y = startY - 1; y >= bottom; y--) { + cursor.setY(y); + if (this.isRoyalGroundBlock(level, cursor)) { + return y + 1; + } + } + return bottom; + } + + protected double ceilingYAbove(double x, double z, double referenceY) { + Level level = this.level(); + net.minecraft.core.BlockPos.MutableBlockPos cursor = new net.minecraft.core.BlockPos.MutableBlockPos( + Mth.floor(x), Mth.floor(referenceY), Mth.floor(z)); + int startY = cursor.getY(); + int top = Math.min(level.getMaxBuildHeight() - 1, startY + GROUND_SCAN_DEPTH); + for (int y = startY; y <= top; y++) { + cursor.setY(y); + if (this.isRoyalGroundBlock(level, cursor)) { + return y; + } + } + return top; + } + + private boolean isRoyalGroundBlock(Level level, net.minecraft.core.BlockPos pos) { + net.minecraft.world.level.block.state.BlockState state = level.getBlockState(pos); + if (state.isAir() || state.is(net.minecraft.tags.BlockTags.LEAVES)) { + return false; + } + return !state.getFluidState().isEmpty() || !state.getCollisionShape(level, pos).isEmpty(); } private void tickFlyingAltitude() { @@ -1022,6 +1689,10 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult } double groundY = this.groundYBelow(this.getX(), this.getZ()); double ceiling = groundY + FLYING_MAX_HOVER_ABOVE_GROUND; + LivingEntity target = this.getTarget(); + if (target != null && target.isAlive()) { + ceiling = Math.max(ceiling, target.getY() + 8.0D); + } if (this.getY() > ceiling) { double desiredY = groundY + FLYING_PREFERRED_HOVER; this.getMoveControl().setWantedPosition(this.getX(), desiredY, this.getZ(), 1.0D); @@ -1032,15 +1703,33 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult } } + private boolean isFightingRoyalRival() { + return this.getTarget() instanceof RoyalBossEntity; + } + private void tickBodyCrush() { - if (!(this.level() instanceof ServerLevel serverLevel) || this.tickCount % 10 != 0) { + if (!(this.level() instanceof ServerLevel serverLevel) + || this.tickCount % (this.isFightingRoyalRival() ? RIVAL_BODY_CRUSH_INTERVAL_TICKS : BODY_CRUSH_INTERVAL_TICKS) != 0) { return; } - if (this.getDeltaMovement().horizontalDistanceSqr() < 0.0016D) { + Vec3 horizontalMovement = this.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D); + boolean moving = horizontalMovement.lengthSqr() >= 0.0016D; + if (!moving && !this.horizontalCollision) { return; } - double yaw = this.yBodyRot * Mth.DEG_TO_RAD; - Vec3 forward = new Vec3(-Math.sin(yaw), 0.0D, Math.cos(yaw)); + Vec3 forward; + if (moving) { + forward = horizontalMovement.normalize(); + } else { + Vec3 toWanted = new Vec3(this.getMoveControl().getWantedX() - this.getX(), 0.0D, + this.getMoveControl().getWantedZ() - this.getZ()); + if (toWanted.lengthSqr() > 1.0E-4D) { + forward = toWanted.normalize(); + } else { + double yaw = this.yBodyRot * Mth.DEG_TO_RAD; + forward = new Vec3(-Math.sin(yaw), 0.0D, Math.cos(yaw)); + } + } Vec3 center = new Vec3( this.getX() + forward.x * (this.getBbWidth() * 0.45D), this.getY() + (this.isRoyalFlying() ? 0.0D : 1.0D), @@ -1163,11 +1852,30 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult protected Vec3 beamDirection(RoyalHead head) { float yaw = this.getYRot() * Mth.DEG_TO_RAD; - Vec3 localDirection = new Vec3(-Math.sin(yaw), 0.0D, Math.cos(yaw)); + double pitch = this.royalBeamPitch(head); + double horizontal = Math.cos(pitch); + Vec3 localDirection = new Vec3(-Math.sin(yaw) * horizontal, Math.sin(pitch), Math.cos(yaw) * horizontal); return GravityRotationUtil.vecPlayerToWorld(localDirection, GravityApi.getGravityDirection(this)).normalize(); } + private double royalBeamPitch(RoyalHead head) { + if (this.level().isClientSide) { + return 0.0D; + } + LivingEntity target = head.target(this.level()); + if (target == null) { + return 0.0D; + } + Vec3 local = GravityRotationUtil.vecWorldToPlayer(target.getEyePosition().subtract(this.beamAnchor(head)), + GravityApi.getGravityDirection(this)); + double horizontal = Math.sqrt(local.x * local.x + local.z * local.z); + if (horizontal < 1.0E-3D) { + return 0.0D; + } + return Mth.clamp(Math.atan2(local.y, horizontal), -MAX_BEAM_PITCH, MAX_BEAM_PITCH); + } + protected boolean targetInBeamLine(RoyalHead head, LivingEntity target) { Vec3 origin = this.beamAnchor(head); Vec3 direction = this.beamDirection(head); diff --git a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalElementalProjectileEntity.java b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalElementalProjectileEntity.java index 58c411fb..a8f86631 100644 --- a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalElementalProjectileEntity.java +++ b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalElementalProjectileEntity.java @@ -131,6 +131,25 @@ public class RoyalElementalProjectileEntity extends ThrowableProjectile implemen } } + @Override + protected boolean canHitEntity(Entity target) { + Entity owner = this.getOwner(); + if (owner != null && target == owner) { + return false; + } + if (owner instanceof com.craisinlord.anthology.multipart.MultipartEntityOwner multipart) { + Entity[] parts = multipart.anthology$getMultipartParts(); + if (parts != null) { + for (Entity part : parts) { + if (part == target) { + return false; + } + } + } + } + return super.canHitEntity(target); + } + @Override protected void onHitEntity(EntityHitResult result) { if (!this.level().isClientSide && this.level() instanceof ServerLevel level) { diff --git a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/attack/RoyalAttackScheduler.java b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/attack/RoyalAttackScheduler.java index b885a307..a7dbb365 100644 --- a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/attack/RoyalAttackScheduler.java +++ b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/attack/RoyalAttackScheduler.java @@ -100,7 +100,8 @@ public final class RoyalAttackScheduler { int total = 0; int[] weights = new int[ids.length]; for (int i = 0; i < ids.length; i++) { - weights[i] = Math.max(0, weightFunction.applyAsInt(ids[i]) - repetitionPenalty(ids[i])); + int baseWeight = weightFunction.applyAsInt(ids[i]); + weights[i] = baseWeight > 0 ? Math.max(1, baseWeight - repetitionPenalty(ids[i])) : 0; total += weights[i]; } if (total <= 0) { diff --git a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalTeleporter.java b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalTeleporter.java index 78123f91..720e3f28 100644 --- a/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalTeleporter.java +++ b/common-1.20.1/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalTeleporter.java @@ -1,6 +1,7 @@ package com.craisinlord.antarchy.content.portal; import com.craisinlord.antarchy.config.AntarchySettings; +import com.craisinlord.antarchy.content.entity.ant.AntTeleportHelper; import java.util.Comparator; import java.util.LinkedHashSet; import java.util.List; @@ -14,6 +15,7 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.ai.village.poi.PoiManager; import net.minecraft.world.entity.ai.village.poi.PoiRecord; import net.minecraft.world.entity.vehicle.DismountHelper; @@ -48,12 +50,23 @@ public final class PermanentPortalTeleporter { entity.setPortalCooldown(); Transition transition = createTransition(sourceLevel, entity, entity.blockPosition(), type); + List companions = entity instanceof ServerPlayer player && transition.newLevel() != sourceLevel + ? AntTeleportHelper.collectCompanions(player) + : List.of(); Entity movedEntity = moveEntity(entity, transition); if (movedEntity != null) { movedEntity.setPortalCooldown(); if (transition.playPortalSound() && movedEntity instanceof ServerPlayer player) { player.connection.send(new ClientboundLevelEventPacket(LevelEvent.SOUND_PORTAL_TRAVEL, BlockPos.ZERO, 0, false)); } + for (Mob companion : companions) { + if (companion.isAlive()) { + Mob movedCompanion = AntTeleportHelper.moveCompanion(companion, transition.newLevel(), transition.pos()); + if (movedCompanion != null) { + movedCompanion.setPortalCooldown(); + } + } + } } } @@ -91,6 +104,7 @@ public final class PermanentPortalTeleporter { return safePortalPosition != null ? safePortalPosition : existing.center(); } + AntTeleportHelper.loadArrivalSearchArea(destination, preferredPos, SEARCH_RADIUS); Vec3 safe = findSafeArrivalPosition(entity, destination, preferredPos, type); if (safe != null) { PermanentPortalShape created = createReturnPortal(destination, safe, type); @@ -100,7 +114,19 @@ public final class PermanentPortalTeleporter { return createFallbackPortal(destination, BlockPos.containing(safe), type); } - return null; + return createFallbackPortal(destination, fallbackArrivalPos(destination, preferredPos, type), type); + } + + private static BlockPos fallbackArrivalPos(ServerLevel destination, BlockPos preferredPos, PermanentPortalType type) { + int[] yRange = getDimensionYRange(destination, type); + if (yRange != null) { + return new BlockPos(preferredPos.getX(), Mth.clamp(preferredPos.getY(), yRange[0] + 1, yRange[1] - 4), preferredPos.getZ()); + } + BlockPos surface = destination.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, preferredPos); + if (surface.getY() > destination.getMinBuildHeight() + 1) { + return surface; + } + return preferredPos; } @Nullable diff --git a/common-1.20.1/src/main/java/com/craisinlord/antarchy/mixins/client/MountedVehicleCameraMixin.java b/common-1.20.1/src/main/java/com/craisinlord/antarchy/mixins/client/MountedVehicleCameraMixin.java index f5dc0c3e..5a4e5c7a 100644 --- a/common-1.20.1/src/main/java/com/craisinlord/antarchy/mixins/client/MountedVehicleCameraMixin.java +++ b/common-1.20.1/src/main/java/com/craisinlord/antarchy/mixins/client/MountedVehicleCameraMixin.java @@ -3,11 +3,14 @@ package com.craisinlord.antarchy.mixins.client; import com.craisinlord.antarchy.content.entity.HerculesBeetleEntity; import net.minecraft.client.Camera; import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.phys.Vec3; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyArg; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(Camera.class) public abstract class MountedVehicleCameraMixin { @@ -17,31 +20,31 @@ public abstract class MountedVehicleCameraMixin { @Shadow private boolean detached; - @ModifyArg( - method = "setup", - at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Camera;move(DDD)V"), - index = 0 - ) - private double antarchy$adjustMountedCameraX(double value) { - return this.antarchy$ridingHerculesBeetle() ? value * 1.45D : value; - } + @Shadow + protected abstract void setPosition(Vec3 position); - @ModifyArg( - method = "setup", - at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Camera;move(DDD)V"), - index = 1 - ) - private double antarchy$adjustMountedCameraY(double value) { - return this.antarchy$ridingHerculesBeetle() ? value + 0.2D : value; - } + @Inject(method = "setup", at = @At("RETURN")) + private void antarchy$adjustMountedCamera( + BlockGetter level, + Entity entity, + boolean detached, + boolean thirdPersonReverse, + float partialTick, + CallbackInfo ci + ) { + if (!this.antarchy$ridingHerculesBeetle()) { + return; + } - @ModifyArg( - method = "setup", - at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Camera;move(DDD)V"), - index = 2 - ) - private double antarchy$adjustMountedCameraZ(double value) { - return this.antarchy$ridingHerculesBeetle() ? value + 0.45D : value; + Camera camera = (Camera) (Object) this; + Vec3 look = new Vec3(camera.getLookVector()); + Vec3 cameraOffset = camera.getPosition().subtract(entity.getEyePosition(partialTick)); + double zoomOffset = cameraOffset.dot(look) * 0.45D; + + Vec3 adjustment = look.scale(zoomOffset) + .add(new Vec3(camera.getUpVector()).scale(0.2D)) + .add(new Vec3(camera.getLeftVector()).scale(0.45D)); + this.setPosition(camera.getPosition().add(adjustment)); } @Unique diff --git a/common-1.20.1/src/main/java/com/craisinlord/antarchy/mixins/client/PortalGunZoomFovMixin.java b/common-1.20.1/src/main/java/com/craisinlord/antarchy/mixins/client/PortalGunZoomFovMixin.java index b3b6b4b2..5c6dc5a6 100644 --- a/common-1.20.1/src/main/java/com/craisinlord/antarchy/mixins/client/PortalGunZoomFovMixin.java +++ b/common-1.20.1/src/main/java/com/craisinlord/antarchy/mixins/client/PortalGunZoomFovMixin.java @@ -1,18 +1,17 @@ package com.craisinlord.antarchy.mixins.client; import com.craisinlord.antarchy.content.client.PortalGunZoomClientState; +import com.llamalad7.mixinextras.injector.ModifyReturnValue; import net.minecraft.client.Camera; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.GameRenderer; 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; @Mixin(GameRenderer.class) public abstract class PortalGunZoomFovMixin { - @Inject(method = "getFov", at = @At("RETURN"), cancellable = true) - private void antarchy$applyPortalGunZoom(Camera camera, float partialTick, boolean useFovSetting, CallbackInfoReturnable cir) { - cir.setReturnValue(PortalGunZoomClientState.applyFov(cir.getReturnValue(), partialTick, Minecraft.getInstance().options)); + @ModifyReturnValue(method = "getFov", at = @At("RETURN")) + private double antarchy$applyPortalGunZoom(double fov, Camera camera, float partialTick, boolean useFovSetting) { + return PortalGunZoomClientState.applyFov(fov, partialTick, Minecraft.getInstance().options); } } diff --git a/common-1.20.1/src/main/resources/assets/antarchy/geo/gravity_gun.geo.json b/common-1.20.1/src/main/resources/assets/antarchy/geo/gravity_gun.geo.json index c1aee484..c61b1fcf 100644 --- a/common-1.20.1/src/main/resources/assets/antarchy/geo/gravity_gun.geo.json +++ b/common-1.20.1/src/main/resources/assets/antarchy/geo/gravity_gun.geo.json @@ -57,7 +57,7 @@ {"origin": [2.5, 3.7, -9.47], "size": [0, 5, 3], "uv": [26, 27]}, {"origin": [-2.5, 3.7, -9.47], "size": [5, 0, 3], "uv": [22, 15]}, {"origin": [-2.5, 3.7, -9.47], "size": [0, 5, 3], "uv": [20, 27]}, - {"origin": [-2.5, 3.7, -6.47], "size": [5, 5, 0], "uv": [20, 22]} + {"origin": [-2.5, 3.7, -6.55], "size": [5, 5, 0], "uv": [20, 22]} ] } ] diff --git a/common-1.20.1/src/main/resources/assets/antarchy/lang/ko_kr.json b/common-1.20.1/src/main/resources/assets/antarchy/lang/ko_kr.json index 030e42ac..86001626 100644 --- a/common-1.20.1/src/main/resources/assets/antarchy/lang/ko_kr.json +++ b/common-1.20.1/src/main/resources/assets/antarchy/lang/ko_kr.json @@ -1,962 +1,1670 @@ { - "block.antarchy.duplicator_log": "복제기 원목", - "block.antarchy.ouranwood_log": "오란우드 원목", - "block.antarchy.ouranwood_wood": "오란우드 목재", - "block.antarchy.mossy_ouranwood_log": "이끼 낀 오란우드 원목", - "block.antarchy.mossy_ouranwood_wood": "이끼 낀 오란우드 목재", - "block.antarchy.stripped_ouranwood_log": "껍질 벗긴 오란우드 원목", - "block.antarchy.stripped_ouranwood_wood": "껍질 벗긴 오란우드 목재", - "block.antarchy.ouranwood_planks": "오란우드 판자", - "block.antarchy.ouranwood_stairs": "오란우드 계단", - "block.antarchy.ouranwood_slab": "오란우드 반 블록", - "block.antarchy.ouranwood_fence": "오란우드 울타리", - "block.antarchy.ouranwood_fence_gate": "오란우드 울타리 문", - "block.antarchy.ouranwood_door": "오란우드 문", - "block.antarchy.ouranwood_trapdoor": "오란우드 다락문", - "block.antarchy.ouranwood_pressure_plate": "오란우드 감압판", - "block.antarchy.ouranwood_button": "오란우드 버튼", - "block.antarchy.ouranwood_leaves": "오란우드 잎", - "block.antarchy.ouranwood_acorn": "오란우드 도토리", - "block.antarchy.ouranwood_sign": "오란우드 표지판", - "block.antarchy.ouranwood_hanging_sign": "오란우드 매다는 표지판", - "block.antarchy.peach_log": "복숭아 원목", - "block.antarchy.peach_wood": "복숭아 목재", - "block.antarchy.stripped_peach_log": "껍질 벗긴 복숭아 원목", - "block.antarchy.stripped_peach_wood": "껍질 벗긴 복숭아 목재", - "block.antarchy.peach_planks": "복숭아 판자", - "block.antarchy.peach_stairs": "복숭아 계단", - "block.antarchy.peach_slab": "복숭아 반 블록", - "block.antarchy.peach_fence": "복숭아 울타리", - "block.antarchy.peach_fence_gate": "복숭아나무 울타리 문", - "block.antarchy.peach_door": "복숭아 문", - "block.antarchy.peach_trapdoor": "복숭아 다락문", - "block.antarchy.peach_pressure_plate": "복숭아 감압판", - "block.antarchy.peach_button": "복숭아 버튼", - "block.antarchy.peach_leaves": "복숭아 잎", - "block.antarchy.hanging_peach": "매달린 복숭아", - "block.antarchy.peach_sapling": "복숭아 묘목", - "block.antarchy.peach_sign": "복숭아 표지판", - "block.antarchy.peach_hanging_sign": "복숭아 매다는 표지판", - "block.antarchy.orange_milkweed": "주황색 박주가리", - "block.antarchy.pink_milkweed": "분홍색 박주가리", - "block.antarchy.camellia": "동백꽃", - "block.antarchy.spider_lily": "석산", - "block.antarchy.lotus": "연꽃", - "item.antarchy.lotus": "연꽃", - "item.antarchy.critter_cage": "동물 우리", - "block.antarchy.giant_lily_pad": "거대 수련잎", - "block.antarchy.seashell": "조개껍데기", - "block.antarchy.critter_cage_block": "동물 우리", - "block.antarchy.hushweed": "허시위드", - "block.antarchy.umbral_moss_block": "그늘 이끼 블록", - "block.antarchy.umbral_moss_carpet": "그늘 이끼 양탄자", - "block.antarchy.blush_moss_block": "분홍 이끼 블록", - "block.antarchy.blush_moss_carpet": "분홍 이끼 양탄자", - "block.antarchy.duplicator_sapling": "복제기 묘목", - "block.antarchy.duct_tape": "덕트 테이프", - "block.antarchy.infested_rooted_dirt": "감염된 뿌리내린 흙", - "block.antarchy.infested_coarse_dirt": "감염된 거친 흙", - "block.antarchy.nyxite": "닉사이트", - "block.antarchy.polished_nyxite": "윤나는 닉사이트", - "block.antarchy.chiseled_nyxite": "조각된 닉사이트", - "block.antarchy.nyxite_bricks": "닉사이트 벽돌", - "block.antarchy.shellstone": "셸스톤", - "block.antarchy.polished_shellstone": "윤나는 셸스톤", - "block.antarchy.shellstone_bricks": "셸스톤 벽돌", - "block.antarchy.chiseled_shellstone": "조각된 셸스톤", - "block.antarchy.mossy_shellstone_bricks": "이끼 낀 셸스톤 벽돌", - "block.antarchy.mossy_shellstone_brick_stairs": "이끼 낀 셸스톤 벽돌 계단", - "block.antarchy.mossy_shellstone_brick_slab": "이끼 낀 셸스톤 벽돌 반 블록", - "block.antarchy.mossy_shellstone_brick_wall": "이끼 낀 셸스톤 벽돌 담장", - "block.antarchy.cracked_shellstone_bricks": "금 간 셸스톤 벽돌", - "block.antarchy.shellstone_stairs": "셸스톤 계단", - "block.antarchy.shellstone_slab": "셸스톤 반 블록", - "block.antarchy.shellstone_wall": "셸스톤 담장", - "block.antarchy.polished_shellstone_stairs": "윤나는 셸스톤 계단", - "block.antarchy.polished_shellstone_slab": "윤나는 셸스톤 반 블록", - "block.antarchy.polished_shellstone_wall": "윤나는 셸스톤 담장", - "block.antarchy.shellstone_brick_stairs": "셸스톤 벽돌 계단", - "block.antarchy.shellstone_brick_slab": "셸스톤 벽돌 반 블록", - "block.antarchy.shellstone_brick_wall": "셸스톤 벽돌 담장", - "block.antarchy.nyxite_stairs": "닉사이트 계단", - "block.antarchy.nyxite_slab": "닉사이트 반 블록", - "block.antarchy.nyxite_wall": "닉사이트 담장", - "block.antarchy.polished_nyxite_stairs": "윤나는 닉사이트 계단", - "block.antarchy.polished_nyxite_slab": "윤나는 닉사이트 반 블록", - "block.antarchy.polished_nyxite_wall": "윤나는 닉사이트 담장", - "block.antarchy.nyxite_brick_stairs": "닉사이트 벽돌 계단", - "block.antarchy.nyxite_brick_slab": "닉사이트 벽돌 반 블록", - "block.antarchy.nyxite_brick_wall": "닉사이트 벽돌 담장", - "block.antarchy.pale_nyxite": "창백한 닉사이트", - "block.antarchy.nyxite_spike": "닉사이트 가시", - "block.antarchy.potent_nyxite": "강력한 닉사이트", - "block.antarchy.flytrap_goo_block": "트리피드 점액 블록", - "block.antarchy.elythia_portal": "엘리티아 차원문", - "block.antarchy.cloud_block": "구름 블록", - "block.antarchy.thoraxis_portal": "토랙시스 차원문", - "block.antarchy.antimetal": "안티메탈", - "block.antarchy.polished_antimetal": "윤나는 안티메탈", - "block.antarchy.antimetal_scaffolding": "안티메탈 비계", - "block.antarchy.cornea_stalk": "코니아 줄기", - "block.antarchy.corn_crop": "옥수수 작물", - "block.antarchy.dream_torch": "꿈 횃불", - "block.antarchy.dream_wall_torch": "꿈 벽 횃불", - "block.antarchy.dream_lantern": "꿈 랜턴", - "block.antarchy.dream_campfire": "꿈 모닥불", - "block.antarchy.dream_fire": "꿈 불", - "block.antarchy.dream_fire_ceiling": "꿈 불", - "block.antarchy.budding_blood_crystal": "싹트는 혈수정", - "block.antarchy.blood_crystal_block": "혈수정 블록", - "block.antarchy.small_blood_crystal_bud": "작은 혈수정 눈", - "block.antarchy.medium_blood_crystal_bud": "중간 혈수정 눈", - "block.antarchy.large_blood_crystal_bud": "큰 혈수정 눈", - "block.antarchy.blood_crystal_cluster": "혈수정 군집", - "block.antarchy.dream_sand": "꿈 모래", - "block.antarchy.dream_sandstone": "꿈 사암", - "block.antarchy.chiseled_dream_sandstone": "조각된 꿈 사암", - "block.antarchy.cut_dream_sandstone": "깎인 꿈 사암", - "block.antarchy.smooth_dream_sandstone": "매끄러운 꿈 사암", - "block.antarchy.dream_sandstone_stairs": "꿈 사암 계단", - "block.antarchy.dream_sandstone_slab": "꿈 사암 반 블록", - "block.antarchy.dream_sandstone_wall": "꿈 사암 담장", - "block.antarchy.smooth_dream_sandstone_stairs": "매끄러운 꿈 사암 계단", - "block.antarchy.smooth_dream_sandstone_slab": "매끄러운 꿈 사암 반 블록", - "block.antarchy.cut_dream_sandstone_slab": "깎인 꿈 사암 반 블록", - "block.antarchy.bed_bug_egg": "빈대 알", - "block.antarchy.wasp_nest": "말벌 둥지", - "block.antarchy.red_ant_nest": "붉은 개미 둥지", - "block.antarchy.brown_ant_nest": "갈색 개미 둥지", - "block.antarchy.rainbow_ant_nest": "무지개 개미 둥지", - "block.antarchy.uranium_ore": "우라늄 광석", - "block.antarchy.deepslate_uranium_ore": "심층암 우라늄 광석", - "block.antarchy.titanium_ore": "티타늄 광석", - "block.antarchy.deepslate_titanium_ore": "심층암 티타늄 광석", - "block.antarchy.uranium_block": "우라늄 블록", - "block.antarchy.titanium_block": "티타늄 블록", - "block.antarchy.raw_uranium_block": "원시 우라늄 블록", - "block.antarchy.raw_titanium_block": "원시 티타늄 블록", - "block.antarchy.cut_uranium": "깎인 우라늄", - "block.antarchy.cut_titanium": "깎인 티타늄", - "block.antarchy.cut_uranium_slab": "깎인 우라늄 반 블록", - "block.antarchy.cut_titanium_slab": "깎인 티타늄 반 블록", - "block.antarchy.cut_uranium_stairs": "깎인 우라늄 계단", - "block.antarchy.cut_titanium_stairs": "깎인 티타늄 계단", - "block.antarchy.chiseled_uranium": "조각된 우라늄", - "block.antarchy.chiseled_titanium": "조각된 티타늄", - "block.antarchy.uranium_bulb": "우라늄 전구", - "block.antarchy.titanium_bulb": "티타늄 전구", - "block.antarchy.uranium_door": "우라늄 문", - "block.antarchy.titanium_door": "티타늄 문", - "block.antarchy.uranium_trapdoor": "우라늄 다락문", - "block.antarchy.titanium_trapdoor": "티타늄 다락문", - "block.antarchy.uranium_bars": "우라늄 창살", - "block.antarchy.titanium_bars": "티타늄 창살", - "tooltip.antarchy.signal_saving_bulb": "켜고 끌 수 있습니다. 밝기는 저장된 신호 세기와 같습니다.", - "block.antarchy.bile": "담즙", - "block.antarchy.ichor": "이코르", - "block.antarchy.antiwater": "역수", - "block.antarchy.lumen": "루멘", - "block.antarchy.lumen_froglight": "루멘 개구리불", - "block.antarchy.roseate_froglight": "장밋빛 개구리불", - "block.antarchy.star_coral": "별 산호", - "block.antarchy.star_coral_fan": "별 부채산호", - "block.antarchy.star_coral_block": "별 산호 블록", - "block.antarchy.dead_star_coral": "죽은 별 산호", - "block.antarchy.dead_star_coral_fan": "죽은 별 부채산호", - "block.antarchy.dead_star_coral_block": "죽은 별 산호 블록", - "entity.antarchy.apple_cow": "사과 소", - "entity.antarchy.golden_apple_cow": "황금 사과 소", - "entity.antarchy.enchanted_golden_apple_cow": "마법이 부여된 황금 사과 소", - "entity.antarchy.easter_bunny": "부활절 토끼", - "entity.antarchy.glimmer": "글리머", - "entity.antarchy.ouranwood_deer": "오란우드 사슴", - "entity.antarchy.elka": "엘카", - "entity.antarchy.dorrie": "도리", - "entity.antarchy.flying_squirrel": "날다람쥐", - "entity.antarchy.caterpillar": "애벌레", - "entity.antarchy.butterfly": "나비", - "entity.antarchy.brutalfly": "브루털플라이", - "entity.antarchy.red_ant": "붉은 개미", - "entity.antarchy.brown_ant": "갈색 개미", - "entity.antarchy.rainbow_ant": "무지개 개미", - "entity.antarchy.diamond_minecart": "다이아몬드 광산 수레", - "entity.antarchy.dr_trayaurus": "트레이오러스 박사", - "entity.antarchy.stratoshark": "구름 상어", - "entity.antarchy.kraken": "크라켄", - "entity.antarchy.missile_squid": "미사일 오징어", - "entity.antarchy.octopus_bomb": "문어 폭탄", - "entity.antarchy.nightmare": "악몽", - "entity.antarchy.bed_bug": "빈대", - "entity.antarchy.wasp": "말벌", - "entity.antarchy.bomber": "폭격충", - "entity.antarchy.moleworm": "몰웜", - "entity.antarchy.molevore": "몰보어", - "entity.antarchy.mantis": "사마귀", - "entity.antarchy.alpha_mantis": "알파 사마귀", - "entity.antarchy.flytrap": "트리피드", - "entity.antarchy.toreterror": "토어테러", - "entity.antarchy.water_bomb": "물 폭탄", - "subtitles.antarchy.mantis_ambient": "사마귀 딸깍거립니다", - "subtitles.antarchy.mantis_hurt": "사마귀 날카롭게 웁니다", - "subtitles.antarchy.mantis_attack": "사마귀 턱을 딱딱거립니다", - "subtitles.antarchy.mantis_fly_loop": "사마귀 날개가 윙윙거립니다", - "item.antarchy.big_bertha": "빅 버사", - "item.antarchy.wasp_nest": "말벌 둥지", - "item.antarchy.stink_bug": "노린재", - "item.antarchy.wasp_spawn_egg": "말벌 생성 알", - "item.antarchy.bomber_spawn_egg": "폭격충 생성 알", - "item.antarchy.big_bertha_blade": "빅 버사 칼날", - "item.antarchy.big_bertha_handle": "빅 버사 손잡이", - "item.antarchy.big_bertha_hilt": "빅 버사 칼자루", - "item.antarchy.battle_axe": "전투 도끼", - "item.antarchy.attitude_adjuster": "태도 교정기", - "tooltip.antarchy.attitude_adjuster.grounded": "지상의 대상을 위로 날리고, 공중의 대상을 땅으로 내리꽂습니다.", - "tooltip.antarchy.attitude_adjuster.slam": "공중에서 우클릭하면 지면 강타를 합니다.", - "item.antarchy.stratoshark_fin": "구름 상어 지느러미", - "item.antarchy.stratoshark_fin_soup": "구름 상어 지느러미 수프", - "tooltip.antarchy.stratoshark_fin_soup": "힘과 느린 낙하를 부여합니다.", - "tooltip.antarchy.critter_cage.empty": "우클릭하여 던지기", - "tooltip.antarchy.critter_cage.contains": "들어 있음: %s", - "tooltip.antarchy.critter_cage.release": "우클릭하여 풀어주기", - "tooltip.antarchy.critter_cage.place": "웅크리기 + 우클릭으로 설치", - "item.antarchy.kraken_tooth": "크라켄 이빨", - "item.antarchy.kraken_tentacle": "크라켄 촉수", - "item.antarchy.krakens_grasp": "크라켄의 손아귀", - "entity.antarchy.tentacle": "촉수", - "item.antarchy.basilisk_fang": "바실리스크 송곳니", - "item.antarchy.basilisk_dagger": "바실리스크 단검", - "item.antarchy.blood_crystal_block": "혈수정 블록", - "item.antarchy.small_blood_crystal_bud": "작은 혈수정 눈", - "item.antarchy.medium_blood_crystal_bud": "중간 혈수정 눈", - "item.antarchy.large_blood_crystal_bud": "큰 혈수정 눈", - "item.antarchy.blood_crystal_cluster": "혈수정 군집", - "item.antarchy.dream_sand": "꿈 모래", - "item.antarchy.dream_sandstone": "꿈 사암", - "item.antarchy.chiseled_dream_sandstone": "조각된 꿈 사암", - "item.antarchy.cut_dream_sandstone": "깎인 꿈 사암", - "item.antarchy.smooth_dream_sandstone": "매끄러운 꿈 사암", - "item.antarchy.dream_sandstone_stairs": "꿈 사암 계단", - "item.antarchy.dream_sandstone_slab": "꿈 사암 반 블록", - "item.antarchy.dream_sandstone_wall": "꿈 사암 담장", - "item.antarchy.smooth_dream_sandstone_stairs": "매끄러운 꿈 사암 계단", - "item.antarchy.smooth_dream_sandstone_slab": "매끄러운 꿈 사암 반 블록", - "item.antarchy.cut_dream_sandstone_slab": "깎인 꿈 사암 반 블록", - "item.antarchy.dream_torch": "꿈 횃불", - "item.antarchy.dream_lantern": "꿈 랜턴", - "item.antarchy.dream_campfire": "꿈 모닥불", - "item.antarchy.giant_lily_pad": "거대 수련잎", - "item.antarchy.seashell": "조개껍데기", - "item.antarchy.nightmare_scale": "악몽 비늘", - "item.antarchy.nightmare_helmet": "악몽 투구", - "item.antarchy.nightmare_chestplate": "악몽 흉갑", - "item.antarchy.nightmare_leggings": "악몽 레깅스", - "item.antarchy.nightmare_boots": "악몽 부츠", - "item.antarchy.nightmare_sword": "악몽 검", - "tooltip.antarchy.nightmare_armor_double_damage": "%s%% 확률로 두 배의 피해를 줍니다", - "tooltip.antarchy.nightmare_armor_set_bonus": "세트 효과: 위더와 공포 면역", - "tooltip.antarchy.nightmare_sword": "체력이 낮을수록 더 많은 피해를 줍니다.", - "tooltip.antarchy.nightmare_sword_damage": "%s의 피해를 줍니다", - "tooltip.antarchy.primordial_helmet_water_breathing": "착용자에게 수중 호흡을 부여합니다", - "tooltip.antarchy.primordial_armor_knockback_dealt": "부위당 공격 밀치기가 %s 증가합니다", - "tooltip.antarchy.primordial_armor_set_bonus": "세트 효과: 공격이 적의 밀치기 저항을 무시합니다", - "attribute.antarchy.double_damage_chance": "두 배 피해 확률", - "attribute.antarchy.bloodglass_max_hearts": "최대 혈유리 심장", - "item.antarchy.molevore_nose": "몰보어 코", - "item.antarchy.moleworm": "몰웜", - "item.antarchy.flytrap_spawn_egg": "트리피드 생성 알", - "item.antarchy.infested_rooted_dirt": "감염된 뿌리내린 흙", - "item.antarchy.infested_coarse_dirt": "감염된 거친 흙", - "item.antarchy.pale_nyxite": "창백한 닉사이트", - "item.antarchy.polished_nyxite": "윤나는 닉사이트", - "item.antarchy.chiseled_nyxite": "조각된 닉사이트", - "item.antarchy.nyxite_bricks": "닉사이트 벽돌", - "item.antarchy.shellstone": "셸스톤", - "item.antarchy.polished_shellstone": "윤나는 셸스톤", - "item.antarchy.shellstone_bricks": "셸스톤 벽돌", - "item.antarchy.chiseled_shellstone": "조각된 셸스톤", - "item.antarchy.mossy_shellstone_bricks": "이끼 낀 셸스톤 벽돌", - "item.antarchy.mossy_shellstone_brick_stairs": "이끼 낀 셸스톤 벽돌 계단", - "item.antarchy.mossy_shellstone_brick_slab": "이끼 낀 셸스톤 벽돌 반 블록", - "item.antarchy.mossy_shellstone_brick_wall": "이끼 낀 셸스톤 벽돌 담장", - "item.antarchy.cracked_shellstone_bricks": "금 간 셸스톤 벽돌", - "item.antarchy.shellstone_stairs": "셸스톤 계단", - "item.antarchy.shellstone_slab": "셸스톤 반 블록", - "item.antarchy.shellstone_wall": "셸스톤 담장", - "item.antarchy.polished_shellstone_stairs": "윤나는 셸스톤 계단", - "item.antarchy.polished_shellstone_slab": "윤나는 셸스톤 반 블록", - "item.antarchy.polished_shellstone_wall": "윤나는 셸스톤 담장", - "item.antarchy.shellstone_brick_stairs": "셸스톤 벽돌 계단", - "item.antarchy.shellstone_brick_slab": "셸스톤 벽돌 반 블록", - "item.antarchy.shellstone_brick_wall": "셸스톤 벽돌 담장", - "item.antarchy.nyxite_stairs": "닉사이트 계단", - "item.antarchy.nyxite_slab": "닉사이트 반 블록", - "item.antarchy.nyxite_wall": "닉사이트 담장", - "item.antarchy.polished_nyxite_stairs": "윤나는 닉사이트 계단", - "item.antarchy.polished_nyxite_slab": "윤나는 닉사이트 반 블록", - "item.antarchy.polished_nyxite_wall": "윤나는 닉사이트 담장", - "item.antarchy.nyxite_brick_stairs": "닉사이트 벽돌 계단", - "item.antarchy.nyxite_brick_slab": "닉사이트 벽돌 반 블록", - "item.antarchy.nyxite_brick_wall": "닉사이트 벽돌 담장", - "item.antarchy.potent_nyxite": "강력한 닉사이트", - "item.antarchy.antimetal": "안티메탈", - "item.antarchy.polished_antimetal": "윤나는 안티메탈", - "item.antarchy.antimetal_scaffolding": "안티메탈 비계", - "item.antarchy.ouranwood_acorn": "오란우드 도토리", - "item.antarchy.ouranwood_boat": "오란우드 보트", - "item.antarchy.ouranwood_chest_boat": "오란우드 상자 보트", - "item.antarchy.raw_venison": "익히지 않은 사슴고기", - "item.antarchy.cooked_venison": "익힌 사슴고기", - "item.antarchy.peach_sapling": "복숭아 묘목", - "item.antarchy.peach": "복숭아", - "item.antarchy.peach_pie": "복숭아 파이", - "item.antarchy.cornbread": "옥수수빵", - "item.antarchy.popcorn": "팝콘", - "item.antarchy.peach_sign": "복숭아 표지판", - "item.antarchy.peach_hanging_sign": "복숭아 매다는 표지판", - "item.antarchy.peach_boat": "복숭아 보트", - "item.antarchy.peach_chest_boat": "복숭아 상자 보트", - "item.antarchy.orange_milkweed": "주황색 박주가리", - "item.antarchy.pink_milkweed": "분홍색 박주가리", - "item.antarchy.camellia": "동백꽃", - "item.antarchy.spider_lily": "석산", - "item.antarchy.hushweed": "허시위드", - "item.antarchy.umbral_moss_block": "그늘 이끼 블록", - "item.antarchy.umbral_moss_carpet": "그늘 이끼 양탄자", - "item.antarchy.blush_moss_block": "분홍 이끼 블록", - "item.antarchy.blush_moss_carpet": "분홍 이끼 양탄자", - "item.antarchy.mud_pie": "진흙 파이", - "item.antarchy.duct_tape": "덕트 테이프", - "item.antarchy.duct_tape.tooltip": "설치한 뒤 우클릭하여 도구를 수리합니다", - "item.antarchy.rainbow_sugar": "무지개 설탕", - "item.antarchy.uranium_nugget": "우라늄 조각", - "item.antarchy.titanium_nugget": "티타늄 조각", - "item.antarchy.raw_uranium_scrap": "익히지 않은 우라늄 파편", - "item.antarchy.raw_titanium_scrap": "익히지 않은 티타늄 파편", - "item.antarchy.raw_uranium": "익히지 않은 우라늄", - "item.antarchy.raw_titanium": "익히지 않은 티타늄", - "item.antarchy.uranium_ingot": "우라늄 주괴", - "item.antarchy.titanium_ingot": "티타늄 주괴", - "item.antarchy.blood_crystal_shard": "혈수정 조각", - "item.antarchy.blood_crystal_apple": "혈수정 사과", - "item.antarchy.blood_crystal_katana": "혈수정 카타나", - "item.antarchy.blood_crystal_helmet": "혈수정 투구", - "item.antarchy.blood_crystal_chestplate": "혈수정 흉갑", - "item.antarchy.blood_crystal_leggings": "혈수정 레깅스", - "item.antarchy.blood_crystal_boots": "혈수정 부츠", - "item.antarchy.blood_crystal_armor.tooltip": "한 번의 공격을 막고 깨진 뒤 다시 충전되는 혈유리 심장을 부여합니다.", - "item.antarchy.blood_crystal_boots.tooltip2": "중력이 반전되어 위로 떨어질 때 낙하 피해를 무효화합니다.", - "item.antarchy.blood_crystal_apple.tooltip": "혈유리 수호를 부여하여 효과가 지속되는 동안 재충전되는 임시 혈유리 심장을 제공합니다.", - "tooltip.antarchy.blood_crystal_katana.launch": "명중 시 앞으로 돌진합니다.", - "tooltip.antarchy.blood_crystal_katana.trail": "뒤에 진홍빛 흔적을 남깁니다.", - "item.antarchy.mantis_claw": "사마귀 발톱", - "tooltip.antarchy.mantis_claw.wall_cling": "Dual wield to cling to walls and jump upward.", - "item.antarchy.king_scale": "왕 비늘", - "item.antarchy.queen_scale": "여왕 비늘", - "item.antarchy.springbug_leg": "점피 벌레 다리", - "item.antarchy.springy_boots": "점피 부츠", - "tooltip.antarchy.springy_boots": "웅크려 충전한 뒤 점프하면 위로 튀어 오릅니다.", - "item.antarchy.brutalfly_wing": "브루털플라이 날개", - "item.antarchy.brutalfly_elytra": "브루털플라이 겉날개", - "tooltip.antarchy.brutalfly_elytra.flap": "비행 중 %s을 길게 눌러 날갯짓합니다", - "item.antarchy.cornea_ear": "코니아의 귀", - "item.antarchy.corn": "옥수수", - "item.antarchy.corn_seeds": "옥수수 씨앗", - "item.antarchy.raw_corndog": "익히지 않은 콘도그", - "item.antarchy.cooked_corndog": "익힌 콘도그", - "item.antarchy.high_fructose_corn_syrup": "고과당 옥수수 시럽", - "jei.antarchy.americanize": "미국식으로 만들기", - "item.antarchy.american_name": "미국식 %s", - "item.antarchy.root_beer": "루트 비어", - "item.antarchy.primordial_scute": "태고의 등딱지 조각", - "item.antarchy.flytrap_goo": "트리피드 점액", - "item.antarchy.flytrap_goo_block": "트리피드 점액 블록", - "tooltip.antarchy.flytrap_goo_block": "빠르게 부딪히면 튀어 오르고, 아니면 안으로 가라앉습니다.", - "item.antarchy.cloud_bucket": "구름 양동이", - "tooltip.antarchy.cloud_bucket.midair": "공중에 설치할 수 있습니다", - "item.antarchy.lumen_bucket": "루멘 양동이", - "item.antarchy.scorpion_whip": "황제전갈 채찍", - "tooltip.antarchy.scorpion_whip.lash": "멀리서 먹잇감을 후려쳐 독성 연결줄을 박습니다.", - "tooltip.antarchy.scorpion_whip.reel": "우클릭하여 연결된 먹잇감을 끌어당깁니다.", - "tooltip.antarchy.scorpion_whip.snap": "연결된 먹잇감을 다시 좌클릭하여 독침을 뽑습니다.", - "item.antarchy.fallen_king_crown": "몰락한 왕의 왕관", - "tooltip.antarchy.fallen_king_crown.hero": "적대적 생물을 처치하면 마을의 영웅을 부여합니다", - "item.antarchy.vortex_charge": "Vortex Charge", - "item.antarchy.ultimate_helmet": "궁극 투구", - "item.antarchy.ultimate_chestplate": "궁극 흉갑", - "item.antarchy.ultimate_leggings": "궁극 레깅스", - "item.antarchy.ultimate_boots": "궁극 부츠", - "item.antarchy.ultimate_sword": "궁극 검", - "item.antarchy.ultimate_pickaxe": "궁극의 곡괭이", - "item.antarchy.ultimate_axe": "궁극 도끼", - "item.antarchy.ultimate_shovel": "궁극 삽", - "item.antarchy.ultimate_hoe": "궁극 괭이", - "item.antarchy.ultimate_bow": "궁극 활", - "item.antarchy.ultimate_crossbow": "궁극 쇠뇌", - "item.antarchy.ultimate_crossbow.capacity": "한 번에 화살을 최대 16발 장전합니다", - "item.antarchy.ultimate_crossbow.arrows_remaining": "%1$s %2$s 장전됨", - "item.antarchy.ultimate_mace": "궁극 철퇴", - "item.antarchy.moggles": "모글스", - "itemGroup.antarchy.antarchy": "앤타키", - "item.antarchy.bile_bucket": "담즙 양동이", - "item.antarchy.ichor_bucket": "이코르 양동이", - "item.antarchy.antiwater_bucket": "역수 양동이", - "item.antarchy.reverie_bottle": "레버리가 든 병", - "item.antarchy.squidzooka": "스퀴드주카", - "item.antarchy.rpo_launcher": "로·추·문 발사기", - "item.antarchy.shrink_ray": "축소 광선총", - "item.antarchy.growth_ray": "성장 광선총", - "tooltip.antarchy.shrink_ray": "대상을 영구적으로 축소합니다. 길게 눌러 충전합니다.", - "tooltip.antarchy.growth_ray": "대상을 영구적으로 성장시킵니다. 길게 눌러 충전합니다.", - "tooltip.antarchy.size_ray_milk_reset": "우유를 마시면 이 효과가 초기화됩니다.", - "tooltip.antarchy.reverie_bottle.capture": "유리병으로 레버리를 우클릭하여 담습니다.", - "tooltip.antarchy.reverie_bottle.release": "우클릭하여 레버리를 풀어줍니다.", - "item.antarchy.gravity_gun": "중력총", - "item.antarchy.diamond_minecart": "다이아몬드 광산 수레", - "item.antarchy.cogwheel_pet": "톱니바퀴 펫", - "item.antarchy.fire_dragon_pet": "화염 드래곤 펫", - "item.antarchy.ice_dragon_pet": "얼음 드래곤 펫", - "item.antarchy.lightning_dragon_pet": "번개 드래곤 펫", - "item.antarchy.gorgon_pet": "고르곤 펫", - "item.antarchy.apple_cow_spawn_egg": "사과 소 생성 알", - "item.antarchy.red_ant_spawn_egg": "붉은 개미 생성 알", - "item.antarchy.brown_ant_spawn_egg": "갈색 개미 생성 알", - "item.antarchy.rainbow_ant_spawn_egg": "무지개 개미 생성 알", - "item.antarchy.golden_apple_cow_spawn_egg": "황금 사과 소 생성 알", - "item.antarchy.enchanted_golden_apple_cow_spawn_egg": "마법이 부여된 황금 사과 소 생성 알", - "item.antarchy.dr_trayaurus_spawn_egg": "트레이오러스 박사 생성 알", - "item.antarchy.easter_bunny_spawn_egg": "부활절 토끼 생성 알", - "item.antarchy.glimmer_spawn_egg": "글리머 생성 알", - "item.antarchy.ouranwood_deer_spawn_egg": "오란우드 사슴 생성 알", - "item.antarchy.spirit_apple": "영혼 사과", - "item.antarchy.elka_spawn_egg": "엘카 생성 알", - "item.antarchy.glimmer_bottle": "글리머가 든 병", - "item.antarchy.glimmer_bottle.contains": "들어 있음: %s", - "glimmer_variant.antarchy.apple_cow": "사과 소", - "glimmer_variant.antarchy.ouranwood_deer": "오란우드 사슴", - "glimmer_variant.antarchy.frog": "개구리", - "glimmer_variant.antarchy.ant": "개미", - "glimmer_variant.antarchy.elka": "엘카", - "entity.antarchy.glimmer.set_sit": "글리머가 앉도록 설정되었습니다.", - "entity.antarchy.glimmer.set_follow": "글리머가 따라오도록 설정되었습니다.", - "entity.antarchy.glimmer.set_wander": "글리머가 돌아다니도록 설정되었습니다.", - "entity.antarchy.glimmer.ability.ant": "개미가 %s에 맞설 투지를 북돋았습니다!", - "entity.antarchy.glimmer.ability.apple_cow": "사과 소가 울며 영양을 채워 줍니다!", - "entity.antarchy.glimmer.ability.elka": "엘카가 울부짖어 수호를 깨뜨립니다!", - "entity.antarchy.glimmer.ability.deer": "오란우드 사슴이 적을 뚫고 돌진합니다!", - "entity.antarchy.glimmer.ability.frog": "개구리가 %s을 삼켰습니다!", - "item.antarchy.glimmer_bottle.passive.apple_cow": "지속 효과: 허기가 25% 느리게 감소합니다", - "item.antarchy.glimmer_bottle.ability.apple_cow": "능력: 배고플 때 울음소리로 포화와 재생을 즉시 부여합니다", - "item.antarchy.glimmer_bottle.passive.ouranwood_deer": "지속 효과: 신속 Ⅰ", - "item.antarchy.glimmer_bottle.ability.ouranwood_deer": "능력: 적대적 생물을 향해 전력 질주하면 돌진하여 날려 버립니다", - "item.antarchy.glimmer_bottle.passive.frog": "지속 효과: 점프 강화 Ⅰ", - "item.antarchy.glimmer_bottle.ability.frog": "능력: 근처 적대적 생물을 삼키고 잠시 더 크고 강해집니다", - "item.antarchy.glimmer_bottle.passive.ant": "지속 효과: 공격 사거리가 약간 늘어납니다", - "item.antarchy.glimmer_bottle.ability.ant": "능력: 큰 적을 공격하면 잠시 힘 Ⅱ를 얻습니다", - "item.antarchy.glimmer_bottle.passive.elka": "지속 효과: 혈유리 수호 Ⅱ", - "item.antarchy.glimmer_bottle.ability.elka": "능력: 수호 심장이 깨지면 울부짖으며 충격파로 산산이 흩어집니다", - "advancements.antarchy.spirant_animal.title": "개미의 정령", - "advancements.antarchy.spirant_animal.description": "개미 글리머를 길들이세요", - "advancements.antarchy.hoppy_together.title": "함께 깡충깡충", - "advancements.antarchy.hoppy_together.description": "개구리 글리머를 길들이세요", - "advancements.antarchy.deerly_beloved.title": "사슴하는 사이", - "advancements.antarchy.deerly_beloved.description": "오란우드 사슴 글리머를 길들이세요", - "advancements.antarchy.elkcellent_choice.title": "엘카다운 선택", - "advancements.antarchy.elkcellent_choice.description": "엘카 글리머를 길들이세요", - "advancements.antarchy.apple_of_my_eye.title": "눈에 넣어도 안 아픈 사과", - "advancements.antarchy.apple_of_my_eye.description": "사과 소 글리머를 길들이세요", - "item.antarchy.dorrie_spawn_egg": "도리 생성 알", - "item.antarchy.flying_squirrel_spawn_egg": "날다람쥐 생성 알", - "item.antarchy.caterpillar_spawn_egg": "애벌레 생성 알", - "item.antarchy.butterfly_spawn_egg": "나비 생성 알", - "item.antarchy.brutalfly_spawn_egg": "브루털플라이 생성 알", - "item.antarchy.stratoshark_spawn_egg": "구름 상어 생성 알", - "item.antarchy.kraken_spawn_egg": "어, 안 돼. 하지 마.", - "item.antarchy.missile_squid_spawn_egg": "미사일 오징어 생성 알", - "item.antarchy.octopus_bomb_spawn_egg": "문어 폭탄 생성 알", - "item.antarchy.nightmare_spawn_egg": "악몽 생성 알", - "item.antarchy.toreterror_spawn_egg": "토어테러 생성 알", - "item.antarchy.water_cannon": "물대포", - "item.antarchy.primordial_helmet": "태고의 투구", - "item.antarchy.primordial_chestplate": "태고의 흉갑", - "item.antarchy.primordial_leggings": "태고의 레깅스", - "item.antarchy.primordial_boots": "태고의 부츠", - "item.antarchy.bed_bug_spawn_egg": "빈대 생성 알", - "item.antarchy.moleworm_spawn_egg": "몰웜 생성 알", - "item.antarchy.molevore_spawn_egg": "몰보어 생성 알", - "item.antarchy.reverie_spawn_egg": "레버리 생성 알", - "item.antarchy.mantis_spawn_egg": "사마귀 생성 알", - "item.antarchy.alpha_mantis_spawn_egg": "알파 사마귀 생성 알", - "biome.antarchy.moleworm_caves": "몰웜 동굴", - "biome.antarchy.elythia_meadow": "엘리티아 초원", - "biome.antarchy.butterfly_fields": "나비 들판", - "biome.antarchy.ouranwood_forest": "오란우드 숲", - "biome.antarchy.glimmering_pools": "반짝이는 웅덩이", - "biome.antarchy.peach_forest": "복숭아 숲", - "biome.antarchy.fungal_ouranwood_forest": "균류 오란우드 숲", - "biome.antarchy.glowcap_caves": "글로우캡 동굴", - "message.antarchy.brown_ant_activated": "갈색 개미가 목적지를 열 준비가 되었습니다.", - "message.antarchy.brown_ant_needs_reagent": "이 갈색 개미가 목적지를 열려면 시약이 필요합니다.", - "message.antarchy.rainbow_ant_activated": "무지개 개미가 새로운 인피니티 목적지와 공명합니다.", - "message.antarchy.rainbow_ant_activated_inherited": "무지개 개미가 물려받은 인피니티 목적지와 공명합니다.", - "message.antarchy.rainbow_ant_activated_inherited_existing": "무지개 개미가 물려받은 인피니티 목적지에 다시 연결됩니다.", - "message.antarchy.rainbow_ant_failed_dimension_create": "차원을 만들지 못했습니다. 인피니티 설정에 문제가 있을 가능성이 큽니다. 재시작하거나 다시 접속한 뒤 시도하세요.", - "message.antarchy.rainbow_ant_infinity_missing": "무지개 개미 차원을 사용하려면 인피니티가 설치되어 있어야 합니다.", - "message.antarchy.rainbow_ant_needs_reagent": "이 무지개 개미가 차원을 열려면 시약이 필요합니다.", - "message.antarchy.red_ant_activated": "붉은 개미가 목적지를 열 준비가 되었습니다.", - "message.antarchy.red_ant_needs_reagent": "이 붉은 개미가 목적지를 열려면 시약이 필요합니다.", - "message.antarchy.termite_activated": "흰개미가 목적지를 열 준비가 되었습니다.", - "message.antarchy.termite_needs_reagent": "이 흰개미가 목적지를 열려면 시약이 필요합니다.", - "death.attack.spit_bug_disrespect": "%1$s이(가) 스핏 벌레에게 무시당했습니다", - "death.attack.springbug_jump": "%1$s이(가) 점피 벌레에게 덮쳐졌습니다", - "death.attack.hercules_beetle_obliteration": "%1$s이(가) 헤라클레스장수풍뎅이에게 소멸당했습니다", - "message.antarchy.big_bertha.mode": "빅 버사 모드: %s", - "message.antarchy.big_bertha.mode.basilisk": "바실리스크", - "message.antarchy.big_bertha.mode.lucid": "루시드", - "message.antarchy.big_bertha.mode.nightmare": "악몽", - "message.antarchy.big_bertha.mode.kraken": "크라켄", - "message.antarchy.big_bertha.mode.molevore": "몰보어", - "message.antarchy.big_bertha.mode.toreterror": "토어테러", - "message.antarchy.ultimate_tool.mode_3x3": "3×3 채굴로 전환했습니다", - "message.antarchy.ultimate_tool.mode_default": "기본 채굴로 전환했습니다", - "advancements.antarchy.hey_listen.title": "이봐, 들어 봐!", - "advancements.antarchy.hey_listen.description": "레버리가 합류했습니다.", - "advancements.antarchy.very_hungry_caterpillar.title": "배고픈 애벌레", - "advancements.antarchy.very_hungry_caterpillar.description": "애벌레가 자라도록 도와주세요.", - "effect.antarchy.dread": "공포", - "effect.antarchy.dread.description": "시각 및 청각 환각을 일으킵니다.", - "effect.antarchy.paralyzed": "마비", - "effect.antarchy.paralyzed.description": "대상이 움직이지 못하게 합니다.", - "effect.antarchy.commanded.description": "명령한 플레이어를 위해 싸웁니다.", - "effect.antarchy.stinky": "악취", - "effect.antarchy.stinky.description": "수동적 및 중립적 몹을 쫓아내고 절지동물을 끌어들입니다.", - "effect.antarchy.gooped.description": "이동 속도와 공격 속도를 늦춥니다.", - "effect.antarchy.shrinking": "축소", - "effect.antarchy.growth": "성장", - "effect.antarchy.bloodglass_ward": "혈유리 수호", - "effect.antarchy.bloodglass_ward.description": "산산이 부서지는 하트를 부여해 피해 한 번을 통째로 흡수합니다. 시간이 지나면 다시 재생됩니다.", - "death.attack.flytrap_mauling": "%1$s이(가) 식물에게 물어뜯겨 죽었습니다", - "death.attack.flytrap_mauling.player": "%1$s이(가) 식물에게 물어뜯겨 죽었습니다", - "death.attack.flytrap_swallow": "%1$s이(가) 트리피드에게 삼켜졌습니다", - "death.attack.flytrap_swallow.player": "%1$s이(가) 트리피드에게 삼켜졌습니다", - "potion.antarchy.haste": "성급함의 물약", - "potion.antarchy.strong_haste": "강한 성급함의 물약", - "tooltip.antarchy.big_bertha.mode": "모드: %s", - "tooltip.antarchy.big_bertha.toggle_mode": "웅크린 채 우클릭하여 보스 모드를 전환합니다.", - "tooltip.antarchy.big_bertha.mode.basilisk": "우클릭으로 대상을 마비시킵니다. 공격 시 독과 둔화를 부여합니다.", - "tooltip.antarchy.big_bertha.mode.lucid": "공격 시 대상을 잠시 반전시킵니다. 자신이 반전된 동안 더 큰 피해를 줍니다.", - "tooltip.antarchy.big_bertha.mode.nightmare": "플레이어는 공포에 시달리고, 공격 시 나약함을 부여합니다.", - "tooltip.antarchy.big_bertha.mode.kraken": "공격 시 대상을 내리꽂고 번개를 부릅니다.", - "tooltip.antarchy.big_bertha.mode.molevore": "우클릭하여 회전하며 전진하고 몰보어 블록을 뚫습니다.", - "tooltip.antarchy.big_bertha.mode.toreterror": "우클릭하여 공중으로 솟은 뒤 광역 충격파와 함께 추락합니다.", - "tooltip.antarchy.ultimate_tools_3x3": "웅크린 채 우클릭하여 3×3 채굴을 전환합니다.", - "tooltip.antarchy.moggles.reveal": "야간 투시를 부여하고 근처 동굴을 가리킵니다.", - "tooltip.antarchy.moggles.underground": "하늘이 보이지 않을 때만 작동합니다.", - "tooltip.antarchy.cornea_ear.vision": "%s초 동안 야간 투시를 부여합니다.", - "tooltip.antarchy.mob_coming_soon": "생물은 곧 추가됩니다!", - "tooltip.antarchy.gravity_gun.primary": "좌클릭: 주변 개체를 날리거나 붙잡은 대상을 던집니다.", - "tooltip.antarchy.gravity_gun.secondary": "우클릭: 개체나 유효한 블록을 끌어당깁니다.", - "tooltip.antarchy.gravity_gun.scroll": "제어 키를 누른 채 스크롤하여 붙잡은 대상을 가까이하거나 멀리합니다.", - "tooltip.antarchy.gravity_gun.blacklist": "차단 목록에 있는 블록이나 개체에는 영향을 주지 않습니다.", - "tooltip.antarchy.antimetal_inversion": "바로 아래의 개체를 반전시킵니다", - "tooltip.antarchy.diamond_minecart.forward": "나중에 구현될 예정입니다.", - "tooltip.antarchy.diamond_minecart.rails": " ", - "tooltip.antarchy.rainbow_sugar": "무지개 개미 차원을 활성화합니다. 그 차원에서 먹으면 집으로 돌아옵니다.", - "advancements.antarchy.visit_elythia.title": "차원개미 이동", - "advancements.antarchy.visit_elythia.description": "갈색 개미를 이용해 엘리티아에 도달하세요.", - "advancements.antarchy.visit_thoraxis.title": "개미 분노 관리", - "advancements.antarchy.visit_thoraxis.description": "붉은 개미를 이용해 토랙시스에 도달하세요.", - "advancements.antarchy.fallen_kingdom_castle.title": "한때는 세상을 지배했지…", - "advancements.antarchy.fallen_kingdom_castle.description": "몰락한 왕국의 성을 발견하세요.", - "advancements.antarchy.fallen_king_crown.title": "내가 명하면 청크가 불러와졌지…", - "advancements.antarchy.fallen_king_crown.description": "몰락한 왕의 왕관을 획득하세요.", - "advancements.antarchy.the_lab.title": "여러분 안녕하세요, 댄입니다!", - "advancements.antarchy.the_lab.description": "트레이오러스 박사의 연구소를 발견하세요.", - "advancements.antarchy.sweater_dreams.title": "스웨터의 꿈", - "advancements.antarchy.sweater_dreams.description": "악몽을 처치하세요.", - "advancements.antarchy.stone_cold.title": "돌처럼 차갑게", - "advancements.antarchy.stone_cold.description": "바실리스크를 처치하세요.", - "advancements.antarchy.moley_poley.title": "두더지 데굴데굴", - "advancements.antarchy.moley_poley.description": "몰보어를 처치하세요.", - "advancements.antarchy.lucid_dreams.title": "자각몽", - "advancements.antarchy.lucid_dreams.description": "루시드를 처치하세요.", - "advancements.antarchy.davy_jones_locker.title": "데이비 존스의 함", - "advancements.antarchy.davy_jones_locker.description": "크라켄을 처치하세요.", - "advancements.antarchy.shark_weak.title": "상어가 날 때", - "advancements.antarchy.shark_weak.description": "구름 상어를 처치하세요.", - "advancements.antarchy.dont_let_the_bed_bugs_bite.title": "빈대에게 물리지 마세요", - "advancements.antarchy.dont_let_the_bed_bugs_bite.description": "빈대를 처치하세요.", - "advancements.antarchy.soups_up.title": "수프 준비 완료", - "advancements.antarchy.soups_up.description": "구름 상어 지느러미 수프를 먹으세요.", - "advancements.antarchy.in_the_upside_down.title": "뒤집힌 세계에서", - "advancements.antarchy.in_the_upside_down.description": "처음으로 반전되세요.", - "advancements.antarchy.whoever_smelt_it_dealt_it.title": "냄새 맡은 사람이 범인", - "advancements.antarchy.whoever_smelt_it_dealt_it.description": "처음으로 악취 상태가 되세요.", - "advancements.antarchy.ultimate_armor.title": "궁극의 보호", - "advancements.antarchy.ultimate_armor.description": "궁극 방어구 세트를 모두 모으세요.", - "advancements.antarchy.ultimate_bow.title": "활헤미안 랩소디", - "advancements.antarchy.ultimate_bow.description": "궁극의 활을 획득하세요.", - "advancements.antarchy.brutalfly.title": "브루털플라이처럼 날고 벌처럼 쏘세요", - "advancements.antarchy.brutalfly.description": "브루털플라이 겉날개를 획득하세요.", - "advancements.antarchy.now_watch_me_whip.title": "이제 내 채찍질을 봐", - "advancements.antarchy.now_watch_me_whip.description": "이제 내 네이네이를 봐", - "advancements.antarchy.kill_molevore.title": "두더지 데굴데굴", - "advancements.antarchy.kill_molevore.description": "몰보어를 처치하세요.", - "advancements.antarchy.water_cannon_craft.title": "더 젖을수록 좋아!", - "advancements.antarchy.water_cannon_craft.description": "물대포를 획득하세요.", - "advancements.antarchy.kill_toreterror.title": "토어-끔찍한 조준 실력!", - "advancements.antarchy.kill_toreterror.description": "토어테러를 처치하세요.", - "advancements.antarchy.challenge_games.title": "도전 게임!", - "advancements.antarchy.challenge_games.description": "폐허가 된 투기장에 입장하세요.", - "advancements.antarchy.bugged_out.title": "벌레투성이", - "advancements.antarchy.bugged_out.description": "알파 사마귀를 처치하세요.", - "death.attack.bed_bug_bite": "%1$s이(가) 빈대에게 물렸습니다", - "death.attack.bed_bug_bite.player": "%1$s이(가) %2$s와(과) 싸우다 빈대에게 물렸습니다", - "message.antarchy.dread_too_scared_to_sleep": "너무 무서워서 잠들 수 없습니다.", - "death.attack.kraken_mauling": "%1$s이(가) 크라켄에게 물속으로 끌려갔습니다", - "death.attack.kraken_mauling.player": "%1$s이(가) %2$s와(과) 싸우다 크라켄에게 물속으로 끌려갔습니다", - "death.attack.kraken_lightning": "%1$s이(가) 크라켄의 폭풍에 쓰러졌습니다", - "death.attack.kraken_lightning.player": "%1$s이(가) %2$s와(과) 싸우다 크라켄의 폭풍에 쓰러졌습니다", - "death.attack.rpo_launcher_blast": "%1$s이(가) 로·추·문에게 녹아웃당했습니다", - "death.attack.rpo_launcher_blast.player": "%1$s이(가) %2$s와(과) 싸우다 로·추·문에게 녹아웃당했습니다", - "death.attack.nightmare_mauling": "%1$s이(가) 악몽에게 잡아먹혔습니다", - "death.attack.nightmare_mauling.player": "%1$s이(가) %2$s와(과) 싸우다 악몽에게 잡아먹혔습니다", - "death.attack.basilisk_bite": "%1$s이(가) 바실리스크에게 삼켜졌습니다", - "death.attack.basilisk_bite.player": "%1$s이(가) %2$s와(과) 싸우다 바실리스크에게 삼켜졌습니다", - "death.attack.emperor_scorpion_sting": "%1$s이(가) 황제전갈에게 쏘였습니다", - "death.attack.emperor_scorpion_sting.player": "%1$s이(가) %2$s와(과) 싸우다 황제전갈에게 쏘였습니다", - "death.attack.cornea_stalk_prick": "%1$s이(가) 코니아 줄기에 찔려 죽었습니다", - "death.attack.toreterror_spin": "%1$s이(가) 토어테러의 회전에 휘말려 죽었습니다", - "death.attack.toreterror_spin.player": "%1$s이(가) 토어테러의 회전에 휘말려 죽었습니다", - "death.attack.toreterror_jump": "%1$s이(가) 토어테러에게 짓눌려 죽었습니다", - "death.attack.toreterror_jump.player": "%1$s이(가) 토어테러에게 짓눌려 죽었습니다", - "death.attack.water_soaked": "%1$s이(가) %2$s에게 흠뻑 젖어 죽었습니다", - "death.attack.water_soaked.player": "%1$s이(가) %2$s에게 흠뻑 젖어 죽었습니다", - "entity.antarchy.lucid": "루시드", - "item.antarchy.lucid_spawn_egg": "루시드 생성 알", - "item.antarchy.lucid_eye": "루시드 눈", - "entity.antarchy.scorpion": "전갈", - "item.antarchy.scorpion_spawn_egg": "전갈 생성 알", - "entity.antarchy.basilisk": "바실리스크", - "item.antarchy.basilisk_spawn_egg": "바실리스크 생성 알", - "entity.antarchy.emperor_scorpion": "황제전갈", - "item.antarchy.emperor_scorpion_spawn_egg": "황제전갈 생성 알", - "item.antarchy.emperor_scorpion_stinger": "황제전갈 독침", - "item.antarchy.lucid_pearl": "루시드 진주", - "tooltip.antarchy.lucid_pearl": "중력이 반전된 투사체를 던집니다.", - "tooltip.antarchy.lucid_pearl.detail": "착지 지점으로 순간이동시키고 반전을 부여합니다.", - "subtitles.antarchy.squidzooka_fire": "스퀴드주카 발사됩니다", - "subtitles.antarchy.shrink_ray": "축소 광선총 발사됩니다", - "subtitles.antarchy.growth_ray": "성장 광선총 발사됩니다", - "subtitles.antarchy.size_ray_charge": "크기 광선총 충전됩니다", - "subtitles.antarchy.ant_ambient": "개미 짹짹거립니다", - "subtitles.antarchy.ant_idle": "개미 소리를 냅니다", - "subtitles.antarchy.ant_hurt": "개미 다칩니다", - "subtitles.antarchy.ant_bite": "개미 뭅니다", - "subtitles.antarchy.ant_gather": "개미 모읍니다", - "subtitles.antarchy.ant_nest": "개미 둥지가 바스락거립니다", - "subtitles.antarchy.stratoshark_bite": "구름 상어 뭅니다", - "subtitles.antarchy.stratoshark_idle": "구름 상어 소리를 냅니다", - "subtitles.antarchy.stratoshark_hurt": "구름 상어 다칩니다", - "subtitles.antarchy.stratoshark_death": "구름 상어 죽습니다", - "subtitles.antarchy.stratoshark_fly": "구름 상어 납니다", - "subtitles.antarchy.caterpillar_idle": "애벌레 소리를 냅니다", - "subtitles.antarchy.caterpillar_hurt": "애벌레 다칩니다", - "subtitles.antarchy.caterpillar_crawl": "애벌레 기어갑니다", - "subtitles.antarchy.butterfly_hurt": "나비 다칩니다", - "subtitles.antarchy.brutalfly_idle": "브루털플라이 소리를 냅니다", - "subtitles.antarchy.brutalfly_death": "브루털플라이 죽습니다", - "subtitles.antarchy.thoraxis_nightmare_wastes_ambient": "악몽 황무지 웅웅거립니다", - "subtitles.antarchy.thoraxis_nightmare_wastes_additions": "악몽 황무지 꿈틀거립니다", - "subtitles.antarchy.thoraxis_nightmare_wastes_mood": "악몽 황무지 웅얼거립니다", - "subtitles.antarchy.thoraxis_dream_dunes_ambient": "꿈의 사구 속삭입니다", - "subtitles.antarchy.thoraxis_dream_dunes_additions": "꿈의 사구 바스락거립니다", - "subtitles.antarchy.thoraxis_dream_dunes_mood": "꿈의 사구 한숨 쉽니다", - "subtitles.antarchy.thoraxis_lucid_pools_ambient": "루시드 웅덩이가 웅웅거립니다", - "subtitles.antarchy.thoraxis_lucid_pools_additions": "루시드 웅덩이 저주를 내뱉습니다", - "subtitles.antarchy.thoraxis_lucid_pools_mood": "루시드 웅덩이 중얼거립니다", - "subtitles.antarchy.lucid_ambient": "루시드 웅웅거립니다", - "subtitles.antarchy.lucid_flying": "루시드 팔랑거립니다", - "subtitles.antarchy.lucid_attack": "루시드 공격합니다", - "subtitles.antarchy.lucid_bolt": "루시드 탄환을 발사합니다", - "subtitles.antarchy.lucid_hurt": "루시드 다칩니다", - "subtitles.antarchy.lucid_death": "루시드 죽습니다", - "subtitles.antarchy.reverie_idle": "레버리 떠다닙니다", - "subtitles.antarchy.reverie_hurt": "레버리 다칩니다", - "subtitles.antarchy.reverie_worry": "레버리 걱정합니다", - "subtitles.antarchy.reverie_save": "레버리 당신을 구합니다", - "subtitles.antarchy.reverie_join_player": "레버리 당신과 함께합니다", - "subtitles.antarchy.reverie_alert": "레버리 당신에게 경고합니다", - "subtitles.antarchy.flying_squirrel_idle": "날다람쥐 짹짹거립니다", - "subtitles.antarchy.flying_squirrel_beg": "날다람쥐 먹이를 달라고 조릅니다", - "subtitles.antarchy.flying_squirrel_nut": "날다람쥐 먹습니다", - "subtitles.antarchy.flying_squirrel_glide_loop": "날다람쥐 활공합니다", - "subtitles.antarchy.flying_squirrel_hurt": "날다람쥐 다칩니다", - "subtitles.antarchy.flying_squirrel_death": "날다람쥐 죽습니다", - "subtitles.antarchy.nightmare_idle": "악몽 으르렁거립니다", - "subtitles.antarchy.nightmare_hurt": "악몽 다칩니다", - "subtitles.antarchy.nightmare_roar": "악몽 포효합니다", - "subtitles.antarchy.nightmare_death": "악몽 죽습니다", - "subtitles.antarchy.nightmare_bite": "악몽 뭅니다", - "subtitles.antarchy.nightmare_flap": "악몽 날갯짓합니다", - "subtitles.antarchy.flytrap_attack": "트리피드 공격합니다", - "subtitles.antarchy.flytrap_grab": "트리피드 붙잡습니다", - "subtitles.antarchy.flytrap_hurt": "트리피드 다칩니다", - "subtitles.antarchy.flytrap_death": "트리피드 죽습니다", - "subtitles.antarchy.flytrap_hiss": "트리피드 쉬익거립니다", - "subtitles.antarchy.flytrap_growl": "트리피드 그르렁거립니다", - "subtitles.antarchy.gravity_gun_pickup": "중력총 들어 올립니다", - "subtitles.antarchy.gravity_gun_drop": "중력총 내려놓습니다", - "subtitles.antarchy.gravity_gun_hold_loop": "중력총 웅웅거립니다", - "subtitles.antarchy.gravity_gun_launch": "중력총 발사합니다", - "subtitles.antarchy.gravity_gun_dryfire": "중력총 헛발사됩니다", - "subtitles.antarchy.antimetal_place": "안티메탈이 쨍그랑거립니다", - "subtitles.antarchy.antimetal_step": "안티메탈이 딸깍거립니다", - "subtitles.antarchy.antimetal_scaffold": "안티메탈 비계가 덜컹거립니다", - "subtitles.antarchy.bed_bug_ambient": "빈대 짹짹거립니다", - "subtitles.antarchy.bed_bug_hurt": "빈대 다칩니다", - "subtitles.antarchy.bed_bug_attack": "빈대 뭅니다", - "subtitles.antarchy.wasp_idle": "말벌이 윙윙거립니다", - "subtitles.antarchy.wasp_hurt": "말벌 다칩니다", - "subtitles.antarchy.wasp_attack": "말벌 쏩니다", - "subtitles.antarchy.wasp_death": "말벌 죽습니다", - "subtitles.antarchy.scorpion_ambient": "전갈 달그락거립니다", - "subtitles.antarchy.scorpion_hurt": "전갈 다칩니다", - "subtitles.antarchy.scorpion_attack": "전갈 공격합니다", - "subtitles.antarchy.emperor_scorpion_ambient": "황제전갈 달그락거립니다", - "subtitles.antarchy.emperor_scorpion_hurt": "황제전갈 다칩니다", - "subtitles.antarchy.emperor_scorpion_attack": "황제전갈 공격합니다", - "subtitles.antarchy.emperor_scorpion_roar": "황제전갈 포효합니다", - "subtitles.antarchy.moleworm_ambient": "몰웜이 바스락거립니다", - "subtitles.antarchy.moleworm_hurt": "몰웜 다칩니다", - "subtitles.antarchy.moleworm_attack": "몰웜 공격합니다", - "subtitles.antarchy.moleworm_dig": "몰웜 땅을 팝니다", - "subtitles.antarchy.molevore_ambient": "몰보어 우르릉거립니다", - "subtitles.antarchy.molevore_hurt": "몰보어 다칩니다", - "subtitles.antarchy.molevore_attack": "몰보어 공격합니다", - "subtitles.antarchy.molevore_dig": "몰보어 땅을 팝니다", - "subtitles.antarchy.duct_tape_use": "덕트 테이프가 찢어집니다", - "subtitles.antarchy.potent_nyxite_hypnotic_gas": "강력한 닉사이트가 쉬익거립니다", - "subtitles.antarchy.potent_nyxite_geyser_eruption": "강력한 닉사이트가 분출합니다", - "subtitles.antarchy.potent_nyxite_geyser_continuous": "강력한 닉사이트 간헐천이 포효합니다", - "subtitles.antarchy.missile_squid_ambient": "미사일 오징어 웅웅거립니다", - "subtitles.antarchy.missile_squid_hurt": "미사일 오징어 다칩니다", - "subtitles.antarchy.missile_squid_death": "미사일 오징어 죽습니다", - "subtitles.antarchy.missile_squid_attack": "미사일 오징어 공격합니다", - "subtitles.antarchy.kraken_flying_loop": "크라켄 활공합니다", - "subtitles.antarchy.kraken_flying_sideways_loop": "크라켄이 맴돕니다", - "subtitles.antarchy.kraken_attack": "크라켄이 내리칩니다", - "subtitles.antarchy.kraken_spin": "크라켄이 회전합니다", - "subtitles.antarchy.kraken_roar": "크라켄 포효합니다", - "subtitles.antarchy.kraken_summon": "크라켄이 나타납니다", - "subtitles.antarchy.kraken_hurt": "크라켄 다칩니다", - "subtitles.antarchy.kraken_death": "크라켄 죽습니다", - "subtitles.antarchy.basilisk_idle_loop": "바실리스크 소리를 냅니다", - "subtitles.antarchy.basilisk_slither_loop": "바실리스크가 미끄러집니다", - "subtitles.antarchy.basilisk_bite": "바실리스크 뭅니다", - "subtitles.antarchy.basilisk_hiss": "바실리스크 쉬익거립니다", - "subtitles.antarchy.basilisk_hurt": "바실리스크 다칩니다", - "subtitles.antarchy.basilisk_death": "바실리스크 죽습니다", - "subtitles.antarchy.bomber_walk": "폭격충이 걷습니다", - "subtitles.antarchy.bomber_knock": "폭격충이 맞습니다", - "subtitles.antarchy.bomber_explode": "폭격충의 도화선이 쉬익거립니다", - "subtitles.antarchy.toreterror_idle": "토어테러 소리를 냅니다", - "subtitles.antarchy.toreterror_hurt": "토어테러 다칩니다", - "subtitles.antarchy.toreterror_death": "토어테러 죽습니다", - "subtitles.antarchy.toreterror_bomber_fire": "토어테러가 폭격충을 발사합니다", - "subtitles.antarchy.toreterror_spin": "토어테러가 회전합니다", - "subtitles.antarchy.toreterror_ricochet": "토어테러가 튕겨 나갑니다", - "subtitles.antarchy.water_cannon_fire": "물대포가 발사됩니다", - "subtitles.antarchy.toreterror_jump_up": "토어테러 뜁니다", - "subtitles.antarchy.toreterror_jump_land": "토어테러가 착지합니다", - "subtitles.antarchy.stinky_fly": "악취 파리가 윙윙거립니다", - "item.minecraft.potion.effect.inversion": "반전 물약", - "item.minecraft.potion.effect.long_inversion": "반전 물약", - "item.minecraft.splash_potion.effect.inversion": "반전 투척용 물약", - "item.minecraft.splash_potion.effect.long_inversion": "반전 투척용 물약", - "item.minecraft.lingering_potion.effect.inversion": "반전 잔류형 물약", - "item.minecraft.lingering_potion.effect.long_inversion": "반전 잔류형 물약", - "item.minecraft.tipped_arrow.effect.inversion": "반전 화살", - "item.minecraft.tipped_arrow.effect.long_inversion": "반전 화살", - "item.minecraft.potion.effect.paralysis": "마비 물약", - "item.minecraft.potion.effect.long_paralysis": "마비 물약", - "item.minecraft.splash_potion.effect.paralysis": "마비 투척용 물약", - "item.minecraft.splash_potion.effect.long_paralysis": "마비 투척용 물약", - "item.minecraft.lingering_potion.effect.paralysis": "마비 잔류형 물약", - "item.minecraft.lingering_potion.effect.long_paralysis": "마비 잔류형 물약", - "item.minecraft.tipped_arrow.effect.paralysis": "마비 화살", - "item.minecraft.tipped_arrow.effect.long_paralysis": "마비 화살", - "item.minecraft.potion.effect.shrinking": "축소 물약", - "item.minecraft.potion.effect.strong_shrinking": "축소 Ⅱ 물약", - "item.minecraft.potion.effect.extreme_shrinking": "축소 Ⅲ 물약", - "item.minecraft.splash_potion.effect.shrinking": "축소 투척용 물약", - "item.minecraft.splash_potion.effect.strong_shrinking": "축소 Ⅱ 투척용 물약", - "item.minecraft.splash_potion.effect.extreme_shrinking": "축소 Ⅲ 투척용 물약", - "item.minecraft.lingering_potion.effect.shrinking": "축소 잔류형 물약", - "item.minecraft.lingering_potion.effect.strong_shrinking": "축소 Ⅱ 잔류형 물약", - "item.minecraft.lingering_potion.effect.extreme_shrinking": "축소 Ⅲ 잔류형 물약", - "item.minecraft.tipped_arrow.effect.shrinking": "축소 화살", - "item.minecraft.tipped_arrow.effect.strong_shrinking": "축소 Ⅱ 화살", - "item.minecraft.tipped_arrow.effect.extreme_shrinking": "축소 Ⅲ 화살", - "item.minecraft.potion.effect.growing": "성장 물약", - "item.minecraft.potion.effect.strong_growing": "성장 Ⅱ 물약", - "item.minecraft.potion.effect.extreme_growing": "성장 Ⅲ 물약", - "item.minecraft.splash_potion.effect.growing": "성장 투척용 물약", - "item.minecraft.splash_potion.effect.strong_growing": "성장 Ⅱ 투척용 물약", - "item.minecraft.splash_potion.effect.extreme_growing": "성장 Ⅲ 투척용 물약", - "item.minecraft.lingering_potion.effect.growing": "성장 잔류형 물약", - "item.minecraft.lingering_potion.effect.strong_growing": "성장 Ⅱ 잔류형 물약", - "item.minecraft.lingering_potion.effect.extreme_growing": "성장 Ⅲ 잔류형 물약", - "item.minecraft.tipped_arrow.effect.growing": "성장 화살", - "item.minecraft.tipped_arrow.effect.strong_growing": "성장 Ⅱ 화살", - "item.minecraft.tipped_arrow.effect.extreme_growing": "성장 Ⅲ 화살", - "item.minecraft.potion.effect.dread": "공포 물약", - "item.minecraft.potion.effect.long_dread": "공포 물약", - "item.minecraft.splash_potion.effect.dread": "공포 투척용 물약", - "item.minecraft.splash_potion.effect.long_dread": "공포 투척용 물약", - "item.minecraft.lingering_potion.effect.dread": "공포 잔류형 물약", - "item.minecraft.lingering_potion.effect.long_dread": "공포 잔류형 물약", - "item.minecraft.tipped_arrow.effect.dread": "공포 화살", - "item.minecraft.tipped_arrow.effect.long_dread": "공포 화살", - "item.minecraft.potion.effect.stinky": "악취 물약", - "item.minecraft.potion.effect.long_stinky": "악취 물약", - "item.minecraft.splash_potion.effect.stinky": "악취 투척용 물약", - "item.minecraft.splash_potion.effect.long_stinky": "악취 투척용 물약", - "item.minecraft.lingering_potion.effect.stinky": "악취 잔류형 물약", - "item.minecraft.lingering_potion.effect.long_stinky": "악취 잔류형 물약", - "item.minecraft.tipped_arrow.effect.stinky": "악취 화살", - "item.minecraft.tipped_arrow.effect.long_stinky": "악취 화살", - "item.minecraft.potion.effect.haste": "성급함 물약", - "item.minecraft.potion.effect.strong_haste": "성급함 Ⅱ 물약", - "item.minecraft.splash_potion.effect.haste": "성급함 투척용 물약", - "item.minecraft.splash_potion.effect.strong_haste": "성급함 Ⅱ 투척용 물약", - "item.minecraft.lingering_potion.effect.haste": "성급함 잔류형 물약", - "item.minecraft.lingering_potion.effect.strong_haste": "성급함 Ⅱ 잔류형 물약", - "item.minecraft.tipped_arrow.effect.haste": "성급함 화살", - "item.minecraft.tipped_arrow.effect.strong_haste": "성급함 Ⅱ 화살", - "advancements.antarchy.cancel_out.title": "1 - 1 = ?", - "advancements.antarchy.cancel_out.description": "성장과 축소 효과를 동시에 받으세요.", - "entity.antarchy.cheep": "칩", - "item.antarchy.cheep": "칩", - "item.antarchy.cheep_spawn_egg": "칩 생성 알", - "entity.antarchy.reverie": "레버리", - "biome.antarchy.thoraxis": "토랙시스", - "biome.antarchy.nightmare_wastes": "악몽 황무지", - "biome.antarchy.umbral_hills": "그늘진 언덕", - "biome.antarchy.lucid_pools": "루시드 웅덩이", - "biome.antarchy.dream_dunes": "꿈의 사구", - "block.antarchy.wild_corn": "야생 옥수수", - "trim_material.antarchy.blood_crystal": "혈수정", - "trim_material.antarchy.nightmare_scale": "악몽 비늘", - "trim_material.antarchy.uranium": "우라늄", - "trim_material.antarchy.titanium": "티타늄", - "advancements.antarchy.duct_tape.title": "이 보트를 반으로 톱질했어!", - "advancements.antarchy.duct_tape.description": "그리고 덕트 테이프의 힘으로 고쳤지!", - "key.categories.antarchy": "앤타키", - "key.antarchy.brutalfly_flap": "브루털플라이 겉날개: 날갯짓", - "advancements.antarchy.shrink_ray_craft.title": "애들아, 내가 몹을 줄였어", - "advancements.antarchy.shrink_ray_craft.description": "축소 광선총을 제작하세요.", - "advancements.antarchy.growth_ray_craft.title": "크게 가거나 집에 가거나", - "advancements.antarchy.growth_ray_craft.description": "성장 광선총을 제작하세요.", - "advancements.antarchy.squidzooka_craft.title": "먹물과 파괴", - "advancements.antarchy.squidzooka_craft.description": "스퀴드주카를 제작하세요.", - "advancements.antarchy.rocket_powered_octopus.title": "로켓 추진 문어", - "advancements.antarchy.rocket_powered_octopus.description": "로·추·문 발사기를 제작하세요.", - "advancements.antarchy.gravity_gun_craft.title": "들어 올리기 선수", - "advancements.antarchy.gravity_gun_craft.description": "중력총을 제작하세요.", - "block.antarchy.cavaryn_portal": "카바린 차원문", - "block.antarchy.termite_nest": "흰개미 둥지", - "block.antarchy.chitin_spike": "치텐 가시", - "block.antarchy.chitin_block": "치텐 블록", - "block.antarchy.myrmite": "미르마이트", - "block.antarchy.broodstone": "브루드스톤", - "block.antarchy.amber_moss_block": "호박색 이끼 블록", - "block.antarchy.amber_moss_carpet": "호박색 이끼 양탄자", - "block.antarchy.amber_lichen": "호박색 지의류", - "block.antarchy.bile_vein": "담즙 광맥", - "block.antarchy.creepvine": "크리프바인", - "block.antarchy.crawling_blight_egg": "기어오는 공포 알", - "block.antarchy.skulking_fright_egg": "도사린 공포 알", - "entity.antarchy.termite": "흰개미", - "entity.antarchy.springbug": "점피 벌레", - "entity.antarchy.spit_bug": "스핏 벌레", - "entity.antarchy.stink_bug": "노린재", - "entity.antarchy.rolly_polly": "공벌레", - "entity.antarchy.crawling_blight": "기어오는 공포", - "entity.antarchy.skulking_fright": "도사린 공포", - "entity.antarchy.hercules_beetle": "헤라클레스장수풍뎅이", - "item.antarchy.springbug_spawn_egg": "점피 벌레 생성 알", - "item.antarchy.spit_bug_spawn_egg": "스핏 벌레 생성 알", - "item.antarchy.stink_bug_spawn_egg": "노린재 생성 알", - "item.antarchy.termite_spawn_egg": "흰개미 생성 알", - "item.antarchy.rolly_polly_spawn_egg": "공벌레 생성 알", - "item.antarchy.crawling_blight_spawn_egg": "기어오는 공포 생성 알", - "item.antarchy.skulking_fright_spawn_egg": "도사린 공포 생성 알", - "item.antarchy.hercules_beetle_spawn_egg": "헤라클레스장수풍뎅이 생성 알", - "item.antarchy.chitin": "치텐", - "block.antarchy.polished_broodstone": "윤나는 브루드스톤", - "block.antarchy.chiseled_broodstone": "조각된 브루드스톤", - "block.antarchy.broodstone_bricks": "브루드스톤 벽돌", - "block.antarchy.broodstone_stairs": "브루드스톤 계단", - "block.antarchy.broodstone_slab": "브루드스톤 반 블록", - "block.antarchy.broodstone_wall": "브루드스톤 담장", - "block.antarchy.polished_broodstone_stairs": "윤나는 브루드스톤 계단", - "block.antarchy.polished_broodstone_slab": "윤나는 브루드스톤 반 블록", - "block.antarchy.polished_broodstone_wall": "윤나는 브루드스톤 담장", - "block.antarchy.broodstone_brick_stairs": "브루드스톤 벽돌 계단", - "block.antarchy.broodstone_brick_slab": "브루드스톤 벽돌 반 블록", - "block.antarchy.broodstone_brick_wall": "브루드스톤 벽돌 담장", - "block.antarchy.myrmite_coal_ore": "미르마이트 석탄 광석", - "block.antarchy.broodstone_uranium_ore": "브루드스톤 우라늄 광석", - "block.antarchy.broodstone_titanium_ore": "브루드스톤 티타늄 광석", - "item.antarchy.raw_bug_meat": "익히지 않은 벌레 고기", - "item.antarchy.cooked_bug_meat": "익힌 벌레 고기", - "item.antarchy.hercules_horn": "헤라클레스 뿔", - "block.antarchy.hanging_creeproots": "매달린 크리프루츠", - "block.antarchy.glowcap_mushroom": "글로우캡 버섯", - "block.antarchy.potted_glowcap_mushroom": "화분에 심은 글로우캡 버섯", - "block.antarchy.glowcap_mushroom_block": "글로우캡 버섯 블록", - "block.antarchy.molting_vines": "탈피 덩굴", - "item.antarchy.broodfruit": "브루드프루트", - "block.antarchy.springbug_egg": "점피 벌레 알", - "subtitles.antarchy.crawling_blight_growl": "기어오는 공포 그르렁거립니다", - "subtitles.antarchy.crawling_blight_hurt": "기어오는 공포 다칩니다", - "subtitles.antarchy.crawling_blight_bite": "기어오는 공포 뭅니다", - "subtitles.antarchy.skulking_fright_snarl": "도사린 공포 으르렁거립니다", - "subtitles.antarchy.skulking_fright_hurt": "도사린 공포 다칩니다", - "subtitles.antarchy.skulking_fright_bite": "도사린 공포 뭅니다", - "subtitles.antarchy.skulking_fright_fly_loop": "도사린 공포 납니다", - "subtitles.antarchy.stink_bug_fart": "노린재 방귀를 뀝니다", - "subtitles.antarchy.stink_bug_idle": "노린재 소리를 냅니다", - "subtitles.antarchy.rolly_polly_idle": "공벌레 소리를 냅니다", - "subtitles.antarchy.rolly_polly_wheel_mode": "공벌레가 몸을 맙니다", - "subtitles.antarchy.rolly_polly_normal_mode": "공벌레가 몸을 폅니다", - "subtitles.antarchy.rolly_polly_roll": "공벌레가 구릅니다", - "subtitles.antarchy.hercules_beetle_idle": "헤라클레스장수풍뎅이 소리를 냅니다", - "subtitles.antarchy.hercules_beetle_hurt": "헤라클레스장수풍뎅이 다칩니다", - "subtitles.antarchy.hercules_beetle_attack": "헤라클레스장수풍뎅이 공격합니다", - "subtitles.antarchy.hercules_beetle_cry": "헤라클레스장수풍뎅이 포효합니다", - "subtitles.antarchy.hercules_beetle_charge_start": "헤라클레스장수풍뎅이 힘을 모읍니다", - "subtitles.antarchy.hercules_beetle_knocked_down": "헤라클레스장수풍뎅이 쓰러집니다", - "subtitles.antarchy.jerry_idle": "제리가 재잘거립니다", - "subtitles.antarchy.jerry_hurt": "제리가 다칩니다", - "subtitles.antarchy.jerry_death": "제리가 죽습니다", - "subtitles.antarchy.jerry_attack": "제리가 공격합니다", - "subtitles.antarchy.springbug_idle": "점피 벌레 소리를 냅니다", - "subtitles.antarchy.spit_bug_idle": "스핏 벌레 소리를 냅니다", - "subtitles.antarchy.springbug_hurt": "점피 벌레 다칩니다", - "subtitles.antarchy.springbug_jump": "점피 벌레 뜁니다", - "subtitles.antarchy.spit_bug_hurt": "스핏 벌레 다칩니다", - "subtitles.antarchy.spit_bug_spit": "스핏 벌레 뱉습니다", - "subtitles.antarchy.brutalfly_spit": "브루털플라이 뱉습니다", - "advancements.antarchy.bug_apetit.title": "벌레 쁘띠", - "advancements.antarchy.bug_apetit.description": "익힌 벌레 고기를 먹으세요.", - "advancements.antarchy.behavioral_correction.title": "행동 교정", - "advancements.antarchy.behavioral_correction.description": "태도 교정기를 획득하세요.", - "advancements.antarchy.beetle_buddies.title": "딱정벌레 친구들", - "advancements.antarchy.beetle_buddies.description": "헤라클레스장수풍뎅이를 길들이세요.", - "advancements.antarchy.herculean_task.title": "헤라클레스의 과업", - "advancements.antarchy.herculean_task.description": "헤라클레스장수풍뎅이를 처치하세요." + "block.antarchy.duplicator_log": "복제나무 원목", + "block.antarchy.ouranwood_log": "오우란나무 원목", + "block.antarchy.ouranwood_wood": "오우란나무", + "block.antarchy.mossy_ouranwood_log": "이끼 낀 오우란나무 원목", + "block.antarchy.mossy_ouranwood_wood": "이끼 낀 오우란나무", + "block.antarchy.stripped_ouranwood_log": "껍질 벗긴 오우란나무 원목", + "block.antarchy.stripped_ouranwood_wood": "껍질 벗긴 오우란나무", + "block.antarchy.ouranwood_planks": "오우란나무 판자", + "block.antarchy.ouranwood_stairs": "오우란나무 계단", + "block.antarchy.ouranwood_slab": "오우란나무 반 블록", + "block.antarchy.ouranwood_fence": "오우란나무 울타리", + "block.antarchy.ouranwood_fence_gate": "오우란나무 울타리 문", + "block.antarchy.ouranwood_door": "오우란나무 문", + "block.antarchy.ouranwood_trapdoor": "오우란나무 다락문", + "block.antarchy.ouranwood_pressure_plate": "오우란나무 압력판", + "block.antarchy.ouranwood_button": "오우란나무 버튼", + "block.antarchy.ouranwood_leaves": "오우란나무 잎", + "block.antarchy.ouranwood_acorn": "오우란나무 도토리", + "block.antarchy.ouranwood_sign": "오우란나무 표지판", + "block.antarchy.ouranwood_hanging_sign": "오우란나무 매다는 표지판", + "block.antarchy.peach_log": "복숭아나무 원목", + "block.antarchy.peach_wood": "복숭아나무", + "block.antarchy.stripped_peach_log": "껍질 벗긴 복숭아나무 원목", + "block.antarchy.stripped_peach_wood": "껍질 벗긴 복숭아나무", + "block.antarchy.peach_planks": "복숭아나무 판자", + "block.antarchy.peach_stairs": "복숭아나무 계단", + "block.antarchy.peach_slab": "복숭아나무 반 블록", + "block.antarchy.peach_fence": "복숭아나무 울타리", + "block.antarchy.peach_fence_gate": "복숭아나무 울타리 문", + "block.antarchy.peach_door": "복숭아나무 문", + "block.antarchy.peach_trapdoor": "복숭아나무 다락문", + "block.antarchy.peach_pressure_plate": "복숭아나무 압력판", + "block.antarchy.peach_button": "복숭아나무 버튼", + "block.antarchy.peach_leaves": "복숭아나무 잎", + "block.antarchy.hanging_peach": "매달린 복숭아", + "block.antarchy.peach_sapling": "복숭아나무 묘목", + "block.antarchy.peach_sign": "복숭아나무 표지판", + "block.antarchy.peach_hanging_sign": "복숭아나무 매다는 표지판", + "block.antarchy.nadir_log": "나디르나무 원목", + "block.antarchy.nadir_wood": "나디르나무", + "block.antarchy.stripped_nadir_log": "껍질 벗긴 나디르나무 원목", + "block.antarchy.stripped_nadir_wood": "껍질 벗긴 나디르나무", + "block.antarchy.nadir_planks": "나디르나무 판자", + "block.antarchy.nadir_stairs": "나디르나무 계단", + "block.antarchy.nadir_slab": "나디르나무 반 블록", + "block.antarchy.nadir_fence": "나디르나무 울타리", + "block.antarchy.nadir_fence_gate": "나디르나무 울타리 문", + "block.antarchy.nadir_door": "나디르나무 문", + "block.antarchy.nadir_trapdoor": "나디르나무 다락문", + "block.antarchy.nadir_pressure_plate": "나디르나무 압력판", + "block.antarchy.nadir_button": "나디르나무 버튼", + "block.antarchy.nadir_veil": "나디르 베일", + "block.antarchy.nadir_sapling": "나디르나무 묘목", + "block.antarchy.nadir_sign": "나디르나무 표지판", + "block.antarchy.nadir_hanging_sign": "나디르나무 매다는 표지판", + "block.antarchy.royal_log": "로얄나무 원목", + "block.antarchy.royal_wood": "로얄나무", + "block.antarchy.stripped_royal_log": "껍질 벗긴 로얄나무 원목", + "block.antarchy.stripped_royal_wood": "껍질 벗긴 로얄나무", + "block.antarchy.royal_planks": "로얄나무 판자", + "block.antarchy.royal_stairs": "로얄나무 계단", + "block.antarchy.royal_slab": "로얄나무 반 블록", + "block.antarchy.royal_fence": "로얄나무 울타리", + "block.antarchy.royal_fence_gate": "로얄나무 울타리 문", + "block.antarchy.royal_door": "로얄나무 문", + "block.antarchy.royal_trapdoor": "로얄나무 다락문", + "block.antarchy.royal_pressure_plate": "로얄나무 압력판", + "block.antarchy.royal_button": "로얄나무 버튼", + "block.antarchy.royal_leaves": "로얄나무 잎", + "block.antarchy.royal_flowering_leaves": "꽃이 핀 로얄나무 잎", + "block.antarchy.royal_sapling": "로얄나무 묘목", + "block.antarchy.royal_sign": "로얄나무 표지판", + "block.antarchy.royal_hanging_sign": "로얄나무 매다는 표지판", + "block.antarchy.truffalo_log": "트러팔로나무 원목", + "block.antarchy.truffalo_wood": "트러팔로나무", + "block.antarchy.stripped_truffalo_log": "껍질 벗긴 트러팔로나무 원목", + "block.antarchy.stripped_truffalo_wood": "껍질 벗긴 트러팔로나무", + "block.antarchy.truffalo_planks": "트러팔로나무 판자", + "block.antarchy.truffalo_stairs": "트러팔로나무 계단", + "block.antarchy.truffalo_slab": "트러팔로나무 반 블록", + "block.antarchy.truffalo_fence": "트러팔로나무 울타리", + "block.antarchy.truffalo_fence_gate": "트러팔로나무 울타리 문", + "block.antarchy.truffalo_door": "트러팔로나무 문", + "block.antarchy.truffalo_trapdoor": "트러팔로나무 다락문", + "block.antarchy.truffalo_pressure_plate": "트러팔로나무 압력판", + "block.antarchy.truffalo_button": "트러팔로나무 버튼", + "block.antarchy.truffalo_sapling": "트러팔로나무 묘목", + "block.antarchy.truffalo_sign": "트러팔로나무 표지판", + "block.antarchy.truffalo_hanging_sign": "트러팔로나무 매다는 표지판", + "block.antarchy.white_truffalo_tuft": "하얀색 트러팔로 다발", + "block.antarchy.orange_truffalo_tuft": "주황색 트러팔로 다발", + "block.antarchy.magenta_truffalo_tuft": "자홍색 트러팔로 다발", + "block.antarchy.light_blue_truffalo_tuft": "하늘색 트러팔로 다발", + "block.antarchy.yellow_truffalo_tuft": "노란색 트러팔로 다발", + "block.antarchy.lime_truffalo_tuft": "연두색 트러팔로 다발", + "block.antarchy.pink_truffalo_tuft": "분홍색 트러팔로 다발", + "block.antarchy.gray_truffalo_tuft": "회색 트러팔로 다발", + "block.antarchy.light_gray_truffalo_tuft": "회백색 트러팔로 다발", + "block.antarchy.cyan_truffalo_tuft": "청록색 트러팔로 다발", + "block.antarchy.purple_truffalo_tuft": "보라색 트러팔로 다발", + "block.antarchy.blue_truffalo_tuft": "파란색 트러팔로 다발", + "block.antarchy.brown_truffalo_tuft": "갈색 트러팔로 다발", + "block.antarchy.green_truffalo_tuft": "초록색 트러팔로 다발", + "block.antarchy.red_truffalo_tuft": "빨간색 트러팔로 다발", + "block.antarchy.black_truffalo_tuft": "검은색 트러팔로 다발", + "block.antarchy.orange_milkweed": "주황색 박주가리", + "block.antarchy.pink_milkweed": "분홍색 박주가리", + "block.antarchy.glimmering_reed": "희미하게 빛나는 갈대", + "block.antarchy.camellia": "동백나무", + "block.antarchy.spider_lily": "상사화", + "block.antarchy.lotus": "연꽃", + "item.antarchy.lotus": "연꽃", + "item.antarchy.critter_cage": "생물 케이지", + "block.antarchy.giant_lily_pad": "거대한 수련잎", + "block.antarchy.seashell": "조개껍데기", + "block.antarchy.lucid_anchor": "루시드 정박기", + "block.antarchy.undertrial_spawner": "언더트라이얼 생성기", + "block.antarchy.undervault": "언더금고", + "item.antarchy.undertrial_key": "언더트라이얼 열쇠", + "block.antarchy.critter_cage_block": "생물 케이지 블록", + "block.antarchy.hushweed": "허쉬위드", + "block.antarchy.umbral_moss_block": "그림자 이끼 블록", + "block.antarchy.umbral_moss_carpet": "그림자 이끼 양탄자", + "block.antarchy.blush_moss_block": "홍조 이끼 블록", + "block.antarchy.blush_moss_carpet": "홍조 이끼 양탄자", + "block.antarchy.duplicator_sapling": "듀플리케이터 묘목", + "block.antarchy.duct_tape": "덕트 테이프", + "block.antarchy.infested_rooted_dirt": "벌레 먹은 뿌리내린 흙", + "block.antarchy.infested_coarse_dirt": "벌레 먹은 거친 흙", + "block.antarchy.nyxite": "닉사이트", + "block.antarchy.polished_nyxite": "윤나는 닉사이트", + "block.antarchy.chiseled_nyxite": "조각된 닉사이트", + "block.antarchy.nyxite_bricks": "닉사이트 벽돌", + "block.antarchy.nyxite_pillar": "닉사이트 기둥", + "block.antarchy.shellstone": "조개돌", + "block.antarchy.polished_shellstone": "윤나는 조개돌", + "block.antarchy.shellstone_bricks": "조개돌 벽돌", + "block.antarchy.chiseled_shellstone": "조각된 조개돌", + "block.antarchy.mossy_shellstone_bricks": "이끼 낀 조개돌 벽돌", + "block.antarchy.mossy_shellstone_brick_stairs": "이끼 낀 조개돌 벽돌 계단", + "block.antarchy.mossy_shellstone_brick_slab": "이끼 낀 조개돌 벽돌 반 블록", + "block.antarchy.mossy_shellstone_brick_wall": "이끼 낀 조개돌 벽돌 담장", + "block.antarchy.cracked_shellstone_bricks": "금 간 조개돌 벽돌", + "block.antarchy.shellstone_pillar": "조개돌 기둥", + "block.antarchy.shellstone_stairs": "조개돌 계단", + "block.antarchy.shellstone_slab": "조개돌 반 블록", + "block.antarchy.shellstone_wall": "조개돌 담장", + "block.antarchy.polished_shellstone_stairs": "윤나는 조개돌 반 블록", + "block.antarchy.polished_shellstone_slab": "윤나는 조개돌 담장", + "block.antarchy.polished_shellstone_wall": "조개돌 벽돌 계단", + "block.antarchy.shellstone_brick_stairs": "조개돌 벽돌 반 블록", + "block.antarchy.shellstone_brick_slab": "조개돌 벽돌 담장", + "block.antarchy.shellstone_brick_wall": "닉사이트 계단", + "block.antarchy.nyxite_stairs": "닉사이트 계단", + "block.antarchy.nyxite_slab": "닉사이트 반 블록", + "block.antarchy.nyxite_wall": "닉사이트 담장", + "block.antarchy.polished_nyxite_stairs": "윤나는 닉사이트 계단", + "block.antarchy.polished_nyxite_slab": "윤나는 닉사이트 반 블록", + "block.antarchy.polished_nyxite_wall": "윤나는 닉사이트 담장", + "block.antarchy.polished_nyxite_pressure_plate": "윤나는 닉사이트 압력판", + "block.antarchy.polished_nyxite_button": "윤나는 닉사이트 버튼", + "block.antarchy.nyxite_brick_stairs": "닉사이트 벽돌 계단", + "block.antarchy.nyxite_brick_slab": "닉사이트 벽돌 반 블록", + "block.antarchy.nyxite_brick_wall": "닉사이트 벽돌 담장", + "block.antarchy.pale_nyxite": "창백한 닉사이트", + "block.antarchy.nyxite_spike": "닉사이트 가시", + "block.antarchy.potent_nyxite": "강력한 닉사이트", + "block.antarchy.flytrap_goo_block": "파리잡이 끈적액 블록", + "block.antarchy.elythia_portal": "엘리시아 차원문", + "block.antarchy.cloud_block": "구름 블록", + "block.antarchy.thoraxis_portal": "소락시스 차원문", + "block.antarchy.antimetal": "안티메탈", + "block.antarchy.antimetal_stairs": "안티메탈 계단", + "block.antarchy.antimetal_slab": "안티메탈 반 블록", + "block.antarchy.polished_antimetal": "윤나는 안티메탈", + "block.antarchy.polished_antimetal_stairs": "윤나는 안티메탈 계단", + "block.antarchy.polished_antimetal_slab": "윤나는 안티메탈 반 블록", + "block.antarchy.antimetal_scaffolding": "안티메탈 비계", + "block.antarchy.antimetal_rail": "안티메탈 레일", + "block.antarchy.antimetal_powered_rail": "안티메탈 동력 레일", + "block.antarchy.antimetal_detector_rail": "안티메탈 감지 레일", + "block.antarchy.antimetal_activator_rail": "안티메탈 활성화 레일", + "block.antarchy.upper": "업퍼", + "container.antarchy.upper": "업퍼", + "block.antarchy.cornea_stalk": "각막 줄기", + "block.antarchy.corn_crop": "옥수수 작물", + "block.antarchy.dream_torch": "꿈 횃불", + "block.antarchy.dream_wall_torch": "벽에 걸린 꿈 횃불", + "block.antarchy.dream_lantern": "꿈 랜턴", + "block.antarchy.dream_campfire": "꿈 모닥불", + "block.antarchy.dream_fire": "꿈 불", + "block.antarchy.dream_fire_ceiling": "꿈 불", + "block.antarchy.budding_blood_crystal": "싹 틔우는 혈수정", + "block.antarchy.blood_crystal_block": "혈수정 블록", + "block.antarchy.small_blood_crystal_bud": "작은 혈수정 봉오리", + "block.antarchy.medium_blood_crystal_bud": "중간 혈수정 봉오리", + "block.antarchy.large_blood_crystal_bud": "큰 혈수정 봉오리", + "block.antarchy.blood_crystal_cluster": "혈수정 군집", + "block.antarchy.dream_sand": "꿈 모래", + "block.antarchy.antigravel": "안티자갈", + "block.antarchy.loam": "양토", + "block.antarchy.dream_sandstone": "꿈 사암", + "block.antarchy.chiseled_dream_sandstone": "조각된 꿈 사암", + "block.antarchy.cut_dream_sandstone": "깎인 꿈 사암", + "block.antarchy.smooth_dream_sandstone": "매끄러운 꿈 사암", + "block.antarchy.dream_sandstone_stairs": "꿈 사암 계단", + "block.antarchy.dream_sandstone_slab": "꿈 사암 반 블록", + "block.antarchy.dream_sandstone_wall": "꿈 사암 담장", + "block.antarchy.smooth_dream_sandstone_stairs": "매끄러운 꿈 사암 계단", + "block.antarchy.smooth_dream_sandstone_slab": "매끄러운 꿈 사암 반 블록", + "block.antarchy.cut_dream_sandstone_slab": "깎인 꿈 사암 반 블록", + "block.antarchy.typhonite": "타이포나이트", + "block.antarchy.typhonite_bricks": "타이포나이트 벽돌", + "block.antarchy.chiseled_typhonite": "조각된 타이포나이트", + "block.antarchy.polished_typhonite": "윤나는 타이포나이트", + "block.antarchy.veined_typhonite": "맥상 타이포나이트", + "block.antarchy.typhonite_spike": "타이포나이트 가시", + "block.antarchy.typhonite_stairs": "타이포나이트 계단", + "block.antarchy.typhonite_slab": "타이포나이트 반 블록", + "block.antarchy.typhonite_wall": "타이포나이트 담장", + "block.antarchy.typhonite_brick_stairs": "타이포나이트 벽돌 계단", + "block.antarchy.typhonite_brick_slab": "타이포나이트 벽돌 반 블록", + "block.antarchy.typhonite_brick_wall": "타이포나이트 벽돌 담장", + "block.antarchy.polished_typhonite_stairs": "윤나는 타이포나이트 계단", + "block.antarchy.polished_typhonite_slab": "윤나는 타이포나이트 반 블록", + "block.antarchy.polished_typhonite_wall": "윤나는 타이포나이트 담장", + "block.antarchy.spiraling_vines": "소라모양 덩굴", + "block.antarchy.whirlflower": "회오리꽃", + "block.antarchy.bed_bug_egg": "빈대 알", + "block.antarchy.wasp_nest": "말벌집", + "block.antarchy.red_ant_nest": "붉은 개미 굴", + "block.antarchy.brown_ant_nest": "갈색 개미 굴", + "block.antarchy.rainbow_ant_nest": "무지개 개미 굴", + "block.antarchy.uranium_ore": "우라늄 광석", + "block.antarchy.deepslate_uranium_ore": "심층암 우라늄 광석", + "block.antarchy.titanium_ore": "티타늄 광석", + "block.antarchy.deepslate_titanium_ore": "심층암 티타늄 광석", + "block.antarchy.bluestone_ore": "블루스톤 광석", + "block.antarchy.bluestone_block": "블루스톤 블록", + "block.antarchy.vortex_lens": "소용돌이 렌즈", + "tooltip.antarchy.vortex_lens": "레드스톤 신호는 엔티티를 광선 안으로 빨아들이고, 블루스톤 신호는 튕겨냅니다. 신호가 강할수록 소용돌이가 커집니다.", + "block.antarchy.bluestone_repeater": "블루스톤 중계기", + "block.antarchy.bluestone_comparator": "블루스톤 비교기", + "block.antarchy.bluestone_torch": "블루스톤 횃불", + "block.antarchy.bluestone_lamp": "블루스톤 조명", + "block.antarchy.uranium_block": "우라늄 블록", + "block.antarchy.titanium_block": "티타늄 블록", + "block.antarchy.raw_uranium_block": "우라늄 원석 블록", + "block.antarchy.raw_titanium_block": "티타늄 원석 블록", + "block.antarchy.cut_uranium": "깎인 우라늄", + "block.antarchy.cut_titanium": "깎인 티타늄", + "block.antarchy.cut_uranium_slab": "깎인 우라늄 반 블록", + "block.antarchy.cut_titanium_slab": "깎인 티타늄 반 블록", + "block.antarchy.cut_uranium_stairs": "깎인 우라늄 계단", + "block.antarchy.cut_titanium_stairs": "깎인 티타늄 계단", + "block.antarchy.chiseled_uranium": "조각된 우라늄", + "block.antarchy.chiseled_titanium": "조각된 티타늄", + "block.antarchy.uranium_bulb": "우라늄 전구", + "block.antarchy.titanium_bulb": "티타늄 전구", + "block.antarchy.uranium_door": "우라늄 문", + "block.antarchy.titanium_door": "티타늄 문", + "block.antarchy.uranium_trapdoor": "우라늄 다락문", + "block.antarchy.titanium_trapdoor": "티타늄 다락문", + "block.antarchy.uranium_bars": "우라늄 창살", + "block.antarchy.titanium_bars": "티타늄 창살", + "tooltip.antarchy.signal_saving_bulb": "켜기/끄기를 전환합니다. 저장된 신호 세기와 동일한 밝기의 빛을 냅니다.", + "tooltip.antarchy.bluestone_placement": "블록 아래에 설치합니다.", + "tooltip.antarchy.ceiling_compatible_placement": "천장에도 설치할 수 있습니다.", + "tooltip.antarchy.antimetal_scaffolding": "일반 비계처럼 작동하거나, 중력이 뒤집혔을 때는 역방향 비계로 작동합니다.", + "block.antarchy.bile": "담즙", + "block.antarchy.ichor": "이코르", + "block.antarchy.antiwater": "역수", + "block.antarchy.lumen": "루멘", + "block.antarchy.lumen_froglight": "루멘 개구리불", + "block.antarchy.roseate_froglight": "장밋빛 개구리불", + "block.antarchy.star_coral": "별 산호", + "block.antarchy.star_coral_fan": "부채꼴 별 산호", + "block.antarchy.star_coral_block": "별 산호 블록", + "block.antarchy.dead_star_coral": "죽은 별 산호", + "block.antarchy.dead_star_coral_fan": "죽은 부채꼴 별 산호", + "block.antarchy.dead_star_coral_block": "죽은 별 산호 블록", + "entity.antarchy.apple_cow": "사과 소", + "entity.antarchy.golden_apple_cow": "황금 사과 소", + "entity.antarchy.enchanted_golden_apple_cow": "마법이 부여된 황금 사과 소", + "entity.antarchy.easter_bunny": "이스터 토끼", + "entity.antarchy.glimmer": "글리머", + "entity.antarchy.ouranwood_deer": "오우란나무 사슴", + "entity.antarchy.elka": "엘카", + "entity.antarchy.dorrie": "도리", + "entity.antarchy.flying_squirrel": "하늘다람쥐", + "entity.antarchy.caterpillar": "애벌레", + "entity.antarchy.butterfly": "나비", + "entity.antarchy.brutalfly": "브루탈플라이", + "entity.antarchy.red_ant": "붉은 개미", + "entity.antarchy.brown_ant": "갈색 개미", + "entity.antarchy.rainbow_ant": "무지개 개미", + "entity.antarchy.diamond_minecart": "다이아몬드 광산 수레", + "entity.antarchy.dr_trayaurus": "트레이오러스 박사", + "entity.antarchy.stratoshark": "스트라토샤크", + "entity.antarchy.kraken": "크라켄", + "entity.antarchy.missile_squid": "미사일 오징어", + "entity.antarchy.octopus_bomb": "문어 폭탄", + "entity.antarchy.nightmare": "나이트메어", + "entity.antarchy.bed_bug": "빈대", + "entity.antarchy.wasp": "말벌", + "entity.antarchy.bomber": "봄버", + "entity.antarchy.moleworm": "웜", + "entity.antarchy.worm": "벌레", + "entity.antarchy.molevore": "몰레보어", + "entity.antarchy.mantis": "맨티스", + "entity.antarchy.alpha_mantis": "알파 맨티스", + "entity.antarchy.flytrap": "파리잡이", + "entity.antarchy.toreterror": "토레테러", + "entity.antarchy.water_bomb": "물폭탄", + "subtitles.antarchy.manticore_idle": "만티코어가 으르렁거림", + "subtitles.antarchy.manticore_walk": "만티코어가 걸어감", + "subtitles.antarchy.manticore_fly": "만티코어가 날아감", + "subtitles.antarchy.manticore_bite": "만티코어가 물어띰", + "subtitles.antarchy.mantis_ambient": "맨티스가 찰칵거림", + "subtitles.antarchy.mantis_hurt": "맨티스가 비명을 지름", + "subtitles.antarchy.mantis_attack": "맨티스가 덤벼듦", + "subtitles.antarchy.mantis_fly_loop": "맨티스 날개가 웅웅거림", + "item.antarchy.big_bertha": "빅 베르타", + "item.antarchy.giant_frying_pan": "거대한 프라이팬", + "tooltip.antarchy.giant_frying_pan.insert": "다른 손에 음식을 들고 우클릭하거나, 인벤토리에서 음식을 우클릭하여 추가합니다.", + "tooltip.antarchy.giant_frying_pan.gui": "Shift + 우클릭하여 조리 슬롯을 엽니다.", + "tooltip.antarchy.giant_frying_pan.campfire": "연료 없이 모닥불 레시피를 조리합니다.", + "tooltip.antarchy.giant_frying_pan.dig": "삽 블록 구역을 5x5 범위로 파냅니다.", + "tooltip.antarchy.giant_frying_pan.launch": "공격 시 적을 공중으로 띄웁니다.", + "item.antarchy.bluestone": "블루스톤 가루", + "item.antarchy.wasp_nest": "말벌집", + "item.antarchy.stink_bug": "노린재", + "item.antarchy.wasp_spawn_egg": "말벌 스폰 알", + "item.antarchy.bomber_spawn_egg": "봄버 스폰 알", + "item.antarchy.big_bertha_blade": "빅 베르타 칼날", + "item.antarchy.big_bertha_handle": "빅 베르타 손잡이", + "item.antarchy.big_bertha_hilt": "빅 베르타 자루", + "item.antarchy.battle_axe": "배틀액스", + "item.antarchy.attitude_adjuster": "어튜드 어저스터", + "tooltip.antarchy.attitude_adjuster.grounded": "지상의 대상을 위로 쳐올리고, 공중의 대상을 지면에 내리꽂습니다.", + "tooltip.antarchy.attitude_adjuster.slam": "공중에 있을 때 사용하여 지면을 강타합니다.", + "item.antarchy.stratoshark_fin": "스트라토샤크 지느러미", + "item.antarchy.stratoshark_fin_soup": "스트라토샤크 지느러미 수프", + "tooltip.antarchy.stratoshark_fin_soup": "성장 및 느린 낙하 효과를 부여합니다.", + "tooltip.antarchy.critter_cage.empty": "사용하여 던집니다", + "tooltip.antarchy.critter_cage.contains": "보관 중: %s", + "tooltip.antarchy.critter_cage.release": "사용하여 풀어줍니다", + "tooltip.antarchy.critter_cage.place": "Shift + 클릭하여 설치합니다", + "item.antarchy.kraken_tooth": "크라켄 이빨", + "item.antarchy.kraken_tentacle": "크라켄 촉수", + "item.antarchy.kraken_kalamari": "크라켄 오징어튀김", + "item.antarchy.krakens_grasp": "크라켄의 아귀", + "entity.antarchy.tentacle": "촉수", + "item.antarchy.basilisk_fang": "바실리스크 송곳니", + "item.antarchy.basilisk_dagger": "바실리스크 단검", + "item.antarchy.blood_crystal_block": "혈수정 블록", + "item.antarchy.small_blood_crystal_bud": "작은 혈수정 봉오리", + "item.antarchy.medium_blood_crystal_bud": "중간 혈수정 봉오리", + "item.antarchy.large_blood_crystal_bud": "큰 혈수정 봉오리", + "item.antarchy.blood_crystal_cluster": "혈수정 군집", + "item.antarchy.dream_sand": "꿈 모래", + "item.antarchy.dream_sandstone": "꿈 사암", + "item.antarchy.chiseled_dream_sandstone": "조각된 꿈 사암", + "item.antarchy.cut_dream_sandstone": "깎인 꿈 사암", + "item.antarchy.smooth_dream_sandstone": "매끄러운 꿈 사암", + "item.antarchy.dream_sandstone_stairs": "꿈 사암 계단", + "item.antarchy.dream_sandstone_slab": "꿈 사암 반 블록", + "item.antarchy.dream_sandstone_wall": "꿈 사암 담장", + "item.antarchy.smooth_dream_sandstone_stairs": "매끄러운 꿈 사암 계단", + "item.antarchy.smooth_dream_sandstone_slab": "매끄러운 꿈 사암 반 블록", + "item.antarchy.cut_dream_sandstone_slab": "깎인 꿈 사암 반 블록", + "item.antarchy.typhonite": "타이포나이트", + "item.antarchy.typhonite_bricks": "타이포나이트 벽돌", + "item.antarchy.chiseled_typhonite": "조각된 타이포나이트", + "item.antarchy.polished_typhonite": "윤나는 타이포나이트", + "item.antarchy.veined_typhonite": "맥상 타이포나이트", + "item.antarchy.typhonite_spike": "타이포나이트 가시", + "item.antarchy.typhonite_stairs": "타이포나이트 계단", + "item.antarchy.typhonite_slab": "타이포나이트 반 블록", + "item.antarchy.typhonite_wall": "타이포나이트 담장", + "item.antarchy.typhonite_brick_stairs": "타이포나이트 벽돌 계단", + "item.antarchy.typhonite_brick_slab": "타이포나이트 벽돌 반 블록", + "item.antarchy.typhonite_brick_wall": "타이포나이트 벽돌 담장", + "item.antarchy.polished_typhonite_stairs": "윤나는 타이포나이트 계단", + "item.antarchy.polished_typhonite_slab": "윤나는 타이포나이트 반 블록", + "item.antarchy.polished_typhonite_wall": "윤나는 타이포나이트 담장", + "item.antarchy.spiraling_vines": "소라모양 덩굴", + "item.antarchy.whirlflower": "회오리꽃", + "item.antarchy.dream_torch": "꿈 횃불", + "item.antarchy.dream_lantern": "꿈 랜턴", + "item.antarchy.dream_campfire": "꿈 모닥불", + "item.antarchy.giant_lily_pad": "거대한 연잎", + "item.antarchy.seashell": "조개껍데기", + "item.antarchy.nightmare_scale": "나이트메어 비늘", + "item.antarchy.music_disc_underside": "음반", + "jukebox_song.antarchy.underside": "docshrekbot - underside", + "item.antarchy.music_disc_the_queen": "음반", + "jukebox_song.antarchy.the_queen": "Karlljp - The Queen", + "item.antarchy.music_disc_verdance": "음반", + "jukebox_song.antarchy.verdance": "Hewo - Verdance", + "item.antarchy.music_disc_grotesque": "음반", + "jukebox_song.antarchy.grotesque": "DocShrekBot - Grotesque", + "item.antarchy.nightmare_helmet": "나이트메어 투구", + "item.antarchy.nightmare_chestplate": "나이트메어 흉갑", + "item.antarchy.nightmare_leggings": "나이트메어 레깅스", + "item.antarchy.nightmare_boots": "나이트메어 부츠", + "item.antarchy.nightmare_sword": "나이트메어 검", + "tooltip.antarchy.nightmare_armor_double_damage": "%s%% 확률로 2배의 피해를 줍니다.", + "tooltip.antarchy.nightmare_armor_set_bonus": "세트 효과: 위더 및 공포 면역", + "tooltip.antarchy.nightmare_sword": "체력이 낮아질수록 더 큰 피해를 줍니다.", + "tooltip.antarchy.nightmare_sword_damage": "%s의 피해를 줍니다.", + "tooltip.antarchy.primordial_helmet_water_breathing": "착용자에게 수중 호흡 효과를 부여합니다.", + "tooltip.antarchy.primordial_armor_knockback_dealt": "조각당 공격 넉백 %s 증가", + "tooltip.antarchy.primordial_armor_set_bonus": "세트 효과: 적의 넉백 저항 무시", + "attribute.antarchy.double_damage_chance": "2배 피해 확률", + "attribute.antarchy.bloodglass_max_hearts": "최대 혈유리 하트", + "item.antarchy.molevore_nose": "몰레보어 코", + "item.antarchy.moleworm": "몰웜", + "item.antarchy.worm_tooth": "벌레 이빨", + "item.antarchy.worm_hook": "웜 갈고리", + "tooltip.antarchy.worm_hook.throw": "블록을 우클릭하여 발사하고 부착합니다.", + "tooltip.antarchy.worm_hook.reel": "웅크리고 감아들이며, 다시 우클릭하여 해제합니다.", + "item.antarchy.flytrap_spawn_egg": "파리잡이 스폰 알", + "item.antarchy.infested_rooted_dirt": "뿌리 내린 감염된 흙", + "item.antarchy.infested_coarse_dirt": "거친 감염된 흙", + "item.antarchy.pale_nyxite": "창백한 닉사이트", + "item.antarchy.polished_nyxite": "윤나는 닉사이트", + "item.antarchy.chiseled_nyxite": "조각된 닉사이트", + "item.antarchy.nyxite_bricks": "닉사이트 벽돌", + "item.antarchy.shellstone": "조개돌", + "item.antarchy.polished_shellstone": "윤나는 조개돌", + "item.antarchy.shellstone_bricks": "조개돌 벽돌", + "item.antarchy.chiseled_shellstone": "조각된 조개돌", + "item.antarchy.mossy_shellstone_bricks": "이끼 낀 조개돌 벽돌", + "item.antarchy.mossy_shellstone_brick_stairs": "이끼 낀 조개돌 벽돌 계단", + "item.antarchy.mossy_shellstone_brick_slab": "이끼 낀 조개돌 벽돌 반 블록", + "item.antarchy.mossy_shellstone_brick_wall": "이끼 낀 조개돌 벽돌 담장", + "item.antarchy.cracked_shellstone_bricks": "금 간 조개돌 벽돌", + "item.antarchy.shellstone_stairs": "조개돌 계단", + "item.antarchy.shellstone_slab": "조개돌 반 블록", + "item.antarchy.shellstone_wall": "조개돌 담장", + "item.antarchy.polished_shellstone_stairs": "윤나는 조개돌 계단", + "item.antarchy.polished_shellstone_slab": "윤나는 조개돌 반 블록", + "item.antarchy.polished_shellstone_wall": "윤나는 조개돌 담장", + "item.antarchy.shellstone_brick_stairs": "조개돌 벽돌 계단", + "item.antarchy.shellstone_brick_slab": "조개돌 벽돌 반 블록", + "item.antarchy.shellstone_brick_wall": "조개돌 벽돌 담장", + "item.antarchy.nyxite_stairs": "닉사이트 계단", + "item.antarchy.nyxite_slab": "닉사이트 반 블록", + "item.antarchy.nyxite_wall": "닉사이트 담장", + "item.antarchy.polished_nyxite_stairs": "윤나는 닉사이트 계단", + "item.antarchy.polished_nyxite_slab": "윤나는 닉사이트 반 블록", + "item.antarchy.polished_nyxite_wall": "윤나는 닉사이트 담장", + "item.antarchy.nyxite_brick_stairs": "닉사이트 벽돌 계단", + "item.antarchy.nyxite_brick_slab": "닉사이트 벽돌 반 블록", + "item.antarchy.nyxite_brick_wall": "닉사이트 벽돌 담장", + "item.antarchy.potent_nyxite": "강력한 닉사이트", + "item.antarchy.antimetal": "안티메탈", + "item.antarchy.polished_antimetal": "윤나는 안티메탈", + "item.antarchy.antimetal_scaffolding": "안티메탈 비계", + "item.antarchy.antimetal_rail": "안티메탈 레일", + "item.antarchy.antimetal_powered_rail": "안티메탈 동력 레일", + "item.antarchy.antimetal_detector_rail": "안티메탈 감지 레일", + "item.antarchy.antimetal_activator_rail": "안티메탈 활성화 레일", + "item.antarchy.ouranwood_acorn": "오우란나무 도토리", + "item.antarchy.ouranwood_boat": "오우란나무 보트", + "item.antarchy.ouranwood_chest_boat": "상자가 실린 오우란나무 보트", + "item.antarchy.hoverboard": "호버보드", + "item.antarchy.hoverboard_white": "하얀색 호버보드", + "item.antarchy.hoverboard_orange": "주황색 호버보드", + "item.antarchy.hoverboard_magenta": "자홍색 호버보드", + "item.antarchy.hoverboard_light_blue": "하늘색 호버보드", + "item.antarchy.hoverboard_yellow": "노란색 호버보드", + "item.antarchy.hoverboard_lime": "연두색 호버보드", + "item.antarchy.hoverboard_pink": "분홍색 호버보드", + "item.antarchy.hoverboard_gray": "회색 호버보드", + "item.antarchy.hoverboard_light_gray": "회백색 호버보드", + "item.antarchy.hoverboard_cyan": "청록색 호버보드", + "item.antarchy.hoverboard_purple": "보라색 호버보드", + "item.antarchy.hoverboard_blue": "파란색 호버보드", + "item.antarchy.hoverboard_brown": "갈색 호버보드", + "item.antarchy.hoverboard_green": "초록색 호버보드", + "item.antarchy.hoverboard_red": "빨간색 호버보드", + "item.antarchy.hoverboard_black": "검은색 호버보드", + "item.antarchy.raw_venison": "익히지 않은 사슴고기", + "item.antarchy.cooked_venison": "익힌 사슴고기", + "item.antarchy.peach_sapling": "복숭아나무 묘목", + "item.antarchy.peach": "복숭아", + "item.antarchy.peach_pie": "복숭아 파이", + "item.antarchy.cornbread": "옥수수빵", + "item.antarchy.popcorn": "팝콘", + "item.antarchy.peach_sign": "복숭아나무 표지판", + "item.antarchy.peach_hanging_sign": "매다는 복숭아나무 표지판", + "item.antarchy.peach_boat": "복숭아나무 보트", + "item.antarchy.peach_chest_boat": "상자가 실린 복숭아나무 보트", + "item.antarchy.nadir_sign": "나디르나무 표지판", + "item.antarchy.nadir_hanging_sign": "매다는 나디르나무 표지판", + "item.antarchy.nadir_boat": "나디르나무 보트", + "item.antarchy.nadir_chest_boat": "상자가 실린 나디르나무 보트", + "entity.antarchy.nadir_boat": "나디르나무 보트", + "entity.antarchy.nadir_chest_boat": "상자가 실린 나디르나무 보트", + "item.antarchy.royal_sign": "로얄나무 표지판", + "item.antarchy.royal_hanging_sign": "매다는 로얄나무 표지판", + "item.antarchy.royal_boat": "로얄나무 보트", + "item.antarchy.royal_chest_boat": "상자가 실린 로얄나무 보트", + "entity.antarchy.royal_boat": "로얄나무 보트", + "entity.antarchy.royal_chest_boat": "상자가 실린 로얄나무 보트", + "item.antarchy.truffalo_sign": "트러팔로나무 표지판", + "item.antarchy.truffalo_hanging_sign": "매다는 트러팔로나무 표지판", + "item.antarchy.truffalo_boat": "트러팔로나무 보트", + "item.antarchy.truffalo_chest_boat": "상자가 실린 트러팔로나무 보트", + "entity.antarchy.truffalo_boat": "트러팔로나무 보트", + "entity.antarchy.truffalo_chest_boat": "상자가 실린 트러팔로나무 보트", + "item.antarchy.orange_milkweed": "주황색 박주가리", + "item.antarchy.pink_milkweed": "분홍색 박주가리", + "item.antarchy.glimmering_reed": "어슴푸레한 갈대", + "item.antarchy.camellia": "동백꽃", + "item.antarchy.spider_lily": "석산", + "item.antarchy.hushweed": "허쉬위드", + "item.antarchy.umbral_moss_block": "그림자 이끼 블록", + "item.antarchy.umbral_moss_carpet": "그림자 이끼 양탄자", + "item.antarchy.blush_moss_block": "홍조 이끼 블록", + "item.antarchy.blush_moss_carpet": "홍조 이끼 양탄자", + "item.antarchy.mud_pie": "진흙 파이", + "item.antarchy.duct_tape": "덕트 테이프", + "item.antarchy.duct_tape.tooltip": "설치 후 상호작용하여 도구를 수리합니다.", + "item.antarchy.rainbow_sugar": "무지개 설탕", + "item.antarchy.uranium_nugget": "우라늄 조각", + "item.antarchy.titanium_nugget": "티타늄 조각", + "item.antarchy.raw_uranium_scrap": "우라늄 원석 파편", + "item.antarchy.raw_titanium_scrap": "티타늄 원석 파편", + "item.antarchy.raw_uranium": "우라늄 원석", + "item.antarchy.raw_titanium": "티타늄 원석", + "item.antarchy.uranium_ingot": "우라늄 주괴", + "item.antarchy.titanium_ingot": "티타늄 주괴", + "item.antarchy.blood_crystal_shard": "혈수정 조각", + "item.antarchy.blood_crystal_apple": "혈수정 사과", + "item.antarchy.blood_crystal_katana": "혈수정 카타나", + "item.antarchy.blood_gods_blade": "혈신의 칼날", + "tooltip.antarchy.blood_gods_blade.bleeding": "공격 시 출혈을 부여합니다.", + "tooltip.antarchy.blood_gods_blade.blood_moon": "우클릭: 블러드 문 소환", + "effect.antarchy.bleeding": "출혈", + "effect.antarchy.blood_moon": "블러드 문", + "item.antarchy.blood_crystal_helmet": "혈수정 투구", + "item.antarchy.blood_crystal_chestplate": "혈수정 흉갑", + "item.antarchy.blood_crystal_leggings": "혈수정 레깅스", + "item.antarchy.blood_crystal_boots": "혈수정 부츠", + "item.antarchy.blood_crystal_armor.tooltip": "받는 피격을 1회 막아주고 산산조각 난 뒤 충전되는 혈유리 하트를 부여합니다.", + "item.antarchy.blood_crystal_boots.tooltip2": "중력이 뒤집혀 위로 떨어질 때 낙하 피해를 무효화합니다.", + "item.antarchy.blood_crystal_apple.tooltip": "혈유리 보호 효과를 부여하여, 지속시간 동안 충전되는 임시 혈유리 하트를 얻습니다.", + "tooltip.antarchy.blood_crystal_katana.launch": "공격 시 앞으로 돌진합니다.", + "tooltip.antarchy.blood_crystal_katana.dash": "조준하는 원거리 대상에게 다가가며, 완충 공격 시 짧은 무적 상태를 얻습니다.", + "tooltip.antarchy.blood_crystal_katana.trail": "지나간 자리에 핏빛 궤적을 남깁니다.", + "item.antarchy.eye_of_the_storm": "폭풍의 눈", + "tooltip.antarchy.eye_of_the_storm.updraft": "사용하여 상승 기류를 타고 하늘로 올라갑니다.", + "tooltip.antarchy.eye_of_the_storm.surge": "공격 시 적을 휩쓸고 끌고 가는 유도 토네이도를 날립니다.", + "item.antarchy.royal_guardian_helmet": "로얄 가디언 투구", + "item.antarchy.royal_guardian_chestplate": "로얄 가디언 흉갑", + "item.antarchy.royal_guardian_leggings": "로얄 가디언 레깅스", + "item.antarchy.royal_guardian_boots": "로얄 가디언 부츠s", + "item.antarchy.royal_guardian_sword": "로얄 가디언 검", + "item.antarchy.royal_guardian_shield": "로얄 가디언 방패", + "tooltip.antarchy.royal_guardian_sword.mode": "모드: %s", + "tooltip.antarchy.royal_guardian_sword.mode.none": "없음", + "tooltip.antarchy.royal_guardian_sword.mode.fire": "화염", + "tooltip.antarchy.royal_guardian_sword.mode.frost": "냉기", + "tooltip.antarchy.royal_guardian_sword.mode.storm": "폭풍", + "tooltip.antarchy.royal_guardian_sword.none": "완충 공격 시 원소 방출 없이 검의 기본 피해를 입힙니다.", + "tooltip.antarchy.royal_guardian_sword.fire": "완충 공격 시 로열 화염이 분출하여 대상과 주변 적을 불태웁니다.", + "tooltip.antarchy.royal_guardian_sword.frost": "완충 공격 시 대상을 빙결시키고 부채꼴 모양의 로열 얼음 가시를 형성합니다.", + "tooltip.antarchy.royal_guardian_sword.storm": "완충 공격 시 주변 적들 사이를 연쇄하는 로열 번개를 불러옵니다.", + "tooltip.antarchy.royal_guardian_sword.controls": "웅크리고 사용하여 모드를 전환합니다. 완충 공격 시 선택한 원소를 방출합니다 (재사용 대기시간 %s초).", + "message.antarchy.royal_guardian_sword.mode": "로얄 가디언 모드: %s", + "item.antarchy.royal_assailant_helmet": "로얄 어설런트 투구", + "item.antarchy.royal_assailant_chestplate": "로얄 어설런트 흉갑", + "item.antarchy.royal_assailant_leggings": "로얄 어설런트 레깅스", + "item.antarchy.royal_assailant_boots": "로얄 어설런트 부츠", + "item.antarchy.royal_assailant_battleaxe": "로얄 어설런트 배틀액스", + "item.antarchy.royal_assailant_staff": "로얄 어설런트 지팡이", + "tooltip.antarchy.royal_assailant_staff": "30초 동안 아군 만티코어 4마리를 소환하는 균열쌍을 엽니다.", + "tooltip.antarchy.royal_assailant_battleaxe.black_hole": "사용하여 블랙홀을 생성합니다.", + "tooltip.antarchy.royal_assailant_battleaxe.dilation": "공격 시 시간 팽창을 부여합니다.", + "tooltip.antarchy.royal_guardian_shield.command": "웅크리고 사용하여 주변 몹에게 전투 명령을 내리며, 몹의 공격력, 이동 속도, 방어력을 강화합니다.", + "tooltip.antarchy.royal_guardian_helmet.judgment": "심판의 표식: 표식이 남은 대상에게 %s%% 의 추가 피해", + "tooltip.antarchy.royal_guardian_chestplate.judgment": "심판의 표식: 표식이 남은 대상에게 %s%% 의 추가 피해", + "tooltip.antarchy.royal_guardian_chestplate.boundary": "로얄 결계 열쇠: 날아오는 적의 투사체를 멈추고 아군에게 힘 효과를 부여합니다.", + "tooltip.antarchy.royal_guardian_leggings.judgment": "심판의 표식: 표식이 남은 대상에게 %s%% 의 추가 피해", + "tooltip.antarchy.royal_guardian_boots.judgment": "심판의 표식: 표식이 남은 대상에게 %s%% 의 추가 피해", + "tooltip.antarchy.royal_assailant_chestplate.invert": "반전 키를 눌러 역중력 상태를 켜거나 끕니다.", + "tooltip.antarchy.royal_assailant_boots.fall": "위로 떨어질 때 낙하 피해를 무효화합니다.", + "item.antarchy.mantis_claw": "맨티스 발톱", + "tooltip.antarchy.mantis_claw.wall_cling": "양손에 들고 벽에 매달려 위로 점프할 수 있습니다.", + "item.antarchy.king_scale": "더 킹의 비늘", + "item.antarchy.queen_scale": "더 퀸의 비늘", + "item.antarchy.temporal_tuner": "시간 조율기", + "tooltip.antarchy.temporal_tuner.description": "개인 시간 팽창을 조절합니다.", + "tooltip.antarchy.temporal_tuner.speed": "현재 속도: %s%%", + "tooltip.antarchy.temporal_tuner.controls": "Shift + 스크롤: 속도 %s%% ~ %s%%", + "tooltip.antarchy.temporal_tuner.availability": "퀵슬롯이나 보조 손에서 벗어나면 초기화됩니다.", + "item.antarchy.jerry_nucleus": "제리의 핵", + "tooltip.antarchy.jerry_nucleus.hatch": "손에 든 채로 벌레 알이나 거북 알과 상호작용하여 즉시 부화시킵니다.", + "key.antarchy.mount_special": "탈것: 특수 / 돌진", + "key.antarchy.royal_boundary": "로얄 결계", + "message.antarchy.royal_boundary.activated": "로얄 결계가 활성화되었습니다.", + "message.antarchy.royal_boundary.recharging": "로얄 결계가 충전 중입니다.", + "key.antarchy.mount_flight_toggle": "탈것: 비행 전환", + "item.antarchy.springbug_leg": "스프링버그 다리", + "item.antarchy.springy_boots": "스프링 부츠", + "tooltip.antarchy.springy_boots": "웅크려 충전한 뒤 점프하여 높이 도약합니다.", + "item.antarchy.brutalfly_wing": "브루탈플라이 날개", + "item.antarchy.brutalfly_elytra": "브루탈플라이 겉날개", + "item.antarchy.manticore_wing": "만티코어 날개", + "item.antarchy.manticore_wings": "만티코어 날개", + "tooltip.antarchy.manticore_wings": "비행 중 적이 아닌 생명체와 충돌하여 큰 피해를 줍니다.", + "item.antarchy.broodfruit_cobbler": "브루드프루트 코블러", + "tooltip.antarchy.brutalfly_elytra.flap": "비행 중 %s 키를 꾹 눌러 날개를 퍼덕입니다.", + "item.antarchy.cornea_ear": "각막 귀", + "item.antarchy.corn": "옥수수", + "item.antarchy.corn_seeds": "옥수수 씨앗", + "item.antarchy.raw_corndog": "익히지 않은 핫도그", + "item.antarchy.cooked_corndog": "익힌 핫도그", + "item.antarchy.high_fructose_corn_syrup": "고과당 옥수수 시럽", + "jei.antarchy.americanize": "미국화", + "item.antarchy.american_name": "미국식 %s", + "item.antarchy.root_beer": "루트 비어", + "item.antarchy.primordial_scute": "원시 등갑", + "item.antarchy.flytrap_goo": "파리잡이 점액", + "item.antarchy.flytrap_goo_block": "파리잡이 점액 블록", + "tooltip.antarchy.flytrap_goo_block": "고속으로 닿으면 튀어 오르고, 그렇지 않으면 가라앉습니다.", + "item.antarchy.cloud_bucket": "구름 양동이", + "tooltip.antarchy.cloud_bucket.midair": "공중에도 설치할 수 있습니다.", + "item.antarchy.lumen_bucket": "루멘 양동이", + "item.antarchy.scorpion_whip": "임페로르 전갈 채찍", + "tooltip.antarchy.scorpion_whip.lash": "멀리 있는 사냥감을 후려쳐 독성 밧줄을 박아 넣습니다.", + "tooltip.antarchy.scorpion_whip.reel": "사용하여 밧줄에 묶인 사냥감을 감아들입니다.", + "tooltip.antarchy.scorpion_whip.snap": "밧줄에 묶인 적을 공격해 침을 끊어냅니다.", + "item.antarchy.fallen_king_crown": "몰락한 더 킹의 왕관", + "tooltip.antarchy.fallen_king_crown.hero": "적대적 몹을 처치하면 마을의 영웅 효과를 부여합니다.", + "item.antarchy.vortex_charge": "소용돌이 충전재", + "entity.antarchy.upward_falling_block": "하늘로 떨어지는 모래", + "entity.antarchy.vortex": "소용돌이", + "entity.antarchy.wind_vortex": "바람 소용돌이", + "entity.antarchy.dimensional_tear": "차원의 균열", + "item.antarchy.vortex_spawn_egg": "소용돌이 생성 알", + "item.antarchy.ultimate_helmet": "얼티밋 투구", + "item.antarchy.ultimate_chestplate": "얼티밋 흉갑", + "item.antarchy.ultimate_leggings": "얼티밋 레깅스", + "item.antarchy.ultimate_boots": "얼티밋 부츠", + "item.antarchy.ultimate_sword": "얼티밋 검", + "item.antarchy.ultimate_pickaxe": "얼티밋 곡괭이", + "item.antarchy.ultimate_axe": "얼티밋 도끼", + "item.antarchy.ultimate_shovel": "얼티밋 삽", + "item.antarchy.ultimate_hoe": "얼티밋 괭이", + "item.antarchy.ultimate_bow": "얼티밋 활", + "item.antarchy.ultimate_crossbow": "얼티밋 쇠뇌", + "item.antarchy.ultimate_crossbow.capacity": "한번에 최대 16발 장전", + "item.antarchy.ultimate_crossbow.arrows_remaining": "%1$s %2$s 장전됨", + "item.antarchy.ultimate_mace": "얼티밋 메이스", + "item.antarchy.moggles": "고글", + "itemGroup.antarchy.antarchy": "앤타키", + "item.antarchy.bile_bucket": "담즙 양동이", + "item.antarchy.ichor_bucket": "이코르 양동이", + "item.antarchy.antiwater_bucket": "역수 양동이", + "item.antarchy.reverie_bottle": "레버리의 병", + "item.antarchy.squidzooka": "오징어주카", + "item.antarchy.rpo_launcher": "R.P.O. 런처", + "item.antarchy.shrink_ray": "축소 광선총", + "item.antarchy.growth_ray": "거대화 광선총", + "tooltip.antarchy.shrink_ray": "대상을 영구적으로 축소합니다. 꾹 눌러 충전하세요.", + "tooltip.antarchy.growth_ray": "대상을 영구적으로 거대화합니다. 꾹 눌러 충전하세요.", + "tooltip.antarchy.size_ray_milk_reset": "우유를 마시면 이 효과가 초기화됩니다.", + "tooltip.antarchy.reverie_bottle.capture": "유리병을 들고 레버리을 우클릭하여 담습니다.", + "tooltip.antarchy.reverie_bottle.release": "우클릭하여 레버리을 풀어줍니다.", + "item.antarchy.gravity_gun": "그래비티 건", + "item.antarchy.portal_gun": "포탈 건", + "item.antarchy.portal_gun_atlas": "아틀라스 포탈 건", + "item.antarchy.portal_gun_p_body": "피바디 포탈 건", + "item.antarchy.portal_gun_craisin": "크레이신 포탈 건", + "item.antarchy.portal_gun_laynce": "라인스 포탈 건", + "item.antarchy.diamond_minecart": "다이아몬드 광산 수레", + "item.antarchy.cogwheel_pet": "톱니바퀴 펫", + "item.antarchy.fire_dragon_pet": "파이어 드래곤 펫", + "item.antarchy.ice_dragon_pet": "아이스 드래곤 펫", + "item.antarchy.lightning_dragon_pet": "라이트닝 드래곤 펫", + "item.antarchy.gorgon_pet": "고르곤 펫", + "item.antarchy.apple_cow_spawn_egg": "사과 소 생성 알", + "item.antarchy.red_ant_spawn_egg": "붉은 개미 생성 알", + "item.antarchy.brown_ant_spawn_egg": "갈색 개미 생성 알", + "item.antarchy.rainbow_ant_spawn_egg": "무지개 개미 생성 알", + "item.antarchy.golden_apple_cow_spawn_egg": "황금 사과 소 생성 알", + "item.antarchy.enchanted_golden_apple_cow_spawn_egg": "마법이 부여된 황금 사과 소 생성 알", + "item.antarchy.dr_trayaurus_spawn_egg": "트레이어러스 박사 생성 알", + "item.antarchy.easter_bunny_spawn_egg": "이스터 토끼 생성 알", + "item.antarchy.glimmer_spawn_egg": "글리머 생성 알", + "item.antarchy.ouranwood_deer_spawn_egg": "오우란나무 사슴 생성 알", + "item.antarchy.spirit_apple": "영혼 사과", + "tooltip.antarchy.spirit_apple": "글리머를 길들입니다.", + "tooltip.antarchy.spirit_apple.eaten": "섭취 시 글리머화를 부여합니다.", + "item.antarchy.elka_spawn_egg": "엘카 생성 알", + "item.antarchy.glimmer_bottle": "글리머 병", + "item.antarchy.glimmer_bottle.contains": "포함됨: %s", + "glimmer_variant.antarchy.apple_cow": "사과 소", + "glimmer_variant.antarchy.ouranwood_deer": "오우란나무 사슴", + "glimmer_variant.antarchy.frog": "개구리", + "glimmer_variant.antarchy.ant": "개미", + "glimmer_variant.antarchy.elka": "엘카", + "entity.antarchy.glimmer.set_sit": "글리머 상태: 앉음", + "entity.antarchy.glimmer.set_follow": "글리머 상태: 따라옴", + "entity.antarchy.glimmer.set_wander": "글리머 상태: 배회함", + "entity.antarchy.glimmer.ability.ant": "개미가 %s 을(를) 상대로 당신의 사기를 북돋웁니다!", + "entity.antarchy.glimmer.ability.apple_cow": "사과 소가 울음소리를 내며 영양을 공급합니다!", + "entity.antarchy.glimmer.ability.elka": "엘카가 울부짖으며 결계를 산산조각 냅니다!", + "entity.antarchy.glimmer.ability.deer": "오우란나무 사슴이 적을 향해 돌진합니다!", + "entity.antarchy.glimmer.ability.frog": "개구리가 %s 을(를) 삼켰습니다!", + "item.antarchy.glimmer_bottle.passive.apple_cow": "패시브: 배고픔 감소 속도 25% 감소", + "item.antarchy.glimmer_bottle.ability.apple_cow": "능력: 식량이 부족할 때 울음소리를 내어 순간적인 포만감과 재생 효과를 부여합니다.", + "item.antarchy.glimmer_bottle.passive.ouranwood_deer": "패시브: 속도 증가 I", + "item.antarchy.glimmer_bottle.ability.ouranwood_deer": "능력: 적대적 몹을 향해 질주 시 돌진하여 몹들을 멀리 날려버립니다.", + "item.antarchy.glimmer_bottle.passive.frog": "패시브: 점프 강화 I", + "item.antarchy.glimmer_bottle.ability.frog": "능력: 주변의 적대적 몹을 삼켜 일정 시간 동안 더 크고 강해집니다.", + "item.antarchy.glimmer_bottle.passive.ant": "패시브: 공격 사거리 약간 증가", + "item.antarchy.glimmer_bottle.ability.ant": "능력: 거대한 적을 공격 성공 시 순간적으로 힘 II 효과를 얻습니다.", + "item.antarchy.glimmer_bottle.passive.elka": "패시브: 혈유리 보호 II", + "item.antarchy.glimmer_bottle.ability.elka": "능력: 보호 하트 중 하나가 깨질 때 울부짖으며 충격파로 산산조각 납니다.", + "advancements.antarchy.spirant_animal.title": "개미 같은 동반자", + "advancements.antarchy.spirant_animal.description": "개미 글리머를 길들이세요.", + "advancements.antarchy.hoppy_together.title": "폴짝폴짝 함께", + "advancements.antarchy.hoppy_together.description": "개구리 글리머를 길들이세요.", + "advancements.antarchy.deerly_beloved.title": "사슴스러운 존재", + "advancements.antarchy.deerly_beloved.description": "오우란나무 사슴 글리머를 길들이세요.", + "advancements.antarchy.elkcellent_choice.title": "탁월한 선택", + "advancements.antarchy.elkcellent_choice.description": "엘카 글리머를 길들이세요.", + "advancements.antarchy.apple_of_my_eye.title": "내 눈의 사과", + "advancements.antarchy.apple_of_my_eye.description": "사과 소 글리머를 길들이세요.", + "item.antarchy.dorrie_spawn_egg": "도리 생성 알", + "item.antarchy.flying_squirrel_spawn_egg": "날다람쥐 생성 알", + "item.antarchy.caterpillar_spawn_egg": "애벌레 생성 알", + "item.antarchy.butterfly_spawn_egg": "나비 생성 알", + "item.antarchy.brutalfly_spawn_egg": "브루탈플라이 생성 알", + "item.antarchy.stratoshark_spawn_egg": "스트라토샤크 생성 알", + "item.antarchy.kraken_spawn_egg": "크라켄 생성 알 ( 아, 안 돼. 소환하지 마. )", + "item.antarchy.missile_squid_spawn_egg": "미사일 오징어 생성 알", + "item.antarchy.octopus_bomb_spawn_egg": "문어 폭탄 생성 알", + "item.antarchy.nightmare_spawn_egg": "나이트메어 생성 알", + "item.antarchy.toreterror_spawn_egg": "토레테러 생성 알", + "item.antarchy.water_cannon": "물대포", + "item.antarchy.primordial_helmet": "프리모디얼 투구", + "item.antarchy.primordial_chestplate": "프리모디얼 흉감", + "item.antarchy.primordial_leggings": "프리모디얼 레깅스", + "item.antarchy.primordial_boots": "프리모디얼 부츠", + "item.antarchy.bed_bug_spawn_egg": "빈대 생성 알", + "item.antarchy.moleworm_spawn_egg": "몰웜 생성 알", + "item.antarchy.worm_spawn_egg": "웜 생성 알", + "item.antarchy.molevore_spawn_egg": "몰레보어 생성 알", + "item.antarchy.reverie_spawn_egg": "레버리 생성 알", + "item.antarchy.mantis_spawn_egg": "맨티스 생성 알", + "item.antarchy.alpha_mantis_spawn_egg": "알파 맨티스 생성 알", + "biome.antarchy.moleworm_caves": "몰웜 동굴", + "biome.antarchy.elythia_meadow": "엘리시아 초원", + "biome.antarchy.truffalo_forest": "트러팔로나무 숲", + "biome.antarchy.elythia_ocean": "엘리시아 바다", + "biome.antarchy.butterfly_fields": "나비 들판", + "biome.antarchy.ouranwood_forest": "오우란나무 숲", + "biome.antarchy.glimmering_pools": "어슴푸레한 웅덩이", + "biome.antarchy.peach_forest": "복숭아나무 숲", + "biome.antarchy.fungal_ouranwood_forest": "버섯 오우란나무 숲", + "biome.antarchy.glowcap_caves": "발광버섯 동굴", + "message.antarchy.brown_ant_activated": "갈색 개미가 목적지를 열 준비가 되었습니다.", + "message.antarchy.brown_ant_needs_reagent": "이 갈색 개미는 목적지를 열기 위해 시약이 필요합니다.", + "message.antarchy.rainbow_ant_activated": "무지개 개미가 새로운 인피니티 목적지를 향해 웅웅거립니다.", + "message.antarchy.rainbow_ant_activated_inherited": "무지개 개미가 계승된 인피니티 목적지를 향해 웅웅거립니다.", + "message.antarchy.rainbow_ant_activated_inherited_existing": "무지개 개미가 계승된 인피니티 목적지에 다시 연결됩니다.", + "message.antarchy.rainbow_ant_failed_dimension_create": "차원 생성에 실패했습니다. 인피니티 설정에 문제가 있을 수 있습니다. 재시작/재접속 후 다시 시도하세요.", + "message.antarchy.rainbow_ant_infinity_missing": "무지개 개미 차원이 작동하려면 Infinity가 설치되어 있어야 합니다.", + "message.antarchy.rainbow_ant_needs_reagent": "이 무지개 개미는 차원을 열기 위해 시약이 필요합니다.", + "message.antarchy.teleport_arrival_failed": "안전한 도착 지점을 찾지 못했습니다. 텔레포트가 취소되었습니다.", + "message.antarchy.red_ant_activated": "붉은 개미가 목적지를 열 준비가 되었습니다.", + "message.antarchy.red_ant_needs_reagent": "이 붉은 개미는 목적지를 열기 위해 시약이 필요합니다.", + "message.antarchy.termite_activated": "흰개미가 목적지를 열 준비가 되었습니다.", + "message.antarchy.termite_needs_reagent": "이 흰개미는 목적지를 열기 위해 시약이 필요합니다.", + "death.attack.spit_bug_disrespect": "%1$s이(가) 침벌레에게 모욕을 당했습니다.", + "death.attack.springbug_jump": "%1$s이(가) 스프링버그에게 기습당했습니다.", + "death.attack.hercules_beetle_obliteration": "%1$s이(가) 헤라클레스 비틀에게 흔적도 없이 말살당했습니다.", + "message.antarchy.big_bertha.mode": "빅 베르타 모드: %s", + "message.antarchy.big_bertha.mode.none": "없음", + "message.antarchy.big_bertha.mode.basilisk": "바실리스크", + "message.antarchy.big_bertha.mode.lucid": "루시드", + "message.antarchy.big_bertha.mode.nightmare": "나이트메어", + "message.antarchy.big_bertha.mode.kraken": "크라켄", + "message.antarchy.big_bertha.mode.hercules": "헤라클레스", + "message.antarchy.big_bertha.mode.molevore": "몰레보어", + "message.antarchy.big_bertha.mode.toreterror": "토레테러", + "message.antarchy.ultimate_tool.mode_3x3": "3x3 채굴 모드로 전환됨", + "message.antarchy.ultimate_tool.mode_default": "기본 채굴 모드로 전환됨", + "advancements.antarchy.hey_listen.title": "야, 들어봐!", + "advancements.antarchy.hey_listen.description": "레버리가 당신과 함께합니다.", + "advancements.antarchy.very_hungry_caterpillar.title": "배고픈 애벌레", + "advancements.antarchy.very_hungry_caterpillar.description": "애벌레가 자라도록 도우세요.", + "effect.antarchy.dread": "공포", + "effect.antarchy.dread.description": "시각 및 청각 환각을 일으킵니다.", + "effect.antarchy.paralyzed": "마비", + "effect.antarchy.paralyzed.description": "대상의 이동을 막습니다.", + "effect.antarchy.commanded": "복종", + "effect.antarchy.commanded.description": "자신을 명령한 플레이어를 위해 싸웁니다.", + "effect.antarchy.stinky": "악취", + "effect.antarchy.stinky.description": "수동적/중립적 몹을 쫓아내고 절지동물을 유인합니다.", + "effect.antarchy.gooped": "점액 범벅", + "effect.antarchy.gooped.description": "이동 속도와 공격 속도를 감소시킵니다.", + "effect.antarchy.shrinking": "축소", + "effect.antarchy.growth": "거대화", + "effect.antarchy.bloodglass_ward": "혈유리 보호", + "effect.antarchy.bloodglass_ward.description": "깨지면서 피해를 완벽히 흡수하는 하트를 부여합니다. 시간이 지나면 회복됩니다.", + "effect.antarchy.glimmering": "글리머화", + "effect.antarchy.glimmering.description": "영혼처럼 개체를 통과하고 피해를 받지 않습니다. 발걸음이 가벼워지고 더 높이 점프합니다.", + "death.attack.flytrap_mauling": "%1$s이(가) 식물에게 물어뜯겨 사망했습니다.", + "death.attack.flytrap_mauling.player": "%1$s이(가) 식물에게 물어뜯겨 사망했습니다.", + "death.attack.flytrap_swallow": "%1$s이(가) 파리잡이에게 삼켜졌습니다.", + "death.attack.flytrap_swallow.player": "%1$s이(가) 파리잡이에게 삼켜졌습니다.", + "potion.antarchy.haste": "성급함의 포션", + "potion.antarchy.strong_haste": "강한 성급함의 포션", + "tooltip.antarchy.big_bertha.mode": "모드: %s", + "tooltip.antarchy.big_bertha.toggle_mode": "Shift + 사용: 보스 모드를 전환합니다.", + "tooltip.antarchy.big_bertha.mode.none": "공격 시 소량의 추가 피해를 입힙니다.", + "tooltip.antarchy.big_bertha.mode.basilisk": "사용 시 대상을 마비시킵니다. 공격 시 독과 감속을 부여합니다.", + "tooltip.antarchy.big_bertha.mode.lucid": "공격 시 수초 동안 대상을 반전시킵니다. 자신이 반전된 동안 더 큰 피해를 입힙니다.", + "tooltip.antarchy.big_bertha.mode.nightmare": "공격 시 수초 동안 대상을 반전시킵니다. 자신이 반전된 동안 더 큰 피해를 입힙니다.", + "tooltip.antarchy.big_bertha.mode.kraken": "공격 시 추가 피해를 입힙니다. 플레이어는 공포 효과를 받고 공격 시 나약함을 부여합니다.", + "tooltip.antarchy.big_bertha.mode.hercules": "공격 시 대상을 내리치고 벼락을 내립니다.", + "tooltip.antarchy.big_bertha.mode.molevore": "공격 시 추가 피해를 입히고 대상을 공중 높이 띄웁니다.", + "tooltip.antarchy.big_bertha.mode.toreterror": "사용하여 앞으로 회전하며 몰레보어 블록을 뚫고 나아갑니다.", + "tooltip.antarchy.ultimate_tools_3x3": "Shift + 사용: 3x3 채굴을 켜거나 끕니다.", + "tooltip.antarchy.moggles.reveal": "야간 시야를 부여하고 근처 동굴을 가리킵니다.", + "tooltip.antarchy.moggles.underground": "하늘이 가려진 곳에서만 작동합니다.", + "tooltip.antarchy.cornea_ear.vision": "%s초 동안 야간 시야를 부여합니다.", + "tooltip.antarchy.mob_coming_soon": "곧 출시될 몹입니다!", + "tooltip.antarchy.gravity_gun.primary": "공격: 주변 엔티티를 날려버리거나 잡고 있는 대상을 던집니다.", + "tooltip.antarchy.gravity_gun.secondary": "사용: 엔티티나 유효한 블록을 끌어당깁니다.", + "tooltip.antarchy.gravity_gun.scroll": "Ctrl을 누른 채 스크롤: 잡고 있는 대상을 가깝게 또는 멀게 이동시킵니다.", + "tooltip.antarchy.gravity_gun.blacklist": "블랙리스트에 등록된 블록이나 엔티티에는 영향을 주지 않습니다.", + "tooltip.antarchy.portal_gun.primary": "공격: %s 포탈을 발사합니다.", + "tooltip.antarchy.portal_gun.secondary": "사용: %s 포탈을 발사합니다.", + "commands.antarchy.portalgun.clear.all": "%s개의 포탈 건 포탈을 제거했습니다.", + "commands.antarchy.portalgun.clear.owners": "%2$s 플레이어의 포탈 건 포탈 %1$s 개를 제거했습니다.", + "tooltip.antarchy.portal_gun.color.blue": "파란색", + "tooltip.antarchy.portal_gun.color.orange": "주황색", + "tooltip.antarchy.portal_gun.color.purple": "보라색", + "tooltip.antarchy.portal_gun.color.yellow": "노란색", + "tooltip.antarchy.portal_gun.color.red": "빨간색", + "tooltip.antarchy.portal_gun.color.gold": "금색", + "tooltip.antarchy.portal_gun.color.green": "초록색", + "tooltip.antarchy.portal_gun.reset": "웅크리고 사용: 활성화된 포탈을 소멸시킵니다.", + "tooltip.antarchy.antimetal_inversion": "바로 아래에 있는 엔티티를 반전시킵니다.", + "tooltip.antarchy.diamond_minecart.forward": "추후 구현될 예정입니다.", + "tooltip.antarchy.diamond_minecart.rails": " ", + "tooltip.antarchy.rainbow_sugar": "무지개 개미 차원을 활성화합니다. 차원 내에서 먹으면 집으로 돌아갑니다.", + "advancements.antarchy.visit_elythia.title": "개미 타고 능선 넘어", + "advancements.antarchy.visit_elythia.description": "갈색 개미를 사용해 엘리시아에 도달하세요.", + "advancements.antarchy.visit_thoraxis.title": "개미도 건드리면 꿈틀한다", + "advancements.antarchy.visit_thoraxis.description": "붉은 개미를 사용해 소랙시스에 도달하세요.", + "advancements.antarchy.visit_cavaryn.title": "여기가 개미굴인가요?", + "advancements.antarchy.visit_cavaryn.description": "감염된 차원인 카바린에 진입하세요.", + "advancements.antarchy.fallen_kingdom_castle.title": "내가 한때 세상을 지배했었지...", + "advancements.antarchy.fallen_kingdom_castle.description": "몰락한 왕국의 성을 발견하세요.", + "advancements.antarchy.a_lovely_world.title": "어디서 많이 본 집인데?", + "advancements.antarchy.a_lovely_world.description": "엘리시아에서 이상하리만치 익숙한 집을 발견했습니다.", + "advancements.antarchy.cops_n_robbers.title": "경찰과 도둑!", + "advancements.antarchy.cops_n_robbers.description": "추억의 구조물일 뿐이며, Sky와는 관계가 없습니다 :)", + "advancements.antarchy.fallen_king_crown.title": "내가 명하면 청크가 불러와졌지..", + "advancements.antarchy.fallen_king_crown.description": "몰락한 더 킹의 왕관을 흭득하세요.", + "advancements.antarchy.long_live_the_prince.title": "더 프린스 만세!", + "advancements.antarchy.long_live_the_prince.description": "더 프린스를 부화시키고 길들이세요.", + "advancements.antarchy.long_live_the_princess.title": "더 프린세스 만세!", + "advancements.antarchy.long_live_the_princess.description": "더 프린세를 부화시키고 길들이세요.", + "advancements.antarchy.the_lab.title": "하이 에브리원, 댄이에요!", + "advancements.antarchy.the_lab.description": "트레이어러스 박사의 연구소를 발견하세요.", + "advancements.antarchy.sweater_dreams.title": "좋은 꿈 꾸시길", + "advancements.antarchy.sweater_dreams.description": "나이트메어를 처치하세요.", + "advancements.antarchy.stone_cold.title": "차가운 바위처럼", + "advancements.antarchy.stone_cold.description": "바실리스크를 처치하세요.", + "advancements.antarchy.moley_poley.title": "몰리의 구멍", + "advancements.antarchy.moley_poley.description": "몰레보어를 처치하세요.", + "advancements.antarchy.lucid_dreams.title": "루시드 드림", + "advancements.antarchy.lucid_dreams.description": "루시드를 처치하세요.", + "advancements.antarchy.davy_jones_locker.title": "데이브 존스의 보물상자", + "advancements.antarchy.davy_jones_locker.description": "크라켄을 처치하세요", + "advancements.antarchy.shark_weak.title": "상어가 날 수 있을 때", + "advancements.antarchy.shark_weak.description": "스트라토샤크를 처치하세요.", + "advancements.antarchy.dont_let_the_bed_bugs_bite.title": "빈대가 물지 않게 조심해", + "advancements.antarchy.dont_let_the_bed_bugs_bite.description": "빈대를 처치하세요.", + "advancements.antarchy.soups_up.title": "따끈한 국물 대령이오", + "advancements.antarchy.soups_up.description": "스트라토샤크 지느러미 수프를 드세요.", + "advancements.antarchy.in_the_upside_down.title": "뒤집힌 세계", + "advancements.antarchy.in_the_upside_down.description": "최근 반전 효과에 처음으로 걸려보세요.", + "advancements.antarchy.whoever_smelt_it_dealt_it.title": "방구 뀐 놈이 성낸다", + "advancements.antarchy.whoever_smelt_it_dealt_it.description": "악취 효과에 처음으로 걸려보세요.", + "advancements.antarchy.ultimate_armor.title": "궁극의 수호자", + "advancements.antarchy.ultimate_armor.description": "얼티밋 방어구 세트를 모두 모으세요.", + "advancements.antarchy.ultimate_bow.title": "보헤미안 랩소디", + "advancements.antarchy.ultimate_bow.description": "얼티밋 활을 획득하세요.", + "advancements.antarchy.sizzling_dedication.title": "지글지글 타오르는 정성", + "advancements.antarchy.sizzling_dedication.description": "대형 프라이팬을 획득하세요.", + "advancements.antarchy.brutalfly.title": "나비처럼 날아서 벌처럼 쏘다", + "advancements.antarchy.brutalfly.description": "브루탈플라이 겉날개를 획득하세요.", + "advancements.antarchy.royal_assailant_staff.title": "날아라 내 귀요미들!", + "advancements.antarchy.royal_assailant_staff.description": "로얄 어세일런트 지팡이를 획득하세요.", + "advancements.antarchy.now_watch_me_whip.title": "이제 내 휩 댄스를 봐", + "advancements.antarchy.now_watch_me_whip.description": "이제 내 네네 댄스를 봐", + "advancements.antarchy.kill_molevore.title": "몰리의 구멍", + "advancements.antarchy.kill_molevore.description": "몰레보어를 처치하세요.", + "advancements.antarchy.water_cannon_craft.title": "물맛 좀 볼래?", + "advancements.antarchy.water_cannon_craft.description": "물대포를 획득하세요.", + "advancements.antarchy.kill_toreterror.title": "에임이 그게 뭐니, 토레테러!", + "advancements.antarchy.kill_toreterror.description": "토레테러를 처치하세요.", + "advancements.antarchy.down_with_the_king.title": "더 킹의 몰락", + "advancements.antarchy.down_with_the_king.description": "더 킹을 처치하세요.", + "advancements.antarchy.down_with_the_queen.title": "더 퀸의 몰락", + "advancements.antarchy.down_with_the_queen.description": "더 퀸을 처치하세요.", + "advancements.antarchy.challenge_games.title": "서바이벌 게임!", + "advancements.antarchy.challenge_games.description": "폐허가 된 아레나에 진입하세요.", + "advancements.antarchy.bugged_out.title": "벌레 잡는 사냥꾼", + "advancements.antarchy.bugged_out.description": "알파 맨티스를 처치하세요.", + "death.attack.bed_bug_bite": "%1$s이(가) 빈대에게 물려 뜯겼습니다.", + "death.attack.bed_bug_bite.player": "%1$s이(가) %2$s와(과) 싸우던 중 빈대에게 물려 뜯겼습니다.", + "death.attack.moon_vacuum": "%1$s이(가) 우주의 진공 속으로 빨려 들어갔습니다.", + "death.attack.moon_vacuum.player": "%1$s이(g) %2$s와(과) 싸우던 중 우주의 진공 속으로 빨려 들어갔습니다.", + "message.antarchy.dread_too_scared_to_sleep": "너무 무서워서 잠에 들 수 없습니다.", + "death.attack.kraken_mauling": "%1$s이(가) 크라켄에게 심해 속으로 끌려갔습니다.", + "death.attack.kraken_mauling.player": "%1$s이(가) %2$s와(과) 싸우던 중 크라켄에게 심해 속으로 끌려갔습니다.", + "death.attack.kraken_lightning": "%1$s이(가) 크라켄의 폭풍우 벼락에 맞아 번갯불이 되었습니다.", + "death.attack.kraken_lightning.player": "%1$s이(가) %2$s와(과) 싸우던 중 크라켄의 폭풍우 벼락에 맞았습니다.", + "death.attack.rpo_launcher_blast": "%1$s이(가) R.P.O.에게 기습 RKO를 맞고 뻗었습니다.", + "death.attack.rpo_launcher_blast.player": "%1$s이(가) %2$s와(과) 싸우던 중 R.P.O.에게 기습 RKO를 맞았습니다.", + "death.attack.nightmare_mauling": "%1$s이(가) 나이트메어에게 집어삼켜졌습니다.", + "death.attack.nightmare_mauling.player": "%1$s이(가) %2$s와(과) 싸우던 중 나이트메어에게 집어삼켜졌습니다.", + "death.attack.basilisk_bite": "%1$s이(가) 바실리스크에게 한입거리로 통째로 꿀꺽당했습니다.", + "death.attack.basilisk_bite.player": "%1$s이(가) %2$s와(과) 싸우던 중 바실리스크에게 꿀꺽당했습니다.", + "death.attack.emperor_scorpion_sting": "%1$s이(가) 엠퍼러 스콜피온의 독침에 찔렸습니다.", + "death.attack.emperor_scorpion_sting.player": "%1$s이(가) %2$s와(과) 싸우던 중 엠퍼러 스콜피온의 독침에 찔렸습니다.", + "death.attack.cornea_stalk_prick": "%1$s이(가) 각막 줄기에 찔려 사망했습니다.", + "death.attack.toreterror_spin": "%1$s이(가) 토레테러의 팽이 회전 공격에 휠체어 신세가 되었습니다.", + "death.attack.toreterror_spin.player": "%1$s이(가) %2$s와(과) 싸우던 중 토레테러의 팽이 공격에 찢겼습니다.", + "death.attack.toreterror_jump": "%1$s이(가) 토레테러에게 바닥까지 짓눌려 찌그러졌습니다.", + "death.attack.toreterror_jump.player": "%1$s이(가) %2$s와(과) 싸우던 중 토레테러에게 짓눌렸습니다.", + "death.attack.water_soaked": "%1$s이(가) %2$s의 물폭탄에 푹 젖어 drowned 당했습니다.", + "death.attack.water_soaked.player": "%1$s이(가) %2$s의 물폭탄에 푹 젖어 drowned 당했습니다.", + "entity.antarchy.lucid": "루시드", + "item.antarchy.lucid_spawn_egg": "루시드 생성 알", + "item.antarchy.lucid_eye": "루시드의 눈", + "entity.antarchy.scorpion": "스콜피온", + "item.antarchy.scorpion_spawn_egg": "스콜피온 생성 알", + "entity.antarchy.basilisk": "바실리스크", + "item.antarchy.basilisk_spawn_egg": "바실리스크 생성 알", + "entity.antarchy.emperor_scorpion": "엠퍼러 스콜피온", + "item.antarchy.emperor_scorpion_spawn_egg": "엠퍼러 스콜피온 생성 알", + "item.antarchy.emperor_scorpion_stinger": "엠퍼러 스콜피온 독침", + "item.antarchy.lucid_pearl": "루시드 진주", + "tooltip.antarchy.lucid_pearl": "반전 중력을 가진 투사체를 던집니다.", + "tooltip.antarchy.lucid_pearl.detail": "낙하 지점으로 텔레포트하고 반전 효과를 부여합니다.", + "subtitles.antarchy.squidzooka_fire": "오징어주카 발사됨", + "subtitles.antarchy.undertrial_detect_player": "언더트라이얼 생성기가 플레이어를 감지함", + "subtitles.antarchy.size_ray_charge": "크기 조절 광선 충전됨", + "subtitles.antarchy.size_ray_fire": "크기 조절 광선 발사됨", + "subtitles.antarchy.ant_ambient": "개미가 지저귐", + "subtitles.antarchy.ant_idle": "개미가 서성거림", + "subtitles.antarchy.ant_hurt": "개미가 다침", + "subtitles.antarchy.ant_bite": "개미가 물음", + "subtitles.antarchy.ant_gather": "개미가 모임", + "subtitles.antarchy.ant_nest": "개미집이 바스락거림", + "subtitles.antarchy.stratoshark_bite": "스트라토샤크가 물음", + "subtitles.antarchy.stratoshark_idle": "스트라토샤크가 서성거림", + "subtitles.antarchy.stratoshark_hurt": "스트라토샤크가 다침", + "subtitles.antarchy.stratoshark_death": "스트라토샤크가 죽음", + "subtitles.antarchy.stratoshark_fly": "스트라토샤크가 날아다님", + "subtitles.antarchy.caterpillar_idle": "애벌레가 서성거림", + "subtitles.antarchy.caterpillar_hurt": "애벌레가 다침", + "subtitles.antarchy.caterpillar_crawl": "애벌레가 기어감", + "subtitles.antarchy.butterfly_hurt": "나비가 다침", + "subtitles.antarchy.brutalfly_idle": "브루탈플라이가 서성거림", + "subtitles.antarchy.brutalfly_death": "브루탈플라이가 죽음", + "subtitles.antarchy.thoraxis_nightmare_wastes_ambient": "나이트메어 황무지가 웅웅거림", + "subtitles.antarchy.thoraxis_nightmare_wastes_additions": "나이트메어 황무지가 술렁임", + "subtitles.antarchy.thoraxis_nightmare_wastes_mood": "나이트메어 황무지가 속삭임", + "subtitles.antarchy.thoraxis_dream_dunes_ambient": "꿈의 사구가 속삭임", + "subtitles.antarchy.thoraxis_dream_dunes_additions": "꿈의 사구가 바스락거림", + "subtitles.antarchy.thoraxis_dream_dunes_mood": "꿈의 사구가 탄식함", + "subtitles.antarchy.thoraxis_lucid_pools_ambient": "루시드 웅덩이가 웅웅거림", + "subtitles.antarchy.dimensional_tear_open": "차원의 균열이 열림", + "subtitles.antarchy.dimensional_tear_idle": "차원의 균열이 아지랑이침", + "subtitles.antarchy.dimensional_tear_creature_leaves": "생물체가 균열에서 나타남", + "subtitles.antarchy.dimensional_tear_close": "차원의 균열이 닫힘", + "subtitles.antarchy.thoraxis_lucid_pools_additions": "루시드 웅덩이가 저주함", + "subtitles.antarchy.thoraxis_lucid_pools_mood": "루시드 웅덩이가 중얼거림", + "subtitles.antarchy.lucid_ambient": "루시드가 웅웅거림", + "subtitles.antarchy.lucid_flying": "루시드가 퍼덕거림", + "subtitles.antarchy.lucid_attack": "루시드가 공격함", + "subtitles.antarchy.lucid_bolt": "루시드 번개가 발사됨", + "subtitles.antarchy.lucid_hurt": "루시드가 다침", + "subtitles.antarchy.lucid_death": "루시드가 죽음", + "subtitles.antarchy.reverie_idle": "레버리가 맴돌음", + "subtitles.antarchy.reverie_hurt": "레버리가 다침", + "subtitles.antarchy.reverie_worry": "레버리가 걱정함", + "subtitles.antarchy.reverie_save": "레버리가 구출함", + "subtitles.antarchy.reverie_join_player": "레버리가 합류함", + "subtitles.antarchy.reverie_alert": "레버리가 경고함", + "subtitles.antarchy.flying_squirrel_idle": "날다람쥐가 지저귐", + "subtitles.antarchy.flying_squirrel_beg": "날다람쥐가 먹이를 구걸함", + "subtitles.antarchy.flying_squirrel_nut": "날다람쥐가 먹이를 먹음", + "subtitles.antarchy.flying_squirrel_glide_loop": "날다람쥐가 활공함", + "subtitles.antarchy.flying_squirrel_hurt": "날다람쥐가 다침", + "subtitles.antarchy.flying_squirrel_death": "날다람쥐가 죽음", + "subtitles.antarchy.nightmare_idle": "나이트메어가 으르렁거림", + "subtitles.antarchy.nightmare_hurt": "나이트메어가 다침", + "subtitles.antarchy.nightmare_roar": "나이트메어가 포효함", + "subtitles.antarchy.nightmare_death": "나이트메어가 죽음", + "subtitles.antarchy.nightmare_bite": "나이트메어가 물음", + "subtitles.antarchy.nightmare_flap": "나이트메어가 날갯짓함", + "subtitles.antarchy.flytrap_attack": "파리잡이가 공격함", + "subtitles.antarchy.flytrap_grab": "파리잡이가 붙잡음", + "subtitles.antarchy.flytrap_hurt": "파리잡이가 다침", + "subtitles.antarchy.flytrap_death": "파리잡이가 죽음", + "subtitles.antarchy.flytrap_hiss": "파리잡이가 슉슉 소리를 냄", + "subtitles.antarchy.flytrap_growl": "파리잡이가 으르렁거림", + "subtitles.antarchy.gravity_gun_pickup": "그래비티 건이 집어 올림", + "subtitles.antarchy.gravity_gun_drop": "그래비티 건이 떨어뜨림", + "subtitles.antarchy.gravity_gun_hold_loop": "그래비티 건이 웅웅거림", + "subtitles.antarchy.gravity_gun_launch": "그래비티 건이 발사함", + "subtitles.antarchy.gravity_gun_dryfire": "그래비티 건이 빈 총소리를 냄", + "subtitles.antarchy.antimetal_place": "안티메탈이 쨍그랑거림", + "subtitles.antarchy.antimetal_step": "안티메탈이 찰깍거림", + "subtitles.antarchy.antimetal_scaffold": "안티메탈 비계가 덜컹거림", + "subtitles.antarchy.portal_gun_fire_blue": "포탈 건 발사됨", + "subtitles.antarchy.portal_gun_fire_orange": "포탈 건 발사됨", + "subtitles.antarchy.portal_gun_invalid_surface": "포탈 건이 픽셀거림", + "subtitles.antarchy.portal_open_blue": "파란색 포탈이 열림", + "subtitles.antarchy.portal_open_orange": "주황색 포탈이 열림", + "subtitles.antarchy.portal_fizzle": "포탈이 소멸함", + "subtitles.antarchy.portal_ambient": "포탈이 웅웅거림", + "subtitles.antarchy.portal_enter": "개체가 포탈로 들어감", + "subtitles.antarchy.portal_exit": "개체가 포탈에서 나와짐", + "subtitles.antarchy.bed_bug_ambient": "빈대가 지저귐", + "subtitles.antarchy.bed_bug_hurt": "빈대가 다침", + "subtitles.antarchy.bed_bug_attack": "빈대가 물음", + "subtitles.antarchy.wasp_idle": "말벌이 윙윙거림", + "subtitles.antarchy.wasp_hurt": "말벌이 다침", + "subtitles.antarchy.wasp_attack": "말벌이 쏘음", + "subtitles.antarchy.wasp_death": "말벌이 죽음", + "subtitles.antarchy.scorpion_ambient": "스콜피온이 달그락거림", + "subtitles.antarchy.scorpion_hurt": "스콜피온이 다침", + "subtitles.antarchy.scorpion_attack": "스콜피온이 공격함", + "subtitles.antarchy.emperor_scorpion_ambient": "엠퍼러 스콜피온이 달그락거림", + "subtitles.antarchy.emperor_scorpion_hurt": "엠퍼러 스콜피온이 다침", + "subtitles.antarchy.emperor_scorpion_attack": "엠퍼러 스콜피온이 공격함", + "subtitles.antarchy.emperor_scorpion_roar": "엠퍼러 스콜피온이 포효함", + "subtitles.antarchy.moleworm_ambient": "몰웜이 바스락거림", + "subtitles.antarchy.moleworm_hurt": "몰웜이 다침", + "subtitles.antarchy.moleworm_attack": "몰웜이 공격함", + "subtitles.antarchy.moleworm_dig": "몰웜이 땅을 파냄", + "subtitles.antarchy.molevore_ambient": "몰레보어가 웅웅거림", + "subtitles.antarchy.molevore_hurt": "몰레보어가 다침", + "subtitles.antarchy.molevore_attack": "몰레보어가 공격함", + "subtitles.antarchy.molevore_dig": "몰레보어가 땅을 파냄", + "subtitles.antarchy.duct_tape_use": "덕트 테이프가 찢어짐", + "subtitles.antarchy.worm_hook_flying": "웜 갈고리가 쌩 하고 날아감", + "subtitles.antarchy.blood_crystal_katana_dash": "혈수정 카타나가 돌진함", + "subtitles.antarchy.blood_crystal_armor_equip": "혈수정 방어구를 착용함", + "subtitles.antarchy.bloodglass_ward_heart_break": "혈유리 하트가 깨짐", + "subtitles.antarchy.bloodglass_ward_heart_regen": "혈유리 하트가 재생됨", + "subtitles.antarchy.potent_nyxite_hypnotic_gas": "강력한 닉사이트가 슉슉 소리를 냄", + "subtitles.antarchy.potent_nyxite_geyser_eruption": "강력한 닉사이트가 분출함", + "subtitles.antarchy.potent_nyxite_geyser_continuous": "강력한 닉사이트 간헐천이 포효함", + "subtitles.antarchy.missile_squid_ambient": "미사일 오징어가 웅웅거림", + "subtitles.antarchy.missile_squid_hurt": "미사일 오징어가 다침", + "subtitles.antarchy.missile_squid_death": "미사일 오징어가 죽음", + "subtitles.antarchy.missile_squid_attack": "미사일 오징어가 공격함", + "subtitles.antarchy.kraken_flying_loop": "크라켄이 활공함", + "subtitles.antarchy.kraken_flying_sideways_loop": "크라켄이 선회함", + "subtitles.antarchy.kraken_attack": "크라켄이 덮침", + "subtitles.antarchy.kraken_spin": "크라켄이 회전함", + "subtitles.antarchy.kraken_roar": "크라켄이 포효함", + "subtitles.antarchy.kraken_summon": "크라켄이 출현함", + "subtitles.antarchy.kraken_hurt": "크라켄이 다침", + "subtitles.antarchy.kraken_death": "크라켄이 죽음", + "subtitles.antarchy.basilisk_idle_loop": "바실리스크가 서성거림", + "subtitles.antarchy.basilisk_slither_loop": "바실리스크가 기어감", + "subtitles.antarchy.basilisk_bite": "바실리스크가 물음", + "subtitles.antarchy.basilisk_hiss": "바실리스크가 슉슉 소리를 냄", + "subtitles.antarchy.basilisk_hurt": "바실리스크가 다침", + "subtitles.antarchy.basilisk_death": "바실리스크가 죽음", + "subtitles.antarchy.bomber_walk": "밤버가 걸어감", + "subtitles.antarchy.bomber_knock": "밤버가 맞음", + "subtitles.antarchy.bomber_explode": "밤버 도화선이 타들어감", + "subtitles.antarchy.toreterror_idle": "토레테러가 서성거림", + "subtitles.antarchy.toreterror_hurt": "토레테러가 다침", + "subtitles.antarchy.toreterror_death": "토레테러가 죽음", + "subtitles.antarchy.toreterror_bomber_fire": "토레테러가 밤버를 발사함", + "subtitles.antarchy.toreterror_spin": "토레테러가 회전함", + "subtitles.antarchy.toreterror_ricochet": "토레테러가 튕겨 나감", + "subtitles.antarchy.water_cannon_fire": "물대포가 발사됨", + "subtitles.antarchy.toreterror_jump_up": "토레테러가 도약함", + "subtitles.antarchy.toreterror_jump_land": "토레테러가 착지함", + "subtitles.antarchy.king_idle": "더 킹이 웅웅거림", + "subtitles.antarchy.king_walk": "더 킹이 발걸음을 옮김", + "subtitles.antarchy.king_fly_loop": "더 킹이 날갯짓함", + "subtitles.antarchy.king_wing_flap": "더 킹이 날개를 치솟음", + "subtitles.antarchy.king_bite": "더 킹이 물음", + "subtitles.antarchy.king_stomp": "더 킹이 발을 구름", + "subtitles.antarchy.king_roar": "더 킹이 포효함", + "subtitles.antarchy.king_hurt": "더 킹이 맞음", + "subtitles.antarchy.king_death": "더 킹이 쓰러짐", + "subtitles.antarchy.king_beam_shoot": "더 킹이 빔을 발사함", + "subtitles.antarchy.king_fireball_shoot": "더 킹이 화염을 내뿜음", + "subtitles.antarchy.king_ice_spikes": "더 킹이 얼음 가시를 소환함", + "subtitles.antarchy.king_decree_cast": "더 킹이 칙령을 선포함", + "subtitles.antarchy.king_decree": "더 킹이 칙령을 내림", + "subtitles.antarchy.king_success": "더 킹이 복종을 인정함", + "subtitles.antarchy.king_judgement": "더 킹이 심판을 내림", + "subtitles.antarchy.queen_idle": "더 퀸이 중얼거림", + "subtitles.antarchy.queen_walk": "더 퀸이 발걸음을 옮김", + "subtitles.antarchy.queen_fly_loop": "더 퀸이 날갯짓함", + "subtitles.antarchy.queen_wing_flap": "더 퀸이 날개를 치솟음", + "subtitles.antarchy.queen_bite": "더 퀸이 물음", + "subtitles.antarchy.queen_stomp": "더 퀸이 발을 구름", + "subtitles.antarchy.queen_roar": "더 퀸이 포효함", + "subtitles.antarchy.queen_hurt": "더 퀸이 맞음", + "subtitles.antarchy.queen_death": "더 퀸이 쓰러짐", + "subtitles.antarchy.queen_beam_shoot": "더 퀸이 빔을 발사함", + "subtitles.antarchy.queen_beam_start": "더 퀸이 빔을 충전함", + "subtitles.antarchy.queen_beam_loop": "더 퀸이 빔을 휩쓸음", + "subtitles.antarchy.queen_beam_end": "더 퀸의 빔이 희미해짐", + "subtitles.antarchy.queen_black_hole_shoot": "더 퀸이 특이점을 찢어 엶", + "subtitles.antarchy.queen_cast_shoot": "더 퀸이 주문을 외움", + "subtitles.antarchy.prince_idle": "더 프린스가 지저귐", + "subtitles.antarchy.prince_bite": "더 프린스가 물음", + "subtitles.antarchy.prince_shoot": "더 프린스가 일사불란하게 뱉어냄", + "subtitles.antarchy.prince_fly": "더 프린스가 날갯짓함", + "subtitles.antarchy.prince_step": "더 프린스가 발걸음을 옮김", + "subtitles.antarchy.princess_idle": "더 프린세스가 지저귐", + "subtitles.antarchy.princess_bite": "더 프린세스가 물음", + "subtitles.antarchy.princess_shoot": "더 프린세스가 일사불란하게 뱉어냄", + "subtitles.antarchy.princess_fly": "더 프린세스가 날갯짓함", + "subtitles.antarchy.princess_step": "더 프린세스가 발걸음을 옮김", + "subtitles.antarchy.stinky_fly": "악취 파리가 윙윙거림", + "item.minecraft.potion.effect.inversion": "반전의 물약", + "item.minecraft.potion.effect.long_inversion": "반전의 물약", + "item.minecraft.splash_potion.effect.inversion": "투척용 반전의 물약", + "item.minecraft.splash_potion.effect.long_inversion": "투척용 반전의 물약", + "item.minecraft.lingering_potion.effect.inversion": "잔류형 반전의 물약", + "item.minecraft.lingering_potion.effect.long_inversion": "잔류형 반전의 물약", + "item.minecraft.tipped_arrow.effect.inversion": "반전의 화살", + "item.minecraft.tipped_arrow.effect.long_inversion": "반전의 화살", + "item.minecraft.potion.effect.command": "지휘의 물약", + "item.minecraft.potion.effect.long_command": "지휘의 물약", + "item.minecraft.splash_potion.effect.command": "투척용 지휘의 물약", + "item.minecraft.splash_potion.effect.long_command": "투척용 지휘의 물약", + "item.minecraft.lingering_potion.effect.command": "잔류형 지휘의 물약", + "item.minecraft.lingering_potion.effect.long_command": "잔류형 지휘의 물약", + "item.minecraft.tipped_arrow.effect.command": "지휘의 화살", + "item.minecraft.tipped_arrow.effect.long_command": "지휘의 화살", + "item.minecraft.potion.effect.time_dilation": "시간 팽창의 물약", + "item.minecraft.potion.effect.long_time_dilation": "강력한 시간 팽창의 물약", + "item.minecraft.splash_potion.effect.time_dilation": "투척용 시간 팽창의 물약", + "item.minecraft.splash_potion.effect.long_time_dilation": "투척용 강력한 시간 팽창의 물약", + "item.minecraft.lingering_potion.effect.time_dilation": "잔류형 시간 팽창의 물약", + "item.minecraft.lingering_potion.effect.long_time_dilation": "잔류형 강력한 시간 팽창의 물약", + "item.minecraft.tipped_arrow.effect.time_dilation": "시간 팽창의 화살", + "item.minecraft.tipped_arrow.effect.long_time_dilation": "강력한 시간 팽창의 화살", + "item.minecraft.potion.effect.time_contraction": "시간 수축의 물약", + "item.minecraft.splash_potion.effect.time_contraction": "투척용 시간 수축의 물약", + "item.minecraft.lingering_potion.effect.time_contraction": "잔류형 시간 수축의 물약", + "item.minecraft.tipped_arrow.effect.time_contraction": "시간 수축의 화살", + "item.minecraft.potion.effect.long_time_contraction": "강력한 시간 수축의 물약", + "item.minecraft.splash_potion.effect.long_time_contraction": "투척용 강력한 시간 수축의 물약", + "item.minecraft.lingering_potion.effect.long_time_contraction": "잔류형 강력한 시간 수축의 물약", + "item.minecraft.tipped_arrow.effect.long_time_contraction": "강력한 시간 수축의 화살", + "item.minecraft.potion.effect.paralysis": "마비의 물약", + "item.minecraft.potion.effect.long_paralysis": "마비의 물약", + "item.minecraft.splash_potion.effect.paralysis": "투척용 마비의 물약", + "item.minecraft.splash_potion.effect.long_paralysis": "투척용 마비의 물약", + "item.minecraft.lingering_potion.effect.paralysis": "잔류형 마비의 물약", + "item.minecraft.lingering_potion.effect.long_paralysis": "잔류형 마비의 물약", + "item.minecraft.tipped_arrow.effect.paralysis": "마비의 화살", + "item.minecraft.tipped_arrow.effect.long_paralysis": "마비의 화살", + "item.minecraft.potion.effect.shrinking": "축소의 물약", + "item.minecraft.potion.effect.strong_shrinking": "축소의 물약 II", + "item.minecraft.potion.effect.extreme_shrinking": "축소의 물약 III", + "item.minecraft.splash_potion.effect.shrinking": "투척용 축소의 물약", + "item.minecraft.splash_potion.effect.strong_shrinking": "투척용 축소의 물약 II", + "item.minecraft.splash_potion.effect.extreme_shrinking": "투척용 축소의 물약 III", + "item.minecraft.lingering_potion.effect.shrinking": "잔류형 축소의 물약", + "item.minecraft.lingering_potion.effect.strong_shrinking": "잔류형 축소의 물약 II", + "item.minecraft.lingering_potion.effect.extreme_shrinking": "잔류형 축소의 물약 III", + "item.minecraft.tipped_arrow.effect.shrinking": "축소의 화살", + "item.minecraft.tipped_arrow.effect.strong_shrinking": "축소의 화살 II", + "item.minecraft.tipped_arrow.effect.extreme_shrinking": "축소의 화살 III", + "item.minecraft.potion.effect.growing": "거대화의 물약", + "item.minecraft.potion.effect.strong_growing": "거대화의 물약 II", + "item.minecraft.potion.effect.extreme_growing": "거대화의 물약 III", + "item.minecraft.splash_potion.effect.growing": "투척용 거대화의 물약", + "item.minecraft.splash_potion.effect.strong_growing": "투척용 거대화의 물약 II", + "item.minecraft.splash_potion.effect.extreme_growing": "투척용 거대화의 물약 III", + "item.minecraft.lingering_potion.effect.growing": "잔류형 거대화의 물약", + "item.minecraft.lingering_potion.effect.strong_growing": "잔류형 거대화의 물약 II", + "item.minecraft.lingering_potion.effect.extreme_growing": "잔류형 거대화의 물약 III", + "item.minecraft.tipped_arrow.effect.growing": "거대화의 화살", + "item.minecraft.tipped_arrow.effect.strong_growing": "거대화의 화살 II", + "item.minecraft.tipped_arrow.effect.extreme_growing": "거대화의 화살 III", + "item.minecraft.potion.effect.dread": "공포의 물약", + "item.minecraft.potion.effect.long_dread": "공포의 물약", + "item.minecraft.splash_potion.effect.dread": "투척용 공포의 물약", + "item.minecraft.splash_potion.effect.long_dread": "투척용 공포의 물약", + "item.minecraft.lingering_potion.effect.dread": "잔류형 공포의 물약", + "item.minecraft.lingering_potion.effect.long_dread": "잔류형 공포의 물약", + "item.minecraft.tipped_arrow.effect.dread": "공포의 화살", + "item.minecraft.tipped_arrow.effect.long_dread": "공포의 화살", + "item.minecraft.potion.effect.stinky": "악취의 물약", + "item.minecraft.potion.effect.long_stinky": "악취의 물약", + "item.minecraft.splash_potion.effect.stinky": "투척용 악취의 물약", + "item.minecraft.splash_potion.effect.long_stinky": "투척용 악취의 물약", + "item.minecraft.lingering_potion.effect.stinky": "잔류형 악취의 물약", + "item.minecraft.lingering_potion.effect.long_stinky": "잔류형 악취의 물약", + "item.minecraft.tipped_arrow.effect.stinky": "악취의 화살", + "item.minecraft.tipped_arrow.effect.long_stinky": "악취의 화살", + "item.minecraft.potion.effect.haste": "성급함의 물약", + "item.minecraft.potion.effect.strong_haste": "성급함의 물약 II", + "item.minecraft.splash_potion.effect.haste": "투척용 성급함의 물약", + "item.minecraft.splash_potion.effect.strong_haste": "투척용 성급함의 물약 II", + "item.minecraft.lingering_potion.effect.haste": "잔류형 성급함의 물약", + "item.minecraft.lingering_potion.effect.strong_haste": "잔류형 성급함의 물약 II", + "item.minecraft.tipped_arrow.effect.haste": "성급함의 화살", + "item.minecraft.tipped_arrow.effect.strong_haste": "성급함의 화살 II", + "advancements.antarchy.cancel_out.title": "1 - 1 = ?", + "advancements.antarchy.cancel_out.description": "거대화 효과와 축소 효과를 동시에 받으세요.", + "advancements.antarchy.enter_the_speed_force.title": "스피드 포스의 세계로", + "advancements.antarchy.enter_the_speed_force.description": "시간 수축 효과를 받으세요.", + "advancements.antarchy.probably_wondering_how_i_got_here.title": "내가 어쩌다 여기까지 왔는지 궁금하지?", + "advancements.antarchy.probably_wondering_how_i_got_here.description": "시간 팽창 효과를 받으세요.", + "advancements.antarchy.temporal_contradiction.title": "시간의 모순", + "advancements.antarchy.temporal_contradiction.description": "시간 팽창과 시간 수축 효과를 동시에 받으세요.", + "entity.antarchy.cheep": "치프", + "item.antarchy.cheep": "치프", + "item.antarchy.cheep_spawn_egg": "치프 생성 알", + "entity.antarchy.reverie": "레버리", + "biome.antarchy.thoraxis": "소랙시스", + "biome.antarchy.nightmare_wastes": "나이트메어 황무지", + "biome.antarchy.umbral_hills": "그림자 언덕", + "biome.antarchy.lucid_pools": "루시드 웅덩이", + "biome.antarchy.dream_dunes": "꿈의 사구", + "biome.antarchy.vortex_expanse": "소용돌이 넓은 들판", + "biome.antarchy.cloud_sea": "구름 바다", + "block.antarchy.wild_corn": "야생 옥수수", + "trim_material.antarchy.blood_crystal": "혈수정", + "trim_material.antarchy.bluestone": "블루스톤", + "trim_material.antarchy.nightmare_scale": "나이트메어 비늘", + "trim_material.antarchy.uranium": "우라늄", + "trim_material.antarchy.titanium": "티타늄", + "advancements.antarchy.duct_tape.title": "이 보트를 반으로 잘랐습니다!", + "advancements.antarchy.duct_tape.description": "그리고 덕트 테이프의 힘으로 다시 붙였죠!", + "key.categories.antarchy": "앤타키", + "key.antarchy.portal_gun_zoom": "포탈 건 확대", + "key.antarchy.portal_gun_reset": "포탈 건 리셋", + "key.antarchy.brutalfly_flap": "브루탈플라이 겉날개: 날갯짓", + "advancements.antarchy.shrink_ray_craft.title": "여보, 몹들을 줄였어요", + "advancements.antarchy.shrink_ray_craft.description": "축소 광선을 제작하세요.", + "advancements.antarchy.growth_ray_craft.title": "모 아니면 도", + "advancements.antarchy.growth_ray_craft.description": "거대화 광선을 제작하세요.", + "advancements.antarchy.squidzooka_craft.title": "먹물 세례", + "advancements.antarchy.squidzooka_craft.description": "오징어주카를 제작하세요.", + "advancements.antarchy.rocket_powered_octopus.title": "로켓 추진 문어", + "advancements.antarchy.rocket_powered_octopus.description": "R.P.O. 발사기를 제작하세요.", + "advancements.antarchy.gravity_gun_craft.title": "손은 눈보다 빠르다", + "advancements.antarchy.gravity_gun_craft.description": "그래비티 건을 제작하세요.", + "advancements.antarchy.upper_craft.title": "안아줘요!! 안아달라고!!!", + "advancements.antarchy.upper_craft.description": "어퍼를 제작하세요.", + "advancements.antarchy.mucus_obtained.title": "에취!", + "advancements.antarchy.mucus_obtained.description": "점액을 구하세요.", + "block.antarchy.cavaryn_portal": "카바린 포탈", + "biome.antarchy.cavaryn_moleworm_caves": "몰웜 동굴", + "biome.antarchy.wormy_caves": "벌레 꿈틀거리는 동굴", + "block.antarchy.termite_nest": "흰개미집", + "block.antarchy.chitin_spike": "키틴 가시", + "block.antarchy.chitin_block": "키틴 블록", + "block.antarchy.myrmite": "미르마이트", + "block.antarchy.broodstone": "브루드스톤", + "block.antarchy.amber_moss_block": "호박 이끼 블록", + "block.antarchy.amber_moss_carpet": "호박 이끼 양탄자", + "block.antarchy.amber_lichen": "호박 지의류", + "block.antarchy.mucus": "점액", + "tooltip.antarchy.mucus_slippery": "설치된 블록을 얼음보다 훨씬 미끄럽게 만듭니다.", + "block.antarchy.bile_vein": "쓸개즙 덩굴", + "block.antarchy.creepvine": "크립덩굴", + "block.antarchy.crawling_blight_egg": "크롤링 블라이트 알", + "block.antarchy.skulking_fright_egg": "스컬킹 프라이트 알", + "entity.antarchy.termite": "흰개미", + "entity.antarchy.springbug": "스프링버그", + "entity.antarchy.spit_bug": "침벌레", + "entity.antarchy.stink_bug": "노린재", + "entity.antarchy.rolly_polly": "공벌레", + "entity.antarchy.crawling_blight": "크롤링 블라이트", + "entity.antarchy.skulking_fright": "스컬킹 프라이트", + "entity.antarchy.hercules_beetle": "헤라클레스 비틀", + "entity.antarchy.prince": "더 프린스", + "entity.antarchy.princess": "더 프린세스", + "entity.antarchy.king": "더 킹", + "entity.antarchy.queen": "더 퀸", + "boss.antarchy.king.phase_two": "조여오는 법률", + "boss.antarchy.king.phase_three": "왕가의 심판", + "boss.antarchy.queen.phase_two": "중력의 지배", + "boss.antarchy.queen.phase_three": "시간의 붕괴", + "entity.antarchy.manticore": "만티코어", + "entity.antarchy.royal_black_hole": "특이점", + "entity.antarchy.royal_bolt": "로얄 번개", + "block.antarchy.prince_egg": "더 프린스 알", + "block.antarchy.princess_egg": "더 프린세스 알", + "item.antarchy.springbug_spawn_egg": "스프링버그 생성 알", + "item.antarchy.spit_bug_spawn_egg": "침벌레 생성 알", + "item.antarchy.stink_bug_spawn_egg": "노린재 생성 알", + "item.antarchy.termite_spawn_egg": "흰개미 생성 알", + "item.antarchy.rolly_polly_spawn_egg": "공벌레 생성 알", + "item.antarchy.crawling_blight_spawn_egg": "크롤링 블라이트 생성 알", + "item.antarchy.skulking_fright_spawn_egg": "스컬킹 프라이트 생성 알", + "item.antarchy.hercules_beetle_spawn_egg": "헤라클레스 비틀 생성 알", + "item.antarchy.king_spawn_egg": "더 킹 생성 알", + "item.antarchy.queen_spawn_egg": "더 퀸 생성 알", + "item.antarchy.manticore_spawn_egg": "만티코어 생성 알", + "item.antarchy.prince_spawn_egg": "더 프린스 생성 알", + "item.antarchy.princess_spawn_egg": "더 프린세스 생성 알", + "item.antarchy.chitin": "키틴", + "block.antarchy.polished_broodstone": "매끄러운 브루드스톤", + "block.antarchy.chiseled_broodstone": "조각된 브루드스톤", + "block.antarchy.broodstone_bricks": "브루드스톤 벽돌", + "block.antarchy.broodstone_stairs": "브루드스톤 계단", + "block.antarchy.broodstone_slab": "브루드스톤 반 블록", + "block.antarchy.broodstone_wall": "브루드스톤 담장", + "block.antarchy.polished_broodstone_stairs": "매끄러운 브루드스톤 계단", + "block.antarchy.polished_broodstone_slab": "매끄러운 브루드스톤 반 블록", + "block.antarchy.polished_broodstone_wall": "매끄러운 브루드스톤 담장", + "block.antarchy.broodstone_brick_stairs": "브루드스톤 벽돌 계단", + "block.antarchy.broodstone_brick_slab": "브루드스톤 벽돌 반 블록", + "block.antarchy.broodstone_brick_wall": "브루드스톤 벽돌 담장", + "block.antarchy.broodstone_pillar": "브루드스톤 기둥", + "block.antarchy.myrmite_coal_ore": "미르마이트 석탄 광석", + "block.antarchy.broodstone_uranium_ore": "브루드스톤 우라늄 광석", + "block.antarchy.broodstone_titanium_ore": "브루드스톤 티타늄 광석", + "item.antarchy.raw_bug_meat": "익히지 않은 벌레 고기", + "item.antarchy.cooked_bug_meat": "익힌 벌레 고기", + "item.antarchy.hercules_horn": "헤라클레스의 뿔", + "block.antarchy.hanging_creeproots": "매달린 크립뿌리", + "block.antarchy.glowcap_mushroom": "글로우캡 버섯", + "block.antarchy.potted_glowcap_mushroom": "화분에 담긴 글로우캡 버섯", + "block.antarchy.glowcap_mushroom_block": "글로우캡 버섯 블록", + "block.antarchy.molting_vines": "탈피 덩굴", + "item.antarchy.broodfruit": "브루드열매", + "block.antarchy.springbug_egg": "스프링버그 알", + "block.antarchy.spit_bug_egg": "침벌레 알", + "block.antarchy.jerry_egg": "제리 알", + "entity.antarchy.jerry": "제리", + "item.antarchy.jerry_spawn_egg": "제리 생성 알", + "block.antarchy.biomite": "바이오마이트", + "block.antarchy.biomite_turf": "바이오마이트 잔디", + "block.antarchy.biowart": "바이오사마귀", + "block.antarchy.biowart_tendrils": "바이오사마귀 덩굴손", + "biome.antarchy.biowart_caves": "바이오사마귀 동굴", + "subtitles.antarchy.crawling_blight_growl": "크롤링 블라이트가 으르렁거림", + "subtitles.antarchy.crawling_blight_hurt": "크롤링 블라이트가 다침", + "subtitles.antarchy.crawling_blight_bite": "크롤링 블라이트가 물음", + "subtitles.antarchy.skulking_fright_snarl": "스컬킹 프라이트가 으르렁거림", + "subtitles.antarchy.skulking_fright_hurt": "스컬킹 프라이트가 다침", + "subtitles.antarchy.skulking_fright_bite": "스컬킹 프라이트가 물음", + "subtitles.antarchy.skulking_fright_fly_loop": "스컬킹 프라이트가 날아다님", + "subtitles.antarchy.stink_bug_fart": "노린재가 방귀를 뀜", + "subtitles.antarchy.cavaryn_heartbeat": "카바린이 맥동함", + "subtitles.antarchy.stink_bug_idle": "노린재가 서성거림", + "subtitles.antarchy.rolly_polly_idle": "공벌레가 서성거림", + "subtitles.antarchy.rolly_polly_wheel_mode": "공벌레가 몸을 웅크림", + "subtitles.antarchy.rolly_polly_normal_mode": "공벌레가 몸을 풀음", + "subtitles.antarchy.rolly_polly_roll": "공벌레가 구름", + "subtitles.antarchy.hercules_beetle_idle": "헤라클레스 비틀이 서성거림", + "subtitles.antarchy.hercules_beetle_hurt": "헤라클레스 비틀이 다침", + "subtitles.antarchy.hercules_beetle_attack": "헤라클레스 비틀이 공격함", + "subtitles.antarchy.hercules_beetle_cry": "헤라클레스 비틀이 포효함", + "subtitles.antarchy.hercules_beetle_charge_start": "헤라클레스 비틀이 돌진 충전을 시작함", + "subtitles.antarchy.hercules_beetle_knocked_down": "헤라클레스 비틀이 픽 쓰러짐", + "subtitles.antarchy.springbug_idle": "스프링버그가 서성거림", + "subtitles.antarchy.spit_bug_idle": "침벌레가 서성거림", + "subtitles.antarchy.springbug_hurt": "스프링버그가 다침", + "subtitles.antarchy.springbug_jump": "스프링버그가 도약함", + "subtitles.antarchy.spit_bug_hurt": "침벌레가 다침", + "subtitles.antarchy.spit_bug_spit": "침벌레가 침을 뱉음", + "subtitles.antarchy.brutalfly_spit": "브루탈플라이가 침을 뱉음", + "subtitles.antarchy.jerry_idle": "제리가 지저귐", + "subtitles.antarchy.jerry_hurt": "제리가 다침", + "subtitles.antarchy.jerry_death": "제리가 죽음", + "subtitles.antarchy.jerry_attack": "제리가 공격함", + "subtitles.antarchy.ambient_elythia_ouranwood_forest": "오우란나무 숲이 바스락거림", + "advancements.antarchy.bug_apetit.title": "벌레 맛나게 드세요!", + "advancements.antarchy.bug_apetit.description": "익힌 벌레 고기를 드세요.", + "advancements.antarchy.behavioral_correction.title": "참교육의 시간", + "advancements.antarchy.behavioral_correction.description": "어튜드 어저스터를 흭득하세요.", + "advancements.antarchy.let_it_die.title": "말라 죽게 내버려둬!", + "advancements.antarchy.let_it_die.description": "트러팔로 다발을 획득하세요.", + "advancements.antarchy.let_it_grow.title": "다시 자라나게 해줘!", + "advancements.antarchy.let_it_grow.description": "트러팔로 묘목을 키우세요.", + "advancements.antarchy.beetle_buddies.title": "비틀즈가 된 기분", + "advancements.antarchy.beetle_buddies.description": "헤라클레스 비틀을 길들이세요.", + "advancements.antarchy.herculean_task.title": "헤라클레스의 난제", + "advancements.antarchy.herculean_task.description": "헤라클레스 비틀을 처치하세요.", + "item.antarchy.tigers_eye": "호안석", + "block.antarchy.tigers_eye_block": "호안석 블록", + "item.antarchy.tigers_eye_helmet": "호안석 투구", + "item.antarchy.tigers_eye_chestplate": "호안석 흉갑", + "item.antarchy.tigers_eye_leggings": "호안석 레깅스", + "item.antarchy.tigers_eye_boots": "호안석 부츠", + "trim_material.antarchy.tigers_eye": "Tiger's Eye", + "item.antarchy.tigers_eye_armor.passive": "발각 범위 최대 10% 감소", + "item.antarchy.tigers_eye_armor.full_set": "풀 세트: 적응형 위장", + "item.antarchy.tigers_eye_armor.activate": "%s 누름: 발밑 블록의 모형으로 위장", + "item.antarchy.tigers_eye_armor.active_bonus": "활성화 중 발각 감소율 2배 적용", + "key.antarchy.tigers_eye_camouflage": "적응형 위장", + "key.antarchy.royal_inversion_toggle": "로얄 어세일런트: 반전 전환", + "message.antarchy.tiger_eye_camouflage.activated": "적응형 위장이 활성화되었습니다", + "message.antarchy.tiger_eye_camouflage.disabled": "적응형 위장이 비활성화되었습니다", + "message.antarchy.tiger_eye_camouflage.full_set_required": "호안석 방어구 풀 세트가 필요합니다", + "message.antarchy.tiger_eye_camouflage.invalid_block": "발밑에 위장할 수 있는 적절한 블록이 없습니다", + "music.antarchy.lucid_lullaby": "루시드의 자장가", + "music.antarchy.lucid_lullaby.credit": "hewo_", + "music.antarchy.whistling_void": "휘파람 부는 보이드", + "music.antarchy.whistling_void.credit": "docshrekbot", + "music.antarchy.venenatus": "베네나투스", + "music.antarchy.venenatus.credit": "hewo_", + "music.antarchy.wistful_wanderings": "아쉬운 방랑", + "music.antarchy.wistful_wanderings.credit": "hewo_", + "tooltip.antarchy.lucid_anchor.pyramid": "상단에 안티메탈 신호기 피라미드가 필요합니다", + "tooltip.antarchy.lucid_anchor.path": "아래 세상으로 막힘없는 경로가 확보되면 아래쪽으로 반전 효과를 투사합니다", + "block.antarchy.myrmite_stairs": "미르마이트 계단", + "block.antarchy.myrmite_slab": "미르마이트 반 블록", + "block.antarchy.myrmite_wall": "미르마이트 담장", + "block.antarchy.polished_myrmite": "매끄러운 미르마이트", + "block.antarchy.polished_myrmite_stairs": "매끄러운 미르마이트 계단", + "block.antarchy.polished_myrmite_slab": "매끄러운 미르마이트 반 블록", + "block.antarchy.polished_myrmite_wall": "매끄러운 미르마이트 담장", + "block.antarchy.chiseled_myrmite": "조각된 미르마이트", + "block.antarchy.myrmite_bricks": "미르마이트 벽돌", + "block.antarchy.myrmite_brick_stairs": "미르마이트 벽돌 계단", + "block.antarchy.myrmite_brick_slab": "미르마이트 벽돌 반 블록", + "block.antarchy.myrmite_brick_wall": "미르마이트 벽돌 담장", + "block.antarchy.mossy_myrmite_bricks": "이끼 낀 미르마이트 벽돌", + "block.antarchy.mossy_myrmite_brick_stairs": "이끼 낀 미르마이트 벽돌 계단", + "block.antarchy.mossy_myrmite_brick_slab": "이끼 낀 미르마이트 벽돌 반 블록", + "block.antarchy.mossy_myrmite_brick_wall": "이끼 낀 미르마이트 벽돌 담장", + "block.antarchy.myrmite_pillar": "미르마이트 기둥", + "block.antarchy.mossy_broodstone_bricks": "이끼 낀 브루드스톤 벽돌", + "block.antarchy.mossy_broodstone_brick_stairs": "이끼 낀 브루드스톤 벽돌 계단", + "block.antarchy.mossy_broodstone_brick_slab": "이끼 낀 브루드스톤 벽돌 반 블록", + "block.antarchy.mossy_broodstone_brick_wall": "이끼 낀 브루드스톤 벽돌 담장", + "block.antarchy.mossy_nyxite_bricks": "이끼 낀 닉사이트 벽돌", + "block.antarchy.mossy_nyxite_brick_stairs": "이끼 낀 닉사이트 벽돌 계단", + "block.antarchy.mossy_nyxite_brick_slab": "이끼 낀 닉사이트 벽돌 반 블록", + "block.antarchy.mossy_nyxite_brick_wall": "이끼 낀 닉사이트 벽돌 담장", + "block.antarchy.packed_loam": "굳은 양토", + "block.antarchy.loam_bricks": "양토 벽돌", + "block.antarchy.loam_brick_stairs": "양토 벽돌 계단", + "block.antarchy.loam_brick_slab": "양토 벽돌 반 블록", + "block.antarchy.loam_brick_wall": "양토 벽돌 담장", + "block.antarchy.chiseled_loam_bricks": "조각된 양토 벽돌", + "item.antarchy.cooked_cheep": "익힌 치프", + "item.antarchy.cheep_bucket": "치프 양동이", + "block.antarchy.nadir_nyxium": "나디르 닉시움", + "block.antarchy.verdant_nyxium": "신록의 닉시움", + "block.antarchy.typhonite_pillar": "타이포나이트 기둥", + "block.antarchy.nadir_fern": "나디르 고사리", + "block.antarchy.large_nadir_fern": "키 큰 나디르 고사리", + "block.antarchy.duskbell": "더스크벨", + "block.antarchy.nadir_roots": "나디르 뿌리", + "block.antarchy.verdant_roots": "신록의 뿌리", + "block.antarchy.gorevine": "핏빛 덩굴" + ,"decree.antarchy.the_sky_is_mine": "하늘은 나의 것이다" + ,"decree.antarchy.the_sky_is_mine.subtitle": "땅에 가만히 계십시오." + ,"decree.antarchy.do_not_run": "달리지 마라" + ,"decree.antarchy.do_not_run.subtitle": "달리기를 즉시 멈추십시오.." + ,"decree.antarchy.kneel": "무릎을 꿇어라" + ,"decree.antarchy.kneel.subtitle": "5초 이내에 움웅크리십시오." + ,"decree.antarchy.close_quarters": "근접전이다" + ,"decree.antarchy.close_quarters.subtitle": "6초 이내에 더 킹의 16블록 원 안으로 진입하십시오. 투사체 사용은 금지됩니다." + ,"decree.antarchy.violated": "칙령 위반" + ,"decree.antarchy.violated.subtitle": "30초 동안 체력이 절반으로 감소합니다. 더 킹의 심판을 받으십시오." + ,"effect.antarchy.royal_vitality_penalty": "왕가의 생명력 약화" + ,"decree.antarchy.come_no_closer": "더 이상 접근하지 마라" + ,"decree.antarchy.come_no_closer.subtitle": "더 킹의 내부 반경에 들어가지 마십시오." + ,"decree.antarchy.fight_me_coward": "덤벼라, 겁쟁이 녀석!" + ,"decree.antarchy.fight_me_coward.subtitle": "더 킹에게 접근하십시오." + ,"decree.antarchy.no_respite": "휴식은 없다" + ,"decree.antarchy.no_respite.subtitle": "치유가 봉인됩니다." + ,"decree.antarchy.stand_tall": "당당히 서라" + ,"decree.antarchy.stand_tall.subtitle": "더 킹 앞에서 웅크리지 마십시오" + ,"decree.antarchy.stand_your_ground": "자리를 지켜라" + ,"decree.antarchy.stand_your_ground.subtitle": "지금 서 있는 위치에서 벗어나지 마십시오." + ,"decree.antarchy.hands_off_the_crown": "왕관에 손대지 마라" + ,"decree.antarchy.hands_off_the_crown.subtitle": "더 킹을 공격하고 심판을 받으십시오." + ,"decree.antarchy.show_no_mercy": "자비를 베풀지 마라" + ,"decree.antarchy.show_no_mercy.subtitle": "끊임없이 피해를 입히십시오." + ,"menu.antarchy.royal_judgment": "왕가의 심판" + ,"enchantment.antarchy.feather_rising": "깃털 상승" + ,"enchantment.antarchy.chronosphere": "크로노스피어" + ,"entity.minecraft.villager.antarchy.computer_scientist": "게임 개발자" + ,"entity.minecraft.villager.computer_scientist": "게임 개발자" + ,"block.antarchy.ant_trap": "개미 트랩" + ,"item.antarchy.bug_spray": "벌레 퇴치 스프레이" + ,"entity.minecraft.villager.antarchy.pest_control": "해충 방제사" + ,"entity.minecraft.villager.pest_control": "해충 방제사" + ,"guide.antarchy.category.general": "일반" + ,"guide.antarchy.category.elythia": "엘리시아" + ,"guide.antarchy.category.thoraxis": "소랙시스" + ,"guide.antarchy.category.cavaryn": "카바린" + ,"guide.antarchy.missing_title": "손상된 파일" + ,"guide.antarchy.missing_disk_title": "읽을 수 없는 디스크" + ,"guide.antarchy.disk.toreterror_arena.title": "토레테러 아레나 데이터" + ,"guide.antarchy.disk.high_fructose_corn_syrup.title": "옥수수 시럽 데이터" + ,"guide.antarchy.disk.elythia.title": "엘리시아 접근 기록" + ,"guide.antarchy.disk.flying_squirrel.title": "하늘다람쥐 야외 관찰 기록" + ,"guide.antarchy.disk.basilisk_game.title": "BASILISK.EXE" + ,"guide.antarchy.disk.antman_game.title": "ANTMAN.EXE" + ,"guide.antarchy.disk.cavaryn.title": "카바린 접근 기록" + ,"guide.antarchy.disk.thoraxis.title": "소랙시스 접근 기록" + ,"guide.antarchy.disk.temporal_fields.title": "시간 조작" + ,"guide.antarchy.disk.bloodglass.title": "혈유리 생존 기록" + ,"guide.antarchy.disk.vortex.title": "보텍스" + ,"guide.antarchy.entry.toreterror.title": "토레테러" + ,"guide.antarchy.entry.toreterror_arena.subtitle": "엘리시아 대양 보스 기록" + ,"guide.antarchy.entry.toreterror_arena.description": "거북목(Testudines)에 속하는 강력한 생물입니다. 엘리시아 대양 어딘가에 있는 원형 경기장에 서식하며, 이 기록 보관소를 통해 가장 가까운 경기장의 위치를 추적할 수 있습니다. 좌표는 아래와 같습니다." + ,"guide.antarchy.entry.toreterror_arena.description2": "영역 본능이 매우 강합니다. 등껍질에 장착된 대포는 초고압의 물을 발사하므로 접근 시 상당한 주의가 필요합니다." + ,"guide.antarchy.disk.hercules_beetle.title": "헤라클레스 비틀 야외 관찰 기록" + ,"guide.antarchy.entry.hercules_beetle.title": "헤라클레스 비틀" + ,"guide.antarchy.entry.hercules_beetle.subtitle": "카바린 대형 곤충 기록" + ,"guide.antarchy.entry.hercules_beetle.description": "카바린에 서성거리는 거대한 곤충입니다. 지형을 붕괴시킬 정도로 매우 강력한 돌진 공격을 퍼부을 수 있습니다." + ,"guide.antarchy.entry.hercules_beetle.description2": "시야에 들어오는 즉시 공격성을 띠는 잡식성 생물입니다." + ,"guide.antarchy.entry.hercules_beetle.description3": "전투 중 부상을 입으면 브루드열매로 진정시킬 수 있습니다. 진정되고 나면 전투가 끝난 뒤 먹이를 준 자를 마치 존경하듯 유대감을 형성합니다." + ,"guide.antarchy.entry.brown_ant.title": "갈색 개미" + ,"guide.antarchy.entry.brown_ant.subtitle": "엘리시아로 가는 길" + ,"guide.antarchy.entry.brown_ant.description": "갈색 개미를 우클릭하면 엘리시아로 이동합니다. 이끼 낀 오우란나무 틀 내부에서 개미 한 마리를 제물로 바치면 영구히 활성화되는 포탈을 만들 수 있습니다." + ,"guide.antarchy.entry.brown_ant.description2": "개미집은 오버월드의 숲, 타이가, 평원 및 엘리시아에서 발견됩니다. 갈색 개미는 해를 끼치지 않으며 설탕으로 번식시킬 수 있습니다." + ,"guide.antarchy.entry.brown_ant.description3": "구름 바다는 하늘 높은 곳에서만 형성되며, 약 5개 지역 중 1곳꼴로 존재합니다. 토레테러 아레나는 엘리시아 대양에 위치해 있습니다." + ,"guide.antarchy.entry.termite.title": "흰개미" + ,"guide.antarchy.entry.termite.subtitle": "카바린으로 가는 길" + ,"guide.antarchy.entry.termite.description": "흰개미를 우클릭하면 카바린으로 이동하거나, 미르마이트 틀 안에서 제물로 바쳐 영구 포탈을 활성화할 수 있습니다." + ,"guide.antarchy.entry.termite.description2": "흰개미는 오버월드 숲, 타이가, 평원 및 카바린 자체에 굴을 팁니다. 주변의 목재를 갉아먹으므로 목조 건축물 근처에 두지 마십시오. 촛불 빛을 피하며 목재로 번식합니다." + ,"guide.antarchy.entry.termite.description3": "카바린에서는 한 자리에 머물며 적대적 몹을 죽이거나 알을 깨뜨리면 주의를 끌게 됩니다. 한계치에 다다르면 무리가 몰려옵니다. 다른 곳으로 이동하면 해당 지역의 경계가 가라앉습니다." + ,"guide.antarchy.entry.termite.description4": "글로우캡, 바이오사마귀, 몰웜, 벌레 및 브루딩 터널 지역은 단계별 격상 방식이 다릅니다. 대부분 마지막 웨이브에서 헤라클레스 비틀이 등장합니다." + ,"guide.antarchy.entry.red_ant.title": "붉은 개미" + ,"guide.antarchy.entry.red_ant.subtitle": "소랙시스로 가는 길" + ,"guide.antarchy.entry.red_ant.description": "붉은 개미를 우클릭하면 소랙시스로 이동하거나, 닉사이트 틀 안에서 제물로 바쳐 포탈을 활성화할 수 있습니다. 네더에 굴을 팁니다." + ,"guide.antarchy.entry.red_ant.description2": "소랙시스는 물리 법칙을 따르지 않습니다. 특히 중력이 완전히 뒤틀려 있으며 심지어 반전되어 있습니다. 위로 흐르는 액체인 안티워터와 안티워터 간헐천도 존재합니다." + ,"guide.antarchy.entry.red_ant.description3": "블루스톤은 레드스톤과 유사하지만 거꾸로 작동합니다. 뒤집힌 철도를 만드는 데에도 사용할 수 있습니다." + ,"guide.antarchy.entry.red_ant.description4": "차원의 균열은 서로 연결된 쌍으로 나타납니다. 들어가면 어디서 어떻게 나올지 아무도 모릅니다." + ,"guide.antarchy.gallery.elythia": "엘리시아에서 발견됨" + ,"guide.antarchy.gallery.cavaryn": "카바린에서 발견됨" + ,"guide.antarchy.gallery.thoraxis": "소랙시스에서 발견됨" + ,"guide.antarchy.gallery.drops": "전리품" + ,"guide.antarchy.entry.flying_squirrel.title": "날다람쥐" + ,"guide.antarchy.entry.flying_squirrel.subtitle": "엘리시아 동반자 기록" + ,"guide.antarchy.entry.flying_squirrel.description": "미쳐보고 싶어? 어디 한번 제대로 미쳐보자고." + ,"guide.antarchy.entry.flying_squirrel.description2": "날다람쥐는 견과류와 나무, 그리고 극적인 탈출을 좋아합니다. 먹이를 주어 친해진 뒤 올라탈 수 있는 풍성한 나뭇잎을 제공해 주세요." + ,"guide.antarchy.entry.flying_squirrel.description3": "머리 위에 올려둘 수도 있습니다. 아주 귀엽지만, 위를 올라다보는 게 쓸데없이 복잡해집니다." + ,"guide.antarchy.entry.flying_squirrel.description4": "떨어지더라도 당황하지 마세요. 활공 중일 수도 있으니까요. 당신이 떨어지는 거라면, 패닉에 빠져도 좋습니다." + ,"guide.antarchy.disk.glimmer.title": "글리머 야외 관찰 기록" + ,"guide.antarchy.entry.glimmer.title": "글리머" + ,"guide.antarchy.entry.glimmer.subtitle": "병에 담는 동반자 및 변종 기록" + ,"guide.antarchy.entry.glimmer.description": "글리머는 엘리시아의 글리머링 웅덩이 주변에서 자주 발견되며, 밤이 되면 오우란나무 숲, 엘리시아 초원, 복숭아 숲에서 희귀하게 나타납니다. 웅덩이에서 떨어진 야생 글리머가 낮빛에 노출되면 사라집니다." + ,"guide.antarchy.entry.glimmer.description2": "야생 글리머에게 영혼 사과를 주어 길들일 수 있습니다. 빈손으로 우클릭하면 따라오기, 방랑하기, 앉기 상태를 순환합니다." + ,"guide.antarchy.entry.glimmer.description3": "길들인 글리머는 병에 담을 수 있습니다. 빈 유리병으로 우클릭하면 쿨타임과 상태를 유지한 채 포획됩니다. 어디서든 병을 다시 우클릭하면 해방됩니다." + ,"guide.antarchy.entry.glimmer.description4": "태어난 장소에 따라 변종이 달라집니다. 글리머링 웅덩이에서는 개구리, 오우란나무 사슴, 사과 소가 등장합니다. 오우란나무 숲에서는 개구리와 사슴이, 엘리시아 초원에서는 사과 소가, 복숭아 숲에서는 엘카가 출현합니다. 개미 변종은 특정 서식지에 귀속되지 않고 무작위 확률로만 나타납니다." + ,"guide.antarchy.entry.glimmer.description5": "사과 소: 허기 소모 속도가 25% 감소하며, 허기 수치가 낮아지면 포만감과 재생 효과를 폭발적으로 부여합니다. 오우란나무 사슴: 신속 I 효과를 주며, 돌진하여 부딪힌 적대적 몹을 넉백시킵니다." + ,"guide.antarchy.entry.glimmer.description6": "개구리: 도약 강화 I 효과를 주며, 주변의 적대적 몹을 삼켜 잠시 동안 더 크게 성장하고 강화됩니다. 개미: 공격 사거리가 약간 늘어나며, 대형 개체를 타격하면 힘 II 효과를 폭발적으로 획득합니다." + ,"guide.antarchy.entry.glimmer.description7": "엘카: 혈유리 보호막 II 효과를 부여합니다. 보호막 하트가 깨지면 주변에 충격파를 분출합니다." + ,"guide.antarchy.entry.temporal_fields.title": "시간 조작" + ,"guide.antarchy.entry.temporal_fields.subtitle": "시간 팽창, 수축 및 크로노스피어 가이드" + ,"guide.antarchy.entry.temporal_fields.description": "시간 팽창과 시간 수축은 영향을 받는 개체가 세상의 시간을 얼마나 빠르게 체감하는지 변화시킵니다." + ,"guide.antarchy.entry.temporal_fields.description2": "크로노스피어를 착용하면 자신 주변에 35% 속도의 영구 영역이 생성됩니다. 영역 반경은 1레벨에서 1.5블록, 2레벨에서 2.5블록, 3레벨 이상에서 3.5블록이며, 개체들은 이 반경의 2배 범위까지 영향을 받습니다." + ,"guide.antarchy.entry.temporal_fields.description3": "이 효과는 생명체, 투사체, 떨어진 아이템, 그리고 영역 내부에서 발사된 모든 것에 해당 영역의 속도를 유지시킵니다. 중첩된 영역은 중복되지 않으며 더 느리거나 더 빠른 규칙이 우선 적용됩니다. 더 킹과 더 퀸은 이 효과에 면역입니다." + ,"guide.antarchy.entry.bloodglass.title": "혈유리" + ,"guide.antarchy.entry.bloodglass.subtitle": "반응형 방어 체계" + ,"guide.antarchy.entry.bloodglass.description": "혈수정 방어구는 피해를 한 번 흡수하고 깨진 뒤 재충전되는 혈유리 하트를 부여합니다." + ,"guide.antarchy.entry.bloodglass.description2": "장착한 방어구 부위당 하트가 1개씩 추가되며, 각 하트는 30초의 자체 쿨타임 후 재충전됩니다. 혈수정 사과를 먹으면 방어구 하트 외에 2분간 유지되는 임시 하트 2개를 추가로 얻습니다." + ,"guide.antarchy.entry.bloodglass.description3": "카타나는 보기보다 긴 사거리를 가지며, 돌진 직후 짧은 무적 판정 시간과 함께 다음 돌진까지의 짧은 쿨타임을 가집니다." + ,"guide.antarchy.entry.vortex.title": "보텍스" + ,"guide.antarchy.entry.vortex.subtitle": "보텍스 렌즈 및 폭풍의 눈 가이드" + ,"guide.antarchy.entry.vortex.description": "보텍스 렌즈는 신호에 따라 당기거나 밀어냅니다. 레드스톤 신호는 당기고, 블루스톤 신호는 밀어냅니다." + ,"guide.antarchy.entry.vortex.description2": "신호 세기에 따라 범위가 조절됩니다. 끌어당기는 반경은 1.5~10블록, 높이는 3~20블록입니다. 렌즈 자체는 아무런 피해도 입히지 않습니다." + ,"guide.antarchy.entry.vortex.description3": "폭풍의 눈은 렌즈의 신호 제어 방식과 달리 자체 조건에 따라 상승 기류와 추적 토네이도를 발사합니다." + ,"guide.antarchy.entry.nightmare.title": "나이트메어" + ,"guide.antarchy.entry.nightmare.subtitle": "소랙시스 적대적 개체 기록" + ,"guide.antarchy.entry.nightmare.description": "소랙시스 가장 깊은 지역에서 관측된 생물입니다." + ,"guide.antarchy.entry.nightmare.description2": "플레이어의 체력이 낮을수록 공격이 더욱 강력해지므로, 불리한 전투 상황이 순식간에 악화됩니다." + ,"guide.antarchy.entry.nightmare.description3": "체력이 절반 이하로 떨어지면 공중으로 떠올라 포탈 한 쌍을 열고, 그중 하나로 들어가 플레이어 뒤로 텔레포트하여 습격합니다. 사라진 포탈뿐만 아니라 두 포탈 모두 주시하십시오." + ,"guide.antarchy.entry.high_fructose_corn_syrup.title": "고농도 옥수수 시럽" + ,"guide.antarchy.entry.high_fructose_corn_syrup.subtitle": "의심스러울 정도로 인기 있는 병에 관한 기록" + ,"guide.antarchy.entry.high_fructose_corn_syrup.description": "야생에서 채집하거나 양식한 옥수수를 물병에 넣어 양조할 수 있습니다." + ,"guide.antarchy.entry.high_fructose_corn_syrup.description2": "그대로 마시면 4초 동안 멀미 효과를 일으킵니다. 의사라면 절대" + ,"guide.antarchy.entry.high_fructose_corn_syrup.description3": "제작 제작대에 아무 음식과 함께 사용하면 미국식으로 바뀝니다: 추가 영양가, 추가 포만감, 그리고 재생 효과가 폭발적으로 부여됩니다." + ,"guide.antarchy.entry.rainbow_ant.title": "무지개 개미" + ,"guide.antarchy.entry.rainbow_ant.subtitle": "차원 관문 기록" + ,"guide.antarchy.entry.rainbow_ant.description": "무지개 개미입니다. 평범한 차원 개미처럼 보이지만... 과연 그럴까요? 무지개 설탕에 특별한 친화력을 보이는 것 같습니다." + ,"guide.antarchy.entry.rainbow_ant.description2": "각 무지개 개미는 내부에 고유한 차원을 품고 있습니다. 무지개 개미야말로 다중우주로 향하는 열쇠입니다." + ,"guide.antarchy.disk.rainbow_ant.title": "무지개 개미 야외 관찰 기록" + ,"guide.antarchy.disk.brutalfly.title": "브루탈플라이 야외 관찰 기록" + ,"guide.antarchy.entry.brutalfly.title": "브루탈플라이" + ,"guide.antarchy.entry.brutalfly.subtitle": "엘리시아 적대적 개체 기록" + ,"guide.antarchy.entry.brutalfly.description": "엘리시아산 대형 나비입니다. 더 작은 친척들과 달리 고치에서 나오는 순간 미친 듯이 공격성을 띱니다." + ,"guide.antarchy.entry.brutalfly.description2": "여느 나비와 마찬가지로 브루탈플라이는 고치 상태로 시작합니다. 고치가 손상되지 않는 한 근처에 있어도 비교적 안전합니다." + ,"guide.antarchy.entry.brutalfly.description3": "브루탈플라이가 공격을 시작하면 처리하는 것 외엔 방법이 없습니다." + ,"guide.antarchy.entry.brutalfly.description4": "브루탈플라이는 엘리시아의 숲 지대에서 발견됩니다. 나뭇가지 아래에 매달린 고치를 찾아보세요." + ,"guide.antarchy.entry.easter_bunny.title": "이스터 토끼" + ,"guide.antarchy.entry.easter_bunny.subtitle": "엔티티 기록" + ,"guide.antarchy.entry.easter_bunny.description": "이스터 토끼는 온갖 생물들의 생성 알을 낳습니다! 인생은 이스터 에그와 같아서, 무엇이 나올지 전혀 알 수 없죠." + ,"guide.antarchy.entry.easter_bunny.description2": "당근, 황금 당근, 또는 민들레를 먹이로 주어 보세요." + ,"guide.antarchy.entry.duplicator_tree.title": "복제나무" + ,"guide.antarchy.entry.duplicator_tree.subtitle": "블록 기록" + ,"guide.antarchy.entry.duplicator_tree.description": "다 자란 복제나무는 옆에 비어 있고 지지되는 공간이 있으면 근처의 고체 블록을 복제합니다." + ,"guide.antarchy.entry.duplicator_tree.description2": "유체, 블록 엔티티, 그리고 다른 복제나무 블록은 복제되지 않으며, 정해진 타이머가 아닌 무작위 간격으로 복제가 발생합니다." + ,"guide.antarchy.disk.kraken.title": "크라켄 야외 관찰 기록" + ,"guide.antarchy.entry.kraken.title": "크라켄" + ,"guide.antarchy.entry.kraken.subtitle": "바다의 수호자 기록" + ,"guide.antarchy.entry.kraken.description": "바다의 파수꾼 역할을 하는 터무니없이 거대한 오징어입니다. 날씨와 바다를 거의 완벽하게 지배하며, 다른 두족류들에게 능숙하게 명령을 내립니다." + ,"guide.antarchy.entry.kraken.description2": "운이 안 좋다 싶으면 무슨 짓이든 간에 어린 친척들을 공격하지 마십시오. 불길한 징조 효과를 받은 상태에서 오징어를 죽이면 오징어가 죽은 자리에 크라켄이 소환될 수 있습니다. 불길한 징조 단계당 확률이 약 1%씩 증가합니다." + ,"guide.antarchy.entry.kraken.description3": "인근 물속에서 솟아오르므로 바다 위에서 싸움을 거십시오. 아주 희귀하게, 오징어 한 마리를 죽였을 때 한꺼번에 열 마리가 몰려오는 경우도 있습니다." + ,"guide.antarchy.entry.kraken.description4": "자신을 자극한 자들을 어떠한 수단을 써서라도 끝장내는 대량 살상 생물입니다." + ,"guide.antarchy.entry.king.title": "더 킹" + ,"guide.antarchy.entry.king.subtitle": "엘리시아 왕가 기록" + ,"guide.antarchy.entry.king.description": "더 킹은 한때 자신의 반려와 함께 엘리시아를 통치했으나, 어느 날 그녀를 베어버리고 추방했습니다. 그날 이후 그는 아래 좌표에 위치한 그들의 왕가 나무 곁에 홀로 남아 있습니다." + ,"guide.antarchy.entry.king.description2": "그에게 남은 것은 법과 질서뿐이며, 그는 그것에 집착하고 있습니다. 그는 무뎌지고 가혹해졌으며, 그에게 유일한 위안을 주는 것은 타인을 고통스럽게 하는 것뿐입니다. 그는 공격적이고, 이기적이며, 가학적이고, 강력합니다." + ,"guide.antarchy.entry.king.description3": "시야에 들어오는 즉시 공격해 오며 당신을 장난감처럼 다룰 것입니다. 전투 중에 칙령을 내립니다: 무릎을 꿇어라, 달리지 마라, 더 이상 접근하지 마라, 자비를 베풀지 마라. 그의 말은 곧 법이며, 즉시 복종하기를 기대합니다." + ,"guide.antarchy.entry.king.description4": "칙령을 위반하면 심판을 받는 30초 동안 체력이 절반으로 감소합니다. 그는 뇌전, 빙결, 화염의 원소 힘을 다루어 심판을 집행합니다." + ,"guide.antarchy.entry.king.description5": "그는 자신의 반쪽만큼 강력하진 않지만, 제대로 준비하지 않는다면 당신을 갈갈이 찢어놓을 것입니다." + ,"guide.antarchy.disk.queen.title": "더 퀸의 참화 흔적 야외 관찰 기록" + ,"guide.antarchy.entry.queen.title": "더 퀸" + ,"guide.antarchy.entry.queen.subtitle": "소랙시스 왕가 기록" + ,"guide.antarchy.entry.queen.description": "더 이상 자신의 반쪽 곁에서 모습을 드러내지 않는 그녀는 가혹하고 분노에 찬 존재가 되었습니다. 엘리시아에서 쫓겨난 그녀는 차원을 넘나드는 여정을 거치며 차원 이동 능력을 얻은 것으로 보입니다." + ,"guide.antarchy.entry.queen.description2": "그녀는 강력하고 공격적입니다. 확실한 준비가 되어 있지 않다면 접근하지 마십시오. 더 퀸은 인간에게 원한을 품고 있진 않지만, 자신의 길을 막아선다면 이 세상에서 당신을 흔적도 없이 지워버릴 것입니다." + ,"guide.antarchy.entry.queen.description3": "더 퀸이 당신을 끝장내고 나면, 그녀의 충직한 만티코어들이 남은 잔해를 처리하도록 내버려둘 것입니다." + ,"guide.antarchy.entry.queen.description4": "소랙시스 밑바닥, 아래 좌표에서 그녀를 찾을 수 있습니다. 행운을 빕니다." + ,"guide.antarchy.entry.queen.description5": "그녀는 중력을 사용하여 전투합니다: 퍼져나가는 충격파를 동반한 지면 강타, 중앙으로 끌어당기는 블랙홀, 그리고 현재 중력 방향으로 당신을 짓눌러 고정시키는 압착 영역을 생성합니다." + ,"guide.antarchy.entry.queen.description6": "최종 페이즈에서는 자신만의 시간 팽창 영역을 펼쳐 그 안에 갇힌 모든 이를 느리게 만듭니다." + ,"guide.antarchy.entry.prince.title": "더 프린스" + ,"guide.antarchy.entry.prince.subtitle": "왕가 탈것 기록" + ,"guide.antarchy.entry.prince.description": "더 프린스 알은 작은 더 프린스로 부화하며, 황금 아이템을 먹이면 성장합니다." + ,"guide.antarchy.entry.prince.description2": "다 자란 더 프린스는 길들여 안장을 얹어 비행할 수 있으며, 적들에게 원소 볼트를 발사하고 근처의 적대적 몹들에게 명령을 내릴 수 있습니다. 책임감 있게 먹이를 주십시오. 작은 비행 군주를 키우는 셈이니까요." + ,"guide.antarchy.entry.princess.title": "더 프린세스" + ,"guide.antarchy.entry.princess.subtitle": "왕가 탈것 기록" + ,"guide.antarchy.entry.princess.description": "더 프린세스 알은 작은 더 프린세스로 부화하며, 황금 아이템을 먹이면 성장합니다." + ,"guide.antarchy.entry.princess.description2": "다 자란 더 프린세스는 길들여 안장을 얹어 비행할 수 있으며, 원소 볼트를 발사하고 적들 주변에 시간 팽창 영역을 생성합니다." + ,"subtitles.antarchy.hoverboard_mount": "호버보드가 시동을 켬" + ,"subtitles.antarchy.hoverboard_dismount": "호버보드가 정지함" + ,"subtitles.antarchy.hoverboard_idle": "호버보드가 웅웅거림" , - "entity.antarchy.portal_gun_portal": "포털 건 포털", - "attribute.antarchy.entity_interaction_range": "개체 상호 작용 범위" + "advancements.antarchy.through_the_throat.title": "발밑을 조심해", + "advancements.antarchy.through_the_throat.description": "중력 협곡을 통해 밑바닥으로 추락하세요.", + "advancements.antarchy.underside_castle.title": "거꾸로 선 성", + "advancements.antarchy.underside_castle.description": "밑바닥에 매달려 있는 성을 찾아내세요.", + "advancements.antarchy.hive_awakened.title": "무자비한 모닝콜", + "advancements.antarchy.hive_awakened.description": "카바린 군단을 깨우세요.", + "advancements.antarchy.survived_the_horde.title": "군단은 기억한다", + "advancements.antarchy.survived_the_horde.description": "카바린 군단의 마지막 웨이브까지 살아남아 격퇴하세요.", + "advancements.antarchy.glimmer_keeper.title": "글리머 수집가", + "advancements.antarchy.glimmer_keeper.description": "모든 종류의 글리머를 길들이세요.", + "entity.antarchy.portal_gun_portal": "포탈 건 포탈", + "guide.antarchy.archive_folder.antlas": "안틀라스", + "guide.antarchy.archive_folder.elythia": "엘리시아", + "guide.antarchy.archive_folder.cavaryn": "카바린", + "guide.antarchy.archive_folder.thoraxis": "소랙시스" } diff --git a/common-1.20.1/src/main/resources/data/antarchy/loot_tables/spawners/undertrial.json b/common-1.20.1/src/main/resources/data/antarchy/loot_tables/spawners/undertrial.json index 6e105225..2a8037fe 100644 --- a/common-1.20.1/src/main/resources/data/antarchy/loot_tables/spawners/undertrial.json +++ b/common-1.20.1/src/main/resources/data/antarchy/loot_tables/spawners/undertrial.json @@ -27,7 +27,7 @@ { "type": "minecraft:item", "name": "antarchy:cornea_ear", - "weight": 8, + "weight": 5, "functions": [ { "function": "minecraft:set_count", @@ -42,7 +42,7 @@ { "type": "minecraft:item", "name": "antarchy:bluestone", - "weight": 10, + "weight": 6, "functions": [ { "function": "minecraft:set_count", @@ -54,6 +54,36 @@ } ] }, + { + "type": "minecraft:item", + "name": "antarchy:uranium_nugget", + "weight": 4, + "functions": [ + { + "function": "minecraft:set_count", + "count": { + "type": "minecraft:uniform", + "min": 2, + "max": 5 + } + } + ] + }, + { + "type": "minecraft:item", + "name": "antarchy:titanium_nugget", + "weight": 4, + "functions": [ + { + "function": "minecraft:set_count", + "count": { + "type": "minecraft:uniform", + "min": 2, + "max": 5 + } + } + ] + }, { "type": "minecraft:item", "name": "minecraft:diamond", diff --git a/common-1.20.1/src/main/resources/data/antarchy/recipes/blood_crystal_katana.json b/common-1.20.1/src/main/resources/data/antarchy/recipes/blood_crystal_katana.json index a298c3a0..421b126e 100644 --- a/common-1.20.1/src/main/resources/data/antarchy/recipes/blood_crystal_katana.json +++ b/common-1.20.1/src/main/resources/data/antarchy/recipes/blood_crystal_katana.json @@ -4,11 +4,11 @@ "pattern": [ " B", " B ", - "N " + "I " ], "key": { - "N": { - "item": "minecraft:netherite_ingot" + "I": { + "item": "minecraft:iron_ingot" }, "B": { "item": "antarchy:blood_crystal_shard" diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/compat/infinity/InfinityConfigRefresh.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/compat/infinity/InfinityConfigRefresh.java index c0f91f7b..d6fe5125 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/compat/infinity/InfinityConfigRefresh.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/compat/infinity/InfinityConfigRefresh.java @@ -15,6 +15,7 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; public final class InfinityConfigRefresh { private static final Map> CHECKED_FILES = Map.of( @@ -22,6 +23,7 @@ public final class InfinityConfigRefresh { "items.json", BuiltInRegistries.ITEM, "effects.json", BuiltInRegistries.MOB_EFFECT ); + private static final Set DISABLED_IDS = Set.of("antarchy:paralyzed"); private InfinityConfigRefresh() { } @@ -43,7 +45,7 @@ public final class InfinityConfigRefresh { try { Files.delete(invocationLock); Antarchy.LOGGER.info( - "[Antarchy] Infinite Dimensions config lists unregistered Antarchy content {}; its config will regenerate on next world join", + "[Antarchy] Infinite Dimensions config lists unregistered or disabled Antarchy content {}; its config will regenerate on next world join", staleIds ); } catch (Exception exception) { @@ -73,6 +75,8 @@ public final class InfinityConfigRefresh { ResourceLocation id = ResourceLocation.tryParse(key); if (id != null && Antarchy.MODID.equals(id.getNamespace()) && !registry.containsKey(id)) { staleIds.add(key); + } else if (DISABLED_IDS.contains(key) && (!entry.has("weight") || entry.get("weight").getAsDouble() > 0.0D)) { + staleIds.add(key); } } } catch (Exception exception) { diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/QueenMusicHandler.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/QueenMusicHandler.java index 69d71742..f854867f 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/QueenMusicHandler.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/QueenMusicHandler.java @@ -11,6 +11,7 @@ import net.minecraft.util.Mth; import net.minecraft.util.RandomSource; import java.util.Comparator; +import java.util.function.Supplier; public final class QueenMusicHandler { private static final double START_RADIUS = 256.0D; @@ -25,7 +26,7 @@ public final class QueenMusicHandler { return music != null; } - public static void tick(Minecraft minecraft, SoundEvent soundEvent) { + public static void tick(Minecraft minecraft, Supplier soundEventSupplier) { if (minecraft.level == null || minecraft.player == null || minecraft.isPaused() || !minecraft.player.isAlive() || minecraft.player.isRemoved() || minecraft.player.isDeadOrDying() || minecraft.screen instanceof DeathScreen) { @@ -51,6 +52,15 @@ public final class QueenMusicHandler { } if (music == null) { + SoundEvent soundEvent; + try { + soundEvent = soundEventSupplier.get(); + } catch (RuntimeException exception) { + return; + } + if (soundEvent == null) { + return; + } minecraft.getMusicManager().stopPlaying(); music = new QueenMusicSound(soundEvent); minecraft.getSoundManager().play(music); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/model/RoyalMountModel.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/model/RoyalMountModel.java index 731eb9c3..55c6a7d1 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/model/RoyalMountModel.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/client/model/RoyalMountModel.java @@ -11,6 +11,12 @@ import software.bernie.geckolib.model.GeoModel; public class RoyalMountModel extends GeoModel { private static final String[] HEADS = {"head_left", "head", "head_right"}; + private static final String[] RIDDEN_NECK_CHAIN = { + "neck", "neck2", "neck3", "head", + "neck_left", "neck_left2", "neck_left3", "head_left", + "neck_right", "neck_right2", "neck_right3", "head_right" + }; + private static final float RIDDEN_NECK_RAISE = 0.35F; @Override public ResourceLocation getModelResource(RoyalMountEntity animatable) { @@ -31,6 +37,11 @@ public class RoyalMountModel extends GeoModel { public void setCustomAnimations(RoyalMountEntity animatable, long instanceId, AnimationState animationState) { super.setCustomAnimations(animatable, instanceId, animationState); + if (animatable.isVehicle()) { + for (String name : RIDDEN_NECK_CHAIN) { + this.getBone(name).ifPresent(bone -> bone.setRotX(bone.getRotX() * RIDDEN_NECK_RAISE)); + } + } for (String head : HEADS) { this.getBone(head).ifPresent(bone -> bone.setTrackingMatrices(true)); } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/HerculesBeetleEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/HerculesBeetleEntity.java index 5c89f30e..66b497ae 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/HerculesBeetleEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/HerculesBeetleEntity.java @@ -758,10 +758,6 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl } } - private boolean isMountedFlightPoseActive() { - return this.isFlying() && (!this.onGround() || this.toLocal(this.getDeltaMovement()).y > 0.08D); - } - private void startMountedFlight() { this.pendingChargeStart = false; this.setFlying(true); @@ -1168,6 +1164,19 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl && this.getControllingPassenger() == player; } + @Override + public boolean isControlledByLocalInstance() { + if (this.level().isClientSide && this.isChargeAnimationActive()) { + return false; + } + return super.isControlledByLocalInstance(); + } + + private boolean isChargeAnimationActive() { + int state = this.getAnimationState(); + return state == ANIM_CHARGE_START || state == ANIM_CHARGE; + } + @Override @Nullable public LivingEntity getControllingPassenger() { @@ -1183,7 +1192,7 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl if (this.hasPassenger(passenger)) { Vec3 localForward = this.toLocalPlane(this.getLookAngle()); Vec3 forward = localForward.lengthSqr() > 1.0E-4D ? this.toWorld(localForward.normalize()) : this.toWorld(0.0D, 0.0D, 1.0D); - boolean mountedFlightPose = this.isMountedFlightPoseActive(); + boolean mountedFlightPose = this.isFlying(); double yOffset = mountedFlightPose ? 5.3D : 3.0D; double forwardOffset = mountedFlightPose ? 2.2D : 1.25D; if (!this.isFlying()) { diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/AntTeleportHelper.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/AntTeleportHelper.java index 3b074c6f..5210ac88 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/AntTeleportHelper.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/ant/AntTeleportHelper.java @@ -64,7 +64,7 @@ public final class AntTeleportHelper { } } - private static List collectCompanions(ServerPlayer player) { + public static List collectCompanions(ServerPlayer player) { List companions = new ArrayList<>(); if (player.getVehicle() instanceof Mob vehicle) { companions.add(vehicle); @@ -96,7 +96,7 @@ public final class AntTeleportHelper { } @Nullable - private static Mob moveCompanion(Mob companion, ServerLevel destination, Vec3 destinationPos) { + public static Mob moveCompanion(Mob companion, ServerLevel destination, Vec3 destinationPos) { companion.stopRiding(); companion.ejectPassengers(); companion.getNavigation().stop(); @@ -398,7 +398,7 @@ public final class AntTeleportHelper { * bounded area up front so unloaded terrain is not mistaken for an unsafe * destination and rejected prematurely. */ - private static void loadArrivalSearchArea(ServerLevel destination, BlockPos preferredPos, int searchRadius) { + public static void loadArrivalSearchArea(ServerLevel destination, BlockPos preferredPos, int searchRadius) { ChunkPos center = new ChunkPos(preferredPos); int chunkRadius = (searchRadius >> 4) + 1; for (int chunkX = center.x - chunkRadius; chunkX <= center.x + chunkRadius; chunkX++) { diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/brutalfly/BrutalflyEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/brutalfly/BrutalflyEntity.java index 982d2d20..0db113ae 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/brutalfly/BrutalflyEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/brutalfly/BrutalflyEntity.java @@ -40,6 +40,8 @@ import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal; import net.minecraft.world.entity.ai.navigation.FlyingPathNavigation; import net.minecraft.world.entity.ai.navigation.PathNavigation; import net.minecraft.world.entity.monster.Monster; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.ServerLevelAccessor; import net.minecraft.world.level.Level; @@ -85,7 +87,7 @@ public class BrutalflyEntity extends Monster implements GeoEntity { private static final int SPIT_WINDUP_TICKS = 16; private static final int SWIPE_TICKS = 18; private static final float SWIPE_KNOCKBACK = 2.8F; - private static final int COCOON_HIT_THRESHOLD = 3; + private static final int COCOON_HIT_THRESHOLD = 5; private static final int COCOON_HIT_COOLDOWN_TICKS = 60; private static final int COCOON_HIT_ANIM_TICKS = 30; private static final int COCOON_HATCH_ANIM_TICKS = 40; @@ -339,6 +341,12 @@ public class BrutalflyEntity extends Monster implements GeoEntity { if (nearbyPlayer != null && !nearbyPlayer.isCreative() && !nearbyPlayer.isSpectator()) { this.setTarget(nearbyPlayer); } + this.spitCooldown = 0; + } + + public float getDamageScale() { + double base = AntarchySettings.brutalflySwipeDamage(); + return base <= 0.0D ? 1.0F : (float) (this.getAttributeValue(Attributes.ATTACK_DAMAGE) / base); } public boolean isCocooned() { @@ -516,6 +524,11 @@ public class BrutalflyEntity extends Monster implements GeoEntity { this.playSound(AntarchySoundEvents.BRUTALFLY_SPIT.get(), 1.0F, 0.9F + this.random.nextFloat() * 0.2F); switch (this.getFightPhase()) { case PHASE_THREE -> { + this.launchOrb(serverLevel, origin, target, BrutalflyOrbEntity.OrbVariant.POISON, -14.0F); + this.launchOrb(serverLevel, origin, target, BrutalflyOrbEntity.OrbVariant.STICKY, 0.0F); + this.launchOrb(serverLevel, origin, target, BrutalflyOrbEntity.OrbVariant.POISON, 14.0F); + } + case PHASE_TWO -> { this.launchOrb(serverLevel, origin, target, BrutalflyOrbEntity.OrbVariant.POISON, -8.0F); this.launchOrb(serverLevel, origin, target, BrutalflyOrbEntity.OrbVariant.STICKY, 8.0F); } @@ -588,7 +601,8 @@ public class BrutalflyEntity extends Monster implements GeoEntity { } private void performSwipeHit() { - float swipeDamage = (float) AntarchySettings.brutalflySwipeDamage(); + float swipeDamage = (float) this.getAttributeValue(Attributes.ATTACK_DAMAGE); + boolean finalPhase = this.getFightPhase() == FightPhase.PHASE_THREE; AABB attackBox = this.getBoundingBox().inflate(4.8D, 2.4D, 4.8D).expandTowards(0.0D, -2.5D, 0.0D); for (LivingEntity target : this.level().getEntitiesOfClass( LivingEntity.class, @@ -600,6 +614,9 @@ public class BrutalflyEntity extends Monster implements GeoEntity { } target.hurt(this.damageSources().mobAttack(this), swipeDamage); + if (finalPhase) { + target.addEffect(new MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, 60, 1, false, true)); + } double dx = target.getX() - this.getX(); double dz = target.getZ() - this.getZ(); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/brutalfly/BrutalflyOrbEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/brutalfly/BrutalflyOrbEntity.java index 81a47441..903c1f34 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/brutalfly/BrutalflyOrbEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/brutalfly/BrutalflyOrbEntity.java @@ -162,6 +162,9 @@ public class BrutalflyOrbEntity extends ThrowableItemProjectile { if (!this.level().isClientSide && result.getEntity() instanceof LivingEntity livingTarget) { float directHitDamage = (float) AntarchySettings.brutalflySpitDamage(); Entity owner = this.getOwner(); + if (owner instanceof BrutalflyEntity brutalfly) { + directHitDamage *= brutalfly.getDamageScale(); + } if (owner instanceof LivingEntity livingOwner) { livingTarget.hurt(this.damageSources().mobProjectile(this, livingOwner), directHitDamage); } else { diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/KingEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/KingEntity.java index 084ae543..86242ae3 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/KingEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/KingEntity.java @@ -132,7 +132,13 @@ public class KingEntity extends RoyalBossEntity { private static final int COMBAT_WAYPOINT_VARIANCE = 35; private static final int GROUND_COMBAT_WAYPOINT_MIN_TICKS = 18; private static final int GROUND_COMBAT_WAYPOINT_VARIANCE = 12; - + private static final int LANDING_DESCENT_TIMEOUT_TICKS = 120; + private static final int LANDING_RETRY_TICKS = 40; + private static final int LANDING_ROUTE_SAMPLES = 6; + private static final int LANDING_ROUTE_CHECK_LIMIT = 4; + private static final double GROUND_COMBAT_BITE_DISTANCE = 19.0D; + private static final double GROUND_COMBAT_BITE_VARIANCE = 4.0D; + private static final int ELEVATED_TARGET_TAKEOFF_TICKS = 40; @Nullable private Vec3 patrolCenter; @Nullable @@ -183,6 +189,7 @@ public class KingEntity extends RoyalBossEntity { @Nullable private Vec3 kingGroundCombatWaypoint; private int kingStrafeDirection = 1; + private int kingLandingRetryTicks; private int royalBoundaryGraceTicks; @Nullable private ServerPlayer exileTarget; @@ -255,6 +262,35 @@ public class KingEntity extends RoyalBossEntity { return this.royalChargeActive; } + @Override + protected SoundEvent royalWingBuffetSound() { + return AntarchySoundEvents.KING_WING_FLAP.get(); + } + + @Override + protected boolean royalShouldFaceTarget(LivingEntity target) { + return !this.royalChargeActive; + } + + @Override + protected void onRoyalStuck(LivingEntity target) { + switch (this.kingLandingStage) { + case GROUND_COMBAT -> this.beginKingTakeoff(target); + case TELEGRAPH, DESCENT -> { + this.resetKingCombatMovement(); + this.kingLandingRetryTicks = LANDING_RETRY_TICKS; + this.groundAssaultCooldownTicks = Math.max(this.groundAssaultCooldownTicks, 160); + this.setRoyalFlying(true); + } + case AERIAL -> { + this.kingCombatWaypoint = null; + this.kingStrafeDirection *= -1; + } + default -> { + } + } + } + @Override protected void onRoyalPhaseTransitionStarted(Phase previousPhase, Phase nextPhase) { this.attackScheduler.cancel(RoyalAttackLane.MOVEMENT); @@ -477,6 +513,14 @@ public class KingEntity extends RoyalBossEntity { } } + @Override + public boolean canDamageWithRoyalAttack(LivingEntity target) { + if (target instanceof QueenEntity) { + return target.isAlive() && !this.isAlliedTo(target); + } + return super.canDamageWithRoyalAttack(target); + } + private void chainLightning(ServerLevel level, Vec3 origin) { java.util.Set struck = new java.util.HashSet<>(); Vec3 from = origin; @@ -486,7 +530,7 @@ public class KingEntity extends RoyalBossEntity { double bestScore = Double.MAX_VALUE; for (LivingEntity candidate : level.getEntitiesOfClass(LivingEntity.class, new AABB(from, from).inflate(CHAIN_LIGHTNING_JUMP_RANGE), - e -> e.isAlive() && !(e instanceof RoyalBossEntity) && e.getType() != this.getType())) { + e -> e.isAlive() && (e instanceof QueenEntity || !(e instanceof RoyalBossEntity)) && e.getType() != this.getType())) { if (struck.contains(candidate.getUUID())) { continue; } @@ -566,17 +610,26 @@ public class KingEntity extends RoyalBossEntity { if (this.royalChargeOpeningDelayTicks > 0) { this.royalChargeOpeningDelayTicks--; } + if (this.kingLandingRetryTicks > 0) { + this.kingLandingRetryTicks--; + } + if (!this.isDeadOrDying()) { + if (this.fireballCooldownTicks > 0) this.fireballCooldownTicks--; + if (this.iceballCooldownTicks > 0) this.iceballCooldownTicks--; + if (this.iceSpikeCooldownTicks > 0) this.iceSpikeCooldownTicks--; + } if (this.isRoyalPhaseTransitionActive()) { return; } LivingEntity target = this.getTarget(); - if (target != null && !this.isDeadOrDying() && this.level() instanceof ServerLevel level) { + if (target != null && target.isAlive() && !this.isDeadOrDying() && this.level() instanceof ServerLevel level) { this.trackBehavior(target); this.tickDecree(level, target); this.tickKingCombatMovement(target); if (!this.blocksRoyalAttacksForMovement()) { this.tickKingWholeBody(level, target); } + this.applyRoyalBoundaryPull(); this.stabilizeKingRotation(); return; } @@ -584,11 +637,15 @@ public class KingEntity extends RoyalBossEntity { if (this.isDeadOrDying() || !(this.level() instanceof ServerLevel)) { return; } + if (this.activeDecree != null) { + this.endDecree(null); + } this.setRoyalFlying(true); this.resetKingCombatMovement(); this.decreeRetreatPressure = false; if (this.treePatrolBound && this.treePatrolCenter != null) { this.tickTreePatrol(); + this.applyRoyalBoundaryPull(); return; } if (this.patrolCenter == null || this.position().distanceToSqr(this.patrolCenter) > 64.0D * 64.0D) { @@ -668,17 +725,6 @@ public class KingEntity extends RoyalBossEntity { return; } double boundaryRadius = Math.max(32.0D, AntarchySettings.royalBoundaryRadius()); - double distance = Math.sqrt(this.horizontalDistanceToTreeSqr()); - if (distance > boundaryRadius) { - Vec3 towardCenter = this.treePatrolCenter.subtract(this.position()).multiply(1.0D, 0.0D, 1.0D); - if (towardCenter.lengthSqr() > 0.001D) { - towardCenter = towardCenter.normalize(); - this.getMoveControl().setWantedPosition(this.getX() + towardCenter.x * 12.0D, - this.groundYBelow(this.getX() + towardCenter.x * 12.0D, - this.getZ() + towardCenter.z * 12.0D) + FLYING_PREFERRED_HOVER, - this.getZ() + towardCenter.z * 12.0D, 1.4D); - } - } LivingEntity target = this.getTarget(); if (target == null || !target.isAlive()) { this.royalBoundaryGraceTicks = 0; @@ -703,6 +749,25 @@ public class KingEntity extends RoyalBossEntity { } } + private void applyRoyalBoundaryPull() { + if (!this.treePatrolBound || this.treePatrolCenter == null || this.royalChargeActive + || this.kingLandingStage != KingLandingStage.AERIAL) { + return; + } + double boundaryRadius = Math.max(32.0D, AntarchySettings.royalBoundaryRadius()); + if (this.horizontalDistanceToTreeSqr() <= boundaryRadius * boundaryRadius) { + return; + } + Vec3 towardCenter = this.treePatrolCenter.subtract(this.position()).multiply(1.0D, 0.0D, 1.0D); + if (towardCenter.lengthSqr() <= 0.001D) { + return; + } + towardCenter = towardCenter.normalize(); + double x = this.getX() + towardCenter.x * 12.0D; + double z = this.getZ() + towardCenter.z * 12.0D; + this.getMoveControl().setWantedPosition(x, this.groundYBelow(x, z) + FLYING_PREFERRED_HOVER, z, 1.4D); + } + private double horizontalDistanceToTreeSqr() { if (this.treePatrolCenter == null) { return 0.0D; @@ -794,9 +859,14 @@ public class KingEntity extends RoyalBossEntity { return; } boolean closeQuarters = this.activeDecree instanceof CloseQuartersDecree; - if (closeQuarters && this.isRoyalFlying() && this.kingLandingStage == KingLandingStage.AERIAL) { + if (!this.isRoyalFlying() && this.kingLandingStage == KingLandingStage.AERIAL) { + this.setRoyalFlying(true); + } + if (closeQuarters && this.isRoyalFlying() && this.kingLandingStage == KingLandingStage.AERIAL + && this.kingLandingRetryTicks <= 0) { this.beginKingLanding(target); } else if (!closeQuarters && this.isRoyalFlying() && this.kingLandingStage == KingLandingStage.AERIAL + && this.kingLandingRetryTicks <= 0 && this.groundAssaultCooldownTicks-- <= 0 && target.onGround()) { this.beginKingLanding(target); } @@ -808,6 +878,7 @@ public class KingEntity extends RoyalBossEntity { this.tickKingLandingIndicator(); if (--this.kingLandingStageTicks <= 0) { this.kingLandingStage = KingLandingStage.DESCENT; + this.kingLandingStageTicks = LANDING_DESCENT_TIMEOUT_TICKS; this.playRoyalSound(AntarchySoundEvents.KING_WING_FLAP.get(), 0.72F); } return; @@ -830,7 +901,10 @@ public class KingEntity extends RoyalBossEntity { || Math.abs(localLandingDelta.y) <= 1.25D && horizontalDistanceSquared <= 4.0D; if (reachedLanding) { this.setRoyalFlying(false); - this.setPos(this.getX(), landing.y, this.getZ()); + AABB snapped = this.getBoundingBox().move(0.0D, landing.y - this.getY(), 0.0D); + if (Math.abs(landing.y - this.getY()) > 1.0E-3D && this.level().noCollision(this, snapped)) { + this.setPos(this.getX(), landing.y, this.getZ()); + } this.kingLandingStage = KingLandingStage.IMPACT; this.kingLandingStageTicks = LANDING_IMPACT_TICKS; this.triggerAnim("body_action", "stomp"); @@ -838,6 +912,10 @@ public class KingEntity extends RoyalBossEntity { if (this.level() instanceof ServerLevel level) { this.performStomp(level, target); } + } else if (--this.kingLandingStageTicks <= 0) { + this.resetKingCombatMovement(); + this.kingLandingRetryTicks = LANDING_RETRY_TICKS; + this.groundAssaultCooldownTicks = Math.max(this.groundAssaultCooldownTicks, 160); } return; } @@ -865,8 +943,12 @@ public class KingEntity extends RoyalBossEntity { this.getMoveControl().setWantedPosition(this.kingGroundCombatWaypoint.x, this.kingGroundCombatWaypoint.y, this.kingGroundCombatWaypoint.z, 1.25D); } - if (--this.kingLandingStageTicks <= 0 && !closeQuarters) { + boolean targetOutOfReach = this.royalElevatedTargetTicks() >= ELEVATED_TARGET_TAKEOFF_TICKS; + if (--this.kingLandingStageTicks <= 0 && !closeQuarters || targetOutOfReach) { this.beginKingTakeoff(target); + if (targetOutOfReach) { + this.kingLandingRetryTicks = 100; + } } return; } @@ -916,6 +998,7 @@ public class KingEntity extends RoyalBossEntity { // The next aerial tick will retry the expanded landing search. this.kingLandingWaypoint = null; this.groundAssaultCooldownTicks = 100; + this.kingLandingRetryTicks = LANDING_RETRY_TICKS; } } @@ -957,7 +1040,9 @@ public class KingEntity extends RoyalBossEntity { private Vec3 findKingLandingPoint(LivingEntity target) { Vec3 away = this.position().subtract(target.position()).multiply(1.0D, 0.0D, 1.0D); double baseAngle = away.lengthSqr() > 1.0E-4D ? Math.atan2(away.z, away.x) : this.random.nextDouble() * Mth.TWO_PI; - double[] radii = {9.0D, 13.0D, 17.0D, 6.0D, 4.0D, 2.0D, 0.0D}; + double[] radii = {20.0D, 23.0D, 17.0D, 13.0D, 9.0D, 6.0D, 0.0D}; + int routeChecks = 0; + Vec3 unroutedCandidate = null; for (int angleIndex = 0; angleIndex < 16; angleIndex++) { double angle = baseAngle + angleIndex * Mth.TWO_PI / 16.0D; for (double radius : radii) { @@ -965,18 +1050,27 @@ public class KingEntity extends RoyalBossEntity { double z = target.getZ() + Math.sin(angle) * radius; double y = GravityApi.isGravityInverted(this) ? target.position().y - 0.1D - : this.groundYBelow(x, z) + 0.1D; + : this.groundYBelow(x, z, target.getY() + 1.0D) + 0.1D; Vec3 candidate = new Vec3(x, y, z); AABB box = this.getBoundingBox().move( candidate.x - this.getX(), candidate.y - this.getY(), candidate.z - this.getZ()); - if (this.level().noCollision(this, box)) { - return candidate; + if (!this.level().noCollision(this, box)) { + continue; + } + if (unroutedCandidate == null) { + unroutedCandidate = candidate; + } + if (this.clearKingLandingRoute(candidate) || ++routeChecks >= LANDING_ROUTE_CHECK_LIMIT) { + return routeChecks >= LANDING_ROUTE_CHECK_LIMIT ? unroutedCandidate : candidate; } } } + if (unroutedCandidate != null) { + return unroutedCandidate; + } double fallbackY = GravityApi.isGravityInverted(this) ? target.position().y - 0.1D - : this.groundYBelow(target.getX(), target.getZ()) + 0.1D; + : this.groundYBelow(target.getX(), target.getZ(), target.getY() + 1.0D) + 0.1D; Vec3 fallback = new Vec3(target.getX(), fallbackY, target.getZ()); AABB fallbackBox = this.getBoundingBox().move( fallback.x - this.getX(), fallback.y - this.getY(), fallback.z - this.getZ()); @@ -995,6 +1089,26 @@ public class KingEntity extends RoyalBossEntity { return this.level().noCollision(this, directBox) ? direct : null; } + private boolean clearKingLandingRoute(Vec3 destination) { + Vec3 start = this.position(); + AABB bounds = this.getBoundingBox(); + for (int sample = 1; sample < LANDING_ROUTE_SAMPLES; sample++) { + Vec3 point = start.lerp(destination, sample / (double) LANDING_ROUTE_SAMPLES); + AABB box = bounds.move(point.x - this.getX(), point.y - this.getY(), point.z - this.getZ()); + if (!this.level().noCollision(this, box)) { + return false; + } + } + return true; + } + + private double kingAerialWaypointY(double x, double z, LivingEntity target, double hoverOffset) { + double groundY = this.groundYBelow(x, z, target.getY() + 1.0D); + double desired = target.getY() + hoverOffset; + return Mth.clamp(desired, groundY + FLYING_MIN_HOVER, + Math.max(groundY + FLYING_MAX_HOVER_ABOVE_GROUND, desired)); + } + private void selectKingCombatWaypoint(LivingEntity target) { Vec3 radial = this.position().subtract(target.position()).multiply(1.0D, 0.0D, 1.0D); if (radial.lengthSqr() < 1.0E-4D) { @@ -1015,9 +1129,7 @@ public class KingEntity extends RoyalBossEntity { double candidateRange = range + (angleAttempt % 2 == 0 ? 0.0D : -6.0D); double x = target.getX() + Math.cos(angle) * candidateRange; double z = target.getZ() + Math.sin(angle) * candidateRange; - double groundY = this.groundYBelow(x, z); - double y = Mth.clamp(target.getY() + hoverOffset, - groundY + FLYING_MIN_HOVER, groundY + FLYING_MAX_HOVER_ABOVE_GROUND); + double y = this.kingAerialWaypointY(x, z, target, hoverOffset); Vec3 candidate = new Vec3(x, y, z); if (treeBoundCombat) { double dx = x - this.treePatrolCenter.x; @@ -1037,9 +1149,7 @@ public class KingEntity extends RoyalBossEntity { double angle = currentAngle + this.kingStrafeDirection * COMBAT_ORBIT_ANGLE_STEP; double x = target.getX() + Math.cos(angle) * range; double z = target.getZ() + Math.sin(angle) * range; - double groundY = this.groundYBelow(x, z); - double y = Mth.clamp(target.getY() + hoverOffset, - groundY + FLYING_MIN_HOVER, groundY + FLYING_MAX_HOVER_ABOVE_GROUND); + double y = this.kingAerialWaypointY(x, z, target, hoverOffset); Vec3 candidate = new Vec3(x, y, z); double dx = candidate.x - this.treePatrolCenter.x; double dz = candidate.z - this.treePatrolCenter.z; @@ -1052,9 +1162,7 @@ public class KingEntity extends RoyalBossEntity { double angle = currentAngle + this.kingStrafeDirection * COMBAT_ORBIT_ANGLE_STEP; double x = target.getX() + Math.cos(angle) * range; double z = target.getZ() + Math.sin(angle) * range; - double groundY = this.groundYBelow(x, z); - double y = Mth.clamp(target.getY() + hoverOffset, - groundY + FLYING_MIN_HOVER, groundY + FLYING_MAX_HOVER_ABOVE_GROUND); + double y = this.kingAerialWaypointY(x, z, target, hoverOffset); orbitWaypoint = new Vec3(x, y, z); if (treeBoundCombat) { orbitWaypoint = this.findTreePatrolWaypoint(this.treePatrolCenter, this.treePatrolAngle); @@ -1069,6 +1177,9 @@ public class KingEntity extends RoyalBossEntity { } private void stabilizeKingRotation() { + if (this.royalFacingPoint() != null) { + return; + } Vec3 movement = this.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D); if (movement.lengthSqr() < 0.0025D) { return; @@ -1102,16 +1213,16 @@ public class KingEntity extends RoyalBossEntity { radial = radial.normalize(); Vec3 tangent = new Vec3(-radial.z * this.kingStrafeDirection, 0.0D, radial.x * this.kingStrafeDirection); - double distance = 4.0D + this.random.nextDouble() * 3.0D; - Vec3 candidate = target.position().add(radial.scale(distance)).add(tangent.scale(2.5D)); - Vec3 waypoint = new Vec3(candidate.x, target.getY(), candidate.z); + double distance = GROUND_COMBAT_BITE_DISTANCE + this.random.nextDouble() * GROUND_COMBAT_BITE_VARIANCE; + Vec3 candidate = target.position().add(radial.scale(distance)).add(tangent.scale(4.0D)); + Vec3 waypoint = this.kingGroundPoint(candidate.x, candidate.z, target); AABB box = this.getBoundingBox().move(waypoint.x - this.getX(), waypoint.y - this.getY(), waypoint.z - this.getZ()); if (!this.level().noCollision(this, box)) { - waypoint = target.position().add(radial.scale(distance)); - waypoint = new Vec3(waypoint.x, target.getY(), waypoint.z); + Vec3 radialOnly = target.position().add(radial.scale(distance)); + waypoint = this.kingGroundPoint(radialOnly.x, radialOnly.z, target); box = this.getBoundingBox().move(waypoint.x - this.getX(), waypoint.y - this.getY(), waypoint.z - this.getZ()); } - this.kingGroundCombatWaypoint = this.level().noCollision(this, box) ? waypoint : target.position(); + this.kingGroundCombatWaypoint = this.level().noCollision(this, box) ? waypoint : this.position(); this.kingGroundCombatWaypointTicks = GROUND_COMBAT_WAYPOINT_MIN_TICKS + this.random.nextInt(GROUND_COMBAT_WAYPOINT_VARIANCE + 1); if (this.random.nextInt(4) == 0) { @@ -1119,6 +1230,13 @@ public class KingEntity extends RoyalBossEntity { } } + private Vec3 kingGroundPoint(double x, double z, LivingEntity target) { + double y = GravityApi.isGravityInverted(this) + ? target.getY() + : this.groundYBelow(x, z, Math.max(this.getY(), target.getY()) + 1.0D); + return new Vec3(x, y, z); + } + public void requestCloseQuartersAssault(LivingEntity target) { if (target != null && target.isAlive() && this.isRoyalFlying() && this.kingLandingStage == KingLandingStage.AERIAL) { @@ -1441,10 +1559,8 @@ public class KingEntity extends RoyalBossEntity { this.bumpBehavior(Behavior.SPRINTING, target.isSprinting() ? 1 : -1); this.bumpBehavior(Behavior.HUGGING, distance <= 10.0D ? 1 : -1); this.bumpBehavior(Behavior.KEEPING_FAR, distance >= 22.0D ? 1 : -1); - if (this.patrolCenter != null) { - this.bumpBehavior(Behavior.RETREATING, distance > 20.0D && target.getDeltaMovement().horizontalDistanceSqr() > 0.02D - && target.position().subtract(this.position()).dot(target.getDeltaMovement()) > 0.0D ? 1 : -1); - } + this.bumpBehavior(Behavior.RETREATING, distance > 20.0D && target.getDeltaMovement().horizontalDistanceSqr() > 0.02D + && target.position().subtract(this.position()).dot(target.getDeltaMovement()) > 0.0D ? 1 : -1); } private void bumpBehavior(Behavior behavior, int delta) { @@ -1716,10 +1832,6 @@ public class KingEntity extends RoyalBossEntity { } private void tickKingElementalProjectiles(ServerLevel level, LivingEntity target) { - if (this.fireballCooldownTicks > 0) this.fireballCooldownTicks--; - if (this.iceballCooldownTicks > 0) this.iceballCooldownTicks--; - if (this.iceSpikeCooldownTicks > 0) this.iceSpikeCooldownTicks--; - double distance = this.distanceTo(target); String[] candidates = {"fireball", "iceball", "ice_spikes"}; String selected = this.attackScheduler.chooseWeighted(candidates, id -> { @@ -1797,14 +1909,25 @@ public class KingEntity extends RoyalBossEntity { Vec3 start = this.position(); Vec3 end = target.position(); Vec3 line = end.subtract(start).multiply(1.0D, 0.0D, 1.0D); - if (line.lengthSqr() < 1.0E-4D) return; - line = line.normalize(); + double reach = line.length(); + if (reach < 6.0D) { + for (int index = 0; index < 8; index++) { + double angle = Mth.TWO_PI * index / 8.0D; + double x = end.x + Math.cos(angle) * 2.5D; + double z = end.z + Math.sin(angle) * 2.5D; + double y = this.groundYBelow(x, z, end.y + 1.0D) + 0.1D; + level.addFreshEntity(RoyalIceSpikeEntity.create(level, new Vec3(x, y, z), this)); + } + return; + } + line = line.scale(1.0D / reach); Vec3 side = new Vec3(-line.z, 0.0D, line.x); - for (int i = 1; i <= 5; i++) { - double distance = i * 4.0D; + double firstDistance = Math.max(4.0D, reach - 16.0D); + for (int i = 0; i < 5; i++) { + double distance = firstDistance + i * 4.0D; for (int lane = -1; lane <= 1; lane++) { - Vec3 point = start.add(line.scale(distance)).add(side.scale(lane * (i % 2 == 0 ? 2.0D : 0.0D))); - double y = this.groundYBelow(point.x, point.z) + 0.1D; + Vec3 point = start.add(line.scale(distance)).add(side.scale(lane * (i % 2 == 1 ? 2.0D : 0.0D))); + double y = this.groundYBelow(point.x, point.z, end.y + 1.0D) + 0.1D; RoyalIceSpikeEntity spike = RoyalIceSpikeEntity.create(level, new Vec3(point.x, y, point.z), this); level.addFreshEntity(spike); } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/PrinceEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/PrinceEntity.java index cb671845..78813207 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/PrinceEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/PrinceEntity.java @@ -3,13 +3,31 @@ package com.craisinlord.antarchy.content.entity.royal; import com.craisinlord.antarchy.config.AntarchySettings; import com.craisinlord.antarchy.content.AntarchyObjects; import com.craisinlord.antarchy.content.AntarchySoundEvents; +import com.craisinlord.antarchy.content.effect.RoyalEffectEligibility; +import com.craisinlord.antarchy.content.effect.RoyalEffectHooks; import com.craisinlord.antarchy.content.entity.royal.beam.RoyalBeamElement; +import java.util.Comparator; +import java.util.List; +import net.minecraft.core.particles.DustParticleOptions; +import net.minecraft.core.particles.ParticleOptions; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.server.level.ServerLevel; import net.minecraft.sounds.SoundEvent; +import net.minecraft.util.Mth; +import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.monster.Enemy; import net.minecraft.world.level.Level; +import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.Nullable; +import org.joml.Vector3f; public class PrinceEntity extends RoyalMountEntity { + private static final DustParticleOptions COMMAND_DUST = new DustParticleOptions(new Vector3f(1.0F, 0.75F, 0.15F), 1.6F); + public PrinceEntity(EntityType entityType, Level level) { super(entityType, level); } @@ -40,6 +58,117 @@ public class PrinceEntity extends RoyalMountEntity { }; } + @Override + protected ParticleOptions beamWindupParticle() { + return switch (this.getBeamElement()) { + case FIRE -> ParticleTypes.FLAME; + case ICE -> ParticleTypes.SNOWFLAKE; + default -> ParticleTypes.ELECTRIC_SPARK; + }; + } + + @Override + protected float beamBaseDamage() { + return 12.0F; + } + + @Override + public boolean prefersAerialCombat() { + return false; + } + + @Override + public double preferredCombatRange() { + return 0.0D; + } + + @Override + protected float biteWeight() { + return 3.0F; + } + + @Override + protected float spitWeight() { + return 1.0F; + } + + @Override + protected float beamWeight() { + return 1.2F; + } + + @Override + protected float signatureWeight() { + return 4.0F; + } + + @Override + protected int signatureCooldownTicks() { + return 360; + } + + private double commandRadius() { + return 14.0D + 2.0D * this.getGrowthScale(); + } + + private int commandLimit() { + return 3 + Mth.floor(this.getGrowthScale()); + } + + private List commandCandidates(Vec3 center) { + double radius = this.commandRadius(); + return this.level().getEntitiesOfClass(Mob.class, this.getBoundingBox().inflate(radius), mob -> + mob != this && mob.isAlive() && mob instanceof Enemy && !mob.isAlliedTo(this) + && !(mob instanceof RoyalBossEntity) && RoyalEffectEligibility.canApplyCommanded(mob) + && RoyalEffectHooks.commandedHolder() != null + && !mob.hasEffect(RoyalEffectHooks.commandedHolder()) + && mob.distanceToSqr(center) <= radius * radius); + } + + @Override + protected boolean isSignatureUseful(LivingEntity target) { + return RoyalEffectHooks.commandedHolder() != null && this.commandCandidates(this.position()).size() >= 2; + } + + @Override + protected void signatureTelegraph(ServerLevel level, int tick, @Nullable LivingEntity target, @Nullable Vec3 aimPoint) { + if (tick % 3 != 0) { + return; + } + double radius = (this.getBbWidth() * 0.5D + 1.0D) + tick * 0.25D * this.getGrowthScale(); + for (int i = 0; i < 16; i++) { + double angle = i * Mth.TWO_PI / 16.0D + tick * 0.1D; + level.sendParticles(COMMAND_DUST, this.getX() + Math.cos(angle) * radius, this.getY() + 0.3D, + this.getZ() + Math.sin(angle) * radius, 1, 0.0D, 0.05D, 0.0D, 0.0D); + } + if (tick == 3) { + level.sendParticles(ParticleTypes.ENCHANTED_HIT, this.getX(), this.getY() + this.getBbHeight(), this.getZ(), + 20, this.getBbWidth() * 0.3D, 0.3D, this.getBbWidth() * 0.3D, 0.1D); + } + } + + @Override + protected boolean performSignature(ServerLevel level, @Nullable LivingEntity target, @Nullable Vec3 aimPoint, boolean ridden) { + if (RoyalEffectHooks.commandedHolder() == null) { + return false; + } + Vec3 center = this.position(); + List candidates = this.commandCandidates(center); + candidates.sort(Comparator.comparingDouble(mob -> mob.distanceToSqr(center))); + int applied = 0; + for (Mob mob : candidates) { + if (applied >= this.commandLimit()) { + break; + } + if (mob.addEffect(new MobEffectInstance(RoyalEffectHooks.commandedHolder(), 300 + 20 * Mth.floor(this.getGrowthScale())), this)) { + applied++; + level.sendParticles(COMMAND_DUST, mob.getX(), mob.getY() + mob.getBbHeight() + 0.3D, mob.getZ(), 8, 0.25D, 0.2D, 0.25D, 0.0D); + } + } + level.sendParticles(ParticleTypes.SONIC_BOOM, this.getX(), this.getY() + this.getBbHeight() * 0.6D, this.getZ(), 1, 0.0D, 0.0D, 0.0D, 0.0D); + return applied > 0; + } + @Override protected String geoName() { return "prince"; diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/PrincessEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/PrincessEntity.java index af6e829d..ef9f3088 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/PrincessEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/PrincessEntity.java @@ -4,10 +4,18 @@ import com.craisinlord.antarchy.config.AntarchySettings; import com.craisinlord.antarchy.content.AntarchyObjects; import com.craisinlord.antarchy.content.AntarchySoundEvents; import com.craisinlord.antarchy.content.entity.royal.beam.RoyalBeamElement; +import com.craisinlord.anthology.time.TimeDilationApi; +import net.minecraft.core.particles.ParticleOptions; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.server.level.ServerLevel; import net.minecraft.sounds.SoundEvent; +import net.minecraft.util.Mth; import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.level.Level; +import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.Nullable; public class PrincessEntity extends RoyalMountEntity { public PrincessEntity(EntityType entityType, Level level) { @@ -24,11 +32,120 @@ public class PrincessEntity extends RoyalMountEntity { @Override protected RoyalBeamElement boltElement(int lateralIndex) { - return switch (lateralIndex) { - case -1 -> RoyalBeamElement.FIRE; - case 1 -> RoyalBeamElement.ICE; - default -> RoyalBeamElement.LIGHTNING; - }; + return RoyalBeamElement.GENERIC; + } + + @Override + protected Vec3 boltOrigin(int lateralIndex) { + float scale = this.getGrowthScale(); + Vec3 forward = Vec3.directionFromRotation(0.0F, this.getYRot()); + Vec3 side = new Vec3(-forward.z, 0.0D, forward.x); + return this.position() + .add(0.0D, (lateralIndex == 0 ? 0.4D : 0.33D) * scale, 0.0D) + .add(forward.scale((lateralIndex == 0 ? 0.32D : 0.23D) * scale + this.getBbWidth() * 0.15D)) + .add(side.scale(lateralIndex * 0.24D * scale)); + } + + @Override + protected int nextBeamHead(int previous) { + return 1; + } + + @Override + protected ParticleOptions beamWindupParticle() { + return ParticleTypes.REVERSE_PORTAL; + } + + @Override + protected float beamBaseDamage() { + return 10.0F; + } + + @Override + public boolean prefersAerialCombat() { + return this.canFly(); + } + + @Override + public double preferredCombatRange() { + return 8.0D + 1.5D * this.getGrowthScale(); + } + + @Override + protected float biteWeight() { + return 1.0F; + } + + @Override + protected float spitWeight() { + return 2.5F; + } + + @Override + protected float beamWeight() { + return 1.6F; + } + + @Override + protected float signatureWeight() { + return 2.5F; + } + + @Override + protected int signatureCooldownTicks() { + return 300; + } + + private double fieldRadius() { + return 5.0D + 0.8D * this.getGrowthScale(); + } + + private boolean ownerInside(Vec3 center) { + LivingEntity owner = this.getOwner(); + if (owner == null || owner.level() != this.level() || this.hasPassenger(owner)) { + return false; + } + double clearance = this.fieldRadius() + 1.5D; + return owner.position().distanceToSqr(center) < clearance * clearance; + } + + @Override + protected boolean isSignatureUseful(LivingEntity target) { + return this.combatGap(target) < 10.0D + 1.5D * this.getGrowthScale() && !this.ownerInside(target.position()); + } + + private Vec3 fieldCenter(@Nullable LivingEntity target, @Nullable Vec3 aimPoint) { + if (target != null && target.isAlive()) { + return target.position(); + } + return aimPoint != null ? aimPoint : this.position().add(Vec3.directionFromRotation(0.0F, this.getYRot()).scale(this.getBbWidth() + 6.0D)); + } + + @Override + protected void signatureTelegraph(ServerLevel level, int tick, @Nullable LivingEntity target, @Nullable Vec3 aimPoint) { + if (tick % 2 != 0) { + return; + } + Vec3 center = this.fieldCenter(target, aimPoint); + double radius = this.fieldRadius() * (1.0D - tick / 24.0D) + 0.5D; + for (int i = 0; i < 12; i++) { + double angle = i * Mth.TWO_PI / 12.0D - tick * 0.15D; + level.sendParticles(ParticleTypes.REVERSE_PORTAL, center.x + Math.cos(angle) * radius, center.y + 0.2D, + center.z + Math.sin(angle) * radius, 1, 0.0D, 0.05D, 0.0D, 0.0D); + } + Vec3 orb = this.boltOrigin(0); + level.sendParticles(ParticleTypes.END_ROD, orb.x, orb.y, orb.z, 2, 0.1D, 0.1D, 0.1D, 0.01D); + } + + @Override + protected boolean performSignature(ServerLevel level, @Nullable LivingEntity target, @Nullable Vec3 aimPoint, boolean ridden) { + Vec3 center = this.fieldCenter(target, aimPoint); + if (this.ownerInside(center)) { + return false; + } + TimeDilationApi.createField(level, center, this.fieldRadius(), 0.35D, 100 + 10 * Mth.floor(this.getGrowthScale()), this.getUUID()); + level.sendParticles(ParticleTypes.END_ROD, center.x, center.y + 0.5D, center.z, 36, this.fieldRadius() * 0.3D, 0.6D, this.fieldRadius() * 0.3D, 0.03D); + return true; } @Override diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/QueenEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/QueenEntity.java index f8464c77..f73c4374 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/QueenEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/QueenEntity.java @@ -44,7 +44,10 @@ import net.minecraft.world.entity.ai.attributes.AttributeInstance; import net.minecraft.world.entity.ai.attributes.AttributeModifier; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal; import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal; +import net.minecraft.world.entity.ambient.AmbientCreature; +import net.minecraft.world.entity.animal.WaterAnimal; import net.minecraft.world.entity.MobSpawnType; import net.minecraft.world.level.GameRules; import net.minecraft.world.level.Level; @@ -128,6 +131,12 @@ public class QueenEntity extends RoyalBossEntity { private static final int ACCELERATION_VOLLEY_DELAY = 18; private static final int ACCELERATION_LANDING_DELAY = 55; private static final int DIRECTED_LANDING_RETRY_TICKS = 60; + private static final int LANDING_TIMEOUT_COOLDOWN_TICKS = 160; + private static final double GROUND_CHARGE_MIN_DISTANCE = 16.0D; + private static final double GROUND_CHARGE_HIT_INFLATE = 1.5D; + private static final double GROUND_CHARGE_DAMAGE_SCALE = 1.1D; + private static final double GROUND_CHARGE_KNOCKBACK = 2.2D; + private static final int ELEVATED_TARGET_TAKEOFF_TICKS = 40; private int manticoreSummonCooldownTicks; private int gravityStompCooldownTicks; @@ -161,6 +170,7 @@ public class QueenEntity extends RoyalBossEntity { private Vec3 queenLandingWaypoint; @Nullable private Vec3 queenGroundChargeDirection; + private final java.util.Set queenGroundChargeHits = new java.util.HashSet<>(); @Nullable private Phase pendingPhaseSignature; private boolean pendingPhaseTwoCrushingGravity; @@ -295,11 +305,34 @@ public class QueenEntity extends RoyalBossEntity { @Override protected double combatStandoffDistance() { if (this.queenLandingStage == QueenLandingStage.GROUND_COMBAT && !this.isRoyalFlying()) { - return 0.0D; + return super.combatStandoffDistance(); } return Math.max(super.combatStandoffDistance(), AntarchySettings.queenBeamMinimumRange() + 6.0D); } + @Override + protected SoundEvent royalWingBuffetSound() { + return AntarchySoundEvents.QUEEN_FLY_LOOP.get(); + } + + @Override + protected boolean royalShouldFaceTarget(LivingEntity target) { + return this.queenGroundChargeWindupTicks <= 0 && this.queenGroundChargeTicks <= 0; + } + + @Override + protected void onRoyalStuck(LivingEntity target) { + switch (this.queenLandingStage) { + case GROUND_COMBAT -> this.beginQueenTakeoff(); + case TELEGRAPH, DESCENT -> { + this.resetQueenLandingSequence(); + this.queenLandingCooldownTicks = LANDING_TIMEOUT_COOLDOWN_TICKS; + } + default -> { + } + } + } + @Override protected double biteDamageMultiplier() { return super.biteDamageMultiplier() * 1.5D; @@ -320,9 +353,13 @@ public class QueenEntity extends RoyalBossEntity { protected void registerRoyalTargetGoals() { this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, KingEntity.class, true)); - this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true)); - this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>( - this, Mob.class, 10, true, false, this::canAttack)); + this.targetSelector.addGoal(2, new HurtByTargetGoal(this).setUnseenMemoryTicks(ROYAL_UNSEEN_MEMORY_TICKS)); + this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Player.class, true) + .setUnseenMemoryTicks(ROYAL_UNSEEN_MEMORY_TICKS)); + this.targetSelector.addGoal(4, new NearestAttackableTargetGoal<>( + this, Mob.class, 10, true, false, + living -> !(living instanceof AmbientCreature) && !(living instanceof WaterAnimal) + && this.canAttack(living))); } @Override @@ -495,6 +532,9 @@ public class QueenEntity extends RoyalBossEntity { } private void tickQueenLandingSequence(LivingEntity target) { + if (this.queenLandingStage == QueenLandingStage.AERIAL && !this.isRoyalFlying()) { + this.setRoyalFlying(true); + } if (this.queenLandingStage == QueenLandingStage.AERIAL && this.isRoyalFlying() && !this.isQueenAbilityTelegraphActive() && this.queenLandingCooldownTicks-- <= 0) { @@ -529,7 +569,7 @@ public class QueenEntity extends RoyalBossEntity { this.performGravityStomp((ServerLevel) this.level(), target); } else if (--this.queenLandingStageTicks <= 0) { this.resetQueenLandingSequence(); - this.queenLandingCooldownTicks = 40; + this.queenLandingCooldownTicks = LANDING_TIMEOUT_COOLDOWN_TICKS; } } case IMPACT -> { @@ -544,7 +584,8 @@ public class QueenEntity extends RoyalBossEntity { } case GROUND_COMBAT -> { this.tickQueenGroundCharge(target); - if (--this.queenLandingStageTicks <= 0) { + if (--this.queenLandingStageTicks <= 0 + || this.royalElevatedTargetTicks() >= ELEVATED_TARGET_TAKEOFF_TICKS) { this.beginQueenTakeoff(); } } @@ -577,7 +618,7 @@ public class QueenEntity extends RoyalBossEntity { double baseAngle = away.lengthSqr() > 1.0E-4D ? Math.atan2(away.z, away.x) : this.random.nextDouble() * Mth.TWO_PI; boolean inverted = GravityApi.isGravityInverted(this); - double[] radii = {10.0D, 14.0D, 18.0D, 7.0D}; + double[] radii = {20.0D, 23.0D, 17.0D, 14.0D, 10.0D}; for (int angleIndex = 0; angleIndex < 12; angleIndex++) { double angle = baseAngle + angleIndex * Mth.TWO_PI / 12.0D; for (double radius : radii) { @@ -585,7 +626,7 @@ public class QueenEntity extends RoyalBossEntity { double z = target.getZ() + Math.sin(angle) * radius; double y = inverted ? target.position().y - 0.1D - : this.groundYBelow(x, z) + 0.1D; + : this.groundYBelow(x, z, target.getY() + 1.0D) + 0.1D; Vec3 candidate = new Vec3(x, y, z); AABB box = this.getBoundingBox().move( candidate.x - this.getX(), candidate.y - this.getY(), candidate.z - this.getZ()); @@ -596,7 +637,7 @@ public class QueenEntity extends RoyalBossEntity { } double fallbackY = inverted ? target.position().y - 0.1D - : this.groundYBelow(target.getX(), target.getZ()) + 0.1D; + : this.groundYBelow(target.getX(), target.getZ(), target.getY() + 1.0D) + 0.1D; Vec3 fallback = new Vec3(target.getX(), fallbackY, target.getZ()); AABB fallbackBox = this.getBoundingBox().move( fallback.x - this.getX(), fallback.y - this.getY(), fallback.z - this.getZ()); @@ -667,6 +708,7 @@ public class QueenEntity extends RoyalBossEntity { if (direction.lengthSqr() > 1.0E-4D) { this.queenGroundChargeDirection = direction.normalize(); this.queenGroundChargeTicks = GROUND_CHARGE_DURATION_TICKS; + this.queenGroundChargeHits.clear(); } else { this.finishQueenGroundCharge(); } @@ -681,6 +723,9 @@ public class QueenEntity extends RoyalBossEntity { this.setYRot((float) (Mth.atan2(-direction.x, direction.z) * Mth.RAD_TO_DEG)); this.yBodyRot = this.getYRot(); this.hasImpulse = true; + if (this.level() instanceof ServerLevel level) { + this.applyQueenGroundChargeHits(level, direction); + } if (--this.queenGroundChargeTicks <= 0) { this.finishQueenGroundCharge(); } @@ -688,7 +733,8 @@ public class QueenEntity extends RoyalBossEntity { } 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) { + .distanceToSqr(this.position().multiply(1.0D, 0.0D, 1.0D)) + < GROUND_CHARGE_MIN_DISTANCE * GROUND_CHARGE_MIN_DISTANCE) { return; } this.queenGroundChargeDirection = target.position().subtract(this.position()) @@ -701,6 +747,34 @@ public class QueenEntity extends RoyalBossEntity { } } + private void applyQueenGroundChargeHits(ServerLevel level, Vec3 direction) { + float damage = (float) (this.getAttributeValue(Attributes.ATTACK_DAMAGE) * GROUND_CHARGE_DAMAGE_SCALE); + DamageSource source = this.damageSources().mobAttack(this); + AABB hitBox = this.getBoundingBox().inflate(GROUND_CHARGE_HIT_INFLATE); + for (LivingEntity living : level.getEntitiesOfClass(LivingEntity.class, hitBox, + entity -> entity.isAlive() && entity != this && this.canDamageWithRoyalAttack(entity))) { + Vec3 offset = living.position().subtract(this.position()).multiply(1.0D, 0.0D, 1.0D); + if (offset.dot(direction) < -this.getBbWidth() * 0.15D + || !this.queenGroundChargeHits.add(living.getUUID())) { + continue; + } + living.hurt(source, damage); + if (!(living instanceof RoyalBossEntity)) { + Vec3 lift = GravityRotationUtil.vecPlayerToWorld( + 0.0D, 0.55D, 0.0D, GravityApi.getGravityDirection(living)); + this.addGravityAwareImpulse(living, direction.scale(GROUND_CHARGE_KNOCKBACK).add(lift)); + living.hasImpulse = true; + living.hurtMarked = true; + } + level.sendParticles(ParticleTypes.CRIT, living.getX(), living.getY() + living.getBbHeight() * 0.5D, + living.getZ(), 16, 0.5D, 0.6D, 0.5D, 0.1D); + } + if (this.queenGroundChargeTicks % 4 == 0) { + Vec3 front = this.position().add(direction.scale(this.getBbWidth() * 0.5D + 1.0D)); + RoyalBlockDestruction.destroySphere(level, this, front.add(0.0D, 2.0D, 0.0D), 3.5D, 24, 60.0D, 0.1F); + } + } + private void finishQueenGroundCharge() { this.queenGroundChargeTicks = 0; this.queenGroundChargeWindupTicks = 0; @@ -710,6 +784,7 @@ public class QueenEntity extends RoyalBossEntity { } private void clearQueenGroundCharge() { + this.queenGroundChargeHits.clear(); this.queenGroundChargeCooldownTicks = 0; this.queenGroundChargeWindupTicks = 0; this.queenGroundChargeTicks = 0; @@ -1048,14 +1123,21 @@ public class QueenEntity extends RoyalBossEntity { : 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 chosen = forcedAttack != null && this.queenAttackReady(forcedAttack, phase, majorBusy) ? forcedAttack : this.attackScheduler.chooseWeighted(candidates, id -> { if (!this.queenAttackReady(id, phase, majorBusy) || id.equals(this.lastQueenMajorAttack)) return 0; return this.queenAttackWeight(id, phase); }, this.random); - if (selected == null) return; + if (chosen == null && this.lastQueenMajorAttack != null + && this.queenAttackReady(this.lastQueenMajorAttack, phase, majorBusy) + && java.util.Arrays.asList(candidates).contains(this.lastQueenMajorAttack) + && this.queenAttackWeight(this.lastQueenMajorAttack, phase) > 0) { + chosen = this.lastQueenMajorAttack; + } + if (chosen == null) return; + final String selected = chosen; int cooldown = switch (selected) { case "gravity_stomp" -> GRAVITY_STOMP_COOLDOWN; case "black_hole" -> BLACK_HOLE_COOLDOWN; @@ -1606,7 +1688,9 @@ public class QueenEntity extends RoyalBossEntity { double radius = this.random.nextDouble() * GRAVITIC_UPHEAVAL_RADIUS; double x = center.x + Math.cos(angle) * radius; double z = center.z + Math.sin(angle) * radius; - BlockPos pos = BlockPos.containing(x, this.groundYBelow(x, z), z); + BlockPos pos = inverted + ? BlockPos.containing(x, this.ceilingYAbove(x, z, this.getBoundingBox().minY + 0.5D) + 0.5D, z) + : BlockPos.containing(x, this.groundYBelow(x, z) - 0.5D, z); BlockState state = level.getBlockState(pos); if (!state.is(AntarchyTags.Blocks.QUEEN_GRABBABLE_BLOCKS) || level.getBlockEntity(pos) != null || state.getDestroySpeed(level, pos) < 0.0F || state.getCollisionShape(level, pos).isEmpty()) { diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBoltEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBoltEntity.java index eaa815da..42da84bd 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBoltEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBoltEntity.java @@ -87,6 +87,14 @@ public class RoyalBoltEntity extends AbstractHurtingProjectile { }; } + @Override + protected boolean canHitEntity(Entity target) { + if (this.getOwner() instanceof RoyalMountEntity mount && mount.isFriendlyTo(target)) { + return false; + } + return super.canHitEntity(target); + } + @Override protected void onHitEntity(EntityHitResult result) { super.onHitEntity(result); @@ -102,7 +110,13 @@ public class RoyalBoltEntity extends AbstractHurtingProjectile { && royal.isTame() && other.isTame()) { return; } + if (owner instanceof RoyalMountEntity mount && mount.isFriendlyTo(target)) { + return; + } float damage = (float) AntarchySettings.royalBoltDamage(); + if (owner instanceof RoyalMountEntity mount) { + damage *= mount.projectileDamageMultiplier(); + } target.hurt(this.damageSources().mobProjectile(this, owner instanceof LivingEntity le ? le : null), damage); if (target instanceof LivingEntity living) { living.knockback(0.35D, this.getX() - target.getX(), this.getZ() - target.getZ()); @@ -126,6 +140,9 @@ public class RoyalBoltEntity extends AbstractHurtingProjectile { } } case GENERIC -> { + if (owner instanceof PrincessEntity) { + living.addEffect(new MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, 60, 1), owner); + } } } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBossEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBossEntity.java index 8b669228..c4f75325 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBossEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalBossEntity.java @@ -57,8 +57,13 @@ import net.minecraft.world.entity.ai.navigation.GroundPathNavigation; import net.minecraft.world.entity.ai.navigation.PathNavigation; import net.minecraft.world.entity.monster.Monster; import net.minecraft.world.entity.player.Player; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.level.ClipContext; import net.minecraft.world.level.Level; import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.Nullable; import software.bernie.geckolib.animatable.GeoEntity; @@ -111,6 +116,9 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult private static final int RECOVERY_AFTER_BEAM_TICKS = 30; private static final ResourceLocation MULTIPLAYER_DAMAGE_ID = ResourceLocation.fromNamespaceAndPath("antarchy", "royal_multiplayer_damage"); private static final int OBSTRUCTION_CLEAR_INTERVAL_TICKS = 5; + private static final int RIVAL_OBSTRUCTION_CLEAR_INTERVAL_TICKS = 10; + private static final int BODY_CRUSH_INTERVAL_TICKS = 10; + private static final int RIVAL_BODY_CRUSH_INTERVAL_TICKS = 20; private static final double OBSTRUCTION_CLEAR_RADIUS = 3.5D; private static final int OBSTRUCTION_CLEAR_MAX_BLOCKS = 24; private static final double OBSTRUCTION_CLEAR_MAX_RESISTANCE = 60.0D; @@ -120,6 +128,36 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult private static final double BEAM_MUZZLE_SIDE_Y = 10.25D; private static final double BEAM_MUZZLE_LATERAL = 2.625D; private static final int HEAVY_BLOCK_CHECK_INTERVAL_TICKS = 4; + private static final String WING_BUFFET_ID = "royal_wing_buffet"; + private static final int WING_BUFFET_WINDUP_TICKS = 16; + private static final double WING_BUFFET_EXTRA_RADIUS = 5.0D; + private static final double WING_BUFFET_BELOW = 14.0D; + private static final double WING_BUFFET_ABOVE = 6.0D; + private static final double WING_BUFFET_DAMAGE_SCALE = 0.85D; + private static final double WING_BUFFET_PUSH = 2.6D; + private static final double WING_BUFFET_LIFT = 0.75D; + private static final String EXCAVATION_ID = "royal_excavation"; + private static final int EXCAVATION_TRIGGER_TICKS = 100; + private static final int EXCAVATION_WINDUP_TICKS = 24; + private static final int EXCAVATION_COOLDOWN_TICKS = 200; + private static final double EXCAVATION_RANGE = 72.0D; + private static final double EXCAVATION_RADIUS = 2.5D; + private static final double EXCAVATION_DEPTH = 10.0D; + private static final int EXCAVATION_MAX_BLOCKS = 20; + private static final double EXCAVATION_CONCEALED_DAMAGE = 5.0D; + private static final int STUCK_SAMPLE_TICKS = 40; + private static final double STUCK_MIN_PROGRESS_SQR = 1.0D; + private static final double STUCK_MIN_WANTED_DISTANCE_SQR = 36.0D; + private static final int STUCK_TAKEOFF_STRIKES = 2; + private static final int STUCK_TELEPORT_STRIKES = 4; + private static final int STUCK_TELEPORT_COOLDOWN_TICKS = 600; + private static final int STUCK_TELEPORT_ATTEMPTS = 16; + private static final int LANDING_FOR_COMBAT_TIMEOUT_TICKS = 120; + private static final int GROUND_SCAN_DEPTH = 48; + private static final int GROUND_SCAN_RISE = 24; + private static final double MAX_BEAM_PITCH = Math.toRadians(55.0D); + private static final int ELEVATED_TARGET_HEIGHT = 10; + private static final float FACING_TURN_RATE = 6.0F; protected static final double FLYING_MIN_HOVER = 2.5D; protected static final double FLYING_PREFERRED_HOVER = 6.0D; @@ -196,6 +234,16 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult private boolean multiplayerScalingInitialized; private final Set encounterParticipants = new HashSet<>(); private double royalDamageMultiplier = 1.0D; + private int landingForCombatTicks; + private int royalDeadZoneTicks; + private int royalConcealedTicks; + private int royalElevatedTargetTicks; + private int royalLastMoveRequestTick = Integer.MIN_VALUE; + @Nullable + private Vec3 royalStuckSamplePosition; + private int royalStuckSampleTicks; + private int royalStuckStrikes; + private int royalTeleportCooldownTicks; @Nullable private Entity[] multipartParts; @@ -206,8 +254,8 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult this.beamControllers[i] = new BeamController(this); } this.xpReward = 500; - this.groundMoveControl = new MoveControl(this); - this.flyingMoveControl = new FlyingMoveControl(this, 20, true); + this.groundMoveControl = new RoyalGroundMoveControl(this); + this.flyingMoveControl = new RoyalFlyingMoveControl(this, 20); this.groundNavigation = new GroundPathNavigation(this, level); FlyingPathNavigation flyingNavigation = new FlyingPathNavigation(this, level); flyingNavigation.setCanFloat(true); @@ -216,6 +264,7 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult this.moveControl = this.flyingMoveControl; this.navigation = this.flyingNavigation; } else { + this.moveControl = this.groundMoveControl; this.navigation = this.groundNavigation; } this.bossEvent = new com.craisinlord.antarchy.content.boss.EntityLinkedServerBossEvent( @@ -386,8 +435,42 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult } protected void registerRoyalTargetGoals() { - this.targetSelector.addGoal(1, new HurtByTargetGoal(this)); - this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true)); + this.targetSelector.addGoal(1, new HurtByTargetGoal(this).setUnseenMemoryTicks(ROYAL_UNSEEN_MEMORY_TICKS)); + this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true) + .setUnseenMemoryTicks(ROYAL_UNSEEN_MEMORY_TICKS)); + } + + protected static final int ROYAL_UNSEEN_MEMORY_TICKS = 400; + + protected SoundEvent royalWingBuffetSound() { + return this.royalBiteSound(); + } + + protected int royalWingBuffetCooldownTicks(Phase phase) { + return switch (phase) { + case ONE -> 110; + case TWO -> 90; + case THREE -> 70; + }; + } + + protected int royalDeadZoneTriggerTicks(Phase phase) { + return switch (phase) { + case ONE -> 40; + case TWO -> 32; + case THREE -> 24; + }; + } + + protected boolean royalShouldFaceTarget(LivingEntity target) { + return true; + } + + protected void onRoyalStuck(LivingEntity target) { + } + + protected final int royalElevatedTargetTicks() { + return this.royalElevatedTargetTicks; } public boolean canDamageWithRoyalAttack(LivingEntity target) { @@ -513,7 +596,7 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult if (this.shouldClearObstruction() && !this.level().isClientSide && !this.isDeadOrDying() - && this.tickCount % OBSTRUCTION_CLEAR_INTERVAL_TICKS == 0 + && this.tickCount % (this.isFightingRoyalRival() ? RIVAL_OBSTRUCTION_CLEAR_INTERVAL_TICKS : OBSTRUCTION_CLEAR_INTERVAL_TICKS) == 0 && this.isInWall()) { RoyalBlockDestruction.destroySphere( (ServerLevel) this.level(), @@ -576,13 +659,16 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult for (RoyalHead head : this.heads) { head.setTarget(null); } + this.resetRoyalCombatTracking(); return; } this.initializeMultiplayerScaling(primaryTarget); this.assignHeadTargets(primaryTarget); + this.tickRoyalTargetElevation(primaryTarget); this.tickCombatLocomotionMode(primaryTarget); + this.tickRoyalStuckRecovery(primaryTarget); boolean movementBlocksAttacks = this.blocksRoyalAttacksForMovement(); if (!movementBlocksAttacks) { boolean aeriallyStabilized = this.steerTowardTarget(primaryTarget); @@ -596,6 +682,8 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult return; } this.tickBodyCrush(); + this.tickRoyalCloseRangeAnswer(primaryTarget); + this.tickRoyalConcealedTarget(primaryTarget); Phase phase = this.phase(); int activeHeadAttacks = 0; @@ -920,15 +1008,18 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult double verticalDistance = Math.abs(target.getY() + target.getBbHeight() * 0.5D - (this.getY() + this.getBbHeight() * 0.5D)); + boolean inverted = GravityApi.isGravityInverted(this); + double groundBelowTarget = this.groundYBelow(wanted.x, wanted.z, target.getY() + 1.0D); + double wantedY = this.landingForCombat + ? (inverted ? target.getY() + target.getBbHeight() - this.getBbHeight() : groundBelowTarget) + : inverted + ? target.getY() - 3.0D + : Mth.clamp(target.getY() + 3.0D, + groundBelowTarget + FLYING_MIN_HOVER, + Math.max(groundBelowTarget + FLYING_MAX_HOVER_ABOVE_GROUND, target.getY() + 4.0D)); if (!this.landingForCombat && verticalDistance > 6.0D) { if (this.aerialCombatAnchor == null || this.aerialCombatAnchorTicks-- <= 0) { - double anchorX = this.getX(); - double anchorZ = this.getZ(); - if (horizontalDistance > 10.0D) { - anchorX = wanted.x; - anchorZ = wanted.z; - } - this.aerialCombatAnchor = new Vec3(anchorX, this.getY(), anchorZ); + this.aerialCombatAnchor = new Vec3(wanted.x, wantedY, wanted.z); this.aerialCombatAnchorTicks = 20; } Vec3 anchor = this.aerialCombatAnchor; @@ -938,15 +1029,6 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult this.aerialCombatAnchor = null; this.aerialCombatAnchorTicks = 0; - boolean inverted = GravityApi.isGravityInverted(this); - double groundBelowTarget = this.groundYBelow(wanted.x, wanted.z); - double wantedY = this.landingForCombat - ? (inverted ? target.getY() + target.getBbHeight() - this.getBbHeight() : groundBelowTarget) - : inverted - ? target.getY() - 3.0D - : Mth.clamp(target.getY() + 3.0D, - groundBelowTarget + FLYING_MIN_HOVER, - groundBelowTarget + FLYING_MAX_HOVER_ABOVE_GROUND); boolean closeVertically = Math.abs(wantedY - this.getY()) <= 2.5D; if (atStandoff && closeVertically) { this.getNavigation().stop(); @@ -956,6 +1038,536 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult return false; } + private void resetRoyalCombatTracking() { + this.royalDeadZoneTicks = 0; + this.royalConcealedTicks = 0; + this.royalElevatedTargetTicks = 0; + this.royalStuckSamplePosition = null; + this.royalStuckSampleTicks = 0; + this.royalStuckStrikes = 0; + } + + private void tickRoyalTargetElevation(LivingEntity target) { + Vec3 local = GravityRotationUtil.vecWorldToPlayer(target.position().subtract(this.position()), + GravityApi.getGravityDirection(this)); + if (local.y > ELEVATED_TARGET_HEIGHT) { + this.royalElevatedTargetTicks++; + } else { + this.royalElevatedTargetTicks = 0; + } + } + + final void markRoyalMoveRequested() { + this.royalLastMoveRequestTick = this.tickCount; + } + + private void tickRoyalStuckRecovery(LivingEntity target) { + if (this.royalTeleportCooldownTicks > 0) { + this.royalTeleportCooldownTicks--; + } + MoveControl control = this.getMoveControl(); + boolean requested = (long) this.tickCount - (long) this.royalLastMoveRequestTick <= 2L + && this.distanceToSqr(control.getWantedX(), control.getWantedY(), control.getWantedZ()) + > STUCK_MIN_WANTED_DISTANCE_SQR; + if (!requested) { + this.royalStuckSamplePosition = null; + this.royalStuckSampleTicks = 0; + this.royalStuckStrikes = 0; + return; + } + if (this.royalStuckSamplePosition == null) { + this.royalStuckSamplePosition = this.position(); + this.royalStuckSampleTicks = 0; + return; + } + if (++this.royalStuckSampleTicks < STUCK_SAMPLE_TICKS) { + return; + } + boolean progressed = this.position().distanceToSqr(this.royalStuckSamplePosition) >= STUCK_MIN_PROGRESS_SQR; + this.royalStuckSamplePosition = this.position(); + this.royalStuckSampleTicks = 0; + if (progressed) { + this.royalStuckStrikes = 0; + return; + } + this.royalStuckStrikes++; + this.onRoyalMovementObstructed(target); + } + + private void onRoyalMovementObstructed(LivingEntity target) { + if (this.level() instanceof ServerLevel serverLevel) { + this.clearRoyalPathTowardWanted(serverLevel); + } + if (this.royalStuckStrikes >= STUCK_TAKEOFF_STRIKES) { + this.onRoyalStuck(target); + if (this.isFlyingBoss()) { + this.addGravityAwareImpulse(this, GravityRotationUtil.vecPlayerToWorld( + 0.0D, 0.6D, 0.0D, GravityApi.getGravityDirection(this))); + this.hasImpulse = true; + } + } + if (this.royalStuckStrikes >= STUCK_TELEPORT_STRIKES && this.royalTeleportCooldownTicks <= 0 + && this.tryRoyalRecoveryTeleport(target)) { + this.royalStuckStrikes = 0; + this.royalStuckSamplePosition = null; + this.royalTeleportCooldownTicks = STUCK_TELEPORT_COOLDOWN_TICKS; + } + } + + private void clearRoyalPathTowardWanted(ServerLevel level) { + MoveControl control = this.getMoveControl(); + Vec3 toWanted = new Vec3(control.getWantedX() - this.getX(), control.getWantedY() - this.getY(), + control.getWantedZ() - this.getZ()); + Vec3 horizontal = toWanted.multiply(1.0D, 0.0D, 1.0D); + Vec3 direction; + if (horizontal.lengthSqr() > 1.0E-4D) { + direction = horizontal.normalize(); + } else { + double yaw = this.yBodyRot * Mth.DEG_TO_RAD; + direction = new Vec3(-Math.sin(yaw), 0.0D, Math.cos(yaw)); + } + Vec3 side = new Vec3(-direction.z, 0.0D, direction.x); + var gravity = GravityApi.getGravityDirection(this); + double reach = this.getBbWidth() * 0.5D + 1.0D; + double[] heights = {1.5D, this.getBbHeight() * 0.4D, this.getBbHeight() * 0.75D}; + double[] laterals = {-this.getBbWidth() * 0.3D, 0.0D, this.getBbWidth() * 0.3D}; + for (double height : heights) { + for (double lateral : laterals) { + Vec3 center = this.position().add(direction.scale(reach)).add(side.scale(lateral)) + .add(GravityRotationUtil.vecPlayerToWorld(0.0D, height, 0.0D, gravity)); + RoyalBlockDestruction.destroySphere(level, this, center, OBSTRUCTION_CLEAR_RADIUS, + OBSTRUCTION_CLEAR_MAX_BLOCKS, OBSTRUCTION_CLEAR_MAX_RESISTANCE, OBSTRUCTION_CLEAR_DROP_CHANCE); + } + } + if (toWanted.y > 3.0D) { + RoyalBlockDestruction.destroySphere(level, this, + this.position().add(GravityRotationUtil.vecPlayerToWorld(0.0D, this.getBbHeight() + 1.0D, 0.0D, gravity)), + OBSTRUCTION_CLEAR_RADIUS, OBSTRUCTION_CLEAR_MAX_BLOCKS, OBSTRUCTION_CLEAR_MAX_RESISTANCE, + OBSTRUCTION_CLEAR_DROP_CHANCE); + } + } + + private boolean tryRoyalRecoveryTeleport(LivingEntity target) { + if (!(this.level() instanceof ServerLevel level)) { + return false; + } + boolean inverted = GravityApi.isGravityInverted(this); + for (int attempt = 0; attempt < STUCK_TELEPORT_ATTEMPTS; attempt++) { + double angle = this.random.nextDouble() * Mth.TWO_PI; + double radius = 22.0D + this.random.nextDouble() * 14.0D; + double x = target.getX() + Math.cos(angle) * radius; + double z = target.getZ() + Math.sin(angle) * radius; + double y = inverted + ? target.getY() + target.getBbHeight() - this.getBbHeight() + : this.groundYBelow(x, z, target.getY() + 1.0D) + + (this.isRoyalFlying() ? FLYING_PREFERRED_HOVER : 0.1D); + AABB box = this.getBoundingBox().move(x - this.getX(), y - this.getY(), z - this.getZ()); + if (!level.noCollision(this, box) || level.containsAnyLiquid(box)) { + continue; + } + this.sendRoyalRelocationBurst(level); + this.getNavigation().stop(); + this.teleportTo(x, y, z); + this.setDeltaMovement(Vec3.ZERO); + this.sendRoyalRelocationBurst(level); + level.playSound(null, x, y, z, SoundEvents.ENDERMAN_TELEPORT, SoundSource.HOSTILE, 3.0F, 0.55F); + return true; + } + return false; + } + + private void sendRoyalRelocationBurst(ServerLevel level) { + level.sendParticles(ParticleTypes.REVERSE_PORTAL, + this.getX(), this.getY() + this.getBbHeight() * 0.5D, this.getZ(), + 80, this.getBbWidth() * 0.3D, this.getBbHeight() * 0.3D, this.getBbWidth() * 0.3D, 0.2D); + } + + private double royalDeadZoneRadius() { + return this.getBbWidth() * 0.5D + WING_BUFFET_EXTRA_RADIUS; + } + + private boolean isInRoyalDeadZone(LivingEntity living) { + Vec3 local = GravityRotationUtil.vecWorldToPlayer(living.position().subtract(this.position()), + GravityApi.getGravityDirection(this)); + double radius = this.royalDeadZoneRadius(); + if (local.x * local.x + local.z * local.z > radius * radius + || local.y < -WING_BUFFET_BELOW + || local.y > this.getBbHeight() + WING_BUFFET_ABOVE) { + return false; + } + for (RoyalHead head : this.heads) { + if (this.headWithinBiteReach(head, living)) { + return false; + } + } + return true; + } + + private boolean hasRoyalDeadZoneIntruder(ServerLevel level, LivingEntity primaryTarget) { + if (!(primaryTarget instanceof Player) && this.isInRoyalDeadZone(primaryTarget)) { + return true; + } + AABB area = this.getBoundingBox().inflate(WING_BUFFET_EXTRA_RADIUS + 1.0D, WING_BUFFET_BELOW, + WING_BUFFET_EXTRA_RADIUS + 1.0D); + for (Player player : level.getEntitiesOfClass(Player.class, area, + candidate -> candidate.isAlive() && !candidate.isSpectator() && !candidate.isCreative())) { + if (this.canDamageWithRoyalAttack(player) && this.isInRoyalDeadZone(player)) { + return true; + } + } + return false; + } + + private void tickRoyalCloseRangeAnswer(LivingEntity primaryTarget) { + if (!(this.level() instanceof ServerLevel level)) { + return; + } + boolean intruder = this.hasRoyalDeadZoneIntruder(level, primaryTarget); + this.royalDeadZoneTicks = intruder ? this.royalDeadZoneTicks + 1 : Math.max(0, this.royalDeadZoneTicks - 2); + Phase phase = this.phase(); + if (this.royalDeadZoneTicks < this.royalDeadZoneTriggerTicks(phase) + || this.recoveryWindowTicks > 0 + || !this.attackScheduler.ready(WING_BUFFET_ID, RoyalAttackLane.BODY)) { + return; + } + if (this.beginRoyalAttack(WING_BUFFET_ID, RoyalAttackLane.BODY, this.royalWingBuffetCooldownTicks(phase), + WING_BUFFET_WINDUP_TICKS, 1, this.animationRecovery(55, WING_BUFFET_WINDUP_TICKS, 1, 12), + new RoyalAttackScheduler.Action() { + @Override + public void onStart() { + RoyalBossEntity.this.triggerAnim("wing_action", "wing_gust"); + RoyalBossEntity.this.playRoyalSound(RoyalBossEntity.this.royalWingBuffetSound(), 0.75F); + } + + @Override + public void onWindup(int elapsedTicks, int remainingTicks) { + RoyalBossEntity.this.sendRoyalWingBuffetTelegraph(level, elapsedTicks); + } + + @Override + public void onActive(int elapsedTicks) { + RoyalBossEntity.this.performRoyalWingBuffet(level); + } + })) { + this.royalDeadZoneTicks = 0; + } + } + + private void sendRoyalWingBuffetTelegraph(ServerLevel level, int elapsedTicks) { + if (elapsedTicks % 2 != 0) { + return; + } + double progress = Math.min(1.0D, elapsedTicks / (double) WING_BUFFET_WINDUP_TICKS); + double radius = Mth.lerp(progress, this.getBbWidth() * 0.3D, this.royalDeadZoneRadius()); + var gravity = GravityApi.getGravityDirection(this); + for (int index = 0; index < 40; index++) { + double angle = Mth.TWO_PI * index / 40.0D; + Vec3 point = this.position().add(GravityRotationUtil.vecPlayerToWorld( + Math.cos(angle) * radius, 0.3D, Math.sin(angle) * radius, gravity)); + level.sendParticles(ParticleTypes.CLOUD, point.x, point.y, point.z, 1, 0.0D, 0.02D, 0.0D, 0.0D); + } + } + + private void performRoyalWingBuffet(ServerLevel level) { + float damage = (float) (this.getAttributeValue(Attributes.ATTACK_DAMAGE) * WING_BUFFET_DAMAGE_SCALE); + DamageSource source = this.damageSources().mobAttack(this); + var gravity = GravityApi.getGravityDirection(this); + double radius = this.royalDeadZoneRadius() + 2.0D; + AABB area = this.getBoundingBox().inflate(WING_BUFFET_EXTRA_RADIUS + 3.0D, WING_BUFFET_BELOW + 2.0D, + WING_BUFFET_EXTRA_RADIUS + 3.0D); + for (LivingEntity living : level.getEntitiesOfClass(LivingEntity.class, area, + entity -> entity.isAlive() && entity != this && this.canDamageWithRoyalAttack(entity))) { + if (living instanceof Player player && (player.isCreative() || player.isSpectator())) { + continue; + } + Vec3 local = GravityRotationUtil.vecWorldToPlayer(living.position().subtract(this.position()), gravity); + double horizontalSqr = local.x * local.x + local.z * local.z; + if (horizontalSqr > radius * radius + || local.y < -WING_BUFFET_BELOW - 2.0D + || local.y > this.getBbHeight() + WING_BUFFET_ABOVE + 2.0D) { + continue; + } + living.hurt(source, damage); + if (living instanceof RoyalBossEntity) { + continue; + } + Vec3 outwardLocal = horizontalSqr > 1.0E-4D + ? new Vec3(local.x, 0.0D, local.z).normalize() + : new Vec3(1.0D, 0.0D, 0.0D); + Vec3 outward = GravityRotationUtil.vecPlayerToWorld(outwardLocal, gravity); + Vec3 lift = GravityRotationUtil.vecPlayerToWorld(0.0D, WING_BUFFET_LIFT, 0.0D, + GravityApi.getGravityDirection(living)); + this.addGravityAwareImpulse(living, outward.scale(WING_BUFFET_PUSH).add(lift)); + living.hasImpulse = true; + living.hurtMarked = true; + } + for (int ring = 1; ring <= 3; ring++) { + double ringRadius = this.getBbWidth() * 0.22D * ring; + int samples = 16 + ring * 8; + for (int sample = 0; sample < samples; sample++) { + double angle = Mth.TWO_PI * sample / samples; + Vec3 point = this.position().add(GravityRotationUtil.vecPlayerToWorld( + Math.cos(angle) * ringRadius, 1.0D, Math.sin(angle) * ringRadius, gravity)); + Vec3 velocity = GravityRotationUtil.vecPlayerToWorld( + Math.cos(angle) * 0.45D, 0.04D, Math.sin(angle) * 0.45D, gravity); + level.sendParticles(ParticleTypes.CLOUD, point.x, point.y, point.z, + 0, velocity.x, velocity.y, velocity.z, 1.0D); + } + } + level.sendParticles(ParticleTypes.SWEEP_ATTACK, this.getX(), this.getY() + 2.0D, this.getZ(), + 16, this.getBbWidth() * 0.3D, 1.0D, this.getBbWidth() * 0.3D, 0.0D); + this.playRoyalSound(this.royalWingBuffetSound(), 0.6F); + } + + private void tickRoyalConcealedTarget(LivingEntity target) { + if (!(this.level() instanceof ServerLevel level) || this.tickCount % 10 != 0) { + return; + } + if (this.distanceToSqr(target) > EXCAVATION_RANGE * EXCAVATION_RANGE || this.royalCanSeeTarget(target)) { + this.royalConcealedTicks = 0; + return; + } + this.royalConcealedTicks += 10; + if (this.royalConcealedTicks < EXCAVATION_TRIGGER_TICKS + || this.recoveryWindowTicks > 0 + || !this.attackScheduler.ready(EXCAVATION_ID, RoyalAttackLane.SUMMON)) { + return; + } + RoyalHead head = this.heads[RoyalHead.Slot.CENTER.ordinal()]; + LivingEntity committedTarget = target; + if (this.beginRoyalAttack(EXCAVATION_ID, RoyalAttackLane.SUMMON, EXCAVATION_COOLDOWN_TICKS, + EXCAVATION_WINDUP_TICKS, 1, 10, new RoyalAttackScheduler.Action() { + @Override + public void onStart() { + if (head.readyToAttack()) { + RoyalBossEntity.this.triggerAnim(head.slot().controllerName(), "shoot"); + } + RoyalBossEntity.this.playRoyalSound(RoyalBossEntity.this.royalBeamStartSound(head), 0.8F); + } + + @Override + public void onWindup(int elapsedTicks, int remainingTicks) { + if (committedTarget.isAlive() && committedTarget.level() == level && elapsedTicks % 2 == 0) { + RoyalBossEntity.this.sendRoyalExcavationTelegraph(level, committedTarget); + } + } + + @Override + public void onActive(int elapsedTicks) { + RoyalBossEntity.this.performRoyalExcavation(level, committedTarget); + } + })) { + this.royalConcealedTicks = 0; + } + } + + private boolean royalCanSeeTarget(LivingEntity target) { + Vec3 targetEye = target.getEyePosition(); + if (this.clearRoyalSightLine(this.getEyePosition(), targetEye)) { + return true; + } + for (RoyalHead head : this.heads) { + if (this.clearRoyalSightLine(this.headAnchor(head), targetEye)) { + return true; + } + } + return false; + } + + private boolean clearRoyalSightLine(Vec3 from, Vec3 to) { + return this.level().clip(new ClipContext(from, to, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)) + .getType() == HitResult.Type.MISS; + } + + private void sendRoyalExcavationTelegraph(ServerLevel level, LivingEntity target) { + Vec3 origin = this.headAnchor(this.heads[RoyalHead.Slot.CENTER.ordinal()]); + Vec3 targetCenter = target.position().add(0.0D, target.getBbHeight() * 0.5D, 0.0D); + Vec3 line = targetCenter.subtract(origin); + double length = line.length(); + if (length > 1.0E-3D) { + Vec3 direction = line.scale(1.0D / length); + for (double walked = 0.0D; walked <= length; walked += 2.0D) { + Vec3 point = origin.add(direction.scale(walked)); + level.sendParticles(ParticleTypes.ELECTRIC_SPARK, point.x, point.y, point.z, 1, 0.05D, 0.05D, 0.05D, 0.0D); + } + } + for (int index = 0; index < 20; index++) { + double angle = Mth.TWO_PI * index / 20.0D; + level.sendParticles(ParticleTypes.END_ROD, + targetCenter.x + Math.cos(angle) * EXCAVATION_RADIUS, targetCenter.y, + targetCenter.z + Math.sin(angle) * EXCAVATION_RADIUS, + 1, 0.0D, 0.0D, 0.0D, 0.0D); + } + } + + private void performRoyalExcavation(ServerLevel level, LivingEntity target) { + if (!target.isAlive() || target.level() != level) { + return; + } + Vec3 targetCenter = target.position().add(0.0D, target.getBbHeight() * 0.5D, 0.0D); + Vec3 origin = this.headAnchor(this.heads[RoyalHead.Slot.CENTER.ordinal()]); + Vec3 toward = origin.subtract(targetCenter); + double length = toward.length(); + Vec3 direction = length > 1.0E-4D ? toward.scale(1.0D / length) : Vec3.ZERO; + double depth = Math.min(length, EXCAVATION_DEPTH); + for (double step = 1.5D; step <= depth; step += EXCAVATION_RADIUS) { + Vec3 center = targetCenter.add(direction.scale(step)); + RoyalBlockDestruction.destroySphere(level, this, center, EXCAVATION_RADIUS, EXCAVATION_MAX_BLOCKS, + OBSTRUCTION_CLEAR_MAX_RESISTANCE, OBSTRUCTION_CLEAR_DROP_CHANCE); + level.sendParticles(ParticleTypes.EXPLOSION, center.x, center.y, center.z, 1, 0.4D, 0.4D, 0.4D, 0.0D); + } + level.playSound(null, targetCenter.x, targetCenter.y, targetCenter.z, + SoundEvents.GENERIC_EXPLODE.value(), SoundSource.HOSTILE, 2.0F, 0.7F); + if (!this.royalCanSeeTarget(target)) { + target.hurt(this.damageSources().indirectMagic(this, this), + this.scaleRoyalDamage(EXCAVATION_CONCEALED_DAMAGE)); + } + } + + @Nullable + final Vec3 royalFacingPoint() { + if (this.level().isClientSide || this.isDeadOrDying() || this.phaseTransitionTicks > 0 + || GravityApi.isGravityInverted(this)) { + return null; + } + LivingEntity target = this.getTarget(); + if (target == null || !target.isAlive() || !this.canAttack(target) || !this.royalShouldFaceTarget(target)) { + return null; + } + return target.position(); + } + + final void turnRoyalBodyToward(Vec3 point) { + double dx = point.x - this.getX(); + double dz = point.z - this.getZ(); + if (dx * dx + dz * dz < 1.0E-4D) { + return; + } + float desiredYaw = (float) (Mth.atan2(dz, dx) * Mth.RAD_TO_DEG) - 90.0F; + float turn = Mth.clamp(Mth.wrapDegrees(desiredYaw - this.getYRot()), -FACING_TURN_RATE, FACING_TURN_RATE); + this.setYRot(this.getYRot() + turn); + this.yBodyRot = this.getYRot(); + } + + private static void applyRelativeInput(Mob mob, double dx, double dz, float speed) { + double length = Math.sqrt(dx * dx + dz * dz); + double yaw = mob.getYRot() * Mth.DEG_TO_RAD; + double nx = dx / length; + double nz = dz / length; + float forward = (float) (-nx * Math.sin(yaw) + nz * Math.cos(yaw)); + float strafe = (float) (nx * Math.cos(yaw) + nz * Math.sin(yaw)); + mob.setSpeed(speed); + mob.setZza(forward * speed); + mob.setXxa(strafe * speed); + } + + private static final class RoyalGroundMoveControl extends MoveControl { + private final RoyalBossEntity boss; + + private RoyalGroundMoveControl(RoyalBossEntity boss) { + super(boss); + this.boss = boss; + } + + @Override + public void setWantedPosition(double x, double y, double z, double speed) { + super.setWantedPosition(x, y, z, speed); + this.boss.markRoyalMoveRequested(); + } + + @Override + public void tick() { + Vec3 facing = this.boss.royalFacingPoint(); + if (facing == null) { + super.tick(); + return; + } + if (this.operation != Operation.MOVE_TO) { + boolean waiting = this.operation == Operation.WAIT; + super.tick(); + if (waiting) { + this.mob.setXxa(0.0F); + } + this.boss.turnRoyalBodyToward(facing); + return; + } + this.operation = Operation.WAIT; + double dx = this.wantedX - this.mob.getX(); + double dy = this.wantedY - this.mob.getY(); + double dz = this.wantedZ - this.mob.getZ(); + double horizontalSqr = dx * dx + dz * dz; + this.boss.turnRoyalBodyToward(facing); + if (horizontalSqr < 2.5E-7D) { + this.mob.setZza(0.0F); + this.mob.setXxa(0.0F); + return; + } + float speed = (float) (this.speedModifier * this.mob.getAttributeValue(Attributes.MOVEMENT_SPEED)); + applyRelativeInput(this.mob, dx, dz, speed); + if (dy > this.mob.maxUpStep() && horizontalSqr < Math.max(1.0F, this.mob.getBbWidth())) { + this.mob.getJumpControl().jump(); + this.operation = Operation.JUMPING; + } + } + } + + private static final class RoyalFlyingMoveControl extends FlyingMoveControl { + private final RoyalBossEntity boss; + private final int maxPitchTurn; + + private RoyalFlyingMoveControl(RoyalBossEntity boss, int maxTurn) { + super(boss, maxTurn, true); + this.boss = boss; + this.maxPitchTurn = maxTurn; + } + + @Override + public void setWantedPosition(double x, double y, double z, double speed) { + super.setWantedPosition(x, y, z, speed); + this.boss.markRoyalMoveRequested(); + } + + @Override + public void tick() { + Vec3 facing = this.boss.royalFacingPoint(); + if (facing == null) { + super.tick(); + return; + } + if (this.operation != Operation.MOVE_TO) { + super.tick(); + this.mob.setXxa(0.0F); + this.boss.turnRoyalBodyToward(facing); + return; + } + this.operation = Operation.WAIT; + this.mob.setNoGravity(true); + double dx = this.wantedX - this.mob.getX(); + double dy = this.wantedY - this.mob.getY(); + double dz = this.wantedZ - this.mob.getZ(); + this.boss.turnRoyalBodyToward(facing); + if (dx * dx + dy * dy + dz * dz < 2.5E-7D) { + this.mob.setYya(0.0F); + this.mob.setZza(0.0F); + this.mob.setXxa(0.0F); + return; + } + float speed = (float) (this.speedModifier * this.mob.getAttributeValue( + this.mob.onGround() ? Attributes.MOVEMENT_SPEED : Attributes.FLYING_SPEED)); + double horizontal = Math.sqrt(dx * dx + dz * dz); + if (horizontal > 1.0E-5D) { + applyRelativeInput(this.mob, dx, dz, speed); + } else { + this.mob.setSpeed(speed); + this.mob.setZza(0.0F); + this.mob.setXxa(0.0F); + } + float pitch = (float) (-(Mth.atan2(dy, horizontal) * Mth.RAD_TO_DEG)); + this.mob.setXRot(this.rotlerp(this.mob.getXRot(), pitch, this.maxPitchTurn)); + this.mob.setYya(dy > 0.0D ? speed : -speed); + } + } + protected double combatStandoffDistance() { return Math.max(this.getBbWidth() * 0.55D, BEAM_MUZZLE_FORWARD - this.biteReach() * 0.65D + 1.0D); @@ -968,8 +1580,9 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult boolean inverted = GravityApi.isGravityInverted(this); double groundY = this.groundYBelow(this.getX(), this.getZ()); if (this.landingForCombat) { - if (!target.onGround()) { + if (!target.onGround() || ++this.landingForCombatTicks > LANDING_FOR_COMBAT_TIMEOUT_TICKS) { this.landingForCombat = false; + this.landingForCombatTicks = 0; this.locomotionDecisionTicks = 60; } else if (this.onGround() || !inverted && this.getY() <= groundY + 1.0D) { this.landingForCombat = false; @@ -986,6 +1599,7 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult this.locomotionDecisionTicks = 60 + this.random.nextInt(80); if (target.onGround() && this.random.nextDouble() < this.groundCombatBias()) { this.landingForCombat = true; + this.landingForCombatTicks = 0; } } else if (!target.onGround() || this.random.nextDouble() >= this.groundCombatBias()) { this.setRoyalFlying(true); @@ -1012,8 +1626,61 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult } protected double groundYBelow(double x, double z) { - return this.level().getHeight(net.minecraft.world.level.levelgen.Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, - Mth.floor(x), Mth.floor(z)); + return this.groundYBelow(x, z, this.getY() + 1.0D); + } + + protected double groundYBelow(double x, double z, double referenceY) { + Level level = this.level(); + int blockX = Mth.floor(x); + int blockZ = Mth.floor(z); + int surface = level.getHeight(net.minecraft.world.level.levelgen.Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, + blockX, blockZ); + int startY = Mth.floor(referenceY); + if (startY >= surface) { + return surface; + } + net.minecraft.core.BlockPos.MutableBlockPos cursor = new net.minecraft.core.BlockPos.MutableBlockPos(blockX, startY, blockZ); + if (this.isRoyalGroundBlock(level, cursor)) { + int top = Math.min(surface, startY + GROUND_SCAN_RISE); + for (int y = startY + 1; y <= top; y++) { + cursor.setY(y); + if (!this.isRoyalGroundBlock(level, cursor)) { + return y; + } + } + return surface; + } + int bottom = Math.max(level.getMinBuildHeight(), startY - GROUND_SCAN_DEPTH); + for (int y = startY - 1; y >= bottom; y--) { + cursor.setY(y); + if (this.isRoyalGroundBlock(level, cursor)) { + return y + 1; + } + } + return bottom; + } + + protected double ceilingYAbove(double x, double z, double referenceY) { + Level level = this.level(); + net.minecraft.core.BlockPos.MutableBlockPos cursor = new net.minecraft.core.BlockPos.MutableBlockPos( + Mth.floor(x), Mth.floor(referenceY), Mth.floor(z)); + int startY = cursor.getY(); + int top = Math.min(level.getMaxBuildHeight() - 1, startY + GROUND_SCAN_DEPTH); + for (int y = startY; y <= top; y++) { + cursor.setY(y); + if (this.isRoyalGroundBlock(level, cursor)) { + return y; + } + } + return top; + } + + private boolean isRoyalGroundBlock(Level level, net.minecraft.core.BlockPos pos) { + net.minecraft.world.level.block.state.BlockState state = level.getBlockState(pos); + if (state.isAir() || state.is(net.minecraft.tags.BlockTags.LEAVES)) { + return false; + } + return !state.getFluidState().isEmpty() || !state.getCollisionShape(level, pos).isEmpty(); } private void tickFlyingAltitude() { @@ -1025,6 +1692,10 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult } double groundY = this.groundYBelow(this.getX(), this.getZ()); double ceiling = groundY + FLYING_MAX_HOVER_ABOVE_GROUND; + LivingEntity target = this.getTarget(); + if (target != null && target.isAlive()) { + ceiling = Math.max(ceiling, target.getY() + 8.0D); + } if (this.getY() > ceiling) { double desiredY = groundY + FLYING_PREFERRED_HOVER; this.getMoveControl().setWantedPosition(this.getX(), desiredY, this.getZ(), 1.0D); @@ -1035,15 +1706,33 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult } } + private boolean isFightingRoyalRival() { + return this.getTarget() instanceof RoyalBossEntity; + } + private void tickBodyCrush() { - if (!(this.level() instanceof ServerLevel serverLevel) || this.tickCount % 10 != 0) { + if (!(this.level() instanceof ServerLevel serverLevel) + || this.tickCount % (this.isFightingRoyalRival() ? RIVAL_BODY_CRUSH_INTERVAL_TICKS : BODY_CRUSH_INTERVAL_TICKS) != 0) { return; } - if (this.getDeltaMovement().horizontalDistanceSqr() < 0.0016D) { + Vec3 horizontalMovement = this.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D); + boolean moving = horizontalMovement.lengthSqr() >= 0.0016D; + if (!moving && !this.horizontalCollision) { return; } - double yaw = this.yBodyRot * Mth.DEG_TO_RAD; - Vec3 forward = new Vec3(-Math.sin(yaw), 0.0D, Math.cos(yaw)); + Vec3 forward; + if (moving) { + forward = horizontalMovement.normalize(); + } else { + Vec3 toWanted = new Vec3(this.getMoveControl().getWantedX() - this.getX(), 0.0D, + this.getMoveControl().getWantedZ() - this.getZ()); + if (toWanted.lengthSqr() > 1.0E-4D) { + forward = toWanted.normalize(); + } else { + double yaw = this.yBodyRot * Mth.DEG_TO_RAD; + forward = new Vec3(-Math.sin(yaw), 0.0D, Math.cos(yaw)); + } + } Vec3 center = new Vec3( this.getX() + forward.x * (this.getBbWidth() * 0.45D), this.getY() + (this.isRoyalFlying() ? 0.0D : 1.0D), @@ -1166,11 +1855,30 @@ public abstract class RoyalBossEntity extends Monster implements GeoEntity, Mult protected Vec3 beamDirection(RoyalHead head) { float yaw = this.getYRot() * Mth.DEG_TO_RAD; - Vec3 localDirection = new Vec3(-Math.sin(yaw), 0.0D, Math.cos(yaw)); + double pitch = this.royalBeamPitch(head); + double horizontal = Math.cos(pitch); + Vec3 localDirection = new Vec3(-Math.sin(yaw) * horizontal, Math.sin(pitch), Math.cos(yaw) * horizontal); return GravityRotationUtil.vecPlayerToWorld(localDirection, GravityApi.getGravityDirection(this)).normalize(); } + private double royalBeamPitch(RoyalHead head) { + if (this.level().isClientSide) { + return 0.0D; + } + LivingEntity target = head.target(this.level()); + if (target == null) { + return 0.0D; + } + Vec3 local = GravityRotationUtil.vecWorldToPlayer(target.getEyePosition().subtract(this.beamAnchor(head)), + GravityApi.getGravityDirection(this)); + double horizontal = Math.sqrt(local.x * local.x + local.z * local.z); + if (horizontal < 1.0E-3D) { + return 0.0D; + } + return Mth.clamp(Math.atan2(local.y, horizontal), -MAX_BEAM_PITCH, MAX_BEAM_PITCH); + } + protected boolean targetInBeamLine(RoyalHead head, LivingEntity target) { Vec3 origin = this.beamAnchor(head); Vec3 direction = this.beamDirection(head); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalElementalProjectileEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalElementalProjectileEntity.java index 193a41f2..2025b9c2 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalElementalProjectileEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalElementalProjectileEntity.java @@ -133,6 +133,25 @@ public class RoyalElementalProjectileEntity extends ThrowableProjectile implemen } } + @Override + protected boolean canHitEntity(Entity target) { + Entity owner = this.getOwner(); + if (owner != null && target == owner) { + return false; + } + if (owner instanceof com.craisinlord.anthology.multipart.MultipartEntityOwner multipart) { + Entity[] parts = multipart.anthology$getMultipartParts(); + if (parts != null) { + for (Entity part : parts) { + if (part == target) { + return false; + } + } + } + } + return super.canHitEntity(target); + } + @Override protected void onHitEntity(EntityHitResult result) { if (!this.level().isClientSide && this.level() instanceof ServerLevel level) { diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalMountCombatGoal.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalMountCombatGoal.java new file mode 100644 index 00000000..dfa6df54 --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalMountCombatGoal.java @@ -0,0 +1,239 @@ +package com.craisinlord.antarchy.content.entity.royal; + +import java.util.EnumSet; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.goal.Goal; +import net.minecraft.world.phys.Vec3; + +public class RoyalMountCombatGoal extends Goal { + private static final int FLIGHT_DECISION_INTERVAL = 40; + + private final RoyalMountEntity mount; + private LivingEntity target; + private int repathTicks; + private int flightDecisionTicks; + private boolean wantsFlight; + private int stuckTicks; + private Vec3 lastCheckPosition = Vec3.ZERO; + private float orbitAngle; + private int orbitDirection = 1; + private int diveTicks; + private int unseenTicks; + + public RoyalMountCombatGoal(RoyalMountEntity mount) { + this.mount = mount; + this.setFlags(EnumSet.of(Goal.Flag.MOVE, Goal.Flag.LOOK)); + } + + @Override + public boolean canUse() { + LivingEntity candidate = this.mount.getTarget(); + if (!this.isValid(candidate)) { + return false; + } + this.target = candidate; + return true; + } + + @Override + public boolean canContinueToUse() { + LivingEntity current = this.mount.getTarget(); + if (current != this.target || !this.isValid(current)) { + return false; + } + double range = this.mount.getAttributeValue(net.minecraft.world.entity.ai.attributes.Attributes.FOLLOW_RANGE) * 1.2D; + return this.mount.distanceToSqr(current) < range * range && this.unseenTicks < 200; + } + + private boolean isValid(LivingEntity candidate) { + return candidate != null && candidate.isAlive() && !this.mount.isVehicle() && !this.mount.isOrderedToSit() + && candidate.level() == this.mount.level() && this.mount.canAttack(candidate); + } + + @Override + public void start() { + this.repathTicks = 0; + this.flightDecisionTicks = 0; + this.wantsFlight = false; + this.stuckTicks = 0; + this.unseenTicks = 0; + this.diveTicks = 0; + this.lastCheckPosition = this.mount.position(); + Vec3 offset = this.mount.position().subtract(this.target.position()); + this.orbitAngle = (float) Mth.atan2(offset.z, offset.x); + this.orbitDirection = this.mount.getRandom().nextBoolean() ? 1 : -1; + } + + @Override + public void stop() { + this.target = null; + this.mount.getNavigation().stop(); + } + + @Override + public boolean requiresUpdateEveryTick() { + return true; + } + + @Override + public void tick() { + LivingEntity current = this.target; + if (current == null) { + return; + } + boolean canSee = this.mount.getSensing().hasLineOfSight(current); + this.unseenTicks = canSee ? 0 : this.unseenTicks + 1; + double gap = this.mount.combatGap(current); + this.mount.getLookControl().setLookAt(current, 30.0F, 30.0F); + this.trackStuck(); + this.updateFlightDecision(current, gap); + + if (this.mount.isActing()) { + this.holdDuringAction(current); + return; + } + + int chosen = this.mount.chooseCombatAction(current, gap, canSee); + if (chosen != RoyalMountEntity.ACTION_NONE && this.isFacing(current, this.facingTolerance(chosen))) { + if (this.mount.startAction(chosen, current, current.getEyePosition(), false)) { + this.diveTicks = 0; + this.holdDuringAction(current); + return; + } + } + if (chosen != RoyalMountEntity.ACTION_NONE) { + this.mount.turnTowards(current.position(), 18.0F); + } + + if (this.mount.isFlying()) { + this.tickAerial(current, gap); + } else { + this.tickGround(current, gap, canSee); + } + } + + private float facingTolerance(int action) { + return switch (action) { + case RoyalMountEntity.ACTION_BITE -> 50.0F; + case RoyalMountEntity.ACTION_SIGNATURE -> 180.0F; + default -> 120.0F; + }; + } + + private boolean isFacing(LivingEntity current, float tolerance) { + Vec3 toTarget = current.position().subtract(this.mount.position()); + float desired = (float) (Mth.atan2(toTarget.z, toTarget.x) * Mth.RAD_TO_DEG) - 90.0F; + return Math.abs(Mth.wrapDegrees(desired - this.mount.getYRot())) <= tolerance; + } + + private void holdDuringAction(LivingEntity current) { + this.mount.getNavigation().stop(); + if (this.mount.isFlying()) { + this.mount.claimFlight(); + if (this.mount.currentAction() == RoyalMountEntity.ACTION_BITE) { + this.mount.getMoveControl().setWantedPosition(current.getX(), current.getY() + current.getBbHeight() * 0.5D, current.getZ(), 0.6D); + } else { + this.mount.getMoveControl().setWantedPosition(this.mount.getX(), this.mount.getY(), this.mount.getZ(), 0.4D); + } + } else if (this.mount.currentAction() != RoyalMountEntity.ACTION_BITE) { + this.mount.setDeltaMovement(this.mount.getDeltaMovement().multiply(0.5D, 1.0D, 0.5D)); + } + } + + private void trackStuck() { + if (this.mount.tickCount % 20 != 0) { + return; + } + Vec3 position = this.mount.position(); + boolean trying = !this.mount.getNavigation().isDone() || this.mount.isFlying(); + if (trying && position.distanceToSqr(this.lastCheckPosition) < 1.0D) { + this.stuckTicks += 20; + } else { + this.stuckTicks = 0; + } + this.lastCheckPosition = position; + } + + private void updateFlightDecision(LivingEntity current, double gap) { + if (!this.mount.canFly()) { + this.wantsFlight = false; + return; + } + if (--this.flightDecisionTicks <= 0 || this.stuckTicks >= 40) { + this.flightDecisionTicks = FLIGHT_DECISION_INTERVAL; + boolean targetAbove = current.getY() - this.mount.getY() > 4.0D + this.mount.getBbHeight() * 0.25D; + boolean targetAirborne = !current.onGround() && !current.isInWater() && RoyalMountEntity.isAirborne(current) || targetAbove; + boolean groundBlocked = !this.mount.isFlying() && (this.stuckTicks >= 40 + || this.mount.getNavigation().isDone() && gap > 4.0D && this.mount.getNavigation().createPath(current, 0) == null); + boolean prefersAir = this.mount.prefersAerialCombat() && gap > 3.0D; + this.wantsFlight = targetAirborne || groundBlocked || prefersAir || (this.mount.isFlying() && this.diveTicks > 0); + if (this.stuckTicks >= 40) { + this.stuckTicks = 0; + } + } + if (this.wantsFlight) { + this.mount.claimFlight(); + } + } + + private void tickAerial(LivingEntity current, double gap) { + if (!this.wantsFlight) { + return; + } + this.mount.claimFlight(); + float scale = this.mount.getGrowthScale(); + boolean wantsBite = this.mount.isActionAvailable(RoyalMountEntity.ACTION_BITE) + && (!this.mount.prefersAerialCombat() || gap < this.mount.preferredCombatRange() * 0.5D || this.diveTicks > 0); + if (wantsBite && this.mount.isActionReady()) { + this.diveTicks++; + Vec3 approach = current.position().subtract(this.mount.position()).multiply(1.0D, 0.0D, 1.0D); + Vec3 offset = approach.lengthSqr() > 1.0E-4D ? approach.normalize().scale(-(this.mount.getBbWidth() * 0.5D + 0.6D * scale)) : Vec3.ZERO; + this.mount.getMoveControl().setWantedPosition(current.getX() + offset.x, current.getY() + 0.2D, current.getZ() + offset.z, 1.4D); + if (this.diveTicks > 80) { + this.diveTicks = 0; + this.orbitDirection = -this.orbitDirection; + } + return; + } + this.diveTicks = 0; + double radius = Math.max(6.0D + 1.5D * scale, this.mount.preferredCombatRange()) + this.mount.getBbWidth() * 0.5D; + this.orbitAngle += this.orbitDirection * (float) Math.min(0.08D, 1.2D / radius); + double x = current.getX() + Math.cos(this.orbitAngle) * radius; + double z = current.getZ() + Math.sin(this.orbitAngle) * radius; + double y = current.getY() + 3.0D + 0.8D * scale; + if (!this.mount.canOccupy(x, y, z)) { + this.orbitDirection = -this.orbitDirection; + y += 2.0D + scale; + } + this.mount.getMoveControl().setWantedPosition(x, y, z, 1.1D); + } + + private void tickGround(LivingEntity current, double gap, boolean canSee) { + double preferred = this.mount.preferredCombatRange(); + boolean ranged = preferred > 0.0D && this.mount.canSpit(); + if (ranged && canSee && gap < preferred * 0.5D && !this.mount.isActionAvailable(RoyalMountEntity.ACTION_BITE)) { + Vec3 away = this.mount.position().subtract(current.position()).multiply(1.0D, 0.0D, 1.0D); + if (away.lengthSqr() > 1.0E-4D && --this.repathTicks <= 0) { + this.repathTicks = 10; + Vec3 destination = this.mount.position().add(away.normalize().scale(4.0D + this.mount.getBbWidth() * 0.5D)); + this.mount.getNavigation().moveTo(destination.x, destination.y, destination.z, 1.2D); + } + return; + } + if (ranged && canSee && gap <= preferred && gap >= preferred * 0.5D && !this.mount.isActionAvailable(RoyalMountEntity.ACTION_BITE)) { + this.mount.getNavigation().stop(); + this.mount.turnTowards(current.position(), 12.0F); + return; + } + if (this.mount.canBiteReach(current)) { + this.mount.getNavigation().stop(); + this.mount.turnTowards(current.position(), 18.0F); + return; + } + if (--this.repathTicks <= 0) { + this.repathTicks = 6 + this.mount.getRandom().nextInt(6); + this.mount.getNavigation().moveTo(current, 1.2D); + } + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalMountCompanionGoal.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalMountCompanionGoal.java new file mode 100644 index 00000000..d715ac1a --- /dev/null +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalMountCompanionGoal.java @@ -0,0 +1,175 @@ +package com.craisinlord.antarchy.content.entity.royal; + +import java.util.EnumSet; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.goal.Goal; +import net.minecraft.world.phys.Vec3; + +public class RoyalMountCompanionGoal extends Goal { + private static final double MAX_OWNER_DISTANCE = 40.0D; + + private final RoyalMountEntity mount; + private LivingEntity owner; + private int side = 1; + private float orbitAngle; + private int repathTicks; + private int settledTicks; + private int cooldown; + private Vec3 spot; + + public RoyalMountCompanionGoal(RoyalMountEntity mount) { + this.mount = mount; + this.setFlags(EnumSet.of(Goal.Flag.MOVE, Goal.Flag.LOOK)); + } + + private boolean isEligible(LivingEntity candidate) { + return candidate != null && candidate.isAlive() && !candidate.isSpectator() + && candidate.level() == this.mount.level() + && this.mount.isTame() && !this.mount.isVehicle() && !this.mount.isOrderedToSit() + && !this.mount.isLeashed() && this.mount.getTarget() == null && !this.mount.isActing() + && this.mount.distanceToSqr(candidate) < MAX_OWNER_DISTANCE * MAX_OWNER_DISTANCE; + } + + private double settleDistance() { + return 4.0D + this.mount.getBbWidth() * 0.6D; + } + + private boolean needsToReposition(LivingEntity candidate) { + if (this.mount.canFly() && RoyalMountEntity.isAirborne(candidate)) { + return true; + } + if (this.mount.isFlying()) { + return true; + } + double settle = this.settleDistance() + 2.0D; + return this.mount.distanceToSqr(candidate) > settle * settle; + } + + @Override + public boolean canUse() { + if (this.cooldown > 0) { + this.cooldown--; + return false; + } + LivingEntity candidate = this.mount.getOwner(); + if (!this.isEligible(candidate) || !this.needsToReposition(candidate)) { + return false; + } + this.owner = candidate; + return true; + } + + @Override + public boolean canContinueToUse() { + return this.isEligible(this.owner) && this.owner == this.mount.getOwner() && this.settledTicks < 40; + } + + @Override + public void start() { + this.side = this.mount.getRandom().nextBoolean() ? 1 : -1; + this.repathTicks = 0; + this.settledTicks = 0; + this.spot = null; + Vec3 offset = this.mount.position().subtract(this.owner.position()); + this.orbitAngle = (float) Mth.atan2(offset.z, offset.x); + } + + @Override + public void stop() { + this.owner = null; + this.spot = null; + this.cooldown = 20; + this.mount.getNavigation().stop(); + } + + @Override + public boolean requiresUpdateEveryTick() { + return true; + } + + @Override + public void tick() { + float scale = this.mount.getGrowthScale(); + if (this.mount.canFly() && RoyalMountEntity.isAirborne(this.owner)) { + this.settledTicks = 0; + this.spot = null; + this.mount.claimFlight(); + this.circleOwner(scale); + return; + } + + if (--this.repathTicks <= 0 || this.spot == null) { + this.repathTicks = 20; + this.spot = this.pickSpotBesideOwner(); + } + + if (this.mount.isFlying()) { + this.settledTicks = 0; + this.mount.getLookControl().setLookAt(this.owner, 10.0F, this.mount.getMaxHeadXRot()); + if (this.mount.onGround() || this.mount.isInWater()) { + this.mount.setFlying(false); + return; + } + this.mount.claimFlight(); + Vec3 target = this.spot != null ? this.spot : this.owner.position(); + double horizontal = Math.sqrt(Mth.square(target.x - this.mount.getX()) + Mth.square(target.z - this.mount.getZ())); + double y = horizontal > 3.0D + scale ? Math.max(target.y + 1.5D * scale, this.mount.getY() - 2.0D) : target.y - 0.5D; + this.mount.getMoveControl().setWantedPosition(target.x, y, target.z, 1.0D); + return; + } + + double settle = this.settleDistance(); + boolean nearOwner = this.mount.distanceToSqr(this.owner) <= settle * settle; + boolean nearSpot = this.spot != null && this.mount.position().distanceToSqr(this.spot) <= Mth.square(1.5D + 0.5D * scale); + if (nearOwner || nearSpot) { + this.mount.getNavigation().stop(); + if (this.settledTicks == 0) { + this.mount.turnTowards(this.mount.position().add(this.owner.getLookAngle().multiply(1.0D, 0.0D, 1.0D)), 30.0F); + if (this.mount.getRandom().nextInt(4) == 0) { + this.mount.triggerQuirk(); + } + } + this.mount.getLookControl().setLookAt(this.owner, 10.0F, this.mount.getMaxHeadXRot()); + this.settledTicks++; + return; + } + this.settledTicks = 0; + this.mount.getLookControl().setLookAt(this.owner, 10.0F, this.mount.getMaxHeadXRot()); + if (this.repathTicks == 20) { + Vec3 destination = this.spot != null ? this.spot : this.owner.position(); + if (!this.mount.getNavigation().moveTo(destination.x, destination.y, destination.z, 1.0D)) { + this.mount.getNavigation().moveTo(this.owner, 1.0D); + } + } + } + + private void circleOwner(float scale) { + double radius = 5.0D + this.mount.getBbWidth() * 0.75D; + this.orbitAngle += this.side * (float) Math.min(0.07D, 1.0D / radius); + double x = this.owner.getX() + Math.cos(this.orbitAngle) * radius; + double z = this.owner.getZ() + Math.sin(this.orbitAngle) * radius; + double y = this.owner.getY() + 2.0D + 0.6D * scale; + if (!this.mount.canOccupy(x, y, z)) { + y += 2.0D + scale; + } + this.mount.getMoveControl().setWantedPosition(x, y, z, 1.2D); + this.mount.getLookControl().setLookAt(this.owner, 10.0F, this.mount.getMaxHeadXRot()); + } + + private Vec3 pickSpotBesideOwner() { + Vec3 facing = Vec3.directionFromRotation(0.0F, this.owner.getYRot()); + Vec3 right = new Vec3(-facing.z, 0.0D, facing.x); + double distance = this.mount.getBbWidth() * 0.5D + 1.5D; + for (int attempt = 0; attempt < 2; attempt++) { + int currentSide = attempt == 0 ? this.side : -this.side; + Vec3 base = this.owner.position().add(right.scale(currentSide * distance)); + double ground = this.mount.findGroundY(base.x, this.owner.getY() + 3.0D, base.z, 10); + if (!Double.isNaN(ground) && this.mount.canOccupy(base.x, ground, base.z)) { + this.side = currentSide; + return new Vec3(base.x, ground, base.z); + } + } + return null; + } +} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalMountEntity.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalMountEntity.java index 3fdb8d95..2d1ab2a0 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalMountEntity.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalMountEntity.java @@ -1,21 +1,20 @@ package com.craisinlord.antarchy.content.entity.royal; -import com.craisinlord.antarchy.config.AntarchySettings; -import com.craisinlord.antarchy.content.AntarchySoundEvents; import com.craisinlord.antarchy.content.AntarchyTags; import com.craisinlord.antarchy.content.entity.royal.beam.RoyalBeamElement; import com.craisinlord.anthology.beam.BeamController; +import com.craisinlord.anthology.beam.BeamOwner; import com.craisinlord.anthology.beam.BeamSettings; import com.craisinlord.anthology.beam.BeamTerrainMode; -import com.craisinlord.antarchy.content.effect.RoyalEffectEligibility; -import com.craisinlord.antarchy.content.effect.RoyalEffectHooks; -import com.craisinlord.anthology.time.TimeDilationApi; -import net.minecraft.resources.ResourceLocation; import net.minecraft.core.BlockPos; +import net.minecraft.core.particles.ParticleOptions; +import net.minecraft.core.particles.ParticleTypes; import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundEvent; @@ -31,10 +30,12 @@ import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.MoverType; +import net.minecraft.world.entity.OwnableEntity; import net.minecraft.world.entity.Pose; import net.minecraft.world.entity.TamableAnimal; -import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.ai.attributes.AttributeInstance; import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.ai.control.FlyingMoveControl; import net.minecraft.world.entity.ai.control.MoveControl; @@ -49,32 +50,37 @@ import net.minecraft.world.entity.ai.goal.target.OwnerHurtTargetGoal; import net.minecraft.world.entity.ai.navigation.FlyingPathNavigation; import net.minecraft.world.entity.ai.navigation.GroundPathNavigation; import net.minecraft.world.entity.ai.navigation.PathNavigation; -import net.minecraft.world.entity.monster.Enemy; import net.minecraft.world.entity.animal.FlyingAnimal; +import net.minecraft.world.entity.monster.Creeper; +import net.minecraft.world.entity.monster.Enemy; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.ProjectileUtil; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; +import net.minecraft.world.level.ClipContext; import net.minecraft.world.level.Level; -import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.pathfinder.PathType; import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.EntityHitResult; import net.minecraft.world.phys.Vec3; -import net.minecraft.world.effect.MobEffectInstance; -import net.minecraft.core.particles.ParticleTypes; import org.jetbrains.annotations.Nullable; import software.bernie.geckolib.animatable.GeoEntity; import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache; -import software.bernie.geckolib.animation.Animation; import software.bernie.geckolib.animation.AnimatableManager; +import software.bernie.geckolib.animation.Animation; import software.bernie.geckolib.animation.AnimationController; import software.bernie.geckolib.animation.AnimationState; import software.bernie.geckolib.animation.PlayState; import software.bernie.geckolib.animation.RawAnimation; import software.bernie.geckolib.util.GeckoLibUtil; -public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntity, FlyingAnimal { +public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntity, FlyingAnimal, BeamOwner { private static final ResourceLocation GROWTH_HEALTH_MODIFIER = ResourceLocation.fromNamespaceAndPath("antarchy", "royal_mount_growth_health"); + private static final ResourceLocation GROWTH_DAMAGE_MODIFIER = ResourceLocation.fromNamespaceAndPath("antarchy", "royal_mount_growth_damage"); + private static final ResourceLocation GROWTH_SPEED_MODIFIER = ResourceLocation.fromNamespaceAndPath("antarchy", "royal_mount_growth_speed"); + private static final ResourceLocation GROWTH_FLYING_SPEED_MODIFIER = ResourceLocation.fromNamespaceAndPath("antarchy", "royal_mount_growth_flying_speed"); + public static final int ANIM_IDLE = 0; public static final int ANIM_WALK = 1; public static final int ANIM_FLY = 2; @@ -83,6 +89,22 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit public static final int ANIM_SHOOT = 5; public static final int ANIM_FLY_SHOOT = 6; + public static final int ACTION_NONE = 0; + public static final int ACTION_BITE = 1; + public static final int ACTION_SPIT = 2; + public static final int ACTION_BEAM = 3; + public static final int ACTION_SIGNATURE = 4; + + public static final float MAX_SCALE = 5.0F; + public static final float JUVENILE_PROGRESS = 0.25F; + public static final float ADULT_PROGRESS = 0.75F; + private static final float GOLDEN_APPLE_GROWTH = 0.025F; + private static final float ENCHANTED_APPLE_GROWTH = 0.125F; + + private static final double SEAT_HEIGHT = 17.0D / 16.0D; + private static final double SEAT_BACK = 2.0D / 16.0D; + private static final double FLY_BOB_HEIGHT = 9.0D / 16.0D; + private static final EntityDataAccessor ANIM_STATE = SynchedEntityData.defineId(RoyalMountEntity.class, EntityDataSerializers.INT); private static final EntityDataAccessor FLYING = @@ -115,33 +137,49 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit private static final RawAnimation SHOOT_ANIM = RawAnimation.begin().then("shoot", Animation.LoopType.PLAY_ONCE); private static final RawAnimation FLY_SHOOT_ANIM = RawAnimation.begin().then("fly_shoot", Animation.LoopType.PLAY_ONCE); - private static final int ACTION_TICKS = 12; + private static final int BITE_TICKS = 12; private static final int BITE_HIT_TICK = 6; + private static final int BITE_COOLDOWN_TICKS = 14; + private static final int SPIT_TICKS = 20; + private static final int SPIT_FIRE_TICK = 8; + private static final int SPIT_COOLDOWN_TICKS = 50; private static final int BEAM_WINDUP_TICKS = 24; + private static final int BEAM_DURATION_TICKS = 14; + private static final int BEAM_RECOVERY_TICKS = 10; private static final int BEAM_COOLDOWN_TICKS = 240; - private static final int BEAM_DURATION_TICKS = 12; - private static final int COMMAND_COOLDOWN_TICKS = 360; - private static final int TIME_FIELD_COOLDOWN_TICKS = 260; + private static final int SIGNATURE_WINDUP_TICKS = 20; + private static final int SIGNATURE_TICKS = 30; + private static final int ACTION_RECOVERY_TICKS = 8; private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this); private final MoveControl groundMoveControl; private final MoveControl flyingMoveControl; private final PathNavigation groundNavigation; private final PathNavigation flyingNavigation; + private final BeamController beamController = new BeamController(this); + private int action = ACTION_NONE; private int actionTicks; - private boolean actionHit; - private int spitCooldown; + private boolean actionFired; + private boolean actionRidden; + @Nullable + private LivingEntity actionTarget; + @Nullable + private Vec3 actionAimPoint; + private int actionRecoveryTicks; + private int lastAction = ACTION_NONE; + private int biteCooldownTicks; + private int spitCooldownTicks; + private int beamCooldownTicks; + private int signatureCooldownTicks; + private int beamHead; + private int quirkTimer; private int flapSoundTimer; + private int flightClaimTick = -100; + private int ownerAwayTicks; private boolean riderAscendPressed; private boolean riderDescendPressed; - private final BeamController beamController = new BeamController(this); - private int beamWindupTicks; - private int beamCooldownTicks; - private int beamHead; - private int commandCooldownTicks; - private int timeFieldCooldownTicks; protected RoyalMountEntity(EntityType entityType, Level level) { super(entityType, level); @@ -172,6 +210,22 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit .add(Attributes.STEP_HEIGHT, 1.5D); } + public enum Stage { + HATCHLING("hatchling"), + JUVENILE("juvenile"), + ADULT("adult"); + + private final String id; + + Stage(String id) { + this.id = id; + } + + public Component displayName() { + return Component.translatable("entity.antarchy.royal_mount.stage." + this.id); + } + } + protected abstract String geoName(); protected abstract EntityType boltType(); @@ -186,6 +240,34 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit protected abstract SoundEvent stepSound(); + protected abstract int signatureCooldownTicks(); + + protected abstract boolean isSignatureUseful(LivingEntity target); + + protected abstract void signatureTelegraph(ServerLevel level, int tick, @Nullable LivingEntity target, @Nullable Vec3 aimPoint); + + protected abstract boolean performSignature(ServerLevel level, @Nullable LivingEntity target, @Nullable Vec3 aimPoint, boolean ridden); + + protected abstract float beamBaseDamage(); + + protected abstract ParticleOptions beamWindupParticle(); + + public abstract boolean prefersAerialCombat(); + + public abstract double preferredCombatRange(); + + protected abstract float biteWeight(); + + protected abstract float spitWeight(); + + protected abstract float beamWeight(); + + protected abstract float signatureWeight(); + + protected int nextBeamHead(int previous) { + return (previous + 1) % 3; + } + @Override protected SoundEvent getAmbientSound() { return this.idleSound(); @@ -193,7 +275,7 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit @Override protected void playStepSound(BlockPos pos, BlockState state) { - this.playSound(this.stepSound(), 0.16F, 1.0F + (this.random.nextFloat() - 0.5F) * 0.2F); + this.playSound(this.stepSound(), 0.16F * this.getGrowthScale(), 1.1F - 0.06F * this.getGrowthScale() + (this.random.nextFloat() - 0.5F) * 0.2F); } @Override @@ -206,60 +288,37 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit @Override protected void registerGoals() { this.goalSelector.addGoal(0, new FloatGoal(this)); - this.goalSelector.addGoal(1, new SitWhenOrderedToGoal(this) { - @Override - public boolean canUse() { - return super.canUse(); - } - }); - this.goalSelector.addGoal(2, new RoyalMountSpitGoal(this)); - this.goalSelector.addGoal(3, new net.minecraft.world.entity.ai.goal.MeleeAttackGoal(this, 1.2D, true) { - @Override - protected void checkAndPerformAttack(LivingEntity target) { - if (this.getTicksUntilNextAttack() <= 0 && this.canPerformAttack(target)) { - this.resetAttackCooldown(); - RoyalMountEntity.this.startBite(); - } - } - - @Override - public boolean canUse() { - return !RoyalMountEntity.this.isVehicle() && super.canUse(); - } - }); + this.goalSelector.addGoal(1, new SitWhenOrderedToGoal(this)); + this.goalSelector.addGoal(2, new RoyalMountCombatGoal(this)); this.goalSelector.addGoal(4, new RoyalMountFollowOwnerGoal(this)); + this.goalSelector.addGoal(5, new RoyalMountCompanionGoal(this)); this.goalSelector.addGoal(6, new WaterAvoidingRandomStrollGoal(this, 0.8D) { @Override public boolean canUse() { - return !RoyalMountEntity.this.isVehicle() - && !RoyalMountEntity.this.isOrderedToSit() && super.canUse(); + return RoyalMountEntity.this.canWanderFreely() && super.canUse(); + } + + @Override + public boolean canContinueToUse() { + return RoyalMountEntity.this.canWanderFreely() && super.canContinueToUse(); } }); this.goalSelector.addGoal(7, new LookAtPlayerGoal(this, Player.class, 12.0F)); - this.goalSelector.addGoal(8, new RandomLookAroundGoal(this) { - @Override - public boolean canUse() { - return super.canUse(); - } - }); - this.targetSelector.addGoal(1, new OwnerHurtByTargetGoal(this) { - @Override - public boolean canUse() { - return super.canUse(); - } - }); - this.targetSelector.addGoal(2, new OwnerHurtTargetGoal(this) { - @Override - public boolean canUse() { - return super.canUse(); - } - }); - this.targetSelector.addGoal(3, new HurtByTargetGoal(this) { - @Override - public boolean canUse() { - return super.canUse(); - } - }.setAlertOthers()); + this.goalSelector.addGoal(8, new RandomLookAroundGoal(this)); + this.targetSelector.addGoal(1, new OwnerHurtByTargetGoal(this)); + this.targetSelector.addGoal(2, new OwnerHurtTargetGoal(this)); + this.targetSelector.addGoal(3, new HurtByTargetGoal(this)); + } + + private boolean canWanderFreely() { + if (this.isVehicle() || this.isOrderedToSit() || this.isFlying() || this.isActing()) { + return false; + } + if (!this.isTame()) { + return true; + } + LivingEntity owner = this.getOwner(); + return owner == null || owner.level() != this.level() || this.distanceToSqr(owner) > 48.0D * 48.0D; } @Override @@ -284,8 +343,7 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit tag.putBoolean("Saddled", this.isSaddled()); tag.putBoolean("Flying", this.isFlying()); tag.putInt("BeamCooldown", this.beamCooldownTicks); - tag.putInt("CommandCooldown", this.commandCooldownTicks); - tag.putInt("TimeFieldCooldown", this.timeFieldCooldownTicks); + tag.putInt("SignatureCooldown", this.signatureCooldownTicks); tag.putFloat("GrowthProgress", this.getGrowthProgress()); } @@ -293,18 +351,20 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit public void readAdditionalSaveData(CompoundTag tag) { super.readAdditionalSaveData(tag); this.setSaddled(tag.getBoolean("Saddled")); - this.setFlying(tag.getBoolean("Flying")); - this.actionTicks = 0; - this.actionHit = false; - this.spitCooldown = 0; + this.clearAction(); + this.biteCooldownTicks = 0; + this.spitCooldownTicks = 0; + this.actionRecoveryTicks = 0; this.beamCooldownTicks = Math.max(0, tag.getInt("BeamCooldown")); - this.commandCooldownTicks = Math.max(0, tag.getInt("CommandCooldown")); - this.timeFieldCooldownTicks = Math.max(0, tag.getInt("TimeFieldCooldown")); + int signatureCooldown = tag.contains("SignatureCooldown") + ? tag.getInt("SignatureCooldown") + : Math.max(tag.getInt("CommandCooldown"), tag.getInt("TimeFieldCooldown")); + this.signatureCooldownTicks = Math.max(0, signatureCooldown); this.setGrowthProgress(tag.contains("GrowthProgress") ? tag.getFloat("GrowthProgress") : 0.0F); - } - - public boolean isFlying() { - return this.entityData.get(FLYING); + if (tag.contains("Health", 99)) { + this.setHealth(tag.getFloat("Health")); + } + this.setFlying(tag.getBoolean("Flying") && this.canFly()); } @Override @@ -321,10 +381,15 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit } } + public boolean isFlying() { + return this.entityData.get(FLYING); + } + public void setFlying(boolean flying) { if (this.entityData.get(FLYING) != flying) { this.entityData.set(FLYING, flying); this.moveControl = flying ? this.flyingMoveControl : this.groundMoveControl; + this.navigation.stop(); this.navigation = flying ? this.flyingNavigation : this.groundNavigation; this.setNoGravity(flying); if (flying && !this.level().isClientSide) { @@ -333,6 +398,15 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit } } + public boolean claimFlight() { + if (!this.canFly()) { + return false; + } + this.setFlying(true); + this.flightClaimTick = this.tickCount; + return true; + } + public boolean isSaddled() { return this.entityData.get(SADDLED); } @@ -350,35 +424,91 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit } public float getGrowthScale() { - return 1.0F + 14.0F * this.getGrowthProgress(); + return 1.0F + (MAX_SCALE - 1.0F) * this.getGrowthProgress(); } public float getGrowthProgress() { return this.entityData.get(GROWTH_PROGRESS); } + public Stage getStage() { + float progress = this.getGrowthProgress(); + if (progress >= ADULT_PROGRESS) { + return Stage.ADULT; + } + return progress >= JUVENILE_PROGRESS ? Stage.JUVENILE : Stage.HATCHLING; + } + + public boolean canBeRidden() { + return this.getStage() != Stage.HATCHLING; + } + + public boolean canFly() { + return this.getStage() == Stage.ADULT; + } + + public boolean canSpit() { + return this.getStage() != Stage.HATCHLING; + } + + public boolean canUseAdultAbilities() { + return this.getStage() == Stage.ADULT; + } + public void setGrowthProgress(float progress) { float clamped = Mth.clamp(progress, 0.0F, 1.0F); if (this.getGrowthProgress() != clamped) { float oldHealth = this.getHealth(); this.entityData.set(GROWTH_PROGRESS, clamped); - var maxHealth = this.getAttribute(Attributes.MAX_HEALTH); - if (maxHealth != null) { - maxHealth.removeModifier(GROWTH_HEALTH_MODIFIER); - if (clamped > 0.0F) { - maxHealth.addTransientModifier(new AttributeModifier(GROWTH_HEALTH_MODIFIER, - this.getGrowthScale() - 1.0D, AttributeModifier.Operation.ADD_MULTIPLIED_BASE)); - } - this.setHealth(Math.min(oldHealth, this.getMaxHealth())); - } + this.applyGrowthModifiers(); + this.setHealth(Math.min(oldHealth, this.getMaxHealth())); this.refreshDimensions(); } } + private void applyGrowthModifiers() { + float bonus = this.getGrowthScale() - 1.0F; + this.applyGrowthModifier(this.getAttribute(Attributes.MAX_HEALTH), GROWTH_HEALTH_MODIFIER, bonus); + this.applyGrowthModifier(this.getAttribute(Attributes.ATTACK_DAMAGE), GROWTH_DAMAGE_MODIFIER, bonus * 0.5D); + this.applyGrowthModifier(this.getAttribute(Attributes.MOVEMENT_SPEED), GROWTH_SPEED_MODIFIER, bonus * 0.1D); + this.applyGrowthModifier(this.getAttribute(Attributes.FLYING_SPEED), GROWTH_FLYING_SPEED_MODIFIER, bonus * 0.1D); + } + + private void applyGrowthModifier(@Nullable AttributeInstance attribute, ResourceLocation id, double amount) { + if (attribute == null) { + return; + } + attribute.removeModifier(id); + if (amount > 0.0D) { + attribute.addTransientModifier(new AttributeModifier(id, amount, AttributeModifier.Operation.ADD_MULTIPLIED_BASE)); + } + } + + private void grow(float amount, @Nullable Player feeder) { + Stage before = this.getStage(); + this.setGrowthProgress(this.getGrowthProgress() + amount); + Stage after = this.getStage(); + if (after != before && this.level() instanceof ServerLevel level) { + double radius = this.getBbWidth() * 0.5D; + level.sendParticles(ParticleTypes.TOTEM_OF_UNDYING, this.getX(), this.getY() + this.getBbHeight() * 0.6D, this.getZ(), + 40, radius, this.getBbHeight() * 0.3D, radius, 0.3D); + this.playSound(this.idleSound(), 2.0F, 0.6F); + this.triggerQuirk(); + if (feeder != null) { + feeder.displayClientMessage(Component.translatable("message.antarchy.royal_mount.stage_up", + this.getDisplayName(), after.displayName()), true); + } + } else if (feeder != null) { + feeder.displayClientMessage(Component.translatable("message.antarchy.royal_mount.growth", + this.getDisplayName(), this.getStage().displayName(), Math.round(this.getGrowthProgress() * 100.0F)), true); + } + } + @Override public boolean hurt(DamageSource source, float amount) { Entity attacker = source.getEntity(); - if (attacker != null && this.hasPassenger(attacker)) { + if (attacker != null && attacker != this && (this.hasPassenger(attacker) + || attacker != this.getOwner() && this.isFriendlyTo(attacker))) { return false; } return super.hurt(source, amount); @@ -389,6 +519,11 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit return super.getDefaultDimensions(pose).scale(this.getGrowthScale()); } + @Override + public float maxUpStep() { + return Math.max(1.1F, 0.5F + 0.6F * this.getGrowthScale()); + } + @Override public boolean isFood(ItemStack stack) { return stack.is(AntarchyTags.Items.ROYAL_MOUNT_FOOD); @@ -397,49 +532,54 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit @Override public InteractionResult mobInteract(Player player, InteractionHand hand) { ItemStack stack = player.getItemInHand(hand); + boolean owned = this.isTame() && this.isOwnedBy(player); if (stack.is(Items.GOLDEN_APPLE) && !this.isTame()) { if (!this.level().isClientSide) { - if (!player.getAbilities().instabuild) { - stack.shrink(1); - } + this.consume(player, stack); this.tame(player); + this.setTarget(null); this.heal(8.0F); this.level().broadcastEntityEvent(this, (byte) 7); } return InteractionResult.sidedSuccess(this.level().isClientSide); } - if (stack.is(Items.ENCHANTED_GOLDEN_APPLE) && this.isTame() && this.isOwnedBy(player)) { + if (owned && (stack.is(Items.ENCHANTED_GOLDEN_APPLE) || stack.is(Items.GOLDEN_APPLE))) { + boolean enchanted = stack.is(Items.ENCHANTED_GOLDEN_APPLE); + boolean canGrow = this.getGrowthProgress() < 1.0F; + if (!canGrow && this.getHealth() >= this.getMaxHealth()) { + return InteractionResult.PASS; + } if (!this.level().isClientSide) { - if (!player.getAbilities().instabuild) { - stack.shrink(1); + this.consume(player, stack); + this.heal(enchanted ? 20.0F : 8.0F); + if (canGrow) { + this.grow(enchanted ? ENCHANTED_APPLE_GROWTH : GOLDEN_APPLE_GROWTH, player); } - this.heal(8.0F); - this.setGrowthProgress(this.getGrowthProgress() + (1.0F - this.getGrowthProgress()) * 0.1F); - this.level().broadcastEntityEvent(this, (byte) 6); + this.level().broadcastEntityEvent(this, (byte) 7); + this.triggerQuirk(); } return InteractionResult.sidedSuccess(this.level().isClientSide); } if (this.isFood(stack)) { - if (!this.level().isClientSide && this.isTame() && this.isOwnedBy(player) && this.getHealth() < this.getMaxHealth()) { - if (!player.getAbilities().instabuild) { - stack.shrink(1); + if (owned && this.getHealth() < this.getMaxHealth()) { + if (!this.level().isClientSide) { + this.consume(player, stack); + this.heal(8.0F); + this.level().broadcastEntityEvent(this, (byte) 7); } - this.heal(8.0F); - this.level().broadcastEntityEvent(this, (byte) 6); + return InteractionResult.sidedSuccess(this.level().isClientSide); } - return InteractionResult.sidedSuccess(this.level().isClientSide); + return InteractionResult.PASS; } - if (this.isTame() && this.isOwnedBy(player)) { + if (owned) { if (!this.isSaddled() && stack.is(Items.SADDLE)) { if (!this.level().isClientSide) { this.setSaddled(true); - if (!player.getAbilities().instabuild) { - stack.shrink(1); - } + this.consume(player, stack); this.playSound(SoundEvents.HORSE_SADDLE, 1.0F, 1.0F); } return InteractionResult.sidedSuccess(this.level().isClientSide); @@ -451,15 +591,14 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit this.setInSittingPose(this.isOrderedToSit()); this.navigation.stop(); this.setTarget(null); + this.clearAction(); } return InteractionResult.sidedSuccess(this.level().isClientSide); } if (stack.isEmpty() && !player.isPassenger()) { if (!this.level().isClientSide) { - this.setOrderedToSit(false); - this.setInSittingPose(false); - player.startRiding(this); + this.tryMount(player); } return InteractionResult.sidedSuccess(this.level().isClientSide); } @@ -468,6 +607,25 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit return super.mobInteract(player, hand); } + private void consume(Player player, ItemStack stack) { + if (!player.getAbilities().instabuild) { + stack.shrink(1); + } + } + + private boolean tryMount(Player player) { + if (!this.canBeRidden()) { + player.displayClientMessage(Component.translatable("message.antarchy.royal_mount.too_young_ride", + this.getDisplayName(), Stage.JUVENILE.displayName()), true); + return false; + } + this.setOrderedToSit(false); + this.setInSittingPose(false); + this.setTarget(null); + this.clearAction(); + return player.startRiding(this); + } + @Nullable @Override public AgeableMob getBreedOffspring(ServerLevel level, AgeableMob other) { @@ -488,35 +646,20 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit } LivingEntity target = this.getTarget(); - if (target != null && !this.canAttack(target)) { + if (target != null && (!target.isAlive() || !this.canAttack(target))) { this.setTarget(null); } - if (this.spitCooldown > 0) { - this.spitCooldown--; - } - this.tickRoyalAbilities(); + this.tickCooldowns(); + this.tickAction(); + this.tickFlightState(); + this.tickOwnerGreeting(); if ((this.isFlying() || !this.onGround()) && --this.flapSoundTimer <= 0) { this.flapSoundTimer = 24 + this.random.nextInt(12); this.playSound(this.flySound(), 0.6F, 1.0F + (this.random.nextFloat() - 0.5F) * 0.3F); } - if (this.actionTicks > 0) { - this.entityData.set(QUIRKING, false); - this.actionTicks--; - if (!this.actionHit && this.actionTicks <= ACTION_TICKS - BITE_HIT_TICK - && (this.getAnimState() == ANIM_BITE || this.getAnimState() == ANIM_FLY_BITE)) { - this.actionHit = true; - this.applyBiteDamage(); - } - if (this.actionTicks == 0) { - this.updateAmbientAnimState(); - } - return; - } - - this.tickFlightState(); this.updateAmbientAnimState(); if (this.quirkTimer > 0) { @@ -525,95 +668,480 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit if (this.getAnimState() == ANIM_IDLE && this.quirkTimer == 0 && this.random.nextInt(600) == 0) { this.quirkTimer = 80; } - this.entityData.set(QUIRKING, this.quirkTimer > 0 && this.getAnimState() == ANIM_IDLE); + this.entityData.set(QUIRKING, this.quirkTimer > 0 && this.getAnimState() == ANIM_IDLE && !this.isActing()); } - private void tickRoyalAbilities() { - if (this.beamCooldownTicks > 0) this.beamCooldownTicks--; - if (this.commandCooldownTicks > 0) this.commandCooldownTicks--; - if (this.timeFieldCooldownTicks > 0) this.timeFieldCooldownTicks--; - if (this.beamWindupTicks > 0) { - this.beamWindupTicks--; - if (this.beamWindupTicks == 0) { - this.beamController.start(this.beamShootFrom(), this.beamTargetPosition(), BEAM_DURATION_TICKS); - this.entityData.set(BEAM_ACTIVE, true); - } + public void triggerQuirk() { + if (!this.isActing()) { + this.quirkTimer = 80; } - if (this.beamController.isFiring()) { - this.beamController.tick(this.beamShootFrom(), this.getTarget(), this.beamSettings(), BeamTerrainMode.NONE, this::setBeamEndPosition); - if (!this.beamController.isFiring()) { - this.entityData.set(BEAM_ACTIVE, false); - this.entityData.set(BEAM_HEAD, -1); - this.beamCooldownTicks = BEAM_COOLDOWN_TICKS; + } + + private void tickCooldowns() { + if (this.biteCooldownTicks > 0) this.biteCooldownTicks--; + if (this.spitCooldownTicks > 0) this.spitCooldownTicks--; + if (this.beamCooldownTicks > 0) this.beamCooldownTicks--; + if (this.signatureCooldownTicks > 0) this.signatureCooldownTicks--; + if (this.actionRecoveryTicks > 0) this.actionRecoveryTicks--; + } + + private void tickFlightState() { + if (!this.isFlying()) { + return; + } + if (this.isVehicle()) { + if (!this.canFly()) { + this.setFlying(false); + } else if (this.onGround() && this.riderDescendPressed) { + this.setFlying(false); } return; } - if (this.isOrderedToSit()) return; - LivingEntity target = this.getTarget(); - if (target == null && this.getControllingPassenger() instanceof Player) { - target = this.frontTarget(); - if (target != null) this.setTarget(target); + if (this.canFly() && this.tickCount - this.flightClaimTick <= 10) { + return; } - if (target == null || !target.isAlive() || !this.hasLineOfSight(target)) return; - double targetDistance = this.distanceTo(target); - if (this.beamCooldownTicks <= 0 && this.beamWindupTicks <= 0 && targetDistance > 7.0D && targetDistance < 28.0D && this.tickCount % 20 == 0) { - this.beamHead = (this.beamHead + 1) % 3; - this.entityData.set(BEAM_HEAD, this.beamHead); - this.beamWindupTicks = BEAM_WINDUP_TICKS; - this.setAnimState(this.isFlying() ? ANIM_FLY_SHOOT : ANIM_SHOOT); - this.triggerAnim("main", this.isFlying() ? "fly_shoot" : "shoot"); - this.playSound(this.shootSound(), 0.9F, 0.75F); + if (this.onGround() || this.isInWater() || this.isInLava()) { + this.setFlying(false); + return; } - if (this instanceof PrinceEntity && this.commandCooldownTicks <= 0 && this.tickCount % 20 == 0) { - this.performPrinceCommand(); + this.navigation.stop(); + this.moveControl.setWantedPosition(this.getX(), this.getY() - 3.0D, this.getZ(), 0.8D); + } + + private void tickOwnerGreeting() { + if (!this.isTame() || this.isVehicle() || this.tickCount % 10 != 0) { + return; } - if (this instanceof PrincessEntity && this.timeFieldCooldownTicks <= 0 && this.tickCount % 20 == 0) { - this.performPrincessTimeField(target); + LivingEntity owner = this.getOwner(); + if (owner == null || owner.level() != this.level()) { + this.ownerAwayTicks = Math.min(this.ownerAwayTicks + 10, 2400); + return; + } + double distance = this.distanceTo(owner); + if (distance > 24.0D + this.getBbWidth()) { + this.ownerAwayTicks = Math.min(this.ownerAwayTicks + 10, 2400); + } else if (distance < 8.0D + this.getBbWidth()) { + if (this.ownerAwayTicks >= 400 && this.getTarget() == null) { + this.triggerQuirk(); + this.playSound(this.idleSound(), 1.4F, 1.15F); + this.lookControl.setLookAt(owner, 30.0F, 30.0F); + } + this.ownerAwayTicks = 0; } } - private void performPrinceCommand() { - if (!(this.level() instanceof ServerLevel level) || RoyalEffectHooks.commandedHolder() == null) return; - int applied = 0; - for (Mob mob : level.getEntitiesOfClass(Mob.class, this.getBoundingBox().inflate(16.0D), mob -> - mob != this && mob.isAlive() && mob instanceof Enemy && !mob.isAlliedTo(this) - && !(mob instanceof RoyalBossEntity) && RoyalEffectEligibility.canApplyCommanded(mob))) { - if (applied >= 5) break; - if (mob.addEffect(new MobEffectInstance(RoyalEffectHooks.commandedHolder(), 300), this)) { - applied++; - level.sendParticles(ParticleTypes.HAPPY_VILLAGER, mob.getX(), mob.getY() + mob.getBbHeight(), mob.getZ(), 4, 0.2D, 0.2D, 0.2D, 0.02D); + private void updateAmbientAnimState() { + if (this.isActing()) { + return; + } + if (this.isFlying() || (!this.onGround() && !this.isInWater())) { + this.setAnimState(ANIM_FLY); + return; + } + boolean moving; + if (this.getControllingPassenger() instanceof Player rider) { + moving = Math.abs(rider.zza) > 0.05F || Math.abs(rider.xxa) > 0.05F; + } else { + moving = this.getDeltaMovement().horizontalDistanceSqr() > 0.0025D; + } + this.setAnimState(moving ? ANIM_WALK : ANIM_IDLE); + } + + public boolean isActing() { + return this.action != ACTION_NONE; + } + + public int currentAction() { + return this.action; + } + + public boolean isActionReady() { + return this.action == ACTION_NONE && this.actionRecoveryTicks <= 0; + } + + @Nullable + public LivingEntity actionTarget() { + return this.actionTarget; + } + + public boolean isActionCommitted() { + return switch (this.action) { + case ACTION_BEAM -> this.actionTicks >= BEAM_WINDUP_TICKS - 6; + case ACTION_SPIT -> this.actionTicks >= SPIT_FIRE_TICK - 3; + case ACTION_SIGNATURE -> this.actionTicks >= SIGNATURE_WINDUP_TICKS - 6; + default -> this.action != ACTION_NONE; + }; + } + + public boolean isActionAvailable(int type) { + return switch (type) { + case ACTION_BITE -> this.biteCooldownTicks <= 0; + case ACTION_SPIT -> this.canSpit() && this.spitCooldownTicks <= 0; + case ACTION_BEAM -> this.canUseAdultAbilities() && this.beamCooldownTicks <= 0; + case ACTION_SIGNATURE -> this.canUseAdultAbilities() && this.signatureCooldownTicks <= 0; + default -> false; + }; + } + + public boolean startAction(int type, @Nullable LivingEntity target, @Nullable Vec3 aimPoint, boolean ridden) { + if (this.level().isClientSide || !this.isActionReady() || !this.isActionAvailable(type)) { + return false; + } + this.action = type; + this.actionTicks = 0; + this.actionFired = false; + this.actionRidden = ridden; + this.actionTarget = target; + this.actionAimPoint = aimPoint; + this.lastAction = type; + this.entityData.set(QUIRKING, false); + this.quirkTimer = 0; + boolean flying = this.isFlying(); + switch (type) { + case ACTION_BITE -> { + this.biteCooldownTicks = BITE_COOLDOWN_TICKS; + this.setAnimState(flying ? ANIM_FLY_BITE : ANIM_BITE); + this.triggerAnim("main", flying ? "fly_bite" : "bite"); + this.playSound(this.biteSound(), 1.2F, 0.95F - 0.04F * this.getGrowthScale() + this.random.nextFloat() * 0.2F); + } + case ACTION_SPIT -> { + this.spitCooldownTicks = SPIT_COOLDOWN_TICKS; + this.setAnimState(flying ? ANIM_FLY_SHOOT : ANIM_SHOOT); + this.triggerAnim("main", flying ? "fly_shoot" : "shoot"); + } + case ACTION_BEAM -> { + this.beamCooldownTicks = BEAM_COOLDOWN_TICKS; + this.beamHead = this.nextBeamHead(this.beamHead); + this.entityData.set(BEAM_HEAD, this.beamHead); + this.setAnimState(flying ? ANIM_FLY_SHOOT : ANIM_SHOOT); + this.triggerAnim("main", flying ? "fly_shoot" : "shoot"); + this.playSound(this.shootSound(), 1.0F, 0.7F); + } + case ACTION_SIGNATURE -> { + this.signatureCooldownTicks = this.signatureCooldownTicks(); + this.setAnimState(flying ? ANIM_FLY_SHOOT : ANIM_SHOOT); + this.triggerAnim("main", flying ? "fly_shoot" : "shoot"); + this.playSound(this.idleSound(), 2.0F, 0.6F); + } + default -> { + this.clearAction(); + return false; } } - if (applied > 0) { - this.commandCooldownTicks = COMMAND_COOLDOWN_TICKS; - this.playSound(this.shootSound(), 1.0F, 0.65F); + return true; + } + + private void tickAction() { + if (this.action == ACTION_NONE) { + if (this.beamController.isFiring()) { + this.stopBeam(); + } + return; + } + if (!(this.level() instanceof ServerLevel level)) { + return; + } + if (this.actionRidden && this.getControllingPassenger() == null) { + this.actionRidden = false; + } + this.actionTicks++; + if (!this.actionRidden && this.actionTarget != null && !this.isActionCommitted()) { + this.turnTowards(this.actionTarget.position(), 14.0F); + } + switch (this.action) { + case ACTION_BITE -> { + if (!this.actionFired && this.actionTicks >= BITE_HIT_TICK) { + this.actionFired = true; + this.applyBiteDamage(); + } + if (this.actionTicks >= BITE_TICKS) { + this.finishAction(); + } + } + case ACTION_SPIT -> { + if (!this.actionFired && this.actionTicks >= SPIT_FIRE_TICK) { + this.actionFired = true; + this.fireSpitVolley(); + } + if (this.actionTicks >= SPIT_TICKS) { + this.finishAction(); + } + } + case ACTION_BEAM -> this.tickBeamAction(level); + case ACTION_SIGNATURE -> { + if (!this.actionFired) { + this.signatureTelegraph(level, this.actionTicks, this.actionTarget, this.actionAimPoint); + if (this.actionTicks >= SIGNATURE_WINDUP_TICKS) { + this.actionFired = true; + if (this.performSignature(level, this.validActionTarget(), this.actionAimPoint, this.actionRidden)) { + this.playSound(this.shootSound(), 1.4F, 0.6F); + } else { + this.signatureCooldownTicks = Math.min(this.signatureCooldownTicks, 60); + } + } + } + if (this.actionTicks >= SIGNATURE_TICKS) { + this.finishAction(); + } + } + default -> this.finishAction(); } } - private void performPrincessTimeField(@Nullable LivingEntity target) { - if (!(this.level() instanceof ServerLevel level)) return; - Vec3 center = target != null && target.isAlive() ? target.position() : this.position(); - TimeDilationApi.createField(level, center, 8.0D, 0.45D, 100, this.getUUID()); - this.timeFieldCooldownTicks = TIME_FIELD_COOLDOWN_TICKS; - level.sendParticles(ParticleTypes.END_ROD, center.x, center.y + 0.5D, center.z, 28, 1.2D, 0.6D, 1.2D, 0.03D); + @Nullable + private LivingEntity validActionTarget() { + LivingEntity target = this.actionTarget; + return target != null && target.isAlive() && target.level() == this.level() ? target : null; + } + + private void tickBeamAction(ServerLevel level) { + if (!this.actionFired) { + if (this.actionTicks % 2 == 0) { + Vec3 origin = this.beamShootFrom(); + level.sendParticles(this.beamWindupParticle(), origin.x, origin.y, origin.z, 3, + 0.15D * this.getGrowthScale(), 0.15D * this.getGrowthScale(), 0.15D * this.getGrowthScale(), 0.02D); + } + if (this.actionTicks >= BEAM_WINDUP_TICKS) { + this.actionFired = true; + Vec3 aim = this.currentBeamAim(); + this.beamController.start(this.beamShootFrom(), aim, BEAM_DURATION_TICKS); + this.entityData.set(BEAM_ACTIVE, true); + this.playSound(this.shootSound(), 1.4F, 0.6F); + } + return; + } + if (this.beamController.isFiring()) { + Vec3 from = this.beamShootFrom(); + LivingEntity target = this.actionRidden ? null : this.validActionTarget(); + Vec3 direction; + if (this.actionRidden && this.getControllingPassenger() instanceof Player rider) { + direction = this.riderAimPoint(rider, this.beamRange()).subtract(from); + } else { + direction = this.getLookAngle(); + } + this.beamController.tick(from, direction, target, this.beamSettings(), BeamTerrainMode.NONE, + this::setBeamEndPosition, !this.actionRidden); + if (!this.beamController.isFiring()) { + this.entityData.set(BEAM_ACTIVE, false); + this.entityData.set(HAS_BEAM_END, false); + } + return; + } + if (this.actionTicks >= BEAM_WINDUP_TICKS + BEAM_DURATION_TICKS + BEAM_RECOVERY_TICKS) { + this.finishAction(); + } + } + + private Vec3 currentBeamAim() { + if (this.actionRidden && this.getControllingPassenger() instanceof Player rider) { + return this.riderAimPoint(rider, this.beamRange()); + } + LivingEntity target = this.validActionTarget(); + if (target != null) { + return target.getEyePosition(); + } + return this.actionAimPoint != null ? this.actionAimPoint : this.getEyePosition().add(this.getLookAngle().scale(20.0D)); + } + + private void finishAction() { + this.clearAction(); + this.actionRecoveryTicks = ACTION_RECOVERY_TICKS; + } + + public void clearAction() { + this.action = ACTION_NONE; + this.actionTicks = 0; + this.actionFired = false; + this.actionRidden = false; + this.actionTarget = null; + this.actionAimPoint = null; + if (this.beamController.isFiring() || this.entityData.get(BEAM_ACTIVE)) { + this.stopBeam(); + } + } + + private void stopBeam() { + this.beamController.stop(); + this.entityData.set(BEAM_ACTIVE, false); + this.entityData.set(HAS_BEAM_END, false); + this.entityData.set(BEAM_HEAD, -1); + } + + public int chooseCombatAction(LivingEntity target, double gap, boolean canSee) { + if (!this.isActionReady()) { + return ACTION_NONE; + } + float bite = this.isActionAvailable(ACTION_BITE) && this.canBiteReach(target) ? this.biteWeight() : 0.0F; + float spit = this.isActionAvailable(ACTION_SPIT) && canSee && gap > 2.0D && gap < 22.0D + this.getGrowthScale() ? this.spitWeight() : 0.0F; + float beam = this.isActionAvailable(ACTION_BEAM) && canSee && gap > 5.0D && gap < this.beamRange() - 2.0D ? this.beamWeight() : 0.0F; + float signature = this.isActionAvailable(ACTION_SIGNATURE) && this.isSignatureUseful(target) ? this.signatureWeight() : 0.0F; + if (this.lastAction == ACTION_SPIT) spit *= 0.5F; + if (this.lastAction == ACTION_BITE && spit > 0.0F) bite *= 0.7F; + float total = bite + spit + beam + signature; + if (total <= 0.0F) { + return ACTION_NONE; + } + float roll = this.random.nextFloat() * total; + if ((roll -= signature) < 0.0F) return ACTION_SIGNATURE; + if ((roll -= beam) < 0.0F) return ACTION_BEAM; + if ((roll -= bite) < 0.0F) return ACTION_BITE; + return ACTION_SPIT; + } + + public void turnTowards(Vec3 point, float maxTurn) { + double dx = point.x - this.getX(); + double dz = point.z - this.getZ(); + if (dx * dx + dz * dz < 1.0E-4D) { + return; + } + float desired = (float) (Mth.atan2(dz, dx) * Mth.RAD_TO_DEG) - 90.0F; + float yaw = Mth.approachDegrees(this.getYRot(), desired, maxTurn); + this.setYRot(yaw); + this.yBodyRot = yaw; + this.yHeadRot = yaw; + } + + public double combatGap(LivingEntity target) { + double horizontal = Math.sqrt(Mth.square(target.getX() - this.getX()) + Mth.square(target.getZ() - this.getZ())); + double vertical = Math.max(0.0D, Math.max(target.getY() - (this.getY() + this.getBbHeight()), this.getY() - (target.getY() + target.getBbHeight()))); + double flat = Math.max(0.0D, horizontal - this.getBbWidth() * 0.5D - target.getBbWidth() * 0.5D); + return Math.sqrt(flat * flat + vertical * vertical); + } + + public AABB biteBox() { + float scale = this.getGrowthScale(); + Vec3 forward = Vec3.directionFromRotation(0.0F, this.getYRot()); + double reach = this.getBbWidth() * 0.5D + 1.0D * scale; + double radius = 1.1D * scale + 0.6D; + Vec3 center = this.position().add(forward.scale(reach)); + return new AABB(center.x - radius, this.getY() - 0.75D, center.z - radius, + center.x + radius, this.getY() + this.getBbHeight() + 0.75D * scale, center.z + radius); + } + + public boolean canBiteReach(LivingEntity target) { + return this.biteBox().intersects(target.getBoundingBox()); + } + + @Override + protected AABB getAttackBoundingBox() { + return this.getBoundingBox().minmax(this.biteBox()); + } + + private void applyBiteDamage() { + AABB box = this.biteBox(); + float damage = (float) this.getAttributeValue(Attributes.ATTACK_DAMAGE); + DamageSource source = this.damageSources().mobAttack(this); + int hits = 0; + LivingEntity primary = this.validActionTarget(); + if (primary != null && box.intersects(primary.getBoundingBox()) && this.canAttack(primary)) { + this.biteHit(primary, damage, source); + hits++; + } + for (LivingEntity candidate : this.level().getEntitiesOfClass(LivingEntity.class, box, + living -> living != primary && living.isAlive() && this.canAttack(living))) { + if (hits >= 3) { + break; + } + if (!this.actionRidden && !(candidate instanceof Enemy) && candidate != this.getTarget()) { + continue; + } + this.biteHit(candidate, damage, source); + hits++; + } + } + + private void biteHit(LivingEntity victim, float damage, DamageSource source) { + if (victim.hurt(source, damage)) { + Vec3 push = victim.position().subtract(this.position()).multiply(1.0D, 0.0D, 1.0D); + if (push.lengthSqr() > 1.0E-4D) { + push = push.normalize(); + victim.knockback(0.3D + 0.1D * this.getGrowthScale(), -push.x, -push.z); + } + } + } + + private void fireSpitVolley() { + Vec3 aim; + LivingEntity target = this.validActionTarget(); + if (this.actionRidden && this.getControllingPassenger() instanceof Player rider) { + aim = this.riderAimPoint(rider, 48.0D).subtract(this.getEyePosition()).normalize(); + } else if (target != null) { + aim = target.getEyePosition().subtract(this.getEyePosition()).normalize(); + } else { + aim = this.getLookAngle(); + } + Vec3 flat = new Vec3(-aim.z, 0.0D, aim.x); + Vec3 right = flat.lengthSqr() < 1.0E-6D ? new Vec3(1.0D, 0.0D, 0.0D) : flat.normalize(); + float speed = 1.3F + 0.06F * this.getGrowthScale(); + for (int i = -1; i <= 1; i++) { + Vec3 origin = this.boltOrigin(i); + Vec3 dir; + if (target != null && !this.actionRidden) { + dir = target.getEyePosition().subtract(origin).normalize().add(right.scale(i * 0.05D)).normalize(); + } else { + dir = aim.add(right.scale(i * 0.06D)).normalize(); + } + RoyalBoltEntity bolt = new RoyalBoltEntity(this.boltType(), this.level()); + bolt.setOwner(this); + bolt.setElement(this.boltElement(i)); + bolt.setPos(origin.x, origin.y, origin.z); + bolt.shoot(dir.x, dir.y, dir.z, speed, 1.0F); + this.level().addFreshEntity(bolt); + } + this.playSound(this.shootSound(), 1.2F, 0.95F - 0.03F * this.getGrowthScale() + this.random.nextFloat() * 0.2F); + } + + protected Vec3 boltOrigin(int lateralIndex) { + float scale = this.getGrowthScale(); + Vec3 forward = Vec3.directionFromRotation(0.0F, this.getYRot()); + Vec3 side = new Vec3(-forward.z, 0.0D, forward.x); + return this.position() + .add(0.0D, 1.05D * scale, 0.0D) + .add(forward.scale(1.75D * scale)) + .add(side.scale(lateralIndex * 0.85D * scale)); + } + + public float projectileDamageMultiplier() { + return 1.0F + 0.35F * (this.getGrowthScale() - 1.0F); + } + + protected RoyalBeamElement boltElement(int lateralIndex) { + return RoyalBeamElement.GENERIC; + } + + public double beamRange() { + return 26.0D + 2.0D * this.getGrowthScale(); } private BeamSettings beamSettings() { - float damage = this instanceof PrincessEntity ? 10.0F : 12.0F; - return new BeamSettings(28.0D, 0.08D, 4.0D, BEAM_DURATION_TICKS, 6, BEAM_COOLDOWN_TICKS, - 0.35F, 0.45F, damage, 0.45F, 3, 0.0D, 0.0F, 0.0F, 0, 0.0F, 0.0F, 0.0F, false, true); + return new BeamSettings(this.beamRange(), 0.08D, 4.0D, BEAM_DURATION_TICKS, 6, BEAM_COOLDOWN_TICKS, + 0.35F + 0.08F * this.getGrowthScale(), 0.45F + 0.15F * this.getGrowthScale(), this.beamBaseDamage(), + 0.45F, 3, 0.0D, 0.0F, 0.0F, 0, 0.0F, 0.0F, 0.0F, false, true); } - private Vec3 beamTargetPosition() { - LivingEntity target = this.getTarget(); - return target != null ? target.getEyePosition() : this.getEyePosition().add(this.getLookAngle().scale(20.0D)); + @Override + public float scaleBeamDamage(float damage) { + return damage * (1.0F + 0.25F * (this.getGrowthScale() - 1.0F)); + } + + @Override + public boolean canBeamDamage(LivingEntity target) { + if (this.isFriendlyTo(target)) { + return false; + } + if (this.actionRidden) { + return true; + } + return target instanceof Enemy || target == this.getTarget() || target == this.actionTarget + || target instanceof Mob mob && mob.getTarget() != null && this.isFriendlyTo(mob.getTarget()); } public Vec3 beamShootFrom() { float scale = this.getGrowthScale(); Vec3 forward = Vec3.directionFromRotation(0.0F, this.getYRot()); Vec3 side = new Vec3(-forward.z, 0.0D, forward.x); - return this.position().add(0.0D, 1.0D * scale, 0.0D).add(forward.scale(1.05D * scale)).add(side.scale((this.getBeamHead() - 1) * 0.72D * scale)); + int head = Math.max(0, this.getBeamHead()); + return this.position().add(0.0D, 1.05D * scale, 0.0D).add(forward.scale(1.75D * scale)).add(side.scale((head - 1) * 0.85D * scale)); } public int getBeamHead() { return this.entityData.get(BEAM_HEAD); } @@ -632,127 +1160,77 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit } } - private void tickFlightState() { - if (this.isVehicle()) { - return; - } - if (this.isFlying() && this.onGround() && this.getTarget() == null) { - this.setFlying(false); - } + public Vec3 riderAimPoint(Player rider, double range) { + Vec3 eye = rider.getEyePosition(); + Vec3 end = eye.add(rider.getViewVector(1.0F).scale(range)); + var blockHit = this.level().clip(new ClipContext(eye, end, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, rider)); + Vec3 limit = blockHit.getLocation(); + EntityHitResult entityHit = ProjectileUtil.getEntityHitResult(this.level(), rider, eye, limit, + new AABB(eye, limit).inflate(1.0D), + entity -> entity instanceof LivingEntity living && living.isAlive() && !entity.isSpectator() && !this.isFriendlyTo(entity)); + return entityHit != null ? entityHit.getLocation() : limit; } - private void updateAmbientAnimState() { - if (this.actionTicks > 0) { - return; - } - if (this.isFlying() || !this.onGround()) { - this.setAnimState(ANIM_FLY); - return; - } - boolean moving; - if (this.getControllingPassenger() instanceof Player rider) { - moving = Math.abs(rider.zza) > 0.05F || Math.abs(rider.xxa) > 0.05F; - } else { - moving = this.getDeltaMovement().horizontalDistanceSqr() > 0.0025D; - } - this.setAnimState(moving ? ANIM_WALK : ANIM_IDLE); + @Nullable + public LivingEntity riderAimEntity(Player rider, double range) { + Vec3 eye = rider.getEyePosition(); + Vec3 end = eye.add(rider.getViewVector(1.0F).scale(range)); + var blockHit = this.level().clip(new ClipContext(eye, end, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, rider)); + Vec3 limit = blockHit.getLocation(); + EntityHitResult entityHit = ProjectileUtil.getEntityHitResult(this.level(), rider, eye, limit, + new AABB(eye, limit).inflate(1.0D), + entity -> entity instanceof LivingEntity living && living.isAlive() && !entity.isSpectator() && !this.isFriendlyTo(entity)); + return entityHit != null && entityHit.getEntity() instanceof LivingEntity living ? living : null; } - public void startBite() { - if (this.actionTicks > 0) { - return; + public boolean isFriendlyTo(@Nullable Entity entity) { + if (entity == null) { + return false; } - this.actionTicks = ACTION_TICKS; - this.actionHit = false; - this.setAnimState(this.isFlying() ? ANIM_FLY_BITE : ANIM_BITE); - this.triggerAnim("main", this.isFlying() ? "fly_bite" : "bite"); - this.playSound(this.biteSound(), 1.2F, 0.9F + this.random.nextFloat() * 0.2F); - } - - private void applyBiteDamage() { - LivingEntity target = this.getTarget(); - if (target == null && this.getControllingPassenger() instanceof Player) { - target = this.frontTarget(); + if (entity == this || this.hasPassenger(entity)) { + return true; } - if (target != null && this.canAttack(target) && target.distanceTo(this) < 5.0D) { - target.hurt(this.damageSources().mobAttack(this), (float) this.getAttributeValue(Attributes.ATTACK_DAMAGE)); + if (entity instanceof RoyalMountEntity other && this.isTame() && other.isTame()) { + return true; } + if (this.isAlliedTo(entity) || entity.isAlliedTo(this)) { + return true; + } + if (!this.isTame()) { + return false; + } + LivingEntity owner = this.getOwner(); + if (owner != null && (entity == owner || entity.isAlliedTo(owner) || owner.isAlliedTo(entity))) { + return true; + } + return entity instanceof OwnableEntity ownable && this.getOwnerUUID() != null + && this.getOwnerUUID().equals(ownable.getOwnerUUID()); } @Override public boolean canAttack(LivingEntity target) { - return !(target instanceof RoyalMountEntity other && this.isTame() && other.isTame()) - && super.canAttack(target); + return !this.isFriendlyTo(target) && super.canAttack(target); } - @Nullable - private LivingEntity frontTarget() { - Vec3 look = this.getLookAngle(); - Vec3 eye = this.getEyePosition(); - LivingEntity best = null; - double bestDot = 0.3D; - for (LivingEntity candidate : this.level().getEntitiesOfClass(LivingEntity.class, this.getBoundingBox().inflate(6.0D))) { - if (candidate == this || candidate == this.getControllingPassenger() || candidate == this.getOwner()) { - continue; - } - if (!this.canAttack(candidate)) { - continue; - } - Vec3 to = candidate.getEyePosition().subtract(eye); - double dist = to.length(); - if (dist > 6.0D || dist < 1.0E-3D) { - continue; - } - double dot = to.scale(1.0D / dist).dot(look); - if (dot > bestDot) { - bestDot = dot; - best = candidate; - } + @Override + public boolean wantsToAttack(LivingEntity target, LivingEntity owner) { + if (target instanceof Creeper || this.isFriendlyTo(target)) { + return false; } - return best; - } - - public void startSpitVolley(@Nullable LivingEntity target) { - if (this.spitCooldown > 0 || this.level().isClientSide) { - return; + if (target instanceof Player victim && owner instanceof Player ownerPlayer && !ownerPlayer.canHarmPlayer(victim)) { + return false; } - this.spitCooldown = 40; - this.actionTicks = ACTION_TICKS; - this.actionHit = true; - this.setAnimState(this.isFlying() ? ANIM_FLY_SHOOT : ANIM_SHOOT); - this.triggerAnim("main", this.isFlying() ? "fly_shoot" : "shoot"); - - Vec3 aim; - if (target != null) { - aim = target.getEyePosition().subtract(this.getEyePosition()).normalize(); - } else if (this.getControllingPassenger() instanceof Player rider) { - aim = rider.getLookAngle(); - } else { - aim = this.getLookAngle(); - } - - Vec3 right = new Vec3(-aim.z, 0.0D, aim.x).normalize(); - for (int i = -1; i <= 1; i++) { - Vec3 dir = aim.add(right.scale(i * 0.14D)).normalize(); - RoyalBoltEntity bolt = new RoyalBoltEntity(this.boltType(), this.level()); - bolt.setOwner(this); - bolt.setElement(this.boltElement(i)); - Vec3 spawn = this.getEyePosition().add(aim.scale(1.6D)).add(right.scale(i * 0.9D)); - bolt.setPos(spawn.x, spawn.y, spawn.z); - bolt.shoot(dir.x, dir.y, dir.z, 1.4F, 1.0F); - this.level().addFreshEntity(bolt); - } - this.playSound(this.shootSound(), 1.2F, 0.9F + this.random.nextFloat() * 0.2F); - } - - protected RoyalBeamElement boltElement(int lateralIndex) { - return RoyalBeamElement.GENERIC; + return super.wantsToAttack(target, owner); } public boolean toggleMountedFlight(ServerPlayer player) { if (!this.canControl(player)) { return false; } + if (!this.isFlying() && !this.canFly()) { + this.notifyLocked(player, "message.antarchy.royal_mount.too_young_fly", Stage.ADULT); + return false; + } this.setFlying(!this.isFlying()); if (this.isFlying()) { this.setDeltaMovement(this.getDeltaMovement().add(0.0D, 0.4D, 0.0D)); @@ -763,19 +1241,51 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit public void handleMountedBite(ServerPlayer player) { if (this.canControl(player)) { - this.startBite(); + this.startAction(ACTION_BITE, null, null, true); } } public void handleMountedSpit(ServerPlayer player) { - if (this.canControl(player)) { - this.startSpitVolley(null); + if (!this.canControl(player)) { + return; } + if (!this.canSpit()) { + this.notifyLocked(player, "message.antarchy.royal_mount.too_young_ability", Stage.JUVENILE); + return; + } + this.startAction(ACTION_SPIT, null, null, true); + } + + public void handleMountedBeam(ServerPlayer player) { + if (!this.canControl(player)) { + return; + } + if (!this.canUseAdultAbilities()) { + this.notifyLocked(player, "message.antarchy.royal_mount.too_young_ability", Stage.ADULT); + return; + } + this.startAction(ACTION_BEAM, null, this.riderAimPoint(player, this.beamRange()), true); + } + + public void handleMountedSignature(ServerPlayer player) { + if (!this.canControl(player)) { + return; + } + if (!this.canUseAdultAbilities()) { + this.notifyLocked(player, "message.antarchy.royal_mount.too_young_ability", Stage.ADULT); + return; + } + LivingEntity aimed = this.riderAimEntity(player, 32.0D); + this.startAction(ACTION_SIGNATURE, aimed, this.riderAimPoint(player, 32.0D), true); + } + + private void notifyLocked(Player player, String key, Stage required) { + player.displayClientMessage(Component.translatable(key, this.getDisplayName(), required.displayName()), true); } public void setRiderAscend(boolean pressed) { this.riderAscendPressed = pressed; - if (pressed && !this.isFlying() && this.getControllingPassenger() != null) { + if (pressed && !this.isFlying() && this.canFly() && this.getControllingPassenger() != null) { this.setFlying(true); this.setDeltaMovement(this.getDeltaMovement().add(0.0D, 0.35D, 0.0D)); this.hasImpulse = true; @@ -807,7 +1317,7 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit Vec3 end = eye.add(player.getViewVector(1.0F).scale(player.entityInteractionRange() + extraReach)); RoyalMountEntity best = null; double bestDistance = Double.MAX_VALUE; - for (RoyalMountEntity mount : player.level().getEntitiesOfClass(RoyalMountEntity.class, player.getBoundingBox().inflate(80.0D), + for (RoyalMountEntity mount : player.level().getEntitiesOfClass(RoyalMountEntity.class, player.getBoundingBox().inflate(40.0D), mount -> mount.isAlive() && mount.isTame() && mount.isOwnedBy(player) && !mount.isVehicle())) { AABB box = mount.assistedMountBox(); double distance; @@ -830,12 +1340,7 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit public static boolean tryAssistedMount(ServerPlayer player) { RoyalMountEntity mount = findAssistedMountTarget(player, 2.0D); - if (mount == null) { - return false; - } - mount.setOrderedToSit(false); - mount.setInSittingPose(false); - return player.startRiding(mount); + return mount != null && mount.tryMount(player); } @Nullable @@ -846,7 +1351,23 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit @Override public boolean canAddPassenger(Entity passenger) { - return this.getPassengers().isEmpty(); + return this.getPassengers().isEmpty() && this.canBeRidden(); + } + + @Override + protected void removePassenger(Entity passenger) { + super.removePassenger(passenger); + this.riderAscendPressed = false; + this.riderDescendPressed = false; + if (this.actionRidden) { + this.clearAction(); + } + } + + public double seatHeight() { + double bob = this.getAnimState() == ANIM_FLY || this.getAnimState() == ANIM_FLY_BITE || this.getAnimState() == ANIM_FLY_SHOOT + ? FLY_BOB_HEIGHT : 0.0D; + return (SEAT_HEIGHT + bob) * this.getGrowthScale(); } @Override @@ -855,10 +1376,17 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit return; } float scale = this.getGrowthScale(); - double yOffset = 1.3D * scale; - double backDistance = 0.35D * scale; - Vec3 back = Vec3.directionFromRotation(0.0F, this.getYRot()).scale(-backDistance); - moveFunction.accept(passenger, this.getX() + back.x, this.getY() + yOffset, this.getZ() + back.z); + Vec3 back = Vec3.directionFromRotation(0.0F, this.yBodyRot).scale(-SEAT_BACK * scale); + double attach = passenger.getVehicleAttachmentPoint(this).y; + moveFunction.accept(passenger, this.getX() + back.x, this.getY() + this.seatHeight() - attach, this.getZ() + back.z); + } + + public float thirdPersonCameraBonus() { + return 1.5F + 2.6F * (this.getGrowthScale() - 1.0F); + } + + public float thirdPersonCameraLift() { + return 0.3F * this.getGrowthScale(); } @Override @@ -891,13 +1419,18 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit return; } - this.setYRot(rider.getYRot()); - this.yBodyRot = this.getYRot(); - this.yHeadRot = this.getYRot(); + float yaw = this.isActionCommittedForRider() ? Mth.approachDegrees(this.getYRot(), rider.getYRot(), 6.0F) : rider.getYRot(); + this.setYRot(yaw); + this.yBodyRot = yaw; + this.yHeadRot = yaw; this.setXRot(rider.getXRot() * 0.5F); Vec3 input = this.getRiddenInput(rider, travelVector); - this.setSpeed(this.getRiddenSpeed(rider)); + float speed = this.getRiddenSpeed(rider); + if (this.action == ACTION_BEAM || this.action == ACTION_SIGNATURE) { + speed *= 0.45F; + } + this.setSpeed(speed); if (this.isFlying()) { this.moveRelative(this.getSpeed(), new Vec3(input.x, 0.0D, input.z)); @@ -911,21 +1444,91 @@ public abstract class RoyalMountEntity extends TamableAnimal implements GeoEntit } } + private boolean isActionCommittedForRider() { + return this.action == ACTION_BEAM && this.actionFired; + } + @Override public boolean causeFallDamage(float fallDistance, float multiplier, DamageSource source) { return false; } - @Override - public float maxUpStep() { - return 1.5F; - } - @Override public boolean removeWhenFarAway(double distanceToClosestPlayer) { return false; } + public static boolean isAirborne(LivingEntity entity) { + if (entity.isFallFlying()) { + return true; + } + if (entity instanceof Player player && player.getAbilities().flying) { + return true; + } + Entity vehicle = entity.getVehicle(); + return vehicle != null && !vehicle.onGround() && !vehicle.isInWater() && vehicle.isNoGravity(); + } + + public double findGroundY(double x, double startY, double z, int maxDepth) { + BlockPos.MutableBlockPos cursor = BlockPos.containing(x, startY, z).mutable(); + for (int i = 0; i < maxDepth; i++) { + BlockState state = this.level().getBlockState(cursor); + if (!state.getCollisionShape(this.level(), cursor).isEmpty() || !state.getFluidState().isEmpty()) { + return cursor.getY() + 1.0D; + } + cursor.move(0, -1, 0); + if (cursor.getY() < this.level().getMinBuildHeight()) { + break; + } + } + return Double.NaN; + } + + public boolean canOccupy(double x, double y, double z) { + AABB box = this.getBoundingBox().move(x - this.getX(), y - this.getY(), z - this.getZ()); + return this.level().noCollision(this, box) && !this.level().containsAnyLiquid(box); + } + + public boolean tryTeleportNear(LivingEntity anchor) { + boolean allowAir = this.canFly() && isAirborne(anchor); + double base = this.getBbWidth() * 0.5D + 1.5D; + float startAngle = this.random.nextFloat() * Mth.TWO_PI; + for (int ring = 0; ring < 3; ring++) { + double radius = base + ring * (1.5D + this.getBbWidth() * 0.25D); + for (int step = 0; step < 12; step++) { + double angle = startAngle + step * (Mth.TWO_PI / 12.0D); + double x = anchor.getX() + Math.cos(angle) * radius; + double z = anchor.getZ() + Math.sin(angle) * radius; + if (allowAir) { + double y = anchor.getY() + 1.0D; + if (this.canOccupy(x, y, z)) { + this.finishTeleport(x, y, z, true); + return true; + } + continue; + } + double ground = this.findGroundY(x, anchor.getY() + 3.0D, z, 8); + if (Double.isNaN(ground) || !this.level().getBlockState(BlockPos.containing(x, ground - 1.0D, z)).getFluidState().isEmpty()) { + continue; + } + if (this.canOccupy(x, ground, z)) { + this.finishTeleport(x, ground, z, false); + return true; + } + } + } + return false; + } + + private void finishTeleport(double x, double y, double z, boolean flying) { + this.navigation.stop(); + this.setFlying(flying && this.canFly()); + if (flying) { + this.flightClaimTick = this.tickCount; + } + this.teleportTo(x, y, z); + } + @Override public void registerControllers(AnimatableManager.ControllerRegistrar controllers) { controllers.add(new AnimationController<>(this, "main", 2, this::animController) diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalMountFollowOwnerGoal.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalMountFollowOwnerGoal.java index 0235984e..57095136 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalMountFollowOwnerGoal.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalMountFollowOwnerGoal.java @@ -1,81 +1,76 @@ package com.craisinlord.antarchy.content.entity.royal; -import net.minecraft.core.BlockPos; +import java.util.EnumSet; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.ai.goal.Goal; import net.minecraft.world.phys.Vec3; public class RoyalMountFollowOwnerGoal extends Goal { - private static final double START_DISTANCE = 12.0D; - private static final double STOP_DISTANCE = 6.0D; - private static final double TELEPORT_DISTANCE = 48.0D; - private final RoyalMountEntity mount; private LivingEntity owner; private int recalcTimer; + private int stuckTicks; + private int teleportCooldown; + private Vec3 lastCheckPosition = Vec3.ZERO; public RoyalMountFollowOwnerGoal(RoyalMountEntity mount) { this.mount = mount; + this.setFlags(EnumSet.of(Goal.Flag.MOVE, Goal.Flag.LOOK)); + } + + private double startDistance() { + return 14.0D + 2.0D * this.mount.getGrowthScale(); + } + + private double stopDistance() { + return 6.0D + 1.5D * this.mount.getGrowthScale(); + } + + private double teleportDistance() { + return 48.0D + 4.0D * this.mount.getGrowthScale(); + } + + private boolean canFollow(LivingEntity candidate) { + return candidate != null && candidate.isAlive() && !candidate.isSpectator() + && candidate.level() == this.mount.level() + && this.mount.isTame() && !this.mount.isVehicle() && !this.mount.isOrderedToSit() + && !this.mount.isLeashed() && this.mount.getTarget() == null; } @Override public boolean canUse() { - if (!this.mount.isTame() || this.mount.isVehicle() || this.mount.isOrderedToSit()) { + LivingEntity candidate = this.mount.getOwner(); + if (!this.canFollow(candidate)) { return false; } - LivingEntity potentialOwner = this.mount.getOwner(); - if (potentialOwner == null || potentialOwner.isSpectator()) { + double start = this.startDistance(); + if (this.mount.distanceToSqr(candidate) < start * start) { return false; } - if (this.mount.distanceToSqr(potentialOwner) < START_DISTANCE * START_DISTANCE) { - return false; - } - this.owner = potentialOwner; + this.owner = candidate; return true; } @Override public boolean canContinueToUse() { - return !this.mount.getNavigation().isDone() - && this.mount.distanceToSqr(this.owner) > STOP_DISTANCE * STOP_DISTANCE - && !this.mount.isOrderedToSit(); + if (!this.canFollow(this.owner) || this.owner != this.mount.getOwner()) { + return false; + } + double stop = this.stopDistance(); + return this.mount.distanceToSqr(this.owner) > stop * stop; } @Override public void start() { this.recalcTimer = 0; + this.stuckTicks = 0; + this.lastCheckPosition = this.mount.position(); } @Override public void stop() { this.owner = null; this.mount.getNavigation().stop(); - this.mount.setFlying(false); - } - - @Override - public void tick() { - this.mount.getLookControl().setLookAt(this.owner, 10.0F, this.mount.getMaxHeadXRot()); - - double distanceSqr = this.mount.distanceToSqr(this.owner); - if (distanceSqr > TELEPORT_DISTANCE * TELEPORT_DISTANCE) { - this.trySafeTeleport(); - return; - } - - boolean ownerAirborne = !this.owner.onGround() || (this.owner.getY() - this.mount.getY()) > 3.0D; - this.mount.setFlying(ownerAirborne || distanceSqr > 24.0D * 24.0D); - - if (--this.recalcTimer <= 0) { - this.recalcTimer = 10; - if (this.mount.isFlying()) { - Vec3 to = this.owner.position().subtract(this.mount.position()); - Vec3 step = this.mount.position().add(to.normalize().scale(Math.min(to.length(), 8.0D))); - this.mount.getMoveControl().setWantedPosition(step.x, step.y + 1.0D, step.z, 1.2D); - } else { - this.mount.getNavigation().moveTo(this.owner, 1.1D); - } - } } @Override @@ -83,28 +78,57 @@ public class RoyalMountFollowOwnerGoal extends Goal { return true; } - private void trySafeTeleport() { - Vec3 ownerPosition = this.owner.position(); - BlockPos ownerBlock = this.owner.blockPosition(); - for (int radius = 0; radius <= 2; radius++) { - for (int dx = -radius; dx <= radius; dx++) { - for (int dz = -radius; dz <= radius; dz++) { - for (int dy = -1; dy <= 2; dy++) { - double x = ownerPosition.x + dx + 0.5D; - double y = ownerBlock.getY() + dy; - double z = ownerPosition.z + dz + 0.5D; - BlockPos floor = BlockPos.containing(x, y - 0.1D, z); - var destination = this.mount.getBoundingBox().move(x - this.mount.getX(), y - this.mount.getY(), z - this.mount.getZ()); - if (!this.mount.level().noCollision(this.mount, destination)) { - continue; - } - if (this.mount.isFlying() || !this.mount.level().getBlockState(floor).getCollisionShape(this.mount.level(), floor).isEmpty()) { - this.mount.teleportTo(x, y, z); - return; - } - } - } + @Override + public void tick() { + this.mount.getLookControl().setLookAt(this.owner, 10.0F, this.mount.getMaxHeadXRot()); + if (this.teleportCooldown > 0) { + this.teleportCooldown--; + } + this.trackStuck(); + + double distance = this.mount.distanceTo(this.owner); + if ((distance > this.teleportDistance() || this.stuckTicks >= 100 && distance > 24.0D) && this.teleportCooldown <= 0) { + this.teleportCooldown = 20; + if (this.mount.tryTeleportNear(this.owner)) { + this.stuckTicks = 0; + return; } } + + boolean ownerAirborne = RoyalMountEntity.isAirborne(this.owner); + boolean wantsFlight = this.mount.canFly() && (ownerAirborne || distance > 24.0D + this.mount.getBbWidth() + || this.stuckTicks >= 40 || this.owner.getY() - this.mount.getY() > 4.0D); + if (wantsFlight && this.mount.claimFlight()) { + if (--this.recalcTimer <= 0) { + this.recalcTimer = 5; + float scale = this.mount.getGrowthScale(); + Vec3 destination = this.owner.position().add(0.0D, 2.0D + 0.6D * scale, 0.0D); + Vec3 to = destination.subtract(this.mount.position()); + double stepLength = Math.min(to.length(), 12.0D + 2.0D * scale); + Vec3 step = to.lengthSqr() > 1.0E-4D ? this.mount.position().add(to.normalize().scale(stepLength)) : destination; + this.mount.getMoveControl().setWantedPosition(step.x, step.y, step.z, 1.3D); + } + return; + } + if (this.mount.isFlying()) { + return; + } + if (--this.recalcTimer <= 0) { + this.recalcTimer = 10; + this.mount.getNavigation().moveTo(this.owner, 1.2D); + } + } + + private void trackStuck() { + if (this.mount.tickCount % 20 != 0) { + return; + } + Vec3 position = this.mount.position(); + if (position.distanceToSqr(this.lastCheckPosition) < 1.0D) { + this.stuckTicks += 20; + } else { + this.stuckTicks = 0; + } + this.lastCheckPosition = position; } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalMountSpitGoal.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalMountSpitGoal.java deleted file mode 100644 index 1dfa4f6b..00000000 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/RoyalMountSpitGoal.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.craisinlord.antarchy.content.entity.royal; - -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.ai.goal.Goal; - -public class RoyalMountSpitGoal extends Goal { - private final RoyalMountEntity mount; - private int cooldown; - - public RoyalMountSpitGoal(RoyalMountEntity mount) { - this.mount = mount; - } - - @Override - public boolean canUse() { - if (this.mount.isVehicle() || this.mount.isOrderedToSit()) { - return false; - } - LivingEntity target = this.mount.getTarget(); - if (target == null || !target.isAlive() || !this.mount.canAttack(target)) { - return false; - } - double distance = this.mount.distanceTo(target); - return distance > 5.0D && distance < 20.0D && this.mount.hasLineOfSight(target); - } - - @Override - public void start() { - this.cooldown = 20; - } - - @Override - public void tick() { - LivingEntity target = this.mount.getTarget(); - if (target == null || !this.mount.canAttack(target)) { - return; - } - this.mount.getLookControl().setLookAt(target, 30.0F, 30.0F); - if (this.cooldown-- <= 0) { - this.mount.startSpitVolley(target); - this.cooldown = 60; - } - } - - @Override - public boolean requiresUpdateEveryTick() { - return true; - } -} diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/attack/RoyalAttackScheduler.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/attack/RoyalAttackScheduler.java index b885a307..a7dbb365 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/attack/RoyalAttackScheduler.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/entity/royal/attack/RoyalAttackScheduler.java @@ -100,7 +100,8 @@ public final class RoyalAttackScheduler { int total = 0; int[] weights = new int[ids.length]; for (int i = 0; i < ids.length; i++) { - weights[i] = Math.max(0, weightFunction.applyAsInt(ids[i]) - repetitionPenalty(ids[i])); + int baseWeight = weightFunction.applyAsInt(ids[i]); + weights[i] = baseWeight > 0 ? Math.max(1, baseWeight - repetitionPenalty(ids[i])) : 0; total += weights[i]; } if (total <= 0) { diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/RoyalMountActionPayload.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/RoyalMountActionPayload.java index 6c8ca85c..8d0633de 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/RoyalMountActionPayload.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/network/RoyalMountActionPayload.java @@ -12,6 +12,8 @@ public record RoyalMountActionPayload(int action) implements CustomPacketPayload public static final int BITE = 1; public static final int SPIT = 2; public static final int MOUNT = 3; + public static final int BEAM = 4; + public static final int SIGNATURE = 5; public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "royal_mount_action")); diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalTeleporter.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalTeleporter.java index 526f1d0b..9ef549cf 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalTeleporter.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/content/portal/PermanentPortalTeleporter.java @@ -1,6 +1,7 @@ package com.craisinlord.antarchy.content.portal; import com.craisinlord.antarchy.config.AntarchySettings; +import com.craisinlord.antarchy.content.entity.ant.AntTeleportHelper; import java.util.Comparator; import java.util.LinkedHashSet; import java.util.List; @@ -13,6 +14,7 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.ai.village.poi.PoiManager; import net.minecraft.world.entity.ai.village.poi.PoiRecord; import net.minecraft.world.entity.vehicle.DismountHelper; @@ -47,7 +49,20 @@ public final class PermanentPortalTeleporter { } return new DimensionTransition(sourceLevel, entity, DimensionTransition.DO_NOTHING); } - return new DimensionTransition(destination, arrival, Vec3.ZERO, entity.getYRot(), entity.getXRot(), DimensionTransition.PLAY_PORTAL_SOUND); + DimensionTransition.PostDimensionTransition postTransition = DimensionTransition.PLAY_PORTAL_SOUND; + if (entity instanceof ServerPlayer player) { + List companions = AntTeleportHelper.collectCompanions(player); + if (!companions.isEmpty()) { + postTransition = postTransition.then(moved -> { + for (Mob companion : companions) { + if (companion.isAlive()) { + AntTeleportHelper.moveCompanion(companion, destination, arrival); + } + } + }); + } + } + return new DimensionTransition(destination, arrival, Vec3.ZERO, entity.getYRot(), entity.getXRot(), postTransition); } @Nullable @@ -68,6 +83,7 @@ public final class PermanentPortalTeleporter { return safePortalPosition != null ? safePortalPosition : existing.center(); } + AntTeleportHelper.loadArrivalSearchArea(destination, preferredPos, SEARCH_RADIUS); Vec3 safe = findSafeArrivalPosition(entity, destination, preferredPos, type); if (safe != null) { PermanentPortalShape created = createReturnPortal(destination, safe, type); @@ -77,7 +93,19 @@ public final class PermanentPortalTeleporter { return createFallbackPortal(destination, BlockPos.containing(safe), type); } - return null; + return createFallbackPortal(destination, fallbackArrivalPos(destination, preferredPos, type), type); + } + + private static BlockPos fallbackArrivalPos(ServerLevel destination, BlockPos preferredPos, PermanentPortalType type) { + int[] yRange = getDimensionYRange(destination, type); + if (yRange != null) { + return new BlockPos(preferredPos.getX(), Mth.clamp(preferredPos.getY(), yRange[0] + 1, yRange[1] - 4), preferredPos.getZ()); + } + BlockPos surface = destination.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, preferredPos); + if (surface.getY() > destination.getMinBuildHeight() + 1) { + return surface; + } + return preferredPos; } @Nullable diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/client/MountedVehicleCameraMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/client/MountedVehicleCameraMixin.java index 680aabce..8982ab88 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/client/MountedVehicleCameraMixin.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/client/MountedVehicleCameraMixin.java @@ -1,12 +1,14 @@ package com.craisinlord.antarchy.mixins.client; import com.craisinlord.antarchy.content.entity.HerculesBeetleEntity; +import com.craisinlord.antarchy.content.entity.royal.RoyalMountEntity; import net.minecraft.client.Camera; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.BlockGetter; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.ModifyArgs; import org.spongepowered.asm.mixin.injection.invoke.arg.Args; @@ -15,6 +17,18 @@ public abstract class MountedVehicleCameraMixin { @Shadow private Entity entity; + @ModifyArg( + method = "setup", + at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Camera;getMaxZoom(F)F"), + index = 0 + ) + private float antarchy$extendRoyalMountZoom(float distance) { + if (this.entity != null && this.entity.getVehicle() instanceof RoyalMountEntity mount) { + return distance + mount.thirdPersonCameraBonus(); + } + return distance; + } + @ModifyArgs( method = "setup", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Camera;move(FFF)V") @@ -38,6 +52,9 @@ public abstract class MountedVehicleCameraMixin { args.set(2, (Float) args.get(2) + 0.45F); return; } + if (vehicle instanceof RoyalMountEntity mount) { + args.set(1, (Float) args.get(1) + mount.thirdPersonCameraLift()); + } } } diff --git a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/client/PortalGunZoomFovMixin.java b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/client/PortalGunZoomFovMixin.java index b3b6b4b2..5c6dc5a6 100644 --- a/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/client/PortalGunZoomFovMixin.java +++ b/common-1.21.1/src/main/java/com/craisinlord/antarchy/mixins/client/PortalGunZoomFovMixin.java @@ -1,18 +1,17 @@ package com.craisinlord.antarchy.mixins.client; import com.craisinlord.antarchy.content.client.PortalGunZoomClientState; +import com.llamalad7.mixinextras.injector.ModifyReturnValue; import net.minecraft.client.Camera; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.GameRenderer; 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; @Mixin(GameRenderer.class) public abstract class PortalGunZoomFovMixin { - @Inject(method = "getFov", at = @At("RETURN"), cancellable = true) - private void antarchy$applyPortalGunZoom(Camera camera, float partialTick, boolean useFovSetting, CallbackInfoReturnable cir) { - cir.setReturnValue(PortalGunZoomClientState.applyFov(cir.getReturnValue(), partialTick, Minecraft.getInstance().options)); + @ModifyReturnValue(method = "getFov", at = @At("RETURN")) + private double antarchy$applyPortalGunZoom(double fov, Camera camera, float partialTick, boolean useFovSetting) { + return PortalGunZoomClientState.applyFov(fov, partialTick, Minecraft.getInstance().options); } } diff --git a/common-1.21.1/src/main/resources/assets/antarchy/geo/gravity_gun.geo.json b/common-1.21.1/src/main/resources/assets/antarchy/geo/gravity_gun.geo.json index c1aee484..c61b1fcf 100644 --- a/common-1.21.1/src/main/resources/assets/antarchy/geo/gravity_gun.geo.json +++ b/common-1.21.1/src/main/resources/assets/antarchy/geo/gravity_gun.geo.json @@ -57,7 +57,7 @@ {"origin": [2.5, 3.7, -9.47], "size": [0, 5, 3], "uv": [26, 27]}, {"origin": [-2.5, 3.7, -9.47], "size": [5, 0, 3], "uv": [22, 15]}, {"origin": [-2.5, 3.7, -9.47], "size": [0, 5, 3], "uv": [20, 27]}, - {"origin": [-2.5, 3.7, -6.47], "size": [5, 5, 0], "uv": [20, 22]} + {"origin": [-2.5, 3.7, -6.55], "size": [5, 5, 0], "uv": [20, 22]} ] } ] diff --git a/common-1.21.1/src/main/resources/assets/antarchy/lang/en_us.json b/common-1.21.1/src/main/resources/assets/antarchy/lang/en_us.json index d643b15b..796617bb 100644 --- a/common-1.21.1/src/main/resources/assets/antarchy/lang/en_us.json +++ b/common-1.21.1/src/main/resources/assets/antarchy/lang/en_us.json @@ -604,6 +604,16 @@ "message.antarchy.royal_boundary.activated": "Royal Boundary raised", "message.antarchy.royal_boundary.recharging": "Royal Boundary is recharging", "key.antarchy.mount_flight_toggle": "Mount: Toggle Flight", + "key.antarchy.mount_beam": "Royal Mount: Beam", + "key.antarchy.mount_signature": "Royal Mount: Command / Time Field", + "entity.antarchy.royal_mount.stage.hatchling": "Hatchling", + "entity.antarchy.royal_mount.stage.juvenile": "Juvenile", + "entity.antarchy.royal_mount.stage.adult": "Adult", + "message.antarchy.royal_mount.stage_up": "%s has reached the %s stage!", + "message.antarchy.royal_mount.growth": "%s: %s, %s%% grown", + "message.antarchy.royal_mount.too_young_ride": "%s must reach the %s stage before it can be ridden", + "message.antarchy.royal_mount.too_young_fly": "%s must reach the %s stage before it can fly", + "message.antarchy.royal_mount.too_young_ability": "%s must reach the %s stage to use that", "item.antarchy.springbug_leg": "Springbug Leg", "item.antarchy.springy_boots": "Springy Boots", "tooltip.antarchy.springy_boots": "Sneak to charge, then jump to spring upward.", @@ -1642,12 +1652,12 @@ ,"guide.antarchy.entry.queen.description6": "In her final phase she also casts her own time dilation field, slowing anyone caught inside it." ,"guide.antarchy.entry.prince.title": "Prince" ,"guide.antarchy.entry.prince.subtitle": "Royal mount record" - ,"guide.antarchy.entry.prince.description": "Prince Eggs hatch into small Princes that grow when fed golden items." - ,"guide.antarchy.entry.prince.description2": "A grown Prince can be tamed and saddled for flight, fires elemental bolts at your enemies, and can command nearby hostile mobs. Feed responsibly; you are raising a small flying warlord." + ,"guide.antarchy.entry.prince.description": "Prince Eggs hatch into Hatchlings bonded to whoever placed the egg. Golden apples grow them a little and enchanted golden apples grow them a lot: Juveniles can be ridden and spit bolts, and Adults can fly, fire beams, and use their signature ability." + ,"guide.antarchy.entry.prince.description2": "The Prince is a ground brawler: he closes in to bite with all three heads, spits fire, ice, and lightning, and as an Adult commands nearby hostile mobs to fight for him. Feed responsibly; you are raising a small flying warlord." ,"guide.antarchy.entry.princess.title": "Princess" ,"guide.antarchy.entry.princess.subtitle": "Royal mount record" - ,"guide.antarchy.entry.princess.description": "Princess Eggs hatch into small Princesses that grow when fed golden items." - ,"guide.antarchy.entry.princess.description2": "A grown Princess can be tamed and saddled for flight, fires elemental bolts, and creates time-dilation fields around enemies." + ,"guide.antarchy.entry.princess.description": "Princess Eggs hatch into Hatchlings bonded to whoever placed the egg. Golden apples grow them a little and enchanted golden apples grow them a lot: Juveniles can be ridden and spit bolts, and Adults can fly, fire beams, and use their signature ability." + ,"guide.antarchy.entry.princess.description2": "The Princess fights at range: she keeps her distance, fires slowing bolts from her orbs, and as an Adult hovers above her foes and traps them in time-dilation fields." ,"subtitles.antarchy.hoverboard_mount": "Hoverboard starts" ,"subtitles.antarchy.hoverboard_dismount": "Hoverboard stops" ,"subtitles.antarchy.hoverboard_idle": "Hoverboard hums" diff --git a/common-1.21.1/src/main/resources/assets/antarchy/lang/ko_kr.json b/common-1.21.1/src/main/resources/assets/antarchy/lang/ko_kr.json index 0bc0c270..86001626 100644 --- a/common-1.21.1/src/main/resources/assets/antarchy/lang/ko_kr.json +++ b/common-1.21.1/src/main/resources/assets/antarchy/lang/ko_kr.json @@ -1,961 +1,1670 @@ { - "block.antarchy.duplicator_log": "복제기 원목", - "block.antarchy.ouranwood_log": "오란우드 원목", - "block.antarchy.ouranwood_wood": "오란우드 목재", - "block.antarchy.mossy_ouranwood_log": "이끼 낀 오란우드 원목", - "block.antarchy.mossy_ouranwood_wood": "이끼 낀 오란우드 목재", - "block.antarchy.stripped_ouranwood_log": "껍질 벗긴 오란우드 원목", - "block.antarchy.stripped_ouranwood_wood": "껍질 벗긴 오란우드 목재", - "block.antarchy.ouranwood_planks": "오란우드 판자", - "block.antarchy.ouranwood_stairs": "오란우드 계단", - "block.antarchy.ouranwood_slab": "오란우드 반 블록", - "block.antarchy.ouranwood_fence": "오란우드 울타리", - "block.antarchy.ouranwood_fence_gate": "오란우드 울타리 문", - "block.antarchy.ouranwood_door": "오란우드 문", - "block.antarchy.ouranwood_trapdoor": "오란우드 다락문", - "block.antarchy.ouranwood_pressure_plate": "오란우드 감압판", - "block.antarchy.ouranwood_button": "오란우드 버튼", - "block.antarchy.ouranwood_leaves": "오란우드 잎", - "block.antarchy.ouranwood_acorn": "오란우드 도토리", - "block.antarchy.ouranwood_sign": "오란우드 표지판", - "block.antarchy.ouranwood_hanging_sign": "오란우드 매다는 표지판", - "block.antarchy.peach_log": "복숭아 원목", - "block.antarchy.peach_wood": "복숭아 목재", - "block.antarchy.stripped_peach_log": "껍질 벗긴 복숭아 원목", - "block.antarchy.stripped_peach_wood": "껍질 벗긴 복숭아 목재", - "block.antarchy.peach_planks": "복숭아 판자", - "block.antarchy.peach_stairs": "복숭아 계단", - "block.antarchy.peach_slab": "복숭아 반 블록", - "block.antarchy.peach_fence": "복숭아 울타리", - "block.antarchy.peach_fence_gate": "복숭아나무 울타리 문", - "block.antarchy.peach_door": "복숭아 문", - "block.antarchy.peach_trapdoor": "복숭아 다락문", - "block.antarchy.peach_pressure_plate": "복숭아 감압판", - "block.antarchy.peach_button": "복숭아 버튼", - "block.antarchy.peach_leaves": "복숭아 잎", - "block.antarchy.hanging_peach": "매달린 복숭아", - "block.antarchy.peach_sapling": "복숭아 묘목", - "block.antarchy.peach_sign": "복숭아 표지판", - "block.antarchy.peach_hanging_sign": "복숭아 매다는 표지판", - "block.antarchy.orange_milkweed": "주황색 박주가리", - "block.antarchy.pink_milkweed": "분홍색 박주가리", - "block.antarchy.camellia": "동백꽃", - "block.antarchy.spider_lily": "석산", - "block.antarchy.lotus": "연꽃", - "item.antarchy.lotus": "연꽃", - "item.antarchy.critter_cage": "동물 우리", - "block.antarchy.giant_lily_pad": "거대 수련잎", - "block.antarchy.seashell": "조개껍데기", - "block.antarchy.critter_cage_block": "동물 우리", - "block.antarchy.hushweed": "허시위드", - "block.antarchy.umbral_moss_block": "그늘 이끼 블록", - "block.antarchy.umbral_moss_carpet": "그늘 이끼 양탄자", - "block.antarchy.blush_moss_block": "분홍 이끼 블록", - "block.antarchy.blush_moss_carpet": "분홍 이끼 양탄자", - "block.antarchy.duplicator_sapling": "복제기 묘목", - "block.antarchy.duct_tape": "덕트 테이프", - "block.antarchy.infested_rooted_dirt": "감염된 뿌리내린 흙", - "block.antarchy.infested_coarse_dirt": "감염된 거친 흙", - "block.antarchy.nyxite": "닉사이트", - "block.antarchy.polished_nyxite": "윤나는 닉사이트", - "block.antarchy.chiseled_nyxite": "조각된 닉사이트", - "block.antarchy.nyxite_bricks": "닉사이트 벽돌", - "block.antarchy.shellstone": "셸스톤", - "block.antarchy.polished_shellstone": "윤나는 셸스톤", - "block.antarchy.shellstone_bricks": "셸스톤 벽돌", - "block.antarchy.chiseled_shellstone": "조각된 셸스톤", - "block.antarchy.mossy_shellstone_bricks": "이끼 낀 셸스톤 벽돌", - "block.antarchy.mossy_shellstone_brick_stairs": "이끼 낀 셸스톤 벽돌 계단", - "block.antarchy.mossy_shellstone_brick_slab": "이끼 낀 셸스톤 벽돌 반 블록", - "block.antarchy.mossy_shellstone_brick_wall": "이끼 낀 셸스톤 벽돌 담장", - "block.antarchy.cracked_shellstone_bricks": "금 간 셸스톤 벽돌", - "block.antarchy.shellstone_stairs": "셸스톤 계단", - "block.antarchy.shellstone_slab": "셸스톤 반 블록", - "block.antarchy.shellstone_wall": "셸스톤 담장", - "block.antarchy.polished_shellstone_stairs": "윤나는 셸스톤 계단", - "block.antarchy.polished_shellstone_slab": "윤나는 셸스톤 반 블록", - "block.antarchy.polished_shellstone_wall": "윤나는 셸스톤 담장", - "block.antarchy.shellstone_brick_stairs": "셸스톤 벽돌 계단", - "block.antarchy.shellstone_brick_slab": "셸스톤 벽돌 반 블록", - "block.antarchy.shellstone_brick_wall": "셸스톤 벽돌 담장", - "block.antarchy.nyxite_stairs": "닉사이트 계단", - "block.antarchy.nyxite_slab": "닉사이트 반 블록", - "block.antarchy.nyxite_wall": "닉사이트 담장", - "block.antarchy.polished_nyxite_stairs": "윤나는 닉사이트 계단", - "block.antarchy.polished_nyxite_slab": "윤나는 닉사이트 반 블록", - "block.antarchy.polished_nyxite_wall": "윤나는 닉사이트 담장", - "block.antarchy.nyxite_brick_stairs": "닉사이트 벽돌 계단", - "block.antarchy.nyxite_brick_slab": "닉사이트 벽돌 반 블록", - "block.antarchy.nyxite_brick_wall": "닉사이트 벽돌 담장", - "block.antarchy.pale_nyxite": "창백한 닉사이트", - "block.antarchy.nyxite_spike": "닉사이트 가시", - "block.antarchy.potent_nyxite": "강력한 닉사이트", - "block.antarchy.flytrap_goo_block": "트리피드 점액 블록", - "block.antarchy.elythia_portal": "엘리티아 차원문", - "block.antarchy.cloud_block": "구름 블록", - "block.antarchy.thoraxis_portal": "토랙시스 차원문", - "block.antarchy.antimetal": "안티메탈", - "block.antarchy.polished_antimetal": "윤나는 안티메탈", - "block.antarchy.antimetal_scaffolding": "안티메탈 비계", - "block.antarchy.cornea_stalk": "코니아 줄기", - "block.antarchy.corn_crop": "옥수수 작물", - "block.antarchy.dream_torch": "꿈 횃불", - "block.antarchy.dream_wall_torch": "꿈 벽 횃불", - "block.antarchy.dream_lantern": "꿈 랜턴", - "block.antarchy.dream_campfire": "꿈 모닥불", - "block.antarchy.dream_fire": "꿈 불", - "block.antarchy.dream_fire_ceiling": "꿈 불", - "block.antarchy.budding_blood_crystal": "싹트는 혈수정", - "block.antarchy.blood_crystal_block": "혈수정 블록", - "block.antarchy.small_blood_crystal_bud": "작은 혈수정 눈", - "block.antarchy.medium_blood_crystal_bud": "중간 혈수정 눈", - "block.antarchy.large_blood_crystal_bud": "큰 혈수정 눈", - "block.antarchy.blood_crystal_cluster": "혈수정 군집", - "block.antarchy.dream_sand": "꿈 모래", - "block.antarchy.dream_sandstone": "꿈 사암", - "block.antarchy.chiseled_dream_sandstone": "조각된 꿈 사암", - "block.antarchy.cut_dream_sandstone": "깎인 꿈 사암", - "block.antarchy.smooth_dream_sandstone": "매끄러운 꿈 사암", - "block.antarchy.dream_sandstone_stairs": "꿈 사암 계단", - "block.antarchy.dream_sandstone_slab": "꿈 사암 반 블록", - "block.antarchy.dream_sandstone_wall": "꿈 사암 담장", - "block.antarchy.smooth_dream_sandstone_stairs": "매끄러운 꿈 사암 계단", - "block.antarchy.smooth_dream_sandstone_slab": "매끄러운 꿈 사암 반 블록", - "block.antarchy.cut_dream_sandstone_slab": "깎인 꿈 사암 반 블록", - "block.antarchy.bed_bug_egg": "빈대 알", - "block.antarchy.wasp_nest": "말벌 둥지", - "block.antarchy.red_ant_nest": "붉은 개미 둥지", - "block.antarchy.brown_ant_nest": "갈색 개미 둥지", - "block.antarchy.rainbow_ant_nest": "무지개 개미 둥지", - "block.antarchy.uranium_ore": "우라늄 광석", - "block.antarchy.deepslate_uranium_ore": "심층암 우라늄 광석", - "block.antarchy.titanium_ore": "티타늄 광석", - "block.antarchy.deepslate_titanium_ore": "심층암 티타늄 광석", - "block.antarchy.uranium_block": "우라늄 블록", - "block.antarchy.titanium_block": "티타늄 블록", - "block.antarchy.raw_uranium_block": "원시 우라늄 블록", - "block.antarchy.raw_titanium_block": "원시 티타늄 블록", - "block.antarchy.cut_uranium": "깎인 우라늄", - "block.antarchy.cut_titanium": "깎인 티타늄", - "block.antarchy.cut_uranium_slab": "깎인 우라늄 반 블록", - "block.antarchy.cut_titanium_slab": "깎인 티타늄 반 블록", - "block.antarchy.cut_uranium_stairs": "깎인 우라늄 계단", - "block.antarchy.cut_titanium_stairs": "깎인 티타늄 계단", - "block.antarchy.chiseled_uranium": "조각된 우라늄", - "block.antarchy.chiseled_titanium": "조각된 티타늄", - "block.antarchy.uranium_bulb": "우라늄 전구", - "block.antarchy.titanium_bulb": "티타늄 전구", - "block.antarchy.uranium_door": "우라늄 문", - "block.antarchy.titanium_door": "티타늄 문", - "block.antarchy.uranium_trapdoor": "우라늄 다락문", - "block.antarchy.titanium_trapdoor": "티타늄 다락문", - "block.antarchy.uranium_bars": "우라늄 창살", - "block.antarchy.titanium_bars": "티타늄 창살", - "tooltip.antarchy.signal_saving_bulb": "켜고 끌 수 있습니다. 밝기는 저장된 신호 세기와 같습니다.", - "block.antarchy.bile": "담즙", - "block.antarchy.ichor": "이코르", - "block.antarchy.antiwater": "역수", - "block.antarchy.lumen": "루멘", - "block.antarchy.lumen_froglight": "루멘 개구리불", - "block.antarchy.roseate_froglight": "장밋빛 개구리불", - "block.antarchy.star_coral": "별 산호", - "block.antarchy.star_coral_fan": "별 부채산호", - "block.antarchy.star_coral_block": "별 산호 블록", - "block.antarchy.dead_star_coral": "죽은 별 산호", - "block.antarchy.dead_star_coral_fan": "죽은 별 부채산호", - "block.antarchy.dead_star_coral_block": "죽은 별 산호 블록", - "entity.antarchy.apple_cow": "사과 소", - "entity.antarchy.golden_apple_cow": "황금 사과 소", - "entity.antarchy.enchanted_golden_apple_cow": "마법이 부여된 황금 사과 소", - "entity.antarchy.easter_bunny": "부활절 토끼", - "entity.antarchy.glimmer": "글리머", - "entity.antarchy.ouranwood_deer": "오란우드 사슴", - "entity.antarchy.elka": "엘카", - "entity.antarchy.dorrie": "도리", - "entity.antarchy.flying_squirrel": "날다람쥐", - "entity.antarchy.caterpillar": "애벌레", - "entity.antarchy.butterfly": "나비", - "entity.antarchy.brutalfly": "브루털플라이", - "entity.antarchy.red_ant": "붉은 개미", - "entity.antarchy.brown_ant": "갈색 개미", - "entity.antarchy.rainbow_ant": "무지개 개미", - "entity.antarchy.diamond_minecart": "다이아몬드 광산 수레", - "entity.antarchy.dr_trayaurus": "트레이오러스 박사", - "entity.antarchy.stratoshark": "구름 상어", - "entity.antarchy.kraken": "크라켄", - "entity.antarchy.missile_squid": "미사일 오징어", - "entity.antarchy.octopus_bomb": "문어 폭탄", - "entity.antarchy.nightmare": "악몽", - "entity.antarchy.bed_bug": "빈대", - "entity.antarchy.wasp": "말벌", - "entity.antarchy.bomber": "폭격충", - "entity.antarchy.moleworm": "몰웜", - "entity.antarchy.molevore": "몰보어", - "entity.antarchy.mantis": "사마귀", - "entity.antarchy.alpha_mantis": "알파 사마귀", - "entity.antarchy.flytrap": "트리피드", - "entity.antarchy.toreterror": "토어테러", - "entity.antarchy.water_bomb": "물 폭탄", - "subtitles.antarchy.mantis_ambient": "사마귀 딸깍거립니다", - "subtitles.antarchy.mantis_hurt": "사마귀 날카롭게 웁니다", - "subtitles.antarchy.mantis_attack": "사마귀 턱을 딱딱거립니다", - "subtitles.antarchy.mantis_fly_loop": "사마귀 날개가 윙윙거립니다", - "item.antarchy.big_bertha": "빅 버사", - "item.antarchy.wasp_nest": "말벌 둥지", - "item.antarchy.stink_bug": "노린재", - "item.antarchy.wasp_spawn_egg": "말벌 생성 알", - "item.antarchy.bomber_spawn_egg": "폭격충 생성 알", - "item.antarchy.big_bertha_blade": "빅 버사 칼날", - "item.antarchy.big_bertha_handle": "빅 버사 손잡이", - "item.antarchy.big_bertha_hilt": "빅 버사 칼자루", - "item.antarchy.battle_axe": "전투 도끼", - "item.antarchy.attitude_adjuster": "태도 교정기", - "tooltip.antarchy.attitude_adjuster.grounded": "지상의 대상을 위로 날리고, 공중의 대상을 땅으로 내리꽂습니다.", - "tooltip.antarchy.attitude_adjuster.slam": "공중에서 우클릭하면 지면 강타를 합니다.", - "item.antarchy.stratoshark_fin": "구름 상어 지느러미", - "item.antarchy.stratoshark_fin_soup": "구름 상어 지느러미 수프", - "tooltip.antarchy.stratoshark_fin_soup": "힘과 느린 낙하를 부여합니다.", - "tooltip.antarchy.critter_cage.empty": "우클릭하여 던지기", - "tooltip.antarchy.critter_cage.contains": "들어 있음: %s", - "tooltip.antarchy.critter_cage.release": "우클릭하여 풀어주기", - "tooltip.antarchy.critter_cage.place": "웅크리기 + 우클릭으로 설치", - "item.antarchy.kraken_tooth": "크라켄 이빨", - "item.antarchy.kraken_tentacle": "크라켄 촉수", - "item.antarchy.krakens_grasp": "크라켄의 손아귀", - "entity.antarchy.tentacle": "촉수", - "item.antarchy.basilisk_fang": "바실리스크 송곳니", - "item.antarchy.basilisk_dagger": "바실리스크 단검", - "item.antarchy.blood_crystal_block": "혈수정 블록", - "item.antarchy.small_blood_crystal_bud": "작은 혈수정 눈", - "item.antarchy.medium_blood_crystal_bud": "중간 혈수정 눈", - "item.antarchy.large_blood_crystal_bud": "큰 혈수정 눈", - "item.antarchy.blood_crystal_cluster": "혈수정 군집", - "item.antarchy.dream_sand": "꿈 모래", - "item.antarchy.dream_sandstone": "꿈 사암", - "item.antarchy.chiseled_dream_sandstone": "조각된 꿈 사암", - "item.antarchy.cut_dream_sandstone": "깎인 꿈 사암", - "item.antarchy.smooth_dream_sandstone": "매끄러운 꿈 사암", - "item.antarchy.dream_sandstone_stairs": "꿈 사암 계단", - "item.antarchy.dream_sandstone_slab": "꿈 사암 반 블록", - "item.antarchy.dream_sandstone_wall": "꿈 사암 담장", - "item.antarchy.smooth_dream_sandstone_stairs": "매끄러운 꿈 사암 계단", - "item.antarchy.smooth_dream_sandstone_slab": "매끄러운 꿈 사암 반 블록", - "item.antarchy.cut_dream_sandstone_slab": "깎인 꿈 사암 반 블록", - "item.antarchy.dream_torch": "꿈 횃불", - "item.antarchy.dream_lantern": "꿈 랜턴", - "item.antarchy.dream_campfire": "꿈 모닥불", - "item.antarchy.giant_lily_pad": "거대 수련잎", - "item.antarchy.seashell": "조개껍데기", - "item.antarchy.nightmare_scale": "악몽 비늘", - "item.antarchy.nightmare_helmet": "악몽 투구", - "item.antarchy.nightmare_chestplate": "악몽 흉갑", - "item.antarchy.nightmare_leggings": "악몽 레깅스", - "item.antarchy.nightmare_boots": "악몽 부츠", - "item.antarchy.nightmare_sword": "악몽 검", - "tooltip.antarchy.nightmare_armor_double_damage": "%s%% 확률로 두 배의 피해를 줍니다", - "tooltip.antarchy.nightmare_armor_set_bonus": "세트 효과: 위더와 공포 면역", - "tooltip.antarchy.nightmare_sword": "체력이 낮을수록 더 많은 피해를 줍니다.", - "tooltip.antarchy.nightmare_sword_damage": "%s의 피해를 줍니다", - "tooltip.antarchy.primordial_helmet_water_breathing": "착용자에게 수중 호흡을 부여합니다", - "tooltip.antarchy.primordial_armor_knockback_dealt": "부위당 공격 밀치기가 %s 증가합니다", - "tooltip.antarchy.primordial_armor_set_bonus": "세트 효과: 공격이 적의 밀치기 저항을 무시합니다", - "attribute.antarchy.double_damage_chance": "두 배 피해 확률", - "attribute.antarchy.bloodglass_max_hearts": "최대 혈유리 심장", - "item.antarchy.molevore_nose": "몰보어 코", - "item.antarchy.moleworm": "몰웜", - "item.antarchy.flytrap_spawn_egg": "트리피드 생성 알", - "item.antarchy.infested_rooted_dirt": "감염된 뿌리내린 흙", - "item.antarchy.infested_coarse_dirt": "감염된 거친 흙", - "item.antarchy.pale_nyxite": "창백한 닉사이트", - "item.antarchy.polished_nyxite": "윤나는 닉사이트", - "item.antarchy.chiseled_nyxite": "조각된 닉사이트", - "item.antarchy.nyxite_bricks": "닉사이트 벽돌", - "item.antarchy.shellstone": "셸스톤", - "item.antarchy.polished_shellstone": "윤나는 셸스톤", - "item.antarchy.shellstone_bricks": "셸스톤 벽돌", - "item.antarchy.chiseled_shellstone": "조각된 셸스톤", - "item.antarchy.mossy_shellstone_bricks": "이끼 낀 셸스톤 벽돌", - "item.antarchy.mossy_shellstone_brick_stairs": "이끼 낀 셸스톤 벽돌 계단", - "item.antarchy.mossy_shellstone_brick_slab": "이끼 낀 셸스톤 벽돌 반 블록", - "item.antarchy.mossy_shellstone_brick_wall": "이끼 낀 셸스톤 벽돌 담장", - "item.antarchy.cracked_shellstone_bricks": "금 간 셸스톤 벽돌", - "item.antarchy.shellstone_stairs": "셸스톤 계단", - "item.antarchy.shellstone_slab": "셸스톤 반 블록", - "item.antarchy.shellstone_wall": "셸스톤 담장", - "item.antarchy.polished_shellstone_stairs": "윤나는 셸스톤 계단", - "item.antarchy.polished_shellstone_slab": "윤나는 셸스톤 반 블록", - "item.antarchy.polished_shellstone_wall": "윤나는 셸스톤 담장", - "item.antarchy.shellstone_brick_stairs": "셸스톤 벽돌 계단", - "item.antarchy.shellstone_brick_slab": "셸스톤 벽돌 반 블록", - "item.antarchy.shellstone_brick_wall": "셸스톤 벽돌 담장", - "item.antarchy.nyxite_stairs": "닉사이트 계단", - "item.antarchy.nyxite_slab": "닉사이트 반 블록", - "item.antarchy.nyxite_wall": "닉사이트 담장", - "item.antarchy.polished_nyxite_stairs": "윤나는 닉사이트 계단", - "item.antarchy.polished_nyxite_slab": "윤나는 닉사이트 반 블록", - "item.antarchy.polished_nyxite_wall": "윤나는 닉사이트 담장", - "item.antarchy.nyxite_brick_stairs": "닉사이트 벽돌 계단", - "item.antarchy.nyxite_brick_slab": "닉사이트 벽돌 반 블록", - "item.antarchy.nyxite_brick_wall": "닉사이트 벽돌 담장", - "item.antarchy.potent_nyxite": "강력한 닉사이트", - "item.antarchy.antimetal": "안티메탈", - "item.antarchy.polished_antimetal": "윤나는 안티메탈", - "item.antarchy.antimetal_scaffolding": "안티메탈 비계", - "item.antarchy.ouranwood_acorn": "오란우드 도토리", - "item.antarchy.ouranwood_boat": "오란우드 보트", - "item.antarchy.ouranwood_chest_boat": "오란우드 상자 보트", - "item.antarchy.raw_venison": "익히지 않은 사슴고기", - "item.antarchy.cooked_venison": "익힌 사슴고기", - "item.antarchy.peach_sapling": "복숭아 묘목", - "item.antarchy.peach": "복숭아", - "item.antarchy.peach_pie": "복숭아 파이", - "item.antarchy.cornbread": "옥수수빵", - "item.antarchy.popcorn": "팝콘", - "item.antarchy.peach_sign": "복숭아 표지판", - "item.antarchy.peach_hanging_sign": "복숭아 매다는 표지판", - "item.antarchy.peach_boat": "복숭아 보트", - "item.antarchy.peach_chest_boat": "복숭아 상자 보트", - "item.antarchy.orange_milkweed": "주황색 박주가리", - "item.antarchy.pink_milkweed": "분홍색 박주가리", - "item.antarchy.camellia": "동백꽃", - "item.antarchy.spider_lily": "석산", - "item.antarchy.hushweed": "허시위드", - "item.antarchy.umbral_moss_block": "그늘 이끼 블록", - "item.antarchy.umbral_moss_carpet": "그늘 이끼 양탄자", - "item.antarchy.blush_moss_block": "분홍 이끼 블록", - "item.antarchy.blush_moss_carpet": "분홍 이끼 양탄자", - "item.antarchy.mud_pie": "진흙 파이", - "item.antarchy.duct_tape": "덕트 테이프", - "item.antarchy.duct_tape.tooltip": "설치한 뒤 우클릭하여 도구를 수리합니다", - "item.antarchy.rainbow_sugar": "무지개 설탕", - "item.antarchy.uranium_nugget": "우라늄 조각", - "item.antarchy.titanium_nugget": "티타늄 조각", - "item.antarchy.raw_uranium_scrap": "익히지 않은 우라늄 파편", - "item.antarchy.raw_titanium_scrap": "익히지 않은 티타늄 파편", - "item.antarchy.raw_uranium": "익히지 않은 우라늄", - "item.antarchy.raw_titanium": "익히지 않은 티타늄", - "item.antarchy.uranium_ingot": "우라늄 주괴", - "item.antarchy.titanium_ingot": "티타늄 주괴", - "item.antarchy.blood_crystal_shard": "혈수정 조각", - "item.antarchy.blood_crystal_apple": "혈수정 사과", - "item.antarchy.blood_crystal_katana": "혈수정 카타나", - "item.antarchy.blood_crystal_helmet": "혈수정 투구", - "item.antarchy.blood_crystal_chestplate": "혈수정 흉갑", - "item.antarchy.blood_crystal_leggings": "혈수정 레깅스", - "item.antarchy.blood_crystal_boots": "혈수정 부츠", - "item.antarchy.blood_crystal_armor.tooltip": "한 번의 공격을 막고 깨진 뒤 다시 충전되는 혈유리 심장을 부여합니다.", - "item.antarchy.blood_crystal_boots.tooltip2": "중력이 반전되어 위로 떨어질 때 낙하 피해를 무효화합니다.", - "item.antarchy.blood_crystal_apple.tooltip": "혈유리 수호를 부여하여 효과가 지속되는 동안 재충전되는 임시 혈유리 심장을 제공합니다.", - "tooltip.antarchy.blood_crystal_katana.launch": "명중 시 앞으로 돌진합니다.", - "tooltip.antarchy.blood_crystal_katana.trail": "뒤에 진홍빛 흔적을 남깁니다.", - "item.antarchy.mantis_claw": "사마귀 발톱", - "tooltip.antarchy.mantis_claw.wall_cling": "Dual wield to cling to walls and jump upward.", - "item.antarchy.king_scale": "왕 비늘", - "item.antarchy.queen_scale": "여왕 비늘", - "item.antarchy.springbug_leg": "점피 벌레 다리", - "item.antarchy.springy_boots": "점피 부츠", - "tooltip.antarchy.springy_boots": "웅크려 충전한 뒤 점프하면 위로 튀어 오릅니다.", - "item.antarchy.brutalfly_wing": "브루털플라이 날개", - "item.antarchy.brutalfly_elytra": "브루털플라이 겉날개", - "tooltip.antarchy.brutalfly_elytra.flap": "비행 중 %s을 길게 눌러 날갯짓합니다", - "item.antarchy.cornea_ear": "코니아의 귀", - "item.antarchy.corn": "옥수수", - "item.antarchy.corn_seeds": "옥수수 씨앗", - "item.antarchy.raw_corndog": "익히지 않은 콘도그", - "item.antarchy.cooked_corndog": "익힌 콘도그", - "item.antarchy.high_fructose_corn_syrup": "고과당 옥수수 시럽", - "jei.antarchy.americanize": "미국식으로 만들기", - "item.antarchy.american_name": "미국식 %s", - "item.antarchy.root_beer": "루트 비어", - "item.antarchy.primordial_scute": "태고의 등딱지 조각", - "item.antarchy.flytrap_goo": "트리피드 점액", - "item.antarchy.flytrap_goo_block": "트리피드 점액 블록", - "tooltip.antarchy.flytrap_goo_block": "빠르게 부딪히면 튀어 오르고, 아니면 안으로 가라앉습니다.", - "item.antarchy.cloud_bucket": "구름 양동이", - "tooltip.antarchy.cloud_bucket.midair": "공중에 설치할 수 있습니다", - "item.antarchy.lumen_bucket": "루멘 양동이", - "item.antarchy.scorpion_whip": "황제전갈 채찍", - "tooltip.antarchy.scorpion_whip.lash": "멀리서 먹잇감을 후려쳐 독성 연결줄을 박습니다.", - "tooltip.antarchy.scorpion_whip.reel": "우클릭하여 연결된 먹잇감을 끌어당깁니다.", - "tooltip.antarchy.scorpion_whip.snap": "연결된 먹잇감을 다시 좌클릭하여 독침을 뽑습니다.", - "item.antarchy.fallen_king_crown": "몰락한 왕의 왕관", - "tooltip.antarchy.fallen_king_crown.hero": "적대적 생물을 처치하면 마을의 영웅을 부여합니다", - "item.antarchy.vortex_charge": "Vortex Charge", - "item.antarchy.ultimate_helmet": "궁극 투구", - "item.antarchy.ultimate_chestplate": "궁극 흉갑", - "item.antarchy.ultimate_leggings": "궁극 레깅스", - "item.antarchy.ultimate_boots": "궁극 부츠", - "item.antarchy.ultimate_sword": "궁극 검", - "item.antarchy.ultimate_pickaxe": "궁극의 곡괭이", - "item.antarchy.ultimate_axe": "궁극 도끼", - "item.antarchy.ultimate_shovel": "궁극 삽", - "item.antarchy.ultimate_hoe": "궁극 괭이", - "item.antarchy.ultimate_bow": "궁극 활", - "item.antarchy.ultimate_crossbow": "궁극 쇠뇌", - "item.antarchy.ultimate_crossbow.capacity": "한 번에 화살을 최대 16발 장전합니다", - "item.antarchy.ultimate_crossbow.arrows_remaining": "%1$s %2$s 장전됨", - "item.antarchy.ultimate_mace": "궁극 철퇴", - "item.antarchy.moggles": "모글스", - "itemGroup.antarchy.antarchy": "앤타키", - "item.antarchy.bile_bucket": "담즙 양동이", - "item.antarchy.ichor_bucket": "이코르 양동이", - "item.antarchy.antiwater_bucket": "역수 양동이", - "item.antarchy.reverie_bottle": "레버리가 든 병", - "item.antarchy.squidzooka": "스퀴드주카", - "item.antarchy.rpo_launcher": "로·추·문 발사기", - "item.antarchy.shrink_ray": "축소 광선총", - "item.antarchy.growth_ray": "성장 광선총", - "tooltip.antarchy.shrink_ray": "대상을 영구적으로 축소합니다. 길게 눌러 충전합니다.", - "tooltip.antarchy.growth_ray": "대상을 영구적으로 성장시킵니다. 길게 눌러 충전합니다.", - "tooltip.antarchy.size_ray_milk_reset": "우유를 마시면 이 효과가 초기화됩니다.", - "tooltip.antarchy.reverie_bottle.capture": "유리병으로 레버리를 우클릭하여 담습니다.", - "tooltip.antarchy.reverie_bottle.release": "우클릭하여 레버리를 풀어줍니다.", - "item.antarchy.gravity_gun": "중력총", - "item.antarchy.diamond_minecart": "다이아몬드 광산 수레", - "item.antarchy.cogwheel_pet": "톱니바퀴 펫", - "item.antarchy.fire_dragon_pet": "화염 드래곤 펫", - "item.antarchy.ice_dragon_pet": "얼음 드래곤 펫", - "item.antarchy.lightning_dragon_pet": "번개 드래곤 펫", - "item.antarchy.gorgon_pet": "고르곤 펫", - "item.antarchy.apple_cow_spawn_egg": "사과 소 생성 알", - "item.antarchy.red_ant_spawn_egg": "붉은 개미 생성 알", - "item.antarchy.brown_ant_spawn_egg": "갈색 개미 생성 알", - "item.antarchy.rainbow_ant_spawn_egg": "무지개 개미 생성 알", - "item.antarchy.golden_apple_cow_spawn_egg": "황금 사과 소 생성 알", - "item.antarchy.enchanted_golden_apple_cow_spawn_egg": "마법이 부여된 황금 사과 소 생성 알", - "item.antarchy.dr_trayaurus_spawn_egg": "트레이오러스 박사 생성 알", - "item.antarchy.easter_bunny_spawn_egg": "부활절 토끼 생성 알", - "item.antarchy.glimmer_spawn_egg": "글리머 생성 알", - "item.antarchy.ouranwood_deer_spawn_egg": "오란우드 사슴 생성 알", - "item.antarchy.spirit_apple": "영혼 사과", - "item.antarchy.elka_spawn_egg": "엘카 생성 알", - "item.antarchy.glimmer_bottle": "글리머가 든 병", - "item.antarchy.glimmer_bottle.contains": "들어 있음: %s", - "glimmer_variant.antarchy.apple_cow": "사과 소", - "glimmer_variant.antarchy.ouranwood_deer": "오란우드 사슴", - "glimmer_variant.antarchy.frog": "개구리", - "glimmer_variant.antarchy.ant": "개미", - "glimmer_variant.antarchy.elka": "엘카", - "entity.antarchy.glimmer.set_sit": "글리머가 앉도록 설정되었습니다.", - "entity.antarchy.glimmer.set_follow": "글리머가 따라오도록 설정되었습니다.", - "entity.antarchy.glimmer.set_wander": "글리머가 돌아다니도록 설정되었습니다.", - "entity.antarchy.glimmer.ability.ant": "개미가 %s에 맞설 투지를 북돋았습니다!", - "entity.antarchy.glimmer.ability.apple_cow": "사과 소가 울며 영양을 채워 줍니다!", - "entity.antarchy.glimmer.ability.elka": "엘카가 울부짖어 수호를 깨뜨립니다!", - "entity.antarchy.glimmer.ability.deer": "오란우드 사슴이 적을 뚫고 돌진합니다!", - "entity.antarchy.glimmer.ability.frog": "개구리가 %s을 삼켰습니다!", - "item.antarchy.glimmer_bottle.passive.apple_cow": "지속 효과: 허기가 25% 느리게 감소합니다", - "item.antarchy.glimmer_bottle.ability.apple_cow": "능력: 배고플 때 울음소리로 포화와 재생을 즉시 부여합니다", - "item.antarchy.glimmer_bottle.passive.ouranwood_deer": "지속 효과: 신속 Ⅰ", - "item.antarchy.glimmer_bottle.ability.ouranwood_deer": "능력: 적대적 생물을 향해 전력 질주하면 돌진하여 날려 버립니다", - "item.antarchy.glimmer_bottle.passive.frog": "지속 효과: 점프 강화 Ⅰ", - "item.antarchy.glimmer_bottle.ability.frog": "능력: 근처 적대적 생물을 삼키고 잠시 더 크고 강해집니다", - "item.antarchy.glimmer_bottle.passive.ant": "지속 효과: 공격 사거리가 약간 늘어납니다", - "item.antarchy.glimmer_bottle.ability.ant": "능력: 큰 적을 공격하면 잠시 힘 Ⅱ를 얻습니다", - "item.antarchy.glimmer_bottle.passive.elka": "지속 효과: 혈유리 수호 Ⅱ", - "item.antarchy.glimmer_bottle.ability.elka": "능력: 수호 심장이 깨지면 울부짖으며 충격파로 산산이 흩어집니다", - "advancements.antarchy.spirant_animal.title": "개미의 정령", - "advancements.antarchy.spirant_animal.description": "개미 글리머를 길들이세요", - "advancements.antarchy.hoppy_together.title": "함께 깡충깡충", - "advancements.antarchy.hoppy_together.description": "개구리 글리머를 길들이세요", - "advancements.antarchy.deerly_beloved.title": "사슴하는 사이", - "advancements.antarchy.deerly_beloved.description": "오란우드 사슴 글리머를 길들이세요", - "advancements.antarchy.elkcellent_choice.title": "엘카다운 선택", - "advancements.antarchy.elkcellent_choice.description": "엘카 글리머를 길들이세요", - "advancements.antarchy.apple_of_my_eye.title": "눈에 넣어도 안 아픈 사과", - "advancements.antarchy.apple_of_my_eye.description": "사과 소 글리머를 길들이세요", - "item.antarchy.dorrie_spawn_egg": "도리 생성 알", - "item.antarchy.flying_squirrel_spawn_egg": "날다람쥐 생성 알", - "item.antarchy.caterpillar_spawn_egg": "애벌레 생성 알", - "item.antarchy.butterfly_spawn_egg": "나비 생성 알", - "item.antarchy.brutalfly_spawn_egg": "브루털플라이 생성 알", - "item.antarchy.stratoshark_spawn_egg": "구름 상어 생성 알", - "item.antarchy.kraken_spawn_egg": "어, 안 돼. 하지 마.", - "item.antarchy.missile_squid_spawn_egg": "미사일 오징어 생성 알", - "item.antarchy.octopus_bomb_spawn_egg": "문어 폭탄 생성 알", - "item.antarchy.nightmare_spawn_egg": "악몽 생성 알", - "item.antarchy.toreterror_spawn_egg": "토어테러 생성 알", - "item.antarchy.water_cannon": "물대포", - "item.antarchy.primordial_helmet": "태고의 투구", - "item.antarchy.primordial_chestplate": "태고의 흉갑", - "item.antarchy.primordial_leggings": "태고의 레깅스", - "item.antarchy.primordial_boots": "태고의 부츠", - "item.antarchy.bed_bug_spawn_egg": "빈대 생성 알", - "item.antarchy.moleworm_spawn_egg": "몰웜 생성 알", - "item.antarchy.molevore_spawn_egg": "몰보어 생성 알", - "item.antarchy.reverie_spawn_egg": "레버리 생성 알", - "item.antarchy.mantis_spawn_egg": "사마귀 생성 알", - "item.antarchy.alpha_mantis_spawn_egg": "알파 사마귀 생성 알", - "biome.antarchy.moleworm_caves": "몰웜 동굴", - "biome.antarchy.elythia_meadow": "엘리티아 초원", - "biome.antarchy.butterfly_fields": "나비 들판", - "biome.antarchy.ouranwood_forest": "오란우드 숲", - "biome.antarchy.glimmering_pools": "반짝이는 웅덩이", - "biome.antarchy.peach_forest": "복숭아 숲", - "biome.antarchy.fungal_ouranwood_forest": "균류 오란우드 숲", - "biome.antarchy.glowcap_caves": "글로우캡 동굴", - "message.antarchy.brown_ant_activated": "갈색 개미가 목적지를 열 준비가 되었습니다.", - "message.antarchy.brown_ant_needs_reagent": "이 갈색 개미가 목적지를 열려면 시약이 필요합니다.", - "message.antarchy.rainbow_ant_activated": "무지개 개미가 새로운 인피니티 목적지와 공명합니다.", - "message.antarchy.rainbow_ant_activated_inherited": "무지개 개미가 물려받은 인피니티 목적지와 공명합니다.", - "message.antarchy.rainbow_ant_activated_inherited_existing": "무지개 개미가 물려받은 인피니티 목적지에 다시 연결됩니다.", - "message.antarchy.rainbow_ant_failed_dimension_create": "차원을 만들지 못했습니다. 인피니티 설정에 문제가 있을 가능성이 큽니다. 재시작하거나 다시 접속한 뒤 시도하세요.", - "message.antarchy.rainbow_ant_infinity_missing": "무지개 개미 차원을 사용하려면 인피니티가 설치되어 있어야 합니다.", - "message.antarchy.rainbow_ant_needs_reagent": "이 무지개 개미가 차원을 열려면 시약이 필요합니다.", - "message.antarchy.red_ant_activated": "붉은 개미가 목적지를 열 준비가 되었습니다.", - "message.antarchy.red_ant_needs_reagent": "이 붉은 개미가 목적지를 열려면 시약이 필요합니다.", - "message.antarchy.termite_activated": "흰개미가 목적지를 열 준비가 되었습니다.", - "message.antarchy.termite_needs_reagent": "이 흰개미가 목적지를 열려면 시약이 필요합니다.", - "death.attack.spit_bug_disrespect": "%1$s이(가) 스핏 벌레에게 무시당했습니다", - "death.attack.springbug_jump": "%1$s이(가) 점피 벌레에게 덮쳐졌습니다", - "death.attack.hercules_beetle_obliteration": "%1$s이(가) 헤라클레스장수풍뎅이에게 소멸당했습니다", - "message.antarchy.big_bertha.mode": "빅 버사 모드: %s", - "message.antarchy.big_bertha.mode.basilisk": "바실리스크", - "message.antarchy.big_bertha.mode.lucid": "루시드", - "message.antarchy.big_bertha.mode.nightmare": "악몽", - "message.antarchy.big_bertha.mode.kraken": "크라켄", - "message.antarchy.big_bertha.mode.molevore": "몰보어", - "message.antarchy.big_bertha.mode.toreterror": "토어테러", - "message.antarchy.ultimate_tool.mode_3x3": "3×3 채굴로 전환했습니다", - "message.antarchy.ultimate_tool.mode_default": "기본 채굴로 전환했습니다", - "advancements.antarchy.hey_listen.title": "이봐, 들어 봐!", - "advancements.antarchy.hey_listen.description": "레버리가 합류했습니다.", - "advancements.antarchy.very_hungry_caterpillar.title": "배고픈 애벌레", - "advancements.antarchy.very_hungry_caterpillar.description": "애벌레가 자라도록 도와주세요.", - "effect.antarchy.dread": "공포", - "effect.antarchy.dread.description": "시각 및 청각 환각을 일으킵니다.", - "effect.antarchy.paralyzed": "마비", - "effect.antarchy.paralyzed.description": "대상이 움직이지 못하게 합니다.", - "effect.antarchy.commanded.description": "명령한 플레이어를 위해 싸웁니다.", - "effect.antarchy.stinky": "악취", - "effect.antarchy.stinky.description": "수동적 및 중립적 몹을 쫓아내고 절지동물을 끌어들입니다.", - "effect.antarchy.gooped.description": "이동 속도와 공격 속도를 늦춥니다.", - "effect.antarchy.shrinking": "축소", - "effect.antarchy.growth": "성장", - "effect.antarchy.bloodglass_ward": "혈유리 수호", - "effect.antarchy.bloodglass_ward.description": "산산이 부서지는 하트를 부여해 피해 한 번을 통째로 흡수합니다. 시간이 지나면 다시 재생됩니다.", - "death.attack.flytrap_mauling": "%1$s이(가) 식물에게 물어뜯겨 죽었습니다", - "death.attack.flytrap_mauling.player": "%1$s이(가) 식물에게 물어뜯겨 죽었습니다", - "death.attack.flytrap_swallow": "%1$s이(가) 트리피드에게 삼켜졌습니다", - "death.attack.flytrap_swallow.player": "%1$s이(가) 트리피드에게 삼켜졌습니다", - "potion.antarchy.haste": "성급함의 물약", - "potion.antarchy.strong_haste": "강한 성급함의 물약", - "tooltip.antarchy.big_bertha.mode": "모드: %s", - "tooltip.antarchy.big_bertha.toggle_mode": "웅크린 채 우클릭하여 보스 모드를 전환합니다.", - "tooltip.antarchy.big_bertha.mode.basilisk": "우클릭으로 대상을 마비시킵니다. 공격 시 독과 둔화를 부여합니다.", - "tooltip.antarchy.big_bertha.mode.lucid": "공격 시 대상을 잠시 반전시킵니다. 자신이 반전된 동안 더 큰 피해를 줍니다.", - "tooltip.antarchy.big_bertha.mode.nightmare": "플레이어는 공포에 시달리고, 공격 시 나약함을 부여합니다.", - "tooltip.antarchy.big_bertha.mode.kraken": "공격 시 대상을 내리꽂고 번개를 부릅니다.", - "tooltip.antarchy.big_bertha.mode.molevore": "우클릭하여 회전하며 전진하고 몰보어 블록을 뚫습니다.", - "tooltip.antarchy.big_bertha.mode.toreterror": "우클릭하여 공중으로 솟은 뒤 광역 충격파와 함께 추락합니다.", - "tooltip.antarchy.ultimate_tools_3x3": "웅크린 채 우클릭하여 3×3 채굴을 전환합니다.", - "tooltip.antarchy.moggles.reveal": "야간 투시를 부여하고 근처 동굴을 가리킵니다.", - "tooltip.antarchy.moggles.underground": "하늘이 보이지 않을 때만 작동합니다.", - "tooltip.antarchy.cornea_ear.vision": "%s초 동안 야간 투시를 부여합니다.", - "tooltip.antarchy.mob_coming_soon": "생물은 곧 추가됩니다!", - "tooltip.antarchy.gravity_gun.primary": "좌클릭: 주변 개체를 날리거나 붙잡은 대상을 던집니다.", - "tooltip.antarchy.gravity_gun.secondary": "우클릭: 개체나 유효한 블록을 끌어당깁니다.", - "tooltip.antarchy.gravity_gun.scroll": "제어 키를 누른 채 스크롤하여 붙잡은 대상을 가까이하거나 멀리합니다.", - "tooltip.antarchy.gravity_gun.blacklist": "차단 목록에 있는 블록이나 개체에는 영향을 주지 않습니다.", - "tooltip.antarchy.antimetal_inversion": "바로 아래의 개체를 반전시킵니다", - "tooltip.antarchy.diamond_minecart.forward": "나중에 구현될 예정입니다.", - "tooltip.antarchy.diamond_minecart.rails": " ", - "tooltip.antarchy.rainbow_sugar": "무지개 개미 차원을 활성화합니다. 그 차원에서 먹으면 집으로 돌아옵니다.", - "advancements.antarchy.visit_elythia.title": "차원개미 이동", - "advancements.antarchy.visit_elythia.description": "갈색 개미를 이용해 엘리티아에 도달하세요.", - "advancements.antarchy.visit_thoraxis.title": "개미 분노 관리", - "advancements.antarchy.visit_thoraxis.description": "붉은 개미를 이용해 토랙시스에 도달하세요.", - "advancements.antarchy.fallen_kingdom_castle.title": "한때는 세상을 지배했지…", - "advancements.antarchy.fallen_kingdom_castle.description": "몰락한 왕국의 성을 발견하세요.", - "advancements.antarchy.fallen_king_crown.title": "내가 명하면 청크가 불러와졌지…", - "advancements.antarchy.fallen_king_crown.description": "몰락한 왕의 왕관을 획득하세요.", - "advancements.antarchy.the_lab.title": "여러분 안녕하세요, 댄입니다!", - "advancements.antarchy.the_lab.description": "트레이오러스 박사의 연구소를 발견하세요.", - "advancements.antarchy.sweater_dreams.title": "스웨터의 꿈", - "advancements.antarchy.sweater_dreams.description": "악몽을 처치하세요.", - "advancements.antarchy.stone_cold.title": "돌처럼 차갑게", - "advancements.antarchy.stone_cold.description": "바실리스크를 처치하세요.", - "advancements.antarchy.moley_poley.title": "두더지 데굴데굴", - "advancements.antarchy.moley_poley.description": "몰보어를 처치하세요.", - "advancements.antarchy.lucid_dreams.title": "자각몽", - "advancements.antarchy.lucid_dreams.description": "루시드를 처치하세요.", - "advancements.antarchy.davy_jones_locker.title": "데이비 존스의 함", - "advancements.antarchy.davy_jones_locker.description": "크라켄을 처치하세요.", - "advancements.antarchy.shark_weak.title": "상어가 날 때", - "advancements.antarchy.shark_weak.description": "구름 상어를 처치하세요.", - "advancements.antarchy.dont_let_the_bed_bugs_bite.title": "빈대에게 물리지 마세요", - "advancements.antarchy.dont_let_the_bed_bugs_bite.description": "빈대를 처치하세요.", - "advancements.antarchy.soups_up.title": "수프 준비 완료", - "advancements.antarchy.soups_up.description": "구름 상어 지느러미 수프를 먹으세요.", - "advancements.antarchy.in_the_upside_down.title": "뒤집힌 세계에서", - "advancements.antarchy.in_the_upside_down.description": "처음으로 반전되세요.", - "advancements.antarchy.whoever_smelt_it_dealt_it.title": "냄새 맡은 사람이 범인", - "advancements.antarchy.whoever_smelt_it_dealt_it.description": "처음으로 악취 상태가 되세요.", - "advancements.antarchy.ultimate_armor.title": "궁극의 보호", - "advancements.antarchy.ultimate_armor.description": "궁극 방어구 세트를 모두 모으세요.", - "advancements.antarchy.ultimate_bow.title": "활헤미안 랩소디", - "advancements.antarchy.ultimate_bow.description": "궁극의 활을 획득하세요.", - "advancements.antarchy.brutalfly.title": "브루털플라이처럼 날고 벌처럼 쏘세요", - "advancements.antarchy.brutalfly.description": "브루털플라이 겉날개를 획득하세요.", - "advancements.antarchy.now_watch_me_whip.title": "이제 내 채찍질을 봐", - "advancements.antarchy.now_watch_me_whip.description": "이제 내 네이네이를 봐", - "advancements.antarchy.kill_molevore.title": "두더지 데굴데굴", - "advancements.antarchy.kill_molevore.description": "몰보어를 처치하세요.", - "advancements.antarchy.water_cannon_craft.title": "더 젖을수록 좋아!", - "advancements.antarchy.water_cannon_craft.description": "물대포를 획득하세요.", - "advancements.antarchy.kill_toreterror.title": "토어-끔찍한 조준 실력!", - "advancements.antarchy.kill_toreterror.description": "토어테러를 처치하세요.", - "advancements.antarchy.challenge_games.title": "도전 게임!", - "advancements.antarchy.challenge_games.description": "폐허가 된 투기장에 입장하세요.", - "advancements.antarchy.bugged_out.title": "벌레투성이", - "advancements.antarchy.bugged_out.description": "알파 사마귀를 처치하세요.", - "death.attack.bed_bug_bite": "%1$s이(가) 빈대에게 물렸습니다", - "death.attack.bed_bug_bite.player": "%1$s이(가) %2$s와(과) 싸우다 빈대에게 물렸습니다", - "message.antarchy.dread_too_scared_to_sleep": "너무 무서워서 잠들 수 없습니다.", - "death.attack.kraken_mauling": "%1$s이(가) 크라켄에게 물속으로 끌려갔습니다", - "death.attack.kraken_mauling.player": "%1$s이(가) %2$s와(과) 싸우다 크라켄에게 물속으로 끌려갔습니다", - "death.attack.kraken_lightning": "%1$s이(가) 크라켄의 폭풍에 쓰러졌습니다", - "death.attack.kraken_lightning.player": "%1$s이(가) %2$s와(과) 싸우다 크라켄의 폭풍에 쓰러졌습니다", - "death.attack.rpo_launcher_blast": "%1$s이(가) 로·추·문에게 녹아웃당했습니다", - "death.attack.rpo_launcher_blast.player": "%1$s이(가) %2$s와(과) 싸우다 로·추·문에게 녹아웃당했습니다", - "death.attack.nightmare_mauling": "%1$s이(가) 악몽에게 잡아먹혔습니다", - "death.attack.nightmare_mauling.player": "%1$s이(가) %2$s와(과) 싸우다 악몽에게 잡아먹혔습니다", - "death.attack.basilisk_bite": "%1$s이(가) 바실리스크에게 삼켜졌습니다", - "death.attack.basilisk_bite.player": "%1$s이(가) %2$s와(과) 싸우다 바실리스크에게 삼켜졌습니다", - "death.attack.emperor_scorpion_sting": "%1$s이(가) 황제전갈에게 쏘였습니다", - "death.attack.emperor_scorpion_sting.player": "%1$s이(가) %2$s와(과) 싸우다 황제전갈에게 쏘였습니다", - "death.attack.cornea_stalk_prick": "%1$s이(가) 코니아 줄기에 찔려 죽었습니다", - "death.attack.toreterror_spin": "%1$s이(가) 토어테러의 회전에 휘말려 죽었습니다", - "death.attack.toreterror_spin.player": "%1$s이(가) 토어테러의 회전에 휘말려 죽었습니다", - "death.attack.toreterror_jump": "%1$s이(가) 토어테러에게 짓눌려 죽었습니다", - "death.attack.toreterror_jump.player": "%1$s이(가) 토어테러에게 짓눌려 죽었습니다", - "death.attack.water_soaked": "%1$s이(가) %2$s에게 흠뻑 젖어 죽었습니다", - "death.attack.water_soaked.player": "%1$s이(가) %2$s에게 흠뻑 젖어 죽었습니다", - "entity.antarchy.lucid": "루시드", - "item.antarchy.lucid_spawn_egg": "루시드 생성 알", - "item.antarchy.lucid_eye": "루시드 눈", - "entity.antarchy.scorpion": "전갈", - "item.antarchy.scorpion_spawn_egg": "전갈 생성 알", - "entity.antarchy.basilisk": "바실리스크", - "item.antarchy.basilisk_spawn_egg": "바실리스크 생성 알", - "entity.antarchy.emperor_scorpion": "황제전갈", - "item.antarchy.emperor_scorpion_spawn_egg": "황제전갈 생성 알", - "item.antarchy.emperor_scorpion_stinger": "황제전갈 독침", - "item.antarchy.lucid_pearl": "루시드 진주", - "tooltip.antarchy.lucid_pearl": "중력이 반전된 투사체를 던집니다.", - "tooltip.antarchy.lucid_pearl.detail": "착지 지점으로 순간이동시키고 반전을 부여합니다.", - "subtitles.antarchy.squidzooka_fire": "스퀴드주카 발사됩니다", - "subtitles.antarchy.shrink_ray": "축소 광선총 발사됩니다", - "subtitles.antarchy.growth_ray": "성장 광선총 발사됩니다", - "subtitles.antarchy.size_ray_charge": "크기 광선총 충전됩니다", - "subtitles.antarchy.ant_ambient": "개미 짹짹거립니다", - "subtitles.antarchy.ant_idle": "개미 소리를 냅니다", - "subtitles.antarchy.ant_hurt": "개미 다칩니다", - "subtitles.antarchy.ant_bite": "개미 뭅니다", - "subtitles.antarchy.ant_gather": "개미 모읍니다", - "subtitles.antarchy.ant_nest": "개미 둥지가 바스락거립니다", - "subtitles.antarchy.stratoshark_bite": "구름 상어 뭅니다", - "subtitles.antarchy.stratoshark_idle": "구름 상어 소리를 냅니다", - "subtitles.antarchy.stratoshark_hurt": "구름 상어 다칩니다", - "subtitles.antarchy.stratoshark_death": "구름 상어 죽습니다", - "subtitles.antarchy.stratoshark_fly": "구름 상어 납니다", - "subtitles.antarchy.caterpillar_idle": "애벌레 소리를 냅니다", - "subtitles.antarchy.caterpillar_hurt": "애벌레 다칩니다", - "subtitles.antarchy.caterpillar_crawl": "애벌레 기어갑니다", - "subtitles.antarchy.butterfly_hurt": "나비 다칩니다", - "subtitles.antarchy.brutalfly_idle": "브루털플라이 소리를 냅니다", - "subtitles.antarchy.brutalfly_death": "브루털플라이 죽습니다", - "subtitles.antarchy.thoraxis_nightmare_wastes_ambient": "악몽 황무지 웅웅거립니다", - "subtitles.antarchy.thoraxis_nightmare_wastes_additions": "악몽 황무지 꿈틀거립니다", - "subtitles.antarchy.thoraxis_nightmare_wastes_mood": "악몽 황무지 웅얼거립니다", - "subtitles.antarchy.thoraxis_dream_dunes_ambient": "꿈의 사구 속삭입니다", - "subtitles.antarchy.thoraxis_dream_dunes_additions": "꿈의 사구 바스락거립니다", - "subtitles.antarchy.thoraxis_dream_dunes_mood": "꿈의 사구 한숨 쉽니다", - "subtitles.antarchy.thoraxis_lucid_pools_ambient": "루시드 웅덩이가 웅웅거립니다", - "subtitles.antarchy.thoraxis_lucid_pools_additions": "루시드 웅덩이 저주를 내뱉습니다", - "subtitles.antarchy.thoraxis_lucid_pools_mood": "루시드 웅덩이 중얼거립니다", - "subtitles.antarchy.lucid_ambient": "루시드 웅웅거립니다", - "subtitles.antarchy.lucid_flying": "루시드 팔랑거립니다", - "subtitles.antarchy.lucid_attack": "루시드 공격합니다", - "subtitles.antarchy.lucid_bolt": "루시드 탄환을 발사합니다", - "subtitles.antarchy.lucid_hurt": "루시드 다칩니다", - "subtitles.antarchy.lucid_death": "루시드 죽습니다", - "subtitles.antarchy.reverie_idle": "레버리 떠다닙니다", - "subtitles.antarchy.reverie_hurt": "레버리 다칩니다", - "subtitles.antarchy.reverie_worry": "레버리 걱정합니다", - "subtitles.antarchy.reverie_save": "레버리 당신을 구합니다", - "subtitles.antarchy.reverie_join_player": "레버리 당신과 함께합니다", - "subtitles.antarchy.reverie_alert": "레버리 당신에게 경고합니다", - "subtitles.antarchy.flying_squirrel_idle": "날다람쥐 짹짹거립니다", - "subtitles.antarchy.flying_squirrel_beg": "날다람쥐 먹이를 달라고 조릅니다", - "subtitles.antarchy.flying_squirrel_nut": "날다람쥐 먹습니다", - "subtitles.antarchy.flying_squirrel_glide_loop": "날다람쥐 활공합니다", - "subtitles.antarchy.flying_squirrel_hurt": "날다람쥐 다칩니다", - "subtitles.antarchy.flying_squirrel_death": "날다람쥐 죽습니다", - "subtitles.antarchy.nightmare_idle": "악몽 으르렁거립니다", - "subtitles.antarchy.nightmare_hurt": "악몽 다칩니다", - "subtitles.antarchy.nightmare_roar": "악몽 포효합니다", - "subtitles.antarchy.nightmare_death": "악몽 죽습니다", - "subtitles.antarchy.nightmare_bite": "악몽 뭅니다", - "subtitles.antarchy.nightmare_flap": "악몽 날갯짓합니다", - "subtitles.antarchy.flytrap_attack": "트리피드 공격합니다", - "subtitles.antarchy.flytrap_grab": "트리피드 붙잡습니다", - "subtitles.antarchy.flytrap_hurt": "트리피드 다칩니다", - "subtitles.antarchy.flytrap_death": "트리피드 죽습니다", - "subtitles.antarchy.flytrap_hiss": "트리피드 쉬익거립니다", - "subtitles.antarchy.flytrap_growl": "트리피드 그르렁거립니다", - "subtitles.antarchy.gravity_gun_pickup": "중력총 들어 올립니다", - "subtitles.antarchy.gravity_gun_drop": "중력총 내려놓습니다", - "subtitles.antarchy.gravity_gun_hold_loop": "중력총 웅웅거립니다", - "subtitles.antarchy.gravity_gun_launch": "중력총 발사합니다", - "subtitles.antarchy.gravity_gun_dryfire": "중력총 헛발사됩니다", - "subtitles.antarchy.antimetal_place": "안티메탈이 쨍그랑거립니다", - "subtitles.antarchy.antimetal_step": "안티메탈이 딸깍거립니다", - "subtitles.antarchy.antimetal_scaffold": "안티메탈 비계가 덜컹거립니다", - "subtitles.antarchy.bed_bug_ambient": "빈대 짹짹거립니다", - "subtitles.antarchy.bed_bug_hurt": "빈대 다칩니다", - "subtitles.antarchy.bed_bug_attack": "빈대 뭅니다", - "subtitles.antarchy.wasp_idle": "말벌이 윙윙거립니다", - "subtitles.antarchy.wasp_hurt": "말벌 다칩니다", - "subtitles.antarchy.wasp_attack": "말벌 쏩니다", - "subtitles.antarchy.wasp_death": "말벌 죽습니다", - "subtitles.antarchy.scorpion_ambient": "전갈 달그락거립니다", - "subtitles.antarchy.scorpion_hurt": "전갈 다칩니다", - "subtitles.antarchy.scorpion_attack": "전갈 공격합니다", - "subtitles.antarchy.emperor_scorpion_ambient": "황제전갈 달그락거립니다", - "subtitles.antarchy.emperor_scorpion_hurt": "황제전갈 다칩니다", - "subtitles.antarchy.emperor_scorpion_attack": "황제전갈 공격합니다", - "subtitles.antarchy.emperor_scorpion_roar": "황제전갈 포효합니다", - "subtitles.antarchy.moleworm_ambient": "몰웜이 바스락거립니다", - "subtitles.antarchy.moleworm_hurt": "몰웜 다칩니다", - "subtitles.antarchy.moleworm_attack": "몰웜 공격합니다", - "subtitles.antarchy.moleworm_dig": "몰웜 땅을 팝니다", - "subtitles.antarchy.molevore_ambient": "몰보어 우르릉거립니다", - "subtitles.antarchy.molevore_hurt": "몰보어 다칩니다", - "subtitles.antarchy.molevore_attack": "몰보어 공격합니다", - "subtitles.antarchy.molevore_dig": "몰보어 땅을 팝니다", - "subtitles.antarchy.duct_tape_use": "덕트 테이프가 찢어집니다", - "subtitles.antarchy.potent_nyxite_hypnotic_gas": "강력한 닉사이트가 쉬익거립니다", - "subtitles.antarchy.potent_nyxite_geyser_eruption": "강력한 닉사이트가 분출합니다", - "subtitles.antarchy.potent_nyxite_geyser_continuous": "강력한 닉사이트 간헐천이 포효합니다", - "subtitles.antarchy.missile_squid_ambient": "미사일 오징어 웅웅거립니다", - "subtitles.antarchy.missile_squid_hurt": "미사일 오징어 다칩니다", - "subtitles.antarchy.missile_squid_death": "미사일 오징어 죽습니다", - "subtitles.antarchy.missile_squid_attack": "미사일 오징어 공격합니다", - "subtitles.antarchy.kraken_flying_loop": "크라켄 활공합니다", - "subtitles.antarchy.kraken_flying_sideways_loop": "크라켄이 맴돕니다", - "subtitles.antarchy.kraken_attack": "크라켄이 내리칩니다", - "subtitles.antarchy.kraken_spin": "크라켄이 회전합니다", - "subtitles.antarchy.kraken_roar": "크라켄 포효합니다", - "subtitles.antarchy.kraken_summon": "크라켄이 나타납니다", - "subtitles.antarchy.kraken_hurt": "크라켄 다칩니다", - "subtitles.antarchy.kraken_death": "크라켄 죽습니다", - "subtitles.antarchy.basilisk_idle_loop": "바실리스크 소리를 냅니다", - "subtitles.antarchy.basilisk_slither_loop": "바실리스크가 미끄러집니다", - "subtitles.antarchy.basilisk_bite": "바실리스크 뭅니다", - "subtitles.antarchy.basilisk_hiss": "바실리스크 쉬익거립니다", - "subtitles.antarchy.basilisk_hurt": "바실리스크 다칩니다", - "subtitles.antarchy.basilisk_death": "바실리스크 죽습니다", - "subtitles.antarchy.bomber_walk": "폭격충이 걷습니다", - "subtitles.antarchy.bomber_knock": "폭격충이 맞습니다", - "subtitles.antarchy.bomber_explode": "폭격충의 도화선이 쉬익거립니다", - "subtitles.antarchy.toreterror_idle": "토어테러 소리를 냅니다", - "subtitles.antarchy.toreterror_hurt": "토어테러 다칩니다", - "subtitles.antarchy.toreterror_death": "토어테러 죽습니다", - "subtitles.antarchy.toreterror_bomber_fire": "토어테러가 폭격충을 발사합니다", - "subtitles.antarchy.toreterror_spin": "토어테러가 회전합니다", - "subtitles.antarchy.toreterror_ricochet": "토어테러가 튕겨 나갑니다", - "subtitles.antarchy.water_cannon_fire": "물대포가 발사됩니다", - "subtitles.antarchy.toreterror_jump_up": "토어테러 뜁니다", - "subtitles.antarchy.toreterror_jump_land": "토어테러가 착지합니다", - "subtitles.antarchy.stinky_fly": "악취 파리가 윙윙거립니다", - "item.minecraft.potion.effect.inversion": "반전 물약", - "item.minecraft.potion.effect.long_inversion": "반전 물약", - "item.minecraft.splash_potion.effect.inversion": "반전 투척용 물약", - "item.minecraft.splash_potion.effect.long_inversion": "반전 투척용 물약", - "item.minecraft.lingering_potion.effect.inversion": "반전 잔류형 물약", - "item.minecraft.lingering_potion.effect.long_inversion": "반전 잔류형 물약", - "item.minecraft.tipped_arrow.effect.inversion": "반전 화살", - "item.minecraft.tipped_arrow.effect.long_inversion": "반전 화살", - "item.minecraft.potion.effect.paralysis": "마비 물약", - "item.minecraft.potion.effect.long_paralysis": "마비 물약", - "item.minecraft.splash_potion.effect.paralysis": "마비 투척용 물약", - "item.minecraft.splash_potion.effect.long_paralysis": "마비 투척용 물약", - "item.minecraft.lingering_potion.effect.paralysis": "마비 잔류형 물약", - "item.minecraft.lingering_potion.effect.long_paralysis": "마비 잔류형 물약", - "item.minecraft.tipped_arrow.effect.paralysis": "마비 화살", - "item.minecraft.tipped_arrow.effect.long_paralysis": "마비 화살", - "item.minecraft.potion.effect.shrinking": "축소 물약", - "item.minecraft.potion.effect.strong_shrinking": "축소 Ⅱ 물약", - "item.minecraft.potion.effect.extreme_shrinking": "축소 Ⅲ 물약", - "item.minecraft.splash_potion.effect.shrinking": "축소 투척용 물약", - "item.minecraft.splash_potion.effect.strong_shrinking": "축소 Ⅱ 투척용 물약", - "item.minecraft.splash_potion.effect.extreme_shrinking": "축소 Ⅲ 투척용 물약", - "item.minecraft.lingering_potion.effect.shrinking": "축소 잔류형 물약", - "item.minecraft.lingering_potion.effect.strong_shrinking": "축소 Ⅱ 잔류형 물약", - "item.minecraft.lingering_potion.effect.extreme_shrinking": "축소 Ⅲ 잔류형 물약", - "item.minecraft.tipped_arrow.effect.shrinking": "축소 화살", - "item.minecraft.tipped_arrow.effect.strong_shrinking": "축소 Ⅱ 화살", - "item.minecraft.tipped_arrow.effect.extreme_shrinking": "축소 Ⅲ 화살", - "item.minecraft.potion.effect.growing": "성장 물약", - "item.minecraft.potion.effect.strong_growing": "성장 Ⅱ 물약", - "item.minecraft.potion.effect.extreme_growing": "성장 Ⅲ 물약", - "item.minecraft.splash_potion.effect.growing": "성장 투척용 물약", - "item.minecraft.splash_potion.effect.strong_growing": "성장 Ⅱ 투척용 물약", - "item.minecraft.splash_potion.effect.extreme_growing": "성장 Ⅲ 투척용 물약", - "item.minecraft.lingering_potion.effect.growing": "성장 잔류형 물약", - "item.minecraft.lingering_potion.effect.strong_growing": "성장 Ⅱ 잔류형 물약", - "item.minecraft.lingering_potion.effect.extreme_growing": "성장 Ⅲ 잔류형 물약", - "item.minecraft.tipped_arrow.effect.growing": "성장 화살", - "item.minecraft.tipped_arrow.effect.strong_growing": "성장 Ⅱ 화살", - "item.minecraft.tipped_arrow.effect.extreme_growing": "성장 Ⅲ 화살", - "item.minecraft.potion.effect.dread": "공포 물약", - "item.minecraft.potion.effect.long_dread": "공포 물약", - "item.minecraft.splash_potion.effect.dread": "공포 투척용 물약", - "item.minecraft.splash_potion.effect.long_dread": "공포 투척용 물약", - "item.minecraft.lingering_potion.effect.dread": "공포 잔류형 물약", - "item.minecraft.lingering_potion.effect.long_dread": "공포 잔류형 물약", - "item.minecraft.tipped_arrow.effect.dread": "공포 화살", - "item.minecraft.tipped_arrow.effect.long_dread": "공포 화살", - "item.minecraft.potion.effect.stinky": "악취 물약", - "item.minecraft.potion.effect.long_stinky": "악취 물약", - "item.minecraft.splash_potion.effect.stinky": "악취 투척용 물약", - "item.minecraft.splash_potion.effect.long_stinky": "악취 투척용 물약", - "item.minecraft.lingering_potion.effect.stinky": "악취 잔류형 물약", - "item.minecraft.lingering_potion.effect.long_stinky": "악취 잔류형 물약", - "item.minecraft.tipped_arrow.effect.stinky": "악취 화살", - "item.minecraft.tipped_arrow.effect.long_stinky": "악취 화살", - "item.minecraft.potion.effect.haste": "성급함 물약", - "item.minecraft.potion.effect.strong_haste": "성급함 Ⅱ 물약", - "item.minecraft.splash_potion.effect.haste": "성급함 투척용 물약", - "item.minecraft.splash_potion.effect.strong_haste": "성급함 Ⅱ 투척용 물약", - "item.minecraft.lingering_potion.effect.haste": "성급함 잔류형 물약", - "item.minecraft.lingering_potion.effect.strong_haste": "성급함 Ⅱ 잔류형 물약", - "item.minecraft.tipped_arrow.effect.haste": "성급함 화살", - "item.minecraft.tipped_arrow.effect.strong_haste": "성급함 Ⅱ 화살", - "advancements.antarchy.cancel_out.title": "1 - 1 = ?", - "advancements.antarchy.cancel_out.description": "성장과 축소 효과를 동시에 받으세요.", - "entity.antarchy.cheep": "칩", - "item.antarchy.cheep": "칩", - "item.antarchy.cheep_spawn_egg": "칩 생성 알", - "entity.antarchy.reverie": "레버리", - "biome.antarchy.thoraxis": "토랙시스", - "biome.antarchy.nightmare_wastes": "악몽 황무지", - "biome.antarchy.umbral_hills": "그늘진 언덕", - "biome.antarchy.lucid_pools": "루시드 웅덩이", - "biome.antarchy.dream_dunes": "꿈의 사구", - "block.antarchy.wild_corn": "야생 옥수수", - "trim_material.antarchy.blood_crystal": "혈수정", - "trim_material.antarchy.nightmare_scale": "악몽 비늘", - "trim_material.antarchy.uranium": "우라늄", - "trim_material.antarchy.titanium": "티타늄", - "advancements.antarchy.duct_tape.title": "이 보트를 반으로 톱질했어!", - "advancements.antarchy.duct_tape.description": "그리고 덕트 테이프의 힘으로 고쳤지!", - "key.categories.antarchy": "앤타키", - "key.antarchy.brutalfly_flap": "브루털플라이 겉날개: 날갯짓", - "advancements.antarchy.shrink_ray_craft.title": "애들아, 내가 몹을 줄였어", - "advancements.antarchy.shrink_ray_craft.description": "축소 광선총을 제작하세요.", - "advancements.antarchy.growth_ray_craft.title": "크게 가거나 집에 가거나", - "advancements.antarchy.growth_ray_craft.description": "성장 광선총을 제작하세요.", - "advancements.antarchy.squidzooka_craft.title": "먹물과 파괴", - "advancements.antarchy.squidzooka_craft.description": "스퀴드주카를 제작하세요.", - "advancements.antarchy.rocket_powered_octopus.title": "로켓 추진 문어", - "advancements.antarchy.rocket_powered_octopus.description": "로·추·문 발사기를 제작하세요.", - "advancements.antarchy.gravity_gun_craft.title": "들어 올리기 선수", - "advancements.antarchy.gravity_gun_craft.description": "중력총을 제작하세요.", - "block.antarchy.cavaryn_portal": "카바린 차원문", - "block.antarchy.termite_nest": "흰개미 둥지", - "block.antarchy.chitin_spike": "치텐 가시", - "block.antarchy.chitin_block": "치텐 블록", - "block.antarchy.myrmite": "미르마이트", - "block.antarchy.broodstone": "브루드스톤", - "block.antarchy.amber_moss_block": "호박색 이끼 블록", - "block.antarchy.amber_moss_carpet": "호박색 이끼 양탄자", - "block.antarchy.amber_lichen": "호박색 지의류", - "block.antarchy.bile_vein": "담즙 광맥", - "block.antarchy.creepvine": "크리프바인", - "block.antarchy.crawling_blight_egg": "기어오는 공포 알", - "block.antarchy.skulking_fright_egg": "도사린 공포 알", - "entity.antarchy.termite": "흰개미", - "entity.antarchy.springbug": "점피 벌레", - "entity.antarchy.spit_bug": "스핏 벌레", - "entity.antarchy.stink_bug": "노린재", - "entity.antarchy.rolly_polly": "공벌레", - "entity.antarchy.crawling_blight": "기어오는 공포", - "entity.antarchy.skulking_fright": "도사린 공포", - "entity.antarchy.hercules_beetle": "헤라클레스장수풍뎅이", - "item.antarchy.springbug_spawn_egg": "점피 벌레 생성 알", - "item.antarchy.spit_bug_spawn_egg": "스핏 벌레 생성 알", - "item.antarchy.stink_bug_spawn_egg": "노린재 생성 알", - "item.antarchy.termite_spawn_egg": "흰개미 생성 알", - "item.antarchy.rolly_polly_spawn_egg": "공벌레 생성 알", - "item.antarchy.crawling_blight_spawn_egg": "기어오는 공포 생성 알", - "item.antarchy.skulking_fright_spawn_egg": "도사린 공포 생성 알", - "item.antarchy.hercules_beetle_spawn_egg": "헤라클레스장수풍뎅이 생성 알", - "item.antarchy.chitin": "치텐", - "block.antarchy.polished_broodstone": "윤나는 브루드스톤", - "block.antarchy.chiseled_broodstone": "조각된 브루드스톤", - "block.antarchy.broodstone_bricks": "브루드스톤 벽돌", - "block.antarchy.broodstone_stairs": "브루드스톤 계단", - "block.antarchy.broodstone_slab": "브루드스톤 반 블록", - "block.antarchy.broodstone_wall": "브루드스톤 담장", - "block.antarchy.polished_broodstone_stairs": "윤나는 브루드스톤 계단", - "block.antarchy.polished_broodstone_slab": "윤나는 브루드스톤 반 블록", - "block.antarchy.polished_broodstone_wall": "윤나는 브루드스톤 담장", - "block.antarchy.broodstone_brick_stairs": "브루드스톤 벽돌 계단", - "block.antarchy.broodstone_brick_slab": "브루드스톤 벽돌 반 블록", - "block.antarchy.broodstone_brick_wall": "브루드스톤 벽돌 담장", - "block.antarchy.myrmite_coal_ore": "미르마이트 석탄 광석", - "block.antarchy.broodstone_uranium_ore": "브루드스톤 우라늄 광석", - "block.antarchy.broodstone_titanium_ore": "브루드스톤 티타늄 광석", - "item.antarchy.raw_bug_meat": "익히지 않은 벌레 고기", - "item.antarchy.cooked_bug_meat": "익힌 벌레 고기", - "item.antarchy.hercules_horn": "헤라클레스 뿔", - "block.antarchy.hanging_creeproots": "매달린 크리프루츠", - "block.antarchy.glowcap_mushroom": "글로우캡 버섯", - "block.antarchy.potted_glowcap_mushroom": "화분에 심은 글로우캡 버섯", - "block.antarchy.glowcap_mushroom_block": "글로우캡 버섯 블록", - "block.antarchy.molting_vines": "탈피 덩굴", - "item.antarchy.broodfruit": "브루드프루트", - "block.antarchy.springbug_egg": "점피 벌레 알", - "subtitles.antarchy.crawling_blight_growl": "기어오는 공포 그르렁거립니다", - "subtitles.antarchy.crawling_blight_hurt": "기어오는 공포 다칩니다", - "subtitles.antarchy.crawling_blight_bite": "기어오는 공포 뭅니다", - "subtitles.antarchy.skulking_fright_snarl": "도사린 공포 으르렁거립니다", - "subtitles.antarchy.skulking_fright_hurt": "도사린 공포 다칩니다", - "subtitles.antarchy.skulking_fright_bite": "도사린 공포 뭅니다", - "subtitles.antarchy.skulking_fright_fly_loop": "도사린 공포 납니다", - "subtitles.antarchy.stink_bug_fart": "노린재 방귀를 뀝니다", - "subtitles.antarchy.stink_bug_idle": "노린재 소리를 냅니다", - "subtitles.antarchy.rolly_polly_idle": "공벌레 소리를 냅니다", - "subtitles.antarchy.rolly_polly_wheel_mode": "공벌레가 몸을 맙니다", - "subtitles.antarchy.rolly_polly_normal_mode": "공벌레가 몸을 폅니다", - "subtitles.antarchy.rolly_polly_roll": "공벌레가 구릅니다", - "subtitles.antarchy.hercules_beetle_idle": "헤라클레스장수풍뎅이 소리를 냅니다", - "subtitles.antarchy.hercules_beetle_hurt": "헤라클레스장수풍뎅이 다칩니다", - "subtitles.antarchy.hercules_beetle_attack": "헤라클레스장수풍뎅이 공격합니다", - "subtitles.antarchy.hercules_beetle_cry": "헤라클레스장수풍뎅이 포효합니다", - "subtitles.antarchy.hercules_beetle_charge_start": "헤라클레스장수풍뎅이 힘을 모읍니다", - "subtitles.antarchy.hercules_beetle_knocked_down": "헤라클레스장수풍뎅이 쓰러집니다", - "subtitles.antarchy.jerry_idle": "제리가 재잘거립니다", - "subtitles.antarchy.jerry_hurt": "제리가 다칩니다", - "subtitles.antarchy.jerry_death": "제리가 죽습니다", - "subtitles.antarchy.jerry_attack": "제리가 공격합니다", - "subtitles.antarchy.springbug_idle": "점피 벌레 소리를 냅니다", - "subtitles.antarchy.spit_bug_idle": "스핏 벌레 소리를 냅니다", - "subtitles.antarchy.springbug_hurt": "점피 벌레 다칩니다", - "subtitles.antarchy.springbug_jump": "점피 벌레 뜁니다", - "subtitles.antarchy.spit_bug_hurt": "스핏 벌레 다칩니다", - "subtitles.antarchy.spit_bug_spit": "스핏 벌레 뱉습니다", - "subtitles.antarchy.brutalfly_spit": "브루털플라이 뱉습니다", - "advancements.antarchy.bug_apetit.title": "벌레 쁘띠", - "advancements.antarchy.bug_apetit.description": "익힌 벌레 고기를 먹으세요.", - "advancements.antarchy.behavioral_correction.title": "행동 교정", - "advancements.antarchy.behavioral_correction.description": "태도 교정기를 획득하세요.", - "advancements.antarchy.beetle_buddies.title": "딱정벌레 친구들", - "advancements.antarchy.beetle_buddies.description": "헤라클레스장수풍뎅이를 길들이세요.", - "advancements.antarchy.herculean_task.title": "헤라클레스의 과업", - "advancements.antarchy.herculean_task.description": "헤라클레스장수풍뎅이를 처치하세요." + "block.antarchy.duplicator_log": "복제나무 원목", + "block.antarchy.ouranwood_log": "오우란나무 원목", + "block.antarchy.ouranwood_wood": "오우란나무", + "block.antarchy.mossy_ouranwood_log": "이끼 낀 오우란나무 원목", + "block.antarchy.mossy_ouranwood_wood": "이끼 낀 오우란나무", + "block.antarchy.stripped_ouranwood_log": "껍질 벗긴 오우란나무 원목", + "block.antarchy.stripped_ouranwood_wood": "껍질 벗긴 오우란나무", + "block.antarchy.ouranwood_planks": "오우란나무 판자", + "block.antarchy.ouranwood_stairs": "오우란나무 계단", + "block.antarchy.ouranwood_slab": "오우란나무 반 블록", + "block.antarchy.ouranwood_fence": "오우란나무 울타리", + "block.antarchy.ouranwood_fence_gate": "오우란나무 울타리 문", + "block.antarchy.ouranwood_door": "오우란나무 문", + "block.antarchy.ouranwood_trapdoor": "오우란나무 다락문", + "block.antarchy.ouranwood_pressure_plate": "오우란나무 압력판", + "block.antarchy.ouranwood_button": "오우란나무 버튼", + "block.antarchy.ouranwood_leaves": "오우란나무 잎", + "block.antarchy.ouranwood_acorn": "오우란나무 도토리", + "block.antarchy.ouranwood_sign": "오우란나무 표지판", + "block.antarchy.ouranwood_hanging_sign": "오우란나무 매다는 표지판", + "block.antarchy.peach_log": "복숭아나무 원목", + "block.antarchy.peach_wood": "복숭아나무", + "block.antarchy.stripped_peach_log": "껍질 벗긴 복숭아나무 원목", + "block.antarchy.stripped_peach_wood": "껍질 벗긴 복숭아나무", + "block.antarchy.peach_planks": "복숭아나무 판자", + "block.antarchy.peach_stairs": "복숭아나무 계단", + "block.antarchy.peach_slab": "복숭아나무 반 블록", + "block.antarchy.peach_fence": "복숭아나무 울타리", + "block.antarchy.peach_fence_gate": "복숭아나무 울타리 문", + "block.antarchy.peach_door": "복숭아나무 문", + "block.antarchy.peach_trapdoor": "복숭아나무 다락문", + "block.antarchy.peach_pressure_plate": "복숭아나무 압력판", + "block.antarchy.peach_button": "복숭아나무 버튼", + "block.antarchy.peach_leaves": "복숭아나무 잎", + "block.antarchy.hanging_peach": "매달린 복숭아", + "block.antarchy.peach_sapling": "복숭아나무 묘목", + "block.antarchy.peach_sign": "복숭아나무 표지판", + "block.antarchy.peach_hanging_sign": "복숭아나무 매다는 표지판", + "block.antarchy.nadir_log": "나디르나무 원목", + "block.antarchy.nadir_wood": "나디르나무", + "block.antarchy.stripped_nadir_log": "껍질 벗긴 나디르나무 원목", + "block.antarchy.stripped_nadir_wood": "껍질 벗긴 나디르나무", + "block.antarchy.nadir_planks": "나디르나무 판자", + "block.antarchy.nadir_stairs": "나디르나무 계단", + "block.antarchy.nadir_slab": "나디르나무 반 블록", + "block.antarchy.nadir_fence": "나디르나무 울타리", + "block.antarchy.nadir_fence_gate": "나디르나무 울타리 문", + "block.antarchy.nadir_door": "나디르나무 문", + "block.antarchy.nadir_trapdoor": "나디르나무 다락문", + "block.antarchy.nadir_pressure_plate": "나디르나무 압력판", + "block.antarchy.nadir_button": "나디르나무 버튼", + "block.antarchy.nadir_veil": "나디르 베일", + "block.antarchy.nadir_sapling": "나디르나무 묘목", + "block.antarchy.nadir_sign": "나디르나무 표지판", + "block.antarchy.nadir_hanging_sign": "나디르나무 매다는 표지판", + "block.antarchy.royal_log": "로얄나무 원목", + "block.antarchy.royal_wood": "로얄나무", + "block.antarchy.stripped_royal_log": "껍질 벗긴 로얄나무 원목", + "block.antarchy.stripped_royal_wood": "껍질 벗긴 로얄나무", + "block.antarchy.royal_planks": "로얄나무 판자", + "block.antarchy.royal_stairs": "로얄나무 계단", + "block.antarchy.royal_slab": "로얄나무 반 블록", + "block.antarchy.royal_fence": "로얄나무 울타리", + "block.antarchy.royal_fence_gate": "로얄나무 울타리 문", + "block.antarchy.royal_door": "로얄나무 문", + "block.antarchy.royal_trapdoor": "로얄나무 다락문", + "block.antarchy.royal_pressure_plate": "로얄나무 압력판", + "block.antarchy.royal_button": "로얄나무 버튼", + "block.antarchy.royal_leaves": "로얄나무 잎", + "block.antarchy.royal_flowering_leaves": "꽃이 핀 로얄나무 잎", + "block.antarchy.royal_sapling": "로얄나무 묘목", + "block.antarchy.royal_sign": "로얄나무 표지판", + "block.antarchy.royal_hanging_sign": "로얄나무 매다는 표지판", + "block.antarchy.truffalo_log": "트러팔로나무 원목", + "block.antarchy.truffalo_wood": "트러팔로나무", + "block.antarchy.stripped_truffalo_log": "껍질 벗긴 트러팔로나무 원목", + "block.antarchy.stripped_truffalo_wood": "껍질 벗긴 트러팔로나무", + "block.antarchy.truffalo_planks": "트러팔로나무 판자", + "block.antarchy.truffalo_stairs": "트러팔로나무 계단", + "block.antarchy.truffalo_slab": "트러팔로나무 반 블록", + "block.antarchy.truffalo_fence": "트러팔로나무 울타리", + "block.antarchy.truffalo_fence_gate": "트러팔로나무 울타리 문", + "block.antarchy.truffalo_door": "트러팔로나무 문", + "block.antarchy.truffalo_trapdoor": "트러팔로나무 다락문", + "block.antarchy.truffalo_pressure_plate": "트러팔로나무 압력판", + "block.antarchy.truffalo_button": "트러팔로나무 버튼", + "block.antarchy.truffalo_sapling": "트러팔로나무 묘목", + "block.antarchy.truffalo_sign": "트러팔로나무 표지판", + "block.antarchy.truffalo_hanging_sign": "트러팔로나무 매다는 표지판", + "block.antarchy.white_truffalo_tuft": "하얀색 트러팔로 다발", + "block.antarchy.orange_truffalo_tuft": "주황색 트러팔로 다발", + "block.antarchy.magenta_truffalo_tuft": "자홍색 트러팔로 다발", + "block.antarchy.light_blue_truffalo_tuft": "하늘색 트러팔로 다발", + "block.antarchy.yellow_truffalo_tuft": "노란색 트러팔로 다발", + "block.antarchy.lime_truffalo_tuft": "연두색 트러팔로 다발", + "block.antarchy.pink_truffalo_tuft": "분홍색 트러팔로 다발", + "block.antarchy.gray_truffalo_tuft": "회색 트러팔로 다발", + "block.antarchy.light_gray_truffalo_tuft": "회백색 트러팔로 다발", + "block.antarchy.cyan_truffalo_tuft": "청록색 트러팔로 다발", + "block.antarchy.purple_truffalo_tuft": "보라색 트러팔로 다발", + "block.antarchy.blue_truffalo_tuft": "파란색 트러팔로 다발", + "block.antarchy.brown_truffalo_tuft": "갈색 트러팔로 다발", + "block.antarchy.green_truffalo_tuft": "초록색 트러팔로 다발", + "block.antarchy.red_truffalo_tuft": "빨간색 트러팔로 다발", + "block.antarchy.black_truffalo_tuft": "검은색 트러팔로 다발", + "block.antarchy.orange_milkweed": "주황색 박주가리", + "block.antarchy.pink_milkweed": "분홍색 박주가리", + "block.antarchy.glimmering_reed": "희미하게 빛나는 갈대", + "block.antarchy.camellia": "동백나무", + "block.antarchy.spider_lily": "상사화", + "block.antarchy.lotus": "연꽃", + "item.antarchy.lotus": "연꽃", + "item.antarchy.critter_cage": "생물 케이지", + "block.antarchy.giant_lily_pad": "거대한 수련잎", + "block.antarchy.seashell": "조개껍데기", + "block.antarchy.lucid_anchor": "루시드 정박기", + "block.antarchy.undertrial_spawner": "언더트라이얼 생성기", + "block.antarchy.undervault": "언더금고", + "item.antarchy.undertrial_key": "언더트라이얼 열쇠", + "block.antarchy.critter_cage_block": "생물 케이지 블록", + "block.antarchy.hushweed": "허쉬위드", + "block.antarchy.umbral_moss_block": "그림자 이끼 블록", + "block.antarchy.umbral_moss_carpet": "그림자 이끼 양탄자", + "block.antarchy.blush_moss_block": "홍조 이끼 블록", + "block.antarchy.blush_moss_carpet": "홍조 이끼 양탄자", + "block.antarchy.duplicator_sapling": "듀플리케이터 묘목", + "block.antarchy.duct_tape": "덕트 테이프", + "block.antarchy.infested_rooted_dirt": "벌레 먹은 뿌리내린 흙", + "block.antarchy.infested_coarse_dirt": "벌레 먹은 거친 흙", + "block.antarchy.nyxite": "닉사이트", + "block.antarchy.polished_nyxite": "윤나는 닉사이트", + "block.antarchy.chiseled_nyxite": "조각된 닉사이트", + "block.antarchy.nyxite_bricks": "닉사이트 벽돌", + "block.antarchy.nyxite_pillar": "닉사이트 기둥", + "block.antarchy.shellstone": "조개돌", + "block.antarchy.polished_shellstone": "윤나는 조개돌", + "block.antarchy.shellstone_bricks": "조개돌 벽돌", + "block.antarchy.chiseled_shellstone": "조각된 조개돌", + "block.antarchy.mossy_shellstone_bricks": "이끼 낀 조개돌 벽돌", + "block.antarchy.mossy_shellstone_brick_stairs": "이끼 낀 조개돌 벽돌 계단", + "block.antarchy.mossy_shellstone_brick_slab": "이끼 낀 조개돌 벽돌 반 블록", + "block.antarchy.mossy_shellstone_brick_wall": "이끼 낀 조개돌 벽돌 담장", + "block.antarchy.cracked_shellstone_bricks": "금 간 조개돌 벽돌", + "block.antarchy.shellstone_pillar": "조개돌 기둥", + "block.antarchy.shellstone_stairs": "조개돌 계단", + "block.antarchy.shellstone_slab": "조개돌 반 블록", + "block.antarchy.shellstone_wall": "조개돌 담장", + "block.antarchy.polished_shellstone_stairs": "윤나는 조개돌 반 블록", + "block.antarchy.polished_shellstone_slab": "윤나는 조개돌 담장", + "block.antarchy.polished_shellstone_wall": "조개돌 벽돌 계단", + "block.antarchy.shellstone_brick_stairs": "조개돌 벽돌 반 블록", + "block.antarchy.shellstone_brick_slab": "조개돌 벽돌 담장", + "block.antarchy.shellstone_brick_wall": "닉사이트 계단", + "block.antarchy.nyxite_stairs": "닉사이트 계단", + "block.antarchy.nyxite_slab": "닉사이트 반 블록", + "block.antarchy.nyxite_wall": "닉사이트 담장", + "block.antarchy.polished_nyxite_stairs": "윤나는 닉사이트 계단", + "block.antarchy.polished_nyxite_slab": "윤나는 닉사이트 반 블록", + "block.antarchy.polished_nyxite_wall": "윤나는 닉사이트 담장", + "block.antarchy.polished_nyxite_pressure_plate": "윤나는 닉사이트 압력판", + "block.antarchy.polished_nyxite_button": "윤나는 닉사이트 버튼", + "block.antarchy.nyxite_brick_stairs": "닉사이트 벽돌 계단", + "block.antarchy.nyxite_brick_slab": "닉사이트 벽돌 반 블록", + "block.antarchy.nyxite_brick_wall": "닉사이트 벽돌 담장", + "block.antarchy.pale_nyxite": "창백한 닉사이트", + "block.antarchy.nyxite_spike": "닉사이트 가시", + "block.antarchy.potent_nyxite": "강력한 닉사이트", + "block.antarchy.flytrap_goo_block": "파리잡이 끈적액 블록", + "block.antarchy.elythia_portal": "엘리시아 차원문", + "block.antarchy.cloud_block": "구름 블록", + "block.antarchy.thoraxis_portal": "소락시스 차원문", + "block.antarchy.antimetal": "안티메탈", + "block.antarchy.antimetal_stairs": "안티메탈 계단", + "block.antarchy.antimetal_slab": "안티메탈 반 블록", + "block.antarchy.polished_antimetal": "윤나는 안티메탈", + "block.antarchy.polished_antimetal_stairs": "윤나는 안티메탈 계단", + "block.antarchy.polished_antimetal_slab": "윤나는 안티메탈 반 블록", + "block.antarchy.antimetal_scaffolding": "안티메탈 비계", + "block.antarchy.antimetal_rail": "안티메탈 레일", + "block.antarchy.antimetal_powered_rail": "안티메탈 동력 레일", + "block.antarchy.antimetal_detector_rail": "안티메탈 감지 레일", + "block.antarchy.antimetal_activator_rail": "안티메탈 활성화 레일", + "block.antarchy.upper": "업퍼", + "container.antarchy.upper": "업퍼", + "block.antarchy.cornea_stalk": "각막 줄기", + "block.antarchy.corn_crop": "옥수수 작물", + "block.antarchy.dream_torch": "꿈 횃불", + "block.antarchy.dream_wall_torch": "벽에 걸린 꿈 횃불", + "block.antarchy.dream_lantern": "꿈 랜턴", + "block.antarchy.dream_campfire": "꿈 모닥불", + "block.antarchy.dream_fire": "꿈 불", + "block.antarchy.dream_fire_ceiling": "꿈 불", + "block.antarchy.budding_blood_crystal": "싹 틔우는 혈수정", + "block.antarchy.blood_crystal_block": "혈수정 블록", + "block.antarchy.small_blood_crystal_bud": "작은 혈수정 봉오리", + "block.antarchy.medium_blood_crystal_bud": "중간 혈수정 봉오리", + "block.antarchy.large_blood_crystal_bud": "큰 혈수정 봉오리", + "block.antarchy.blood_crystal_cluster": "혈수정 군집", + "block.antarchy.dream_sand": "꿈 모래", + "block.antarchy.antigravel": "안티자갈", + "block.antarchy.loam": "양토", + "block.antarchy.dream_sandstone": "꿈 사암", + "block.antarchy.chiseled_dream_sandstone": "조각된 꿈 사암", + "block.antarchy.cut_dream_sandstone": "깎인 꿈 사암", + "block.antarchy.smooth_dream_sandstone": "매끄러운 꿈 사암", + "block.antarchy.dream_sandstone_stairs": "꿈 사암 계단", + "block.antarchy.dream_sandstone_slab": "꿈 사암 반 블록", + "block.antarchy.dream_sandstone_wall": "꿈 사암 담장", + "block.antarchy.smooth_dream_sandstone_stairs": "매끄러운 꿈 사암 계단", + "block.antarchy.smooth_dream_sandstone_slab": "매끄러운 꿈 사암 반 블록", + "block.antarchy.cut_dream_sandstone_slab": "깎인 꿈 사암 반 블록", + "block.antarchy.typhonite": "타이포나이트", + "block.antarchy.typhonite_bricks": "타이포나이트 벽돌", + "block.antarchy.chiseled_typhonite": "조각된 타이포나이트", + "block.antarchy.polished_typhonite": "윤나는 타이포나이트", + "block.antarchy.veined_typhonite": "맥상 타이포나이트", + "block.antarchy.typhonite_spike": "타이포나이트 가시", + "block.antarchy.typhonite_stairs": "타이포나이트 계단", + "block.antarchy.typhonite_slab": "타이포나이트 반 블록", + "block.antarchy.typhonite_wall": "타이포나이트 담장", + "block.antarchy.typhonite_brick_stairs": "타이포나이트 벽돌 계단", + "block.antarchy.typhonite_brick_slab": "타이포나이트 벽돌 반 블록", + "block.antarchy.typhonite_brick_wall": "타이포나이트 벽돌 담장", + "block.antarchy.polished_typhonite_stairs": "윤나는 타이포나이트 계단", + "block.antarchy.polished_typhonite_slab": "윤나는 타이포나이트 반 블록", + "block.antarchy.polished_typhonite_wall": "윤나는 타이포나이트 담장", + "block.antarchy.spiraling_vines": "소라모양 덩굴", + "block.antarchy.whirlflower": "회오리꽃", + "block.antarchy.bed_bug_egg": "빈대 알", + "block.antarchy.wasp_nest": "말벌집", + "block.antarchy.red_ant_nest": "붉은 개미 굴", + "block.antarchy.brown_ant_nest": "갈색 개미 굴", + "block.antarchy.rainbow_ant_nest": "무지개 개미 굴", + "block.antarchy.uranium_ore": "우라늄 광석", + "block.antarchy.deepslate_uranium_ore": "심층암 우라늄 광석", + "block.antarchy.titanium_ore": "티타늄 광석", + "block.antarchy.deepslate_titanium_ore": "심층암 티타늄 광석", + "block.antarchy.bluestone_ore": "블루스톤 광석", + "block.antarchy.bluestone_block": "블루스톤 블록", + "block.antarchy.vortex_lens": "소용돌이 렌즈", + "tooltip.antarchy.vortex_lens": "레드스톤 신호는 엔티티를 광선 안으로 빨아들이고, 블루스톤 신호는 튕겨냅니다. 신호가 강할수록 소용돌이가 커집니다.", + "block.antarchy.bluestone_repeater": "블루스톤 중계기", + "block.antarchy.bluestone_comparator": "블루스톤 비교기", + "block.antarchy.bluestone_torch": "블루스톤 횃불", + "block.antarchy.bluestone_lamp": "블루스톤 조명", + "block.antarchy.uranium_block": "우라늄 블록", + "block.antarchy.titanium_block": "티타늄 블록", + "block.antarchy.raw_uranium_block": "우라늄 원석 블록", + "block.antarchy.raw_titanium_block": "티타늄 원석 블록", + "block.antarchy.cut_uranium": "깎인 우라늄", + "block.antarchy.cut_titanium": "깎인 티타늄", + "block.antarchy.cut_uranium_slab": "깎인 우라늄 반 블록", + "block.antarchy.cut_titanium_slab": "깎인 티타늄 반 블록", + "block.antarchy.cut_uranium_stairs": "깎인 우라늄 계단", + "block.antarchy.cut_titanium_stairs": "깎인 티타늄 계단", + "block.antarchy.chiseled_uranium": "조각된 우라늄", + "block.antarchy.chiseled_titanium": "조각된 티타늄", + "block.antarchy.uranium_bulb": "우라늄 전구", + "block.antarchy.titanium_bulb": "티타늄 전구", + "block.antarchy.uranium_door": "우라늄 문", + "block.antarchy.titanium_door": "티타늄 문", + "block.antarchy.uranium_trapdoor": "우라늄 다락문", + "block.antarchy.titanium_trapdoor": "티타늄 다락문", + "block.antarchy.uranium_bars": "우라늄 창살", + "block.antarchy.titanium_bars": "티타늄 창살", + "tooltip.antarchy.signal_saving_bulb": "켜기/끄기를 전환합니다. 저장된 신호 세기와 동일한 밝기의 빛을 냅니다.", + "tooltip.antarchy.bluestone_placement": "블록 아래에 설치합니다.", + "tooltip.antarchy.ceiling_compatible_placement": "천장에도 설치할 수 있습니다.", + "tooltip.antarchy.antimetal_scaffolding": "일반 비계처럼 작동하거나, 중력이 뒤집혔을 때는 역방향 비계로 작동합니다.", + "block.antarchy.bile": "담즙", + "block.antarchy.ichor": "이코르", + "block.antarchy.antiwater": "역수", + "block.antarchy.lumen": "루멘", + "block.antarchy.lumen_froglight": "루멘 개구리불", + "block.antarchy.roseate_froglight": "장밋빛 개구리불", + "block.antarchy.star_coral": "별 산호", + "block.antarchy.star_coral_fan": "부채꼴 별 산호", + "block.antarchy.star_coral_block": "별 산호 블록", + "block.antarchy.dead_star_coral": "죽은 별 산호", + "block.antarchy.dead_star_coral_fan": "죽은 부채꼴 별 산호", + "block.antarchy.dead_star_coral_block": "죽은 별 산호 블록", + "entity.antarchy.apple_cow": "사과 소", + "entity.antarchy.golden_apple_cow": "황금 사과 소", + "entity.antarchy.enchanted_golden_apple_cow": "마법이 부여된 황금 사과 소", + "entity.antarchy.easter_bunny": "이스터 토끼", + "entity.antarchy.glimmer": "글리머", + "entity.antarchy.ouranwood_deer": "오우란나무 사슴", + "entity.antarchy.elka": "엘카", + "entity.antarchy.dorrie": "도리", + "entity.antarchy.flying_squirrel": "하늘다람쥐", + "entity.antarchy.caterpillar": "애벌레", + "entity.antarchy.butterfly": "나비", + "entity.antarchy.brutalfly": "브루탈플라이", + "entity.antarchy.red_ant": "붉은 개미", + "entity.antarchy.brown_ant": "갈색 개미", + "entity.antarchy.rainbow_ant": "무지개 개미", + "entity.antarchy.diamond_minecart": "다이아몬드 광산 수레", + "entity.antarchy.dr_trayaurus": "트레이오러스 박사", + "entity.antarchy.stratoshark": "스트라토샤크", + "entity.antarchy.kraken": "크라켄", + "entity.antarchy.missile_squid": "미사일 오징어", + "entity.antarchy.octopus_bomb": "문어 폭탄", + "entity.antarchy.nightmare": "나이트메어", + "entity.antarchy.bed_bug": "빈대", + "entity.antarchy.wasp": "말벌", + "entity.antarchy.bomber": "봄버", + "entity.antarchy.moleworm": "웜", + "entity.antarchy.worm": "벌레", + "entity.antarchy.molevore": "몰레보어", + "entity.antarchy.mantis": "맨티스", + "entity.antarchy.alpha_mantis": "알파 맨티스", + "entity.antarchy.flytrap": "파리잡이", + "entity.antarchy.toreterror": "토레테러", + "entity.antarchy.water_bomb": "물폭탄", + "subtitles.antarchy.manticore_idle": "만티코어가 으르렁거림", + "subtitles.antarchy.manticore_walk": "만티코어가 걸어감", + "subtitles.antarchy.manticore_fly": "만티코어가 날아감", + "subtitles.antarchy.manticore_bite": "만티코어가 물어띰", + "subtitles.antarchy.mantis_ambient": "맨티스가 찰칵거림", + "subtitles.antarchy.mantis_hurt": "맨티스가 비명을 지름", + "subtitles.antarchy.mantis_attack": "맨티스가 덤벼듦", + "subtitles.antarchy.mantis_fly_loop": "맨티스 날개가 웅웅거림", + "item.antarchy.big_bertha": "빅 베르타", + "item.antarchy.giant_frying_pan": "거대한 프라이팬", + "tooltip.antarchy.giant_frying_pan.insert": "다른 손에 음식을 들고 우클릭하거나, 인벤토리에서 음식을 우클릭하여 추가합니다.", + "tooltip.antarchy.giant_frying_pan.gui": "Shift + 우클릭하여 조리 슬롯을 엽니다.", + "tooltip.antarchy.giant_frying_pan.campfire": "연료 없이 모닥불 레시피를 조리합니다.", + "tooltip.antarchy.giant_frying_pan.dig": "삽 블록 구역을 5x5 범위로 파냅니다.", + "tooltip.antarchy.giant_frying_pan.launch": "공격 시 적을 공중으로 띄웁니다.", + "item.antarchy.bluestone": "블루스톤 가루", + "item.antarchy.wasp_nest": "말벌집", + "item.antarchy.stink_bug": "노린재", + "item.antarchy.wasp_spawn_egg": "말벌 스폰 알", + "item.antarchy.bomber_spawn_egg": "봄버 스폰 알", + "item.antarchy.big_bertha_blade": "빅 베르타 칼날", + "item.antarchy.big_bertha_handle": "빅 베르타 손잡이", + "item.antarchy.big_bertha_hilt": "빅 베르타 자루", + "item.antarchy.battle_axe": "배틀액스", + "item.antarchy.attitude_adjuster": "어튜드 어저스터", + "tooltip.antarchy.attitude_adjuster.grounded": "지상의 대상을 위로 쳐올리고, 공중의 대상을 지면에 내리꽂습니다.", + "tooltip.antarchy.attitude_adjuster.slam": "공중에 있을 때 사용하여 지면을 강타합니다.", + "item.antarchy.stratoshark_fin": "스트라토샤크 지느러미", + "item.antarchy.stratoshark_fin_soup": "스트라토샤크 지느러미 수프", + "tooltip.antarchy.stratoshark_fin_soup": "성장 및 느린 낙하 효과를 부여합니다.", + "tooltip.antarchy.critter_cage.empty": "사용하여 던집니다", + "tooltip.antarchy.critter_cage.contains": "보관 중: %s", + "tooltip.antarchy.critter_cage.release": "사용하여 풀어줍니다", + "tooltip.antarchy.critter_cage.place": "Shift + 클릭하여 설치합니다", + "item.antarchy.kraken_tooth": "크라켄 이빨", + "item.antarchy.kraken_tentacle": "크라켄 촉수", + "item.antarchy.kraken_kalamari": "크라켄 오징어튀김", + "item.antarchy.krakens_grasp": "크라켄의 아귀", + "entity.antarchy.tentacle": "촉수", + "item.antarchy.basilisk_fang": "바실리스크 송곳니", + "item.antarchy.basilisk_dagger": "바실리스크 단검", + "item.antarchy.blood_crystal_block": "혈수정 블록", + "item.antarchy.small_blood_crystal_bud": "작은 혈수정 봉오리", + "item.antarchy.medium_blood_crystal_bud": "중간 혈수정 봉오리", + "item.antarchy.large_blood_crystal_bud": "큰 혈수정 봉오리", + "item.antarchy.blood_crystal_cluster": "혈수정 군집", + "item.antarchy.dream_sand": "꿈 모래", + "item.antarchy.dream_sandstone": "꿈 사암", + "item.antarchy.chiseled_dream_sandstone": "조각된 꿈 사암", + "item.antarchy.cut_dream_sandstone": "깎인 꿈 사암", + "item.antarchy.smooth_dream_sandstone": "매끄러운 꿈 사암", + "item.antarchy.dream_sandstone_stairs": "꿈 사암 계단", + "item.antarchy.dream_sandstone_slab": "꿈 사암 반 블록", + "item.antarchy.dream_sandstone_wall": "꿈 사암 담장", + "item.antarchy.smooth_dream_sandstone_stairs": "매끄러운 꿈 사암 계단", + "item.antarchy.smooth_dream_sandstone_slab": "매끄러운 꿈 사암 반 블록", + "item.antarchy.cut_dream_sandstone_slab": "깎인 꿈 사암 반 블록", + "item.antarchy.typhonite": "타이포나이트", + "item.antarchy.typhonite_bricks": "타이포나이트 벽돌", + "item.antarchy.chiseled_typhonite": "조각된 타이포나이트", + "item.antarchy.polished_typhonite": "윤나는 타이포나이트", + "item.antarchy.veined_typhonite": "맥상 타이포나이트", + "item.antarchy.typhonite_spike": "타이포나이트 가시", + "item.antarchy.typhonite_stairs": "타이포나이트 계단", + "item.antarchy.typhonite_slab": "타이포나이트 반 블록", + "item.antarchy.typhonite_wall": "타이포나이트 담장", + "item.antarchy.typhonite_brick_stairs": "타이포나이트 벽돌 계단", + "item.antarchy.typhonite_brick_slab": "타이포나이트 벽돌 반 블록", + "item.antarchy.typhonite_brick_wall": "타이포나이트 벽돌 담장", + "item.antarchy.polished_typhonite_stairs": "윤나는 타이포나이트 계단", + "item.antarchy.polished_typhonite_slab": "윤나는 타이포나이트 반 블록", + "item.antarchy.polished_typhonite_wall": "윤나는 타이포나이트 담장", + "item.antarchy.spiraling_vines": "소라모양 덩굴", + "item.antarchy.whirlflower": "회오리꽃", + "item.antarchy.dream_torch": "꿈 횃불", + "item.antarchy.dream_lantern": "꿈 랜턴", + "item.antarchy.dream_campfire": "꿈 모닥불", + "item.antarchy.giant_lily_pad": "거대한 연잎", + "item.antarchy.seashell": "조개껍데기", + "item.antarchy.nightmare_scale": "나이트메어 비늘", + "item.antarchy.music_disc_underside": "음반", + "jukebox_song.antarchy.underside": "docshrekbot - underside", + "item.antarchy.music_disc_the_queen": "음반", + "jukebox_song.antarchy.the_queen": "Karlljp - The Queen", + "item.antarchy.music_disc_verdance": "음반", + "jukebox_song.antarchy.verdance": "Hewo - Verdance", + "item.antarchy.music_disc_grotesque": "음반", + "jukebox_song.antarchy.grotesque": "DocShrekBot - Grotesque", + "item.antarchy.nightmare_helmet": "나이트메어 투구", + "item.antarchy.nightmare_chestplate": "나이트메어 흉갑", + "item.antarchy.nightmare_leggings": "나이트메어 레깅스", + "item.antarchy.nightmare_boots": "나이트메어 부츠", + "item.antarchy.nightmare_sword": "나이트메어 검", + "tooltip.antarchy.nightmare_armor_double_damage": "%s%% 확률로 2배의 피해를 줍니다.", + "tooltip.antarchy.nightmare_armor_set_bonus": "세트 효과: 위더 및 공포 면역", + "tooltip.antarchy.nightmare_sword": "체력이 낮아질수록 더 큰 피해를 줍니다.", + "tooltip.antarchy.nightmare_sword_damage": "%s의 피해를 줍니다.", + "tooltip.antarchy.primordial_helmet_water_breathing": "착용자에게 수중 호흡 효과를 부여합니다.", + "tooltip.antarchy.primordial_armor_knockback_dealt": "조각당 공격 넉백 %s 증가", + "tooltip.antarchy.primordial_armor_set_bonus": "세트 효과: 적의 넉백 저항 무시", + "attribute.antarchy.double_damage_chance": "2배 피해 확률", + "attribute.antarchy.bloodglass_max_hearts": "최대 혈유리 하트", + "item.antarchy.molevore_nose": "몰레보어 코", + "item.antarchy.moleworm": "몰웜", + "item.antarchy.worm_tooth": "벌레 이빨", + "item.antarchy.worm_hook": "웜 갈고리", + "tooltip.antarchy.worm_hook.throw": "블록을 우클릭하여 발사하고 부착합니다.", + "tooltip.antarchy.worm_hook.reel": "웅크리고 감아들이며, 다시 우클릭하여 해제합니다.", + "item.antarchy.flytrap_spawn_egg": "파리잡이 스폰 알", + "item.antarchy.infested_rooted_dirt": "뿌리 내린 감염된 흙", + "item.antarchy.infested_coarse_dirt": "거친 감염된 흙", + "item.antarchy.pale_nyxite": "창백한 닉사이트", + "item.antarchy.polished_nyxite": "윤나는 닉사이트", + "item.antarchy.chiseled_nyxite": "조각된 닉사이트", + "item.antarchy.nyxite_bricks": "닉사이트 벽돌", + "item.antarchy.shellstone": "조개돌", + "item.antarchy.polished_shellstone": "윤나는 조개돌", + "item.antarchy.shellstone_bricks": "조개돌 벽돌", + "item.antarchy.chiseled_shellstone": "조각된 조개돌", + "item.antarchy.mossy_shellstone_bricks": "이끼 낀 조개돌 벽돌", + "item.antarchy.mossy_shellstone_brick_stairs": "이끼 낀 조개돌 벽돌 계단", + "item.antarchy.mossy_shellstone_brick_slab": "이끼 낀 조개돌 벽돌 반 블록", + "item.antarchy.mossy_shellstone_brick_wall": "이끼 낀 조개돌 벽돌 담장", + "item.antarchy.cracked_shellstone_bricks": "금 간 조개돌 벽돌", + "item.antarchy.shellstone_stairs": "조개돌 계단", + "item.antarchy.shellstone_slab": "조개돌 반 블록", + "item.antarchy.shellstone_wall": "조개돌 담장", + "item.antarchy.polished_shellstone_stairs": "윤나는 조개돌 계단", + "item.antarchy.polished_shellstone_slab": "윤나는 조개돌 반 블록", + "item.antarchy.polished_shellstone_wall": "윤나는 조개돌 담장", + "item.antarchy.shellstone_brick_stairs": "조개돌 벽돌 계단", + "item.antarchy.shellstone_brick_slab": "조개돌 벽돌 반 블록", + "item.antarchy.shellstone_brick_wall": "조개돌 벽돌 담장", + "item.antarchy.nyxite_stairs": "닉사이트 계단", + "item.antarchy.nyxite_slab": "닉사이트 반 블록", + "item.antarchy.nyxite_wall": "닉사이트 담장", + "item.antarchy.polished_nyxite_stairs": "윤나는 닉사이트 계단", + "item.antarchy.polished_nyxite_slab": "윤나는 닉사이트 반 블록", + "item.antarchy.polished_nyxite_wall": "윤나는 닉사이트 담장", + "item.antarchy.nyxite_brick_stairs": "닉사이트 벽돌 계단", + "item.antarchy.nyxite_brick_slab": "닉사이트 벽돌 반 블록", + "item.antarchy.nyxite_brick_wall": "닉사이트 벽돌 담장", + "item.antarchy.potent_nyxite": "강력한 닉사이트", + "item.antarchy.antimetal": "안티메탈", + "item.antarchy.polished_antimetal": "윤나는 안티메탈", + "item.antarchy.antimetal_scaffolding": "안티메탈 비계", + "item.antarchy.antimetal_rail": "안티메탈 레일", + "item.antarchy.antimetal_powered_rail": "안티메탈 동력 레일", + "item.antarchy.antimetal_detector_rail": "안티메탈 감지 레일", + "item.antarchy.antimetal_activator_rail": "안티메탈 활성화 레일", + "item.antarchy.ouranwood_acorn": "오우란나무 도토리", + "item.antarchy.ouranwood_boat": "오우란나무 보트", + "item.antarchy.ouranwood_chest_boat": "상자가 실린 오우란나무 보트", + "item.antarchy.hoverboard": "호버보드", + "item.antarchy.hoverboard_white": "하얀색 호버보드", + "item.antarchy.hoverboard_orange": "주황색 호버보드", + "item.antarchy.hoverboard_magenta": "자홍색 호버보드", + "item.antarchy.hoverboard_light_blue": "하늘색 호버보드", + "item.antarchy.hoverboard_yellow": "노란색 호버보드", + "item.antarchy.hoverboard_lime": "연두색 호버보드", + "item.antarchy.hoverboard_pink": "분홍색 호버보드", + "item.antarchy.hoverboard_gray": "회색 호버보드", + "item.antarchy.hoverboard_light_gray": "회백색 호버보드", + "item.antarchy.hoverboard_cyan": "청록색 호버보드", + "item.antarchy.hoverboard_purple": "보라색 호버보드", + "item.antarchy.hoverboard_blue": "파란색 호버보드", + "item.antarchy.hoverboard_brown": "갈색 호버보드", + "item.antarchy.hoverboard_green": "초록색 호버보드", + "item.antarchy.hoverboard_red": "빨간색 호버보드", + "item.antarchy.hoverboard_black": "검은색 호버보드", + "item.antarchy.raw_venison": "익히지 않은 사슴고기", + "item.antarchy.cooked_venison": "익힌 사슴고기", + "item.antarchy.peach_sapling": "복숭아나무 묘목", + "item.antarchy.peach": "복숭아", + "item.antarchy.peach_pie": "복숭아 파이", + "item.antarchy.cornbread": "옥수수빵", + "item.antarchy.popcorn": "팝콘", + "item.antarchy.peach_sign": "복숭아나무 표지판", + "item.antarchy.peach_hanging_sign": "매다는 복숭아나무 표지판", + "item.antarchy.peach_boat": "복숭아나무 보트", + "item.antarchy.peach_chest_boat": "상자가 실린 복숭아나무 보트", + "item.antarchy.nadir_sign": "나디르나무 표지판", + "item.antarchy.nadir_hanging_sign": "매다는 나디르나무 표지판", + "item.antarchy.nadir_boat": "나디르나무 보트", + "item.antarchy.nadir_chest_boat": "상자가 실린 나디르나무 보트", + "entity.antarchy.nadir_boat": "나디르나무 보트", + "entity.antarchy.nadir_chest_boat": "상자가 실린 나디르나무 보트", + "item.antarchy.royal_sign": "로얄나무 표지판", + "item.antarchy.royal_hanging_sign": "매다는 로얄나무 표지판", + "item.antarchy.royal_boat": "로얄나무 보트", + "item.antarchy.royal_chest_boat": "상자가 실린 로얄나무 보트", + "entity.antarchy.royal_boat": "로얄나무 보트", + "entity.antarchy.royal_chest_boat": "상자가 실린 로얄나무 보트", + "item.antarchy.truffalo_sign": "트러팔로나무 표지판", + "item.antarchy.truffalo_hanging_sign": "매다는 트러팔로나무 표지판", + "item.antarchy.truffalo_boat": "트러팔로나무 보트", + "item.antarchy.truffalo_chest_boat": "상자가 실린 트러팔로나무 보트", + "entity.antarchy.truffalo_boat": "트러팔로나무 보트", + "entity.antarchy.truffalo_chest_boat": "상자가 실린 트러팔로나무 보트", + "item.antarchy.orange_milkweed": "주황색 박주가리", + "item.antarchy.pink_milkweed": "분홍색 박주가리", + "item.antarchy.glimmering_reed": "어슴푸레한 갈대", + "item.antarchy.camellia": "동백꽃", + "item.antarchy.spider_lily": "석산", + "item.antarchy.hushweed": "허쉬위드", + "item.antarchy.umbral_moss_block": "그림자 이끼 블록", + "item.antarchy.umbral_moss_carpet": "그림자 이끼 양탄자", + "item.antarchy.blush_moss_block": "홍조 이끼 블록", + "item.antarchy.blush_moss_carpet": "홍조 이끼 양탄자", + "item.antarchy.mud_pie": "진흙 파이", + "item.antarchy.duct_tape": "덕트 테이프", + "item.antarchy.duct_tape.tooltip": "설치 후 상호작용하여 도구를 수리합니다.", + "item.antarchy.rainbow_sugar": "무지개 설탕", + "item.antarchy.uranium_nugget": "우라늄 조각", + "item.antarchy.titanium_nugget": "티타늄 조각", + "item.antarchy.raw_uranium_scrap": "우라늄 원석 파편", + "item.antarchy.raw_titanium_scrap": "티타늄 원석 파편", + "item.antarchy.raw_uranium": "우라늄 원석", + "item.antarchy.raw_titanium": "티타늄 원석", + "item.antarchy.uranium_ingot": "우라늄 주괴", + "item.antarchy.titanium_ingot": "티타늄 주괴", + "item.antarchy.blood_crystal_shard": "혈수정 조각", + "item.antarchy.blood_crystal_apple": "혈수정 사과", + "item.antarchy.blood_crystal_katana": "혈수정 카타나", + "item.antarchy.blood_gods_blade": "혈신의 칼날", + "tooltip.antarchy.blood_gods_blade.bleeding": "공격 시 출혈을 부여합니다.", + "tooltip.antarchy.blood_gods_blade.blood_moon": "우클릭: 블러드 문 소환", + "effect.antarchy.bleeding": "출혈", + "effect.antarchy.blood_moon": "블러드 문", + "item.antarchy.blood_crystal_helmet": "혈수정 투구", + "item.antarchy.blood_crystal_chestplate": "혈수정 흉갑", + "item.antarchy.blood_crystal_leggings": "혈수정 레깅스", + "item.antarchy.blood_crystal_boots": "혈수정 부츠", + "item.antarchy.blood_crystal_armor.tooltip": "받는 피격을 1회 막아주고 산산조각 난 뒤 충전되는 혈유리 하트를 부여합니다.", + "item.antarchy.blood_crystal_boots.tooltip2": "중력이 뒤집혀 위로 떨어질 때 낙하 피해를 무효화합니다.", + "item.antarchy.blood_crystal_apple.tooltip": "혈유리 보호 효과를 부여하여, 지속시간 동안 충전되는 임시 혈유리 하트를 얻습니다.", + "tooltip.antarchy.blood_crystal_katana.launch": "공격 시 앞으로 돌진합니다.", + "tooltip.antarchy.blood_crystal_katana.dash": "조준하는 원거리 대상에게 다가가며, 완충 공격 시 짧은 무적 상태를 얻습니다.", + "tooltip.antarchy.blood_crystal_katana.trail": "지나간 자리에 핏빛 궤적을 남깁니다.", + "item.antarchy.eye_of_the_storm": "폭풍의 눈", + "tooltip.antarchy.eye_of_the_storm.updraft": "사용하여 상승 기류를 타고 하늘로 올라갑니다.", + "tooltip.antarchy.eye_of_the_storm.surge": "공격 시 적을 휩쓸고 끌고 가는 유도 토네이도를 날립니다.", + "item.antarchy.royal_guardian_helmet": "로얄 가디언 투구", + "item.antarchy.royal_guardian_chestplate": "로얄 가디언 흉갑", + "item.antarchy.royal_guardian_leggings": "로얄 가디언 레깅스", + "item.antarchy.royal_guardian_boots": "로얄 가디언 부츠s", + "item.antarchy.royal_guardian_sword": "로얄 가디언 검", + "item.antarchy.royal_guardian_shield": "로얄 가디언 방패", + "tooltip.antarchy.royal_guardian_sword.mode": "모드: %s", + "tooltip.antarchy.royal_guardian_sword.mode.none": "없음", + "tooltip.antarchy.royal_guardian_sword.mode.fire": "화염", + "tooltip.antarchy.royal_guardian_sword.mode.frost": "냉기", + "tooltip.antarchy.royal_guardian_sword.mode.storm": "폭풍", + "tooltip.antarchy.royal_guardian_sword.none": "완충 공격 시 원소 방출 없이 검의 기본 피해를 입힙니다.", + "tooltip.antarchy.royal_guardian_sword.fire": "완충 공격 시 로열 화염이 분출하여 대상과 주변 적을 불태웁니다.", + "tooltip.antarchy.royal_guardian_sword.frost": "완충 공격 시 대상을 빙결시키고 부채꼴 모양의 로열 얼음 가시를 형성합니다.", + "tooltip.antarchy.royal_guardian_sword.storm": "완충 공격 시 주변 적들 사이를 연쇄하는 로열 번개를 불러옵니다.", + "tooltip.antarchy.royal_guardian_sword.controls": "웅크리고 사용하여 모드를 전환합니다. 완충 공격 시 선택한 원소를 방출합니다 (재사용 대기시간 %s초).", + "message.antarchy.royal_guardian_sword.mode": "로얄 가디언 모드: %s", + "item.antarchy.royal_assailant_helmet": "로얄 어설런트 투구", + "item.antarchy.royal_assailant_chestplate": "로얄 어설런트 흉갑", + "item.antarchy.royal_assailant_leggings": "로얄 어설런트 레깅스", + "item.antarchy.royal_assailant_boots": "로얄 어설런트 부츠", + "item.antarchy.royal_assailant_battleaxe": "로얄 어설런트 배틀액스", + "item.antarchy.royal_assailant_staff": "로얄 어설런트 지팡이", + "tooltip.antarchy.royal_assailant_staff": "30초 동안 아군 만티코어 4마리를 소환하는 균열쌍을 엽니다.", + "tooltip.antarchy.royal_assailant_battleaxe.black_hole": "사용하여 블랙홀을 생성합니다.", + "tooltip.antarchy.royal_assailant_battleaxe.dilation": "공격 시 시간 팽창을 부여합니다.", + "tooltip.antarchy.royal_guardian_shield.command": "웅크리고 사용하여 주변 몹에게 전투 명령을 내리며, 몹의 공격력, 이동 속도, 방어력을 강화합니다.", + "tooltip.antarchy.royal_guardian_helmet.judgment": "심판의 표식: 표식이 남은 대상에게 %s%% 의 추가 피해", + "tooltip.antarchy.royal_guardian_chestplate.judgment": "심판의 표식: 표식이 남은 대상에게 %s%% 의 추가 피해", + "tooltip.antarchy.royal_guardian_chestplate.boundary": "로얄 결계 열쇠: 날아오는 적의 투사체를 멈추고 아군에게 힘 효과를 부여합니다.", + "tooltip.antarchy.royal_guardian_leggings.judgment": "심판의 표식: 표식이 남은 대상에게 %s%% 의 추가 피해", + "tooltip.antarchy.royal_guardian_boots.judgment": "심판의 표식: 표식이 남은 대상에게 %s%% 의 추가 피해", + "tooltip.antarchy.royal_assailant_chestplate.invert": "반전 키를 눌러 역중력 상태를 켜거나 끕니다.", + "tooltip.antarchy.royal_assailant_boots.fall": "위로 떨어질 때 낙하 피해를 무효화합니다.", + "item.antarchy.mantis_claw": "맨티스 발톱", + "tooltip.antarchy.mantis_claw.wall_cling": "양손에 들고 벽에 매달려 위로 점프할 수 있습니다.", + "item.antarchy.king_scale": "더 킹의 비늘", + "item.antarchy.queen_scale": "더 퀸의 비늘", + "item.antarchy.temporal_tuner": "시간 조율기", + "tooltip.antarchy.temporal_tuner.description": "개인 시간 팽창을 조절합니다.", + "tooltip.antarchy.temporal_tuner.speed": "현재 속도: %s%%", + "tooltip.antarchy.temporal_tuner.controls": "Shift + 스크롤: 속도 %s%% ~ %s%%", + "tooltip.antarchy.temporal_tuner.availability": "퀵슬롯이나 보조 손에서 벗어나면 초기화됩니다.", + "item.antarchy.jerry_nucleus": "제리의 핵", + "tooltip.antarchy.jerry_nucleus.hatch": "손에 든 채로 벌레 알이나 거북 알과 상호작용하여 즉시 부화시킵니다.", + "key.antarchy.mount_special": "탈것: 특수 / 돌진", + "key.antarchy.royal_boundary": "로얄 결계", + "message.antarchy.royal_boundary.activated": "로얄 결계가 활성화되었습니다.", + "message.antarchy.royal_boundary.recharging": "로얄 결계가 충전 중입니다.", + "key.antarchy.mount_flight_toggle": "탈것: 비행 전환", + "item.antarchy.springbug_leg": "스프링버그 다리", + "item.antarchy.springy_boots": "스프링 부츠", + "tooltip.antarchy.springy_boots": "웅크려 충전한 뒤 점프하여 높이 도약합니다.", + "item.antarchy.brutalfly_wing": "브루탈플라이 날개", + "item.antarchy.brutalfly_elytra": "브루탈플라이 겉날개", + "item.antarchy.manticore_wing": "만티코어 날개", + "item.antarchy.manticore_wings": "만티코어 날개", + "tooltip.antarchy.manticore_wings": "비행 중 적이 아닌 생명체와 충돌하여 큰 피해를 줍니다.", + "item.antarchy.broodfruit_cobbler": "브루드프루트 코블러", + "tooltip.antarchy.brutalfly_elytra.flap": "비행 중 %s 키를 꾹 눌러 날개를 퍼덕입니다.", + "item.antarchy.cornea_ear": "각막 귀", + "item.antarchy.corn": "옥수수", + "item.antarchy.corn_seeds": "옥수수 씨앗", + "item.antarchy.raw_corndog": "익히지 않은 핫도그", + "item.antarchy.cooked_corndog": "익힌 핫도그", + "item.antarchy.high_fructose_corn_syrup": "고과당 옥수수 시럽", + "jei.antarchy.americanize": "미국화", + "item.antarchy.american_name": "미국식 %s", + "item.antarchy.root_beer": "루트 비어", + "item.antarchy.primordial_scute": "원시 등갑", + "item.antarchy.flytrap_goo": "파리잡이 점액", + "item.antarchy.flytrap_goo_block": "파리잡이 점액 블록", + "tooltip.antarchy.flytrap_goo_block": "고속으로 닿으면 튀어 오르고, 그렇지 않으면 가라앉습니다.", + "item.antarchy.cloud_bucket": "구름 양동이", + "tooltip.antarchy.cloud_bucket.midair": "공중에도 설치할 수 있습니다.", + "item.antarchy.lumen_bucket": "루멘 양동이", + "item.antarchy.scorpion_whip": "임페로르 전갈 채찍", + "tooltip.antarchy.scorpion_whip.lash": "멀리 있는 사냥감을 후려쳐 독성 밧줄을 박아 넣습니다.", + "tooltip.antarchy.scorpion_whip.reel": "사용하여 밧줄에 묶인 사냥감을 감아들입니다.", + "tooltip.antarchy.scorpion_whip.snap": "밧줄에 묶인 적을 공격해 침을 끊어냅니다.", + "item.antarchy.fallen_king_crown": "몰락한 더 킹의 왕관", + "tooltip.antarchy.fallen_king_crown.hero": "적대적 몹을 처치하면 마을의 영웅 효과를 부여합니다.", + "item.antarchy.vortex_charge": "소용돌이 충전재", + "entity.antarchy.upward_falling_block": "하늘로 떨어지는 모래", + "entity.antarchy.vortex": "소용돌이", + "entity.antarchy.wind_vortex": "바람 소용돌이", + "entity.antarchy.dimensional_tear": "차원의 균열", + "item.antarchy.vortex_spawn_egg": "소용돌이 생성 알", + "item.antarchy.ultimate_helmet": "얼티밋 투구", + "item.antarchy.ultimate_chestplate": "얼티밋 흉갑", + "item.antarchy.ultimate_leggings": "얼티밋 레깅스", + "item.antarchy.ultimate_boots": "얼티밋 부츠", + "item.antarchy.ultimate_sword": "얼티밋 검", + "item.antarchy.ultimate_pickaxe": "얼티밋 곡괭이", + "item.antarchy.ultimate_axe": "얼티밋 도끼", + "item.antarchy.ultimate_shovel": "얼티밋 삽", + "item.antarchy.ultimate_hoe": "얼티밋 괭이", + "item.antarchy.ultimate_bow": "얼티밋 활", + "item.antarchy.ultimate_crossbow": "얼티밋 쇠뇌", + "item.antarchy.ultimate_crossbow.capacity": "한번에 최대 16발 장전", + "item.antarchy.ultimate_crossbow.arrows_remaining": "%1$s %2$s 장전됨", + "item.antarchy.ultimate_mace": "얼티밋 메이스", + "item.antarchy.moggles": "고글", + "itemGroup.antarchy.antarchy": "앤타키", + "item.antarchy.bile_bucket": "담즙 양동이", + "item.antarchy.ichor_bucket": "이코르 양동이", + "item.antarchy.antiwater_bucket": "역수 양동이", + "item.antarchy.reverie_bottle": "레버리의 병", + "item.antarchy.squidzooka": "오징어주카", + "item.antarchy.rpo_launcher": "R.P.O. 런처", + "item.antarchy.shrink_ray": "축소 광선총", + "item.antarchy.growth_ray": "거대화 광선총", + "tooltip.antarchy.shrink_ray": "대상을 영구적으로 축소합니다. 꾹 눌러 충전하세요.", + "tooltip.antarchy.growth_ray": "대상을 영구적으로 거대화합니다. 꾹 눌러 충전하세요.", + "tooltip.antarchy.size_ray_milk_reset": "우유를 마시면 이 효과가 초기화됩니다.", + "tooltip.antarchy.reverie_bottle.capture": "유리병을 들고 레버리을 우클릭하여 담습니다.", + "tooltip.antarchy.reverie_bottle.release": "우클릭하여 레버리을 풀어줍니다.", + "item.antarchy.gravity_gun": "그래비티 건", + "item.antarchy.portal_gun": "포탈 건", + "item.antarchy.portal_gun_atlas": "아틀라스 포탈 건", + "item.antarchy.portal_gun_p_body": "피바디 포탈 건", + "item.antarchy.portal_gun_craisin": "크레이신 포탈 건", + "item.antarchy.portal_gun_laynce": "라인스 포탈 건", + "item.antarchy.diamond_minecart": "다이아몬드 광산 수레", + "item.antarchy.cogwheel_pet": "톱니바퀴 펫", + "item.antarchy.fire_dragon_pet": "파이어 드래곤 펫", + "item.antarchy.ice_dragon_pet": "아이스 드래곤 펫", + "item.antarchy.lightning_dragon_pet": "라이트닝 드래곤 펫", + "item.antarchy.gorgon_pet": "고르곤 펫", + "item.antarchy.apple_cow_spawn_egg": "사과 소 생성 알", + "item.antarchy.red_ant_spawn_egg": "붉은 개미 생성 알", + "item.antarchy.brown_ant_spawn_egg": "갈색 개미 생성 알", + "item.antarchy.rainbow_ant_spawn_egg": "무지개 개미 생성 알", + "item.antarchy.golden_apple_cow_spawn_egg": "황금 사과 소 생성 알", + "item.antarchy.enchanted_golden_apple_cow_spawn_egg": "마법이 부여된 황금 사과 소 생성 알", + "item.antarchy.dr_trayaurus_spawn_egg": "트레이어러스 박사 생성 알", + "item.antarchy.easter_bunny_spawn_egg": "이스터 토끼 생성 알", + "item.antarchy.glimmer_spawn_egg": "글리머 생성 알", + "item.antarchy.ouranwood_deer_spawn_egg": "오우란나무 사슴 생성 알", + "item.antarchy.spirit_apple": "영혼 사과", + "tooltip.antarchy.spirit_apple": "글리머를 길들입니다.", + "tooltip.antarchy.spirit_apple.eaten": "섭취 시 글리머화를 부여합니다.", + "item.antarchy.elka_spawn_egg": "엘카 생성 알", + "item.antarchy.glimmer_bottle": "글리머 병", + "item.antarchy.glimmer_bottle.contains": "포함됨: %s", + "glimmer_variant.antarchy.apple_cow": "사과 소", + "glimmer_variant.antarchy.ouranwood_deer": "오우란나무 사슴", + "glimmer_variant.antarchy.frog": "개구리", + "glimmer_variant.antarchy.ant": "개미", + "glimmer_variant.antarchy.elka": "엘카", + "entity.antarchy.glimmer.set_sit": "글리머 상태: 앉음", + "entity.antarchy.glimmer.set_follow": "글리머 상태: 따라옴", + "entity.antarchy.glimmer.set_wander": "글리머 상태: 배회함", + "entity.antarchy.glimmer.ability.ant": "개미가 %s 을(를) 상대로 당신의 사기를 북돋웁니다!", + "entity.antarchy.glimmer.ability.apple_cow": "사과 소가 울음소리를 내며 영양을 공급합니다!", + "entity.antarchy.glimmer.ability.elka": "엘카가 울부짖으며 결계를 산산조각 냅니다!", + "entity.antarchy.glimmer.ability.deer": "오우란나무 사슴이 적을 향해 돌진합니다!", + "entity.antarchy.glimmer.ability.frog": "개구리가 %s 을(를) 삼켰습니다!", + "item.antarchy.glimmer_bottle.passive.apple_cow": "패시브: 배고픔 감소 속도 25% 감소", + "item.antarchy.glimmer_bottle.ability.apple_cow": "능력: 식량이 부족할 때 울음소리를 내어 순간적인 포만감과 재생 효과를 부여합니다.", + "item.antarchy.glimmer_bottle.passive.ouranwood_deer": "패시브: 속도 증가 I", + "item.antarchy.glimmer_bottle.ability.ouranwood_deer": "능력: 적대적 몹을 향해 질주 시 돌진하여 몹들을 멀리 날려버립니다.", + "item.antarchy.glimmer_bottle.passive.frog": "패시브: 점프 강화 I", + "item.antarchy.glimmer_bottle.ability.frog": "능력: 주변의 적대적 몹을 삼켜 일정 시간 동안 더 크고 강해집니다.", + "item.antarchy.glimmer_bottle.passive.ant": "패시브: 공격 사거리 약간 증가", + "item.antarchy.glimmer_bottle.ability.ant": "능력: 거대한 적을 공격 성공 시 순간적으로 힘 II 효과를 얻습니다.", + "item.antarchy.glimmer_bottle.passive.elka": "패시브: 혈유리 보호 II", + "item.antarchy.glimmer_bottle.ability.elka": "능력: 보호 하트 중 하나가 깨질 때 울부짖으며 충격파로 산산조각 납니다.", + "advancements.antarchy.spirant_animal.title": "개미 같은 동반자", + "advancements.antarchy.spirant_animal.description": "개미 글리머를 길들이세요.", + "advancements.antarchy.hoppy_together.title": "폴짝폴짝 함께", + "advancements.antarchy.hoppy_together.description": "개구리 글리머를 길들이세요.", + "advancements.antarchy.deerly_beloved.title": "사슴스러운 존재", + "advancements.antarchy.deerly_beloved.description": "오우란나무 사슴 글리머를 길들이세요.", + "advancements.antarchy.elkcellent_choice.title": "탁월한 선택", + "advancements.antarchy.elkcellent_choice.description": "엘카 글리머를 길들이세요.", + "advancements.antarchy.apple_of_my_eye.title": "내 눈의 사과", + "advancements.antarchy.apple_of_my_eye.description": "사과 소 글리머를 길들이세요.", + "item.antarchy.dorrie_spawn_egg": "도리 생성 알", + "item.antarchy.flying_squirrel_spawn_egg": "날다람쥐 생성 알", + "item.antarchy.caterpillar_spawn_egg": "애벌레 생성 알", + "item.antarchy.butterfly_spawn_egg": "나비 생성 알", + "item.antarchy.brutalfly_spawn_egg": "브루탈플라이 생성 알", + "item.antarchy.stratoshark_spawn_egg": "스트라토샤크 생성 알", + "item.antarchy.kraken_spawn_egg": "크라켄 생성 알 ( 아, 안 돼. 소환하지 마. )", + "item.antarchy.missile_squid_spawn_egg": "미사일 오징어 생성 알", + "item.antarchy.octopus_bomb_spawn_egg": "문어 폭탄 생성 알", + "item.antarchy.nightmare_spawn_egg": "나이트메어 생성 알", + "item.antarchy.toreterror_spawn_egg": "토레테러 생성 알", + "item.antarchy.water_cannon": "물대포", + "item.antarchy.primordial_helmet": "프리모디얼 투구", + "item.antarchy.primordial_chestplate": "프리모디얼 흉감", + "item.antarchy.primordial_leggings": "프리모디얼 레깅스", + "item.antarchy.primordial_boots": "프리모디얼 부츠", + "item.antarchy.bed_bug_spawn_egg": "빈대 생성 알", + "item.antarchy.moleworm_spawn_egg": "몰웜 생성 알", + "item.antarchy.worm_spawn_egg": "웜 생성 알", + "item.antarchy.molevore_spawn_egg": "몰레보어 생성 알", + "item.antarchy.reverie_spawn_egg": "레버리 생성 알", + "item.antarchy.mantis_spawn_egg": "맨티스 생성 알", + "item.antarchy.alpha_mantis_spawn_egg": "알파 맨티스 생성 알", + "biome.antarchy.moleworm_caves": "몰웜 동굴", + "biome.antarchy.elythia_meadow": "엘리시아 초원", + "biome.antarchy.truffalo_forest": "트러팔로나무 숲", + "biome.antarchy.elythia_ocean": "엘리시아 바다", + "biome.antarchy.butterfly_fields": "나비 들판", + "biome.antarchy.ouranwood_forest": "오우란나무 숲", + "biome.antarchy.glimmering_pools": "어슴푸레한 웅덩이", + "biome.antarchy.peach_forest": "복숭아나무 숲", + "biome.antarchy.fungal_ouranwood_forest": "버섯 오우란나무 숲", + "biome.antarchy.glowcap_caves": "발광버섯 동굴", + "message.antarchy.brown_ant_activated": "갈색 개미가 목적지를 열 준비가 되었습니다.", + "message.antarchy.brown_ant_needs_reagent": "이 갈색 개미는 목적지를 열기 위해 시약이 필요합니다.", + "message.antarchy.rainbow_ant_activated": "무지개 개미가 새로운 인피니티 목적지를 향해 웅웅거립니다.", + "message.antarchy.rainbow_ant_activated_inherited": "무지개 개미가 계승된 인피니티 목적지를 향해 웅웅거립니다.", + "message.antarchy.rainbow_ant_activated_inherited_existing": "무지개 개미가 계승된 인피니티 목적지에 다시 연결됩니다.", + "message.antarchy.rainbow_ant_failed_dimension_create": "차원 생성에 실패했습니다. 인피니티 설정에 문제가 있을 수 있습니다. 재시작/재접속 후 다시 시도하세요.", + "message.antarchy.rainbow_ant_infinity_missing": "무지개 개미 차원이 작동하려면 Infinity가 설치되어 있어야 합니다.", + "message.antarchy.rainbow_ant_needs_reagent": "이 무지개 개미는 차원을 열기 위해 시약이 필요합니다.", + "message.antarchy.teleport_arrival_failed": "안전한 도착 지점을 찾지 못했습니다. 텔레포트가 취소되었습니다.", + "message.antarchy.red_ant_activated": "붉은 개미가 목적지를 열 준비가 되었습니다.", + "message.antarchy.red_ant_needs_reagent": "이 붉은 개미는 목적지를 열기 위해 시약이 필요합니다.", + "message.antarchy.termite_activated": "흰개미가 목적지를 열 준비가 되었습니다.", + "message.antarchy.termite_needs_reagent": "이 흰개미는 목적지를 열기 위해 시약이 필요합니다.", + "death.attack.spit_bug_disrespect": "%1$s이(가) 침벌레에게 모욕을 당했습니다.", + "death.attack.springbug_jump": "%1$s이(가) 스프링버그에게 기습당했습니다.", + "death.attack.hercules_beetle_obliteration": "%1$s이(가) 헤라클레스 비틀에게 흔적도 없이 말살당했습니다.", + "message.antarchy.big_bertha.mode": "빅 베르타 모드: %s", + "message.antarchy.big_bertha.mode.none": "없음", + "message.antarchy.big_bertha.mode.basilisk": "바실리스크", + "message.antarchy.big_bertha.mode.lucid": "루시드", + "message.antarchy.big_bertha.mode.nightmare": "나이트메어", + "message.antarchy.big_bertha.mode.kraken": "크라켄", + "message.antarchy.big_bertha.mode.hercules": "헤라클레스", + "message.antarchy.big_bertha.mode.molevore": "몰레보어", + "message.antarchy.big_bertha.mode.toreterror": "토레테러", + "message.antarchy.ultimate_tool.mode_3x3": "3x3 채굴 모드로 전환됨", + "message.antarchy.ultimate_tool.mode_default": "기본 채굴 모드로 전환됨", + "advancements.antarchy.hey_listen.title": "야, 들어봐!", + "advancements.antarchy.hey_listen.description": "레버리가 당신과 함께합니다.", + "advancements.antarchy.very_hungry_caterpillar.title": "배고픈 애벌레", + "advancements.antarchy.very_hungry_caterpillar.description": "애벌레가 자라도록 도우세요.", + "effect.antarchy.dread": "공포", + "effect.antarchy.dread.description": "시각 및 청각 환각을 일으킵니다.", + "effect.antarchy.paralyzed": "마비", + "effect.antarchy.paralyzed.description": "대상의 이동을 막습니다.", + "effect.antarchy.commanded": "복종", + "effect.antarchy.commanded.description": "자신을 명령한 플레이어를 위해 싸웁니다.", + "effect.antarchy.stinky": "악취", + "effect.antarchy.stinky.description": "수동적/중립적 몹을 쫓아내고 절지동물을 유인합니다.", + "effect.antarchy.gooped": "점액 범벅", + "effect.antarchy.gooped.description": "이동 속도와 공격 속도를 감소시킵니다.", + "effect.antarchy.shrinking": "축소", + "effect.antarchy.growth": "거대화", + "effect.antarchy.bloodglass_ward": "혈유리 보호", + "effect.antarchy.bloodglass_ward.description": "깨지면서 피해를 완벽히 흡수하는 하트를 부여합니다. 시간이 지나면 회복됩니다.", + "effect.antarchy.glimmering": "글리머화", + "effect.antarchy.glimmering.description": "영혼처럼 개체를 통과하고 피해를 받지 않습니다. 발걸음이 가벼워지고 더 높이 점프합니다.", + "death.attack.flytrap_mauling": "%1$s이(가) 식물에게 물어뜯겨 사망했습니다.", + "death.attack.flytrap_mauling.player": "%1$s이(가) 식물에게 물어뜯겨 사망했습니다.", + "death.attack.flytrap_swallow": "%1$s이(가) 파리잡이에게 삼켜졌습니다.", + "death.attack.flytrap_swallow.player": "%1$s이(가) 파리잡이에게 삼켜졌습니다.", + "potion.antarchy.haste": "성급함의 포션", + "potion.antarchy.strong_haste": "강한 성급함의 포션", + "tooltip.antarchy.big_bertha.mode": "모드: %s", + "tooltip.antarchy.big_bertha.toggle_mode": "Shift + 사용: 보스 모드를 전환합니다.", + "tooltip.antarchy.big_bertha.mode.none": "공격 시 소량의 추가 피해를 입힙니다.", + "tooltip.antarchy.big_bertha.mode.basilisk": "사용 시 대상을 마비시킵니다. 공격 시 독과 감속을 부여합니다.", + "tooltip.antarchy.big_bertha.mode.lucid": "공격 시 수초 동안 대상을 반전시킵니다. 자신이 반전된 동안 더 큰 피해를 입힙니다.", + "tooltip.antarchy.big_bertha.mode.nightmare": "공격 시 수초 동안 대상을 반전시킵니다. 자신이 반전된 동안 더 큰 피해를 입힙니다.", + "tooltip.antarchy.big_bertha.mode.kraken": "공격 시 추가 피해를 입힙니다. 플레이어는 공포 효과를 받고 공격 시 나약함을 부여합니다.", + "tooltip.antarchy.big_bertha.mode.hercules": "공격 시 대상을 내리치고 벼락을 내립니다.", + "tooltip.antarchy.big_bertha.mode.molevore": "공격 시 추가 피해를 입히고 대상을 공중 높이 띄웁니다.", + "tooltip.antarchy.big_bertha.mode.toreterror": "사용하여 앞으로 회전하며 몰레보어 블록을 뚫고 나아갑니다.", + "tooltip.antarchy.ultimate_tools_3x3": "Shift + 사용: 3x3 채굴을 켜거나 끕니다.", + "tooltip.antarchy.moggles.reveal": "야간 시야를 부여하고 근처 동굴을 가리킵니다.", + "tooltip.antarchy.moggles.underground": "하늘이 가려진 곳에서만 작동합니다.", + "tooltip.antarchy.cornea_ear.vision": "%s초 동안 야간 시야를 부여합니다.", + "tooltip.antarchy.mob_coming_soon": "곧 출시될 몹입니다!", + "tooltip.antarchy.gravity_gun.primary": "공격: 주변 엔티티를 날려버리거나 잡고 있는 대상을 던집니다.", + "tooltip.antarchy.gravity_gun.secondary": "사용: 엔티티나 유효한 블록을 끌어당깁니다.", + "tooltip.antarchy.gravity_gun.scroll": "Ctrl을 누른 채 스크롤: 잡고 있는 대상을 가깝게 또는 멀게 이동시킵니다.", + "tooltip.antarchy.gravity_gun.blacklist": "블랙리스트에 등록된 블록이나 엔티티에는 영향을 주지 않습니다.", + "tooltip.antarchy.portal_gun.primary": "공격: %s 포탈을 발사합니다.", + "tooltip.antarchy.portal_gun.secondary": "사용: %s 포탈을 발사합니다.", + "commands.antarchy.portalgun.clear.all": "%s개의 포탈 건 포탈을 제거했습니다.", + "commands.antarchy.portalgun.clear.owners": "%2$s 플레이어의 포탈 건 포탈 %1$s 개를 제거했습니다.", + "tooltip.antarchy.portal_gun.color.blue": "파란색", + "tooltip.antarchy.portal_gun.color.orange": "주황색", + "tooltip.antarchy.portal_gun.color.purple": "보라색", + "tooltip.antarchy.portal_gun.color.yellow": "노란색", + "tooltip.antarchy.portal_gun.color.red": "빨간색", + "tooltip.antarchy.portal_gun.color.gold": "금색", + "tooltip.antarchy.portal_gun.color.green": "초록색", + "tooltip.antarchy.portal_gun.reset": "웅크리고 사용: 활성화된 포탈을 소멸시킵니다.", + "tooltip.antarchy.antimetal_inversion": "바로 아래에 있는 엔티티를 반전시킵니다.", + "tooltip.antarchy.diamond_minecart.forward": "추후 구현될 예정입니다.", + "tooltip.antarchy.diamond_minecart.rails": " ", + "tooltip.antarchy.rainbow_sugar": "무지개 개미 차원을 활성화합니다. 차원 내에서 먹으면 집으로 돌아갑니다.", + "advancements.antarchy.visit_elythia.title": "개미 타고 능선 넘어", + "advancements.antarchy.visit_elythia.description": "갈색 개미를 사용해 엘리시아에 도달하세요.", + "advancements.antarchy.visit_thoraxis.title": "개미도 건드리면 꿈틀한다", + "advancements.antarchy.visit_thoraxis.description": "붉은 개미를 사용해 소랙시스에 도달하세요.", + "advancements.antarchy.visit_cavaryn.title": "여기가 개미굴인가요?", + "advancements.antarchy.visit_cavaryn.description": "감염된 차원인 카바린에 진입하세요.", + "advancements.antarchy.fallen_kingdom_castle.title": "내가 한때 세상을 지배했었지...", + "advancements.antarchy.fallen_kingdom_castle.description": "몰락한 왕국의 성을 발견하세요.", + "advancements.antarchy.a_lovely_world.title": "어디서 많이 본 집인데?", + "advancements.antarchy.a_lovely_world.description": "엘리시아에서 이상하리만치 익숙한 집을 발견했습니다.", + "advancements.antarchy.cops_n_robbers.title": "경찰과 도둑!", + "advancements.antarchy.cops_n_robbers.description": "추억의 구조물일 뿐이며, Sky와는 관계가 없습니다 :)", + "advancements.antarchy.fallen_king_crown.title": "내가 명하면 청크가 불러와졌지..", + "advancements.antarchy.fallen_king_crown.description": "몰락한 더 킹의 왕관을 흭득하세요.", + "advancements.antarchy.long_live_the_prince.title": "더 프린스 만세!", + "advancements.antarchy.long_live_the_prince.description": "더 프린스를 부화시키고 길들이세요.", + "advancements.antarchy.long_live_the_princess.title": "더 프린세스 만세!", + "advancements.antarchy.long_live_the_princess.description": "더 프린세를 부화시키고 길들이세요.", + "advancements.antarchy.the_lab.title": "하이 에브리원, 댄이에요!", + "advancements.antarchy.the_lab.description": "트레이어러스 박사의 연구소를 발견하세요.", + "advancements.antarchy.sweater_dreams.title": "좋은 꿈 꾸시길", + "advancements.antarchy.sweater_dreams.description": "나이트메어를 처치하세요.", + "advancements.antarchy.stone_cold.title": "차가운 바위처럼", + "advancements.antarchy.stone_cold.description": "바실리스크를 처치하세요.", + "advancements.antarchy.moley_poley.title": "몰리의 구멍", + "advancements.antarchy.moley_poley.description": "몰레보어를 처치하세요.", + "advancements.antarchy.lucid_dreams.title": "루시드 드림", + "advancements.antarchy.lucid_dreams.description": "루시드를 처치하세요.", + "advancements.antarchy.davy_jones_locker.title": "데이브 존스의 보물상자", + "advancements.antarchy.davy_jones_locker.description": "크라켄을 처치하세요", + "advancements.antarchy.shark_weak.title": "상어가 날 수 있을 때", + "advancements.antarchy.shark_weak.description": "스트라토샤크를 처치하세요.", + "advancements.antarchy.dont_let_the_bed_bugs_bite.title": "빈대가 물지 않게 조심해", + "advancements.antarchy.dont_let_the_bed_bugs_bite.description": "빈대를 처치하세요.", + "advancements.antarchy.soups_up.title": "따끈한 국물 대령이오", + "advancements.antarchy.soups_up.description": "스트라토샤크 지느러미 수프를 드세요.", + "advancements.antarchy.in_the_upside_down.title": "뒤집힌 세계", + "advancements.antarchy.in_the_upside_down.description": "최근 반전 효과에 처음으로 걸려보세요.", + "advancements.antarchy.whoever_smelt_it_dealt_it.title": "방구 뀐 놈이 성낸다", + "advancements.antarchy.whoever_smelt_it_dealt_it.description": "악취 효과에 처음으로 걸려보세요.", + "advancements.antarchy.ultimate_armor.title": "궁극의 수호자", + "advancements.antarchy.ultimate_armor.description": "얼티밋 방어구 세트를 모두 모으세요.", + "advancements.antarchy.ultimate_bow.title": "보헤미안 랩소디", + "advancements.antarchy.ultimate_bow.description": "얼티밋 활을 획득하세요.", + "advancements.antarchy.sizzling_dedication.title": "지글지글 타오르는 정성", + "advancements.antarchy.sizzling_dedication.description": "대형 프라이팬을 획득하세요.", + "advancements.antarchy.brutalfly.title": "나비처럼 날아서 벌처럼 쏘다", + "advancements.antarchy.brutalfly.description": "브루탈플라이 겉날개를 획득하세요.", + "advancements.antarchy.royal_assailant_staff.title": "날아라 내 귀요미들!", + "advancements.antarchy.royal_assailant_staff.description": "로얄 어세일런트 지팡이를 획득하세요.", + "advancements.antarchy.now_watch_me_whip.title": "이제 내 휩 댄스를 봐", + "advancements.antarchy.now_watch_me_whip.description": "이제 내 네네 댄스를 봐", + "advancements.antarchy.kill_molevore.title": "몰리의 구멍", + "advancements.antarchy.kill_molevore.description": "몰레보어를 처치하세요.", + "advancements.antarchy.water_cannon_craft.title": "물맛 좀 볼래?", + "advancements.antarchy.water_cannon_craft.description": "물대포를 획득하세요.", + "advancements.antarchy.kill_toreterror.title": "에임이 그게 뭐니, 토레테러!", + "advancements.antarchy.kill_toreterror.description": "토레테러를 처치하세요.", + "advancements.antarchy.down_with_the_king.title": "더 킹의 몰락", + "advancements.antarchy.down_with_the_king.description": "더 킹을 처치하세요.", + "advancements.antarchy.down_with_the_queen.title": "더 퀸의 몰락", + "advancements.antarchy.down_with_the_queen.description": "더 퀸을 처치하세요.", + "advancements.antarchy.challenge_games.title": "서바이벌 게임!", + "advancements.antarchy.challenge_games.description": "폐허가 된 아레나에 진입하세요.", + "advancements.antarchy.bugged_out.title": "벌레 잡는 사냥꾼", + "advancements.antarchy.bugged_out.description": "알파 맨티스를 처치하세요.", + "death.attack.bed_bug_bite": "%1$s이(가) 빈대에게 물려 뜯겼습니다.", + "death.attack.bed_bug_bite.player": "%1$s이(가) %2$s와(과) 싸우던 중 빈대에게 물려 뜯겼습니다.", + "death.attack.moon_vacuum": "%1$s이(가) 우주의 진공 속으로 빨려 들어갔습니다.", + "death.attack.moon_vacuum.player": "%1$s이(g) %2$s와(과) 싸우던 중 우주의 진공 속으로 빨려 들어갔습니다.", + "message.antarchy.dread_too_scared_to_sleep": "너무 무서워서 잠에 들 수 없습니다.", + "death.attack.kraken_mauling": "%1$s이(가) 크라켄에게 심해 속으로 끌려갔습니다.", + "death.attack.kraken_mauling.player": "%1$s이(가) %2$s와(과) 싸우던 중 크라켄에게 심해 속으로 끌려갔습니다.", + "death.attack.kraken_lightning": "%1$s이(가) 크라켄의 폭풍우 벼락에 맞아 번갯불이 되었습니다.", + "death.attack.kraken_lightning.player": "%1$s이(가) %2$s와(과) 싸우던 중 크라켄의 폭풍우 벼락에 맞았습니다.", + "death.attack.rpo_launcher_blast": "%1$s이(가) R.P.O.에게 기습 RKO를 맞고 뻗었습니다.", + "death.attack.rpo_launcher_blast.player": "%1$s이(가) %2$s와(과) 싸우던 중 R.P.O.에게 기습 RKO를 맞았습니다.", + "death.attack.nightmare_mauling": "%1$s이(가) 나이트메어에게 집어삼켜졌습니다.", + "death.attack.nightmare_mauling.player": "%1$s이(가) %2$s와(과) 싸우던 중 나이트메어에게 집어삼켜졌습니다.", + "death.attack.basilisk_bite": "%1$s이(가) 바실리스크에게 한입거리로 통째로 꿀꺽당했습니다.", + "death.attack.basilisk_bite.player": "%1$s이(가) %2$s와(과) 싸우던 중 바실리스크에게 꿀꺽당했습니다.", + "death.attack.emperor_scorpion_sting": "%1$s이(가) 엠퍼러 스콜피온의 독침에 찔렸습니다.", + "death.attack.emperor_scorpion_sting.player": "%1$s이(가) %2$s와(과) 싸우던 중 엠퍼러 스콜피온의 독침에 찔렸습니다.", + "death.attack.cornea_stalk_prick": "%1$s이(가) 각막 줄기에 찔려 사망했습니다.", + "death.attack.toreterror_spin": "%1$s이(가) 토레테러의 팽이 회전 공격에 휠체어 신세가 되었습니다.", + "death.attack.toreterror_spin.player": "%1$s이(가) %2$s와(과) 싸우던 중 토레테러의 팽이 공격에 찢겼습니다.", + "death.attack.toreterror_jump": "%1$s이(가) 토레테러에게 바닥까지 짓눌려 찌그러졌습니다.", + "death.attack.toreterror_jump.player": "%1$s이(가) %2$s와(과) 싸우던 중 토레테러에게 짓눌렸습니다.", + "death.attack.water_soaked": "%1$s이(가) %2$s의 물폭탄에 푹 젖어 drowned 당했습니다.", + "death.attack.water_soaked.player": "%1$s이(가) %2$s의 물폭탄에 푹 젖어 drowned 당했습니다.", + "entity.antarchy.lucid": "루시드", + "item.antarchy.lucid_spawn_egg": "루시드 생성 알", + "item.antarchy.lucid_eye": "루시드의 눈", + "entity.antarchy.scorpion": "스콜피온", + "item.antarchy.scorpion_spawn_egg": "스콜피온 생성 알", + "entity.antarchy.basilisk": "바실리스크", + "item.antarchy.basilisk_spawn_egg": "바실리스크 생성 알", + "entity.antarchy.emperor_scorpion": "엠퍼러 스콜피온", + "item.antarchy.emperor_scorpion_spawn_egg": "엠퍼러 스콜피온 생성 알", + "item.antarchy.emperor_scorpion_stinger": "엠퍼러 스콜피온 독침", + "item.antarchy.lucid_pearl": "루시드 진주", + "tooltip.antarchy.lucid_pearl": "반전 중력을 가진 투사체를 던집니다.", + "tooltip.antarchy.lucid_pearl.detail": "낙하 지점으로 텔레포트하고 반전 효과를 부여합니다.", + "subtitles.antarchy.squidzooka_fire": "오징어주카 발사됨", + "subtitles.antarchy.undertrial_detect_player": "언더트라이얼 생성기가 플레이어를 감지함", + "subtitles.antarchy.size_ray_charge": "크기 조절 광선 충전됨", + "subtitles.antarchy.size_ray_fire": "크기 조절 광선 발사됨", + "subtitles.antarchy.ant_ambient": "개미가 지저귐", + "subtitles.antarchy.ant_idle": "개미가 서성거림", + "subtitles.antarchy.ant_hurt": "개미가 다침", + "subtitles.antarchy.ant_bite": "개미가 물음", + "subtitles.antarchy.ant_gather": "개미가 모임", + "subtitles.antarchy.ant_nest": "개미집이 바스락거림", + "subtitles.antarchy.stratoshark_bite": "스트라토샤크가 물음", + "subtitles.antarchy.stratoshark_idle": "스트라토샤크가 서성거림", + "subtitles.antarchy.stratoshark_hurt": "스트라토샤크가 다침", + "subtitles.antarchy.stratoshark_death": "스트라토샤크가 죽음", + "subtitles.antarchy.stratoshark_fly": "스트라토샤크가 날아다님", + "subtitles.antarchy.caterpillar_idle": "애벌레가 서성거림", + "subtitles.antarchy.caterpillar_hurt": "애벌레가 다침", + "subtitles.antarchy.caterpillar_crawl": "애벌레가 기어감", + "subtitles.antarchy.butterfly_hurt": "나비가 다침", + "subtitles.antarchy.brutalfly_idle": "브루탈플라이가 서성거림", + "subtitles.antarchy.brutalfly_death": "브루탈플라이가 죽음", + "subtitles.antarchy.thoraxis_nightmare_wastes_ambient": "나이트메어 황무지가 웅웅거림", + "subtitles.antarchy.thoraxis_nightmare_wastes_additions": "나이트메어 황무지가 술렁임", + "subtitles.antarchy.thoraxis_nightmare_wastes_mood": "나이트메어 황무지가 속삭임", + "subtitles.antarchy.thoraxis_dream_dunes_ambient": "꿈의 사구가 속삭임", + "subtitles.antarchy.thoraxis_dream_dunes_additions": "꿈의 사구가 바스락거림", + "subtitles.antarchy.thoraxis_dream_dunes_mood": "꿈의 사구가 탄식함", + "subtitles.antarchy.thoraxis_lucid_pools_ambient": "루시드 웅덩이가 웅웅거림", + "subtitles.antarchy.dimensional_tear_open": "차원의 균열이 열림", + "subtitles.antarchy.dimensional_tear_idle": "차원의 균열이 아지랑이침", + "subtitles.antarchy.dimensional_tear_creature_leaves": "생물체가 균열에서 나타남", + "subtitles.antarchy.dimensional_tear_close": "차원의 균열이 닫힘", + "subtitles.antarchy.thoraxis_lucid_pools_additions": "루시드 웅덩이가 저주함", + "subtitles.antarchy.thoraxis_lucid_pools_mood": "루시드 웅덩이가 중얼거림", + "subtitles.antarchy.lucid_ambient": "루시드가 웅웅거림", + "subtitles.antarchy.lucid_flying": "루시드가 퍼덕거림", + "subtitles.antarchy.lucid_attack": "루시드가 공격함", + "subtitles.antarchy.lucid_bolt": "루시드 번개가 발사됨", + "subtitles.antarchy.lucid_hurt": "루시드가 다침", + "subtitles.antarchy.lucid_death": "루시드가 죽음", + "subtitles.antarchy.reverie_idle": "레버리가 맴돌음", + "subtitles.antarchy.reverie_hurt": "레버리가 다침", + "subtitles.antarchy.reverie_worry": "레버리가 걱정함", + "subtitles.antarchy.reverie_save": "레버리가 구출함", + "subtitles.antarchy.reverie_join_player": "레버리가 합류함", + "subtitles.antarchy.reverie_alert": "레버리가 경고함", + "subtitles.antarchy.flying_squirrel_idle": "날다람쥐가 지저귐", + "subtitles.antarchy.flying_squirrel_beg": "날다람쥐가 먹이를 구걸함", + "subtitles.antarchy.flying_squirrel_nut": "날다람쥐가 먹이를 먹음", + "subtitles.antarchy.flying_squirrel_glide_loop": "날다람쥐가 활공함", + "subtitles.antarchy.flying_squirrel_hurt": "날다람쥐가 다침", + "subtitles.antarchy.flying_squirrel_death": "날다람쥐가 죽음", + "subtitles.antarchy.nightmare_idle": "나이트메어가 으르렁거림", + "subtitles.antarchy.nightmare_hurt": "나이트메어가 다침", + "subtitles.antarchy.nightmare_roar": "나이트메어가 포효함", + "subtitles.antarchy.nightmare_death": "나이트메어가 죽음", + "subtitles.antarchy.nightmare_bite": "나이트메어가 물음", + "subtitles.antarchy.nightmare_flap": "나이트메어가 날갯짓함", + "subtitles.antarchy.flytrap_attack": "파리잡이가 공격함", + "subtitles.antarchy.flytrap_grab": "파리잡이가 붙잡음", + "subtitles.antarchy.flytrap_hurt": "파리잡이가 다침", + "subtitles.antarchy.flytrap_death": "파리잡이가 죽음", + "subtitles.antarchy.flytrap_hiss": "파리잡이가 슉슉 소리를 냄", + "subtitles.antarchy.flytrap_growl": "파리잡이가 으르렁거림", + "subtitles.antarchy.gravity_gun_pickup": "그래비티 건이 집어 올림", + "subtitles.antarchy.gravity_gun_drop": "그래비티 건이 떨어뜨림", + "subtitles.antarchy.gravity_gun_hold_loop": "그래비티 건이 웅웅거림", + "subtitles.antarchy.gravity_gun_launch": "그래비티 건이 발사함", + "subtitles.antarchy.gravity_gun_dryfire": "그래비티 건이 빈 총소리를 냄", + "subtitles.antarchy.antimetal_place": "안티메탈이 쨍그랑거림", + "subtitles.antarchy.antimetal_step": "안티메탈이 찰깍거림", + "subtitles.antarchy.antimetal_scaffold": "안티메탈 비계가 덜컹거림", + "subtitles.antarchy.portal_gun_fire_blue": "포탈 건 발사됨", + "subtitles.antarchy.portal_gun_fire_orange": "포탈 건 발사됨", + "subtitles.antarchy.portal_gun_invalid_surface": "포탈 건이 픽셀거림", + "subtitles.antarchy.portal_open_blue": "파란색 포탈이 열림", + "subtitles.antarchy.portal_open_orange": "주황색 포탈이 열림", + "subtitles.antarchy.portal_fizzle": "포탈이 소멸함", + "subtitles.antarchy.portal_ambient": "포탈이 웅웅거림", + "subtitles.antarchy.portal_enter": "개체가 포탈로 들어감", + "subtitles.antarchy.portal_exit": "개체가 포탈에서 나와짐", + "subtitles.antarchy.bed_bug_ambient": "빈대가 지저귐", + "subtitles.antarchy.bed_bug_hurt": "빈대가 다침", + "subtitles.antarchy.bed_bug_attack": "빈대가 물음", + "subtitles.antarchy.wasp_idle": "말벌이 윙윙거림", + "subtitles.antarchy.wasp_hurt": "말벌이 다침", + "subtitles.antarchy.wasp_attack": "말벌이 쏘음", + "subtitles.antarchy.wasp_death": "말벌이 죽음", + "subtitles.antarchy.scorpion_ambient": "스콜피온이 달그락거림", + "subtitles.antarchy.scorpion_hurt": "스콜피온이 다침", + "subtitles.antarchy.scorpion_attack": "스콜피온이 공격함", + "subtitles.antarchy.emperor_scorpion_ambient": "엠퍼러 스콜피온이 달그락거림", + "subtitles.antarchy.emperor_scorpion_hurt": "엠퍼러 스콜피온이 다침", + "subtitles.antarchy.emperor_scorpion_attack": "엠퍼러 스콜피온이 공격함", + "subtitles.antarchy.emperor_scorpion_roar": "엠퍼러 스콜피온이 포효함", + "subtitles.antarchy.moleworm_ambient": "몰웜이 바스락거림", + "subtitles.antarchy.moleworm_hurt": "몰웜이 다침", + "subtitles.antarchy.moleworm_attack": "몰웜이 공격함", + "subtitles.antarchy.moleworm_dig": "몰웜이 땅을 파냄", + "subtitles.antarchy.molevore_ambient": "몰레보어가 웅웅거림", + "subtitles.antarchy.molevore_hurt": "몰레보어가 다침", + "subtitles.antarchy.molevore_attack": "몰레보어가 공격함", + "subtitles.antarchy.molevore_dig": "몰레보어가 땅을 파냄", + "subtitles.antarchy.duct_tape_use": "덕트 테이프가 찢어짐", + "subtitles.antarchy.worm_hook_flying": "웜 갈고리가 쌩 하고 날아감", + "subtitles.antarchy.blood_crystal_katana_dash": "혈수정 카타나가 돌진함", + "subtitles.antarchy.blood_crystal_armor_equip": "혈수정 방어구를 착용함", + "subtitles.antarchy.bloodglass_ward_heart_break": "혈유리 하트가 깨짐", + "subtitles.antarchy.bloodglass_ward_heart_regen": "혈유리 하트가 재생됨", + "subtitles.antarchy.potent_nyxite_hypnotic_gas": "강력한 닉사이트가 슉슉 소리를 냄", + "subtitles.antarchy.potent_nyxite_geyser_eruption": "강력한 닉사이트가 분출함", + "subtitles.antarchy.potent_nyxite_geyser_continuous": "강력한 닉사이트 간헐천이 포효함", + "subtitles.antarchy.missile_squid_ambient": "미사일 오징어가 웅웅거림", + "subtitles.antarchy.missile_squid_hurt": "미사일 오징어가 다침", + "subtitles.antarchy.missile_squid_death": "미사일 오징어가 죽음", + "subtitles.antarchy.missile_squid_attack": "미사일 오징어가 공격함", + "subtitles.antarchy.kraken_flying_loop": "크라켄이 활공함", + "subtitles.antarchy.kraken_flying_sideways_loop": "크라켄이 선회함", + "subtitles.antarchy.kraken_attack": "크라켄이 덮침", + "subtitles.antarchy.kraken_spin": "크라켄이 회전함", + "subtitles.antarchy.kraken_roar": "크라켄이 포효함", + "subtitles.antarchy.kraken_summon": "크라켄이 출현함", + "subtitles.antarchy.kraken_hurt": "크라켄이 다침", + "subtitles.antarchy.kraken_death": "크라켄이 죽음", + "subtitles.antarchy.basilisk_idle_loop": "바실리스크가 서성거림", + "subtitles.antarchy.basilisk_slither_loop": "바실리스크가 기어감", + "subtitles.antarchy.basilisk_bite": "바실리스크가 물음", + "subtitles.antarchy.basilisk_hiss": "바실리스크가 슉슉 소리를 냄", + "subtitles.antarchy.basilisk_hurt": "바실리스크가 다침", + "subtitles.antarchy.basilisk_death": "바실리스크가 죽음", + "subtitles.antarchy.bomber_walk": "밤버가 걸어감", + "subtitles.antarchy.bomber_knock": "밤버가 맞음", + "subtitles.antarchy.bomber_explode": "밤버 도화선이 타들어감", + "subtitles.antarchy.toreterror_idle": "토레테러가 서성거림", + "subtitles.antarchy.toreterror_hurt": "토레테러가 다침", + "subtitles.antarchy.toreterror_death": "토레테러가 죽음", + "subtitles.antarchy.toreterror_bomber_fire": "토레테러가 밤버를 발사함", + "subtitles.antarchy.toreterror_spin": "토레테러가 회전함", + "subtitles.antarchy.toreterror_ricochet": "토레테러가 튕겨 나감", + "subtitles.antarchy.water_cannon_fire": "물대포가 발사됨", + "subtitles.antarchy.toreterror_jump_up": "토레테러가 도약함", + "subtitles.antarchy.toreterror_jump_land": "토레테러가 착지함", + "subtitles.antarchy.king_idle": "더 킹이 웅웅거림", + "subtitles.antarchy.king_walk": "더 킹이 발걸음을 옮김", + "subtitles.antarchy.king_fly_loop": "더 킹이 날갯짓함", + "subtitles.antarchy.king_wing_flap": "더 킹이 날개를 치솟음", + "subtitles.antarchy.king_bite": "더 킹이 물음", + "subtitles.antarchy.king_stomp": "더 킹이 발을 구름", + "subtitles.antarchy.king_roar": "더 킹이 포효함", + "subtitles.antarchy.king_hurt": "더 킹이 맞음", + "subtitles.antarchy.king_death": "더 킹이 쓰러짐", + "subtitles.antarchy.king_beam_shoot": "더 킹이 빔을 발사함", + "subtitles.antarchy.king_fireball_shoot": "더 킹이 화염을 내뿜음", + "subtitles.antarchy.king_ice_spikes": "더 킹이 얼음 가시를 소환함", + "subtitles.antarchy.king_decree_cast": "더 킹이 칙령을 선포함", + "subtitles.antarchy.king_decree": "더 킹이 칙령을 내림", + "subtitles.antarchy.king_success": "더 킹이 복종을 인정함", + "subtitles.antarchy.king_judgement": "더 킹이 심판을 내림", + "subtitles.antarchy.queen_idle": "더 퀸이 중얼거림", + "subtitles.antarchy.queen_walk": "더 퀸이 발걸음을 옮김", + "subtitles.antarchy.queen_fly_loop": "더 퀸이 날갯짓함", + "subtitles.antarchy.queen_wing_flap": "더 퀸이 날개를 치솟음", + "subtitles.antarchy.queen_bite": "더 퀸이 물음", + "subtitles.antarchy.queen_stomp": "더 퀸이 발을 구름", + "subtitles.antarchy.queen_roar": "더 퀸이 포효함", + "subtitles.antarchy.queen_hurt": "더 퀸이 맞음", + "subtitles.antarchy.queen_death": "더 퀸이 쓰러짐", + "subtitles.antarchy.queen_beam_shoot": "더 퀸이 빔을 발사함", + "subtitles.antarchy.queen_beam_start": "더 퀸이 빔을 충전함", + "subtitles.antarchy.queen_beam_loop": "더 퀸이 빔을 휩쓸음", + "subtitles.antarchy.queen_beam_end": "더 퀸의 빔이 희미해짐", + "subtitles.antarchy.queen_black_hole_shoot": "더 퀸이 특이점을 찢어 엶", + "subtitles.antarchy.queen_cast_shoot": "더 퀸이 주문을 외움", + "subtitles.antarchy.prince_idle": "더 프린스가 지저귐", + "subtitles.antarchy.prince_bite": "더 프린스가 물음", + "subtitles.antarchy.prince_shoot": "더 프린스가 일사불란하게 뱉어냄", + "subtitles.antarchy.prince_fly": "더 프린스가 날갯짓함", + "subtitles.antarchy.prince_step": "더 프린스가 발걸음을 옮김", + "subtitles.antarchy.princess_idle": "더 프린세스가 지저귐", + "subtitles.antarchy.princess_bite": "더 프린세스가 물음", + "subtitles.antarchy.princess_shoot": "더 프린세스가 일사불란하게 뱉어냄", + "subtitles.antarchy.princess_fly": "더 프린세스가 날갯짓함", + "subtitles.antarchy.princess_step": "더 프린세스가 발걸음을 옮김", + "subtitles.antarchy.stinky_fly": "악취 파리가 윙윙거림", + "item.minecraft.potion.effect.inversion": "반전의 물약", + "item.minecraft.potion.effect.long_inversion": "반전의 물약", + "item.minecraft.splash_potion.effect.inversion": "투척용 반전의 물약", + "item.minecraft.splash_potion.effect.long_inversion": "투척용 반전의 물약", + "item.minecraft.lingering_potion.effect.inversion": "잔류형 반전의 물약", + "item.minecraft.lingering_potion.effect.long_inversion": "잔류형 반전의 물약", + "item.minecraft.tipped_arrow.effect.inversion": "반전의 화살", + "item.minecraft.tipped_arrow.effect.long_inversion": "반전의 화살", + "item.minecraft.potion.effect.command": "지휘의 물약", + "item.minecraft.potion.effect.long_command": "지휘의 물약", + "item.minecraft.splash_potion.effect.command": "투척용 지휘의 물약", + "item.minecraft.splash_potion.effect.long_command": "투척용 지휘의 물약", + "item.minecraft.lingering_potion.effect.command": "잔류형 지휘의 물약", + "item.minecraft.lingering_potion.effect.long_command": "잔류형 지휘의 물약", + "item.minecraft.tipped_arrow.effect.command": "지휘의 화살", + "item.minecraft.tipped_arrow.effect.long_command": "지휘의 화살", + "item.minecraft.potion.effect.time_dilation": "시간 팽창의 물약", + "item.minecraft.potion.effect.long_time_dilation": "강력한 시간 팽창의 물약", + "item.minecraft.splash_potion.effect.time_dilation": "투척용 시간 팽창의 물약", + "item.minecraft.splash_potion.effect.long_time_dilation": "투척용 강력한 시간 팽창의 물약", + "item.minecraft.lingering_potion.effect.time_dilation": "잔류형 시간 팽창의 물약", + "item.minecraft.lingering_potion.effect.long_time_dilation": "잔류형 강력한 시간 팽창의 물약", + "item.minecraft.tipped_arrow.effect.time_dilation": "시간 팽창의 화살", + "item.minecraft.tipped_arrow.effect.long_time_dilation": "강력한 시간 팽창의 화살", + "item.minecraft.potion.effect.time_contraction": "시간 수축의 물약", + "item.minecraft.splash_potion.effect.time_contraction": "투척용 시간 수축의 물약", + "item.minecraft.lingering_potion.effect.time_contraction": "잔류형 시간 수축의 물약", + "item.minecraft.tipped_arrow.effect.time_contraction": "시간 수축의 화살", + "item.minecraft.potion.effect.long_time_contraction": "강력한 시간 수축의 물약", + "item.minecraft.splash_potion.effect.long_time_contraction": "투척용 강력한 시간 수축의 물약", + "item.minecraft.lingering_potion.effect.long_time_contraction": "잔류형 강력한 시간 수축의 물약", + "item.minecraft.tipped_arrow.effect.long_time_contraction": "강력한 시간 수축의 화살", + "item.minecraft.potion.effect.paralysis": "마비의 물약", + "item.minecraft.potion.effect.long_paralysis": "마비의 물약", + "item.minecraft.splash_potion.effect.paralysis": "투척용 마비의 물약", + "item.minecraft.splash_potion.effect.long_paralysis": "투척용 마비의 물약", + "item.minecraft.lingering_potion.effect.paralysis": "잔류형 마비의 물약", + "item.minecraft.lingering_potion.effect.long_paralysis": "잔류형 마비의 물약", + "item.minecraft.tipped_arrow.effect.paralysis": "마비의 화살", + "item.minecraft.tipped_arrow.effect.long_paralysis": "마비의 화살", + "item.minecraft.potion.effect.shrinking": "축소의 물약", + "item.minecraft.potion.effect.strong_shrinking": "축소의 물약 II", + "item.minecraft.potion.effect.extreme_shrinking": "축소의 물약 III", + "item.minecraft.splash_potion.effect.shrinking": "투척용 축소의 물약", + "item.minecraft.splash_potion.effect.strong_shrinking": "투척용 축소의 물약 II", + "item.minecraft.splash_potion.effect.extreme_shrinking": "투척용 축소의 물약 III", + "item.minecraft.lingering_potion.effect.shrinking": "잔류형 축소의 물약", + "item.minecraft.lingering_potion.effect.strong_shrinking": "잔류형 축소의 물약 II", + "item.minecraft.lingering_potion.effect.extreme_shrinking": "잔류형 축소의 물약 III", + "item.minecraft.tipped_arrow.effect.shrinking": "축소의 화살", + "item.minecraft.tipped_arrow.effect.strong_shrinking": "축소의 화살 II", + "item.minecraft.tipped_arrow.effect.extreme_shrinking": "축소의 화살 III", + "item.minecraft.potion.effect.growing": "거대화의 물약", + "item.minecraft.potion.effect.strong_growing": "거대화의 물약 II", + "item.minecraft.potion.effect.extreme_growing": "거대화의 물약 III", + "item.minecraft.splash_potion.effect.growing": "투척용 거대화의 물약", + "item.minecraft.splash_potion.effect.strong_growing": "투척용 거대화의 물약 II", + "item.minecraft.splash_potion.effect.extreme_growing": "투척용 거대화의 물약 III", + "item.minecraft.lingering_potion.effect.growing": "잔류형 거대화의 물약", + "item.minecraft.lingering_potion.effect.strong_growing": "잔류형 거대화의 물약 II", + "item.minecraft.lingering_potion.effect.extreme_growing": "잔류형 거대화의 물약 III", + "item.minecraft.tipped_arrow.effect.growing": "거대화의 화살", + "item.minecraft.tipped_arrow.effect.strong_growing": "거대화의 화살 II", + "item.minecraft.tipped_arrow.effect.extreme_growing": "거대화의 화살 III", + "item.minecraft.potion.effect.dread": "공포의 물약", + "item.minecraft.potion.effect.long_dread": "공포의 물약", + "item.minecraft.splash_potion.effect.dread": "투척용 공포의 물약", + "item.minecraft.splash_potion.effect.long_dread": "투척용 공포의 물약", + "item.minecraft.lingering_potion.effect.dread": "잔류형 공포의 물약", + "item.minecraft.lingering_potion.effect.long_dread": "잔류형 공포의 물약", + "item.minecraft.tipped_arrow.effect.dread": "공포의 화살", + "item.minecraft.tipped_arrow.effect.long_dread": "공포의 화살", + "item.minecraft.potion.effect.stinky": "악취의 물약", + "item.minecraft.potion.effect.long_stinky": "악취의 물약", + "item.minecraft.splash_potion.effect.stinky": "투척용 악취의 물약", + "item.minecraft.splash_potion.effect.long_stinky": "투척용 악취의 물약", + "item.minecraft.lingering_potion.effect.stinky": "잔류형 악취의 물약", + "item.minecraft.lingering_potion.effect.long_stinky": "잔류형 악취의 물약", + "item.minecraft.tipped_arrow.effect.stinky": "악취의 화살", + "item.minecraft.tipped_arrow.effect.long_stinky": "악취의 화살", + "item.minecraft.potion.effect.haste": "성급함의 물약", + "item.minecraft.potion.effect.strong_haste": "성급함의 물약 II", + "item.minecraft.splash_potion.effect.haste": "투척용 성급함의 물약", + "item.minecraft.splash_potion.effect.strong_haste": "투척용 성급함의 물약 II", + "item.minecraft.lingering_potion.effect.haste": "잔류형 성급함의 물약", + "item.minecraft.lingering_potion.effect.strong_haste": "잔류형 성급함의 물약 II", + "item.minecraft.tipped_arrow.effect.haste": "성급함의 화살", + "item.minecraft.tipped_arrow.effect.strong_haste": "성급함의 화살 II", + "advancements.antarchy.cancel_out.title": "1 - 1 = ?", + "advancements.antarchy.cancel_out.description": "거대화 효과와 축소 효과를 동시에 받으세요.", + "advancements.antarchy.enter_the_speed_force.title": "스피드 포스의 세계로", + "advancements.antarchy.enter_the_speed_force.description": "시간 수축 효과를 받으세요.", + "advancements.antarchy.probably_wondering_how_i_got_here.title": "내가 어쩌다 여기까지 왔는지 궁금하지?", + "advancements.antarchy.probably_wondering_how_i_got_here.description": "시간 팽창 효과를 받으세요.", + "advancements.antarchy.temporal_contradiction.title": "시간의 모순", + "advancements.antarchy.temporal_contradiction.description": "시간 팽창과 시간 수축 효과를 동시에 받으세요.", + "entity.antarchy.cheep": "치프", + "item.antarchy.cheep": "치프", + "item.antarchy.cheep_spawn_egg": "치프 생성 알", + "entity.antarchy.reverie": "레버리", + "biome.antarchy.thoraxis": "소랙시스", + "biome.antarchy.nightmare_wastes": "나이트메어 황무지", + "biome.antarchy.umbral_hills": "그림자 언덕", + "biome.antarchy.lucid_pools": "루시드 웅덩이", + "biome.antarchy.dream_dunes": "꿈의 사구", + "biome.antarchy.vortex_expanse": "소용돌이 넓은 들판", + "biome.antarchy.cloud_sea": "구름 바다", + "block.antarchy.wild_corn": "야생 옥수수", + "trim_material.antarchy.blood_crystal": "혈수정", + "trim_material.antarchy.bluestone": "블루스톤", + "trim_material.antarchy.nightmare_scale": "나이트메어 비늘", + "trim_material.antarchy.uranium": "우라늄", + "trim_material.antarchy.titanium": "티타늄", + "advancements.antarchy.duct_tape.title": "이 보트를 반으로 잘랐습니다!", + "advancements.antarchy.duct_tape.description": "그리고 덕트 테이프의 힘으로 다시 붙였죠!", + "key.categories.antarchy": "앤타키", + "key.antarchy.portal_gun_zoom": "포탈 건 확대", + "key.antarchy.portal_gun_reset": "포탈 건 리셋", + "key.antarchy.brutalfly_flap": "브루탈플라이 겉날개: 날갯짓", + "advancements.antarchy.shrink_ray_craft.title": "여보, 몹들을 줄였어요", + "advancements.antarchy.shrink_ray_craft.description": "축소 광선을 제작하세요.", + "advancements.antarchy.growth_ray_craft.title": "모 아니면 도", + "advancements.antarchy.growth_ray_craft.description": "거대화 광선을 제작하세요.", + "advancements.antarchy.squidzooka_craft.title": "먹물 세례", + "advancements.antarchy.squidzooka_craft.description": "오징어주카를 제작하세요.", + "advancements.antarchy.rocket_powered_octopus.title": "로켓 추진 문어", + "advancements.antarchy.rocket_powered_octopus.description": "R.P.O. 발사기를 제작하세요.", + "advancements.antarchy.gravity_gun_craft.title": "손은 눈보다 빠르다", + "advancements.antarchy.gravity_gun_craft.description": "그래비티 건을 제작하세요.", + "advancements.antarchy.upper_craft.title": "안아줘요!! 안아달라고!!!", + "advancements.antarchy.upper_craft.description": "어퍼를 제작하세요.", + "advancements.antarchy.mucus_obtained.title": "에취!", + "advancements.antarchy.mucus_obtained.description": "점액을 구하세요.", + "block.antarchy.cavaryn_portal": "카바린 포탈", + "biome.antarchy.cavaryn_moleworm_caves": "몰웜 동굴", + "biome.antarchy.wormy_caves": "벌레 꿈틀거리는 동굴", + "block.antarchy.termite_nest": "흰개미집", + "block.antarchy.chitin_spike": "키틴 가시", + "block.antarchy.chitin_block": "키틴 블록", + "block.antarchy.myrmite": "미르마이트", + "block.antarchy.broodstone": "브루드스톤", + "block.antarchy.amber_moss_block": "호박 이끼 블록", + "block.antarchy.amber_moss_carpet": "호박 이끼 양탄자", + "block.antarchy.amber_lichen": "호박 지의류", + "block.antarchy.mucus": "점액", + "tooltip.antarchy.mucus_slippery": "설치된 블록을 얼음보다 훨씬 미끄럽게 만듭니다.", + "block.antarchy.bile_vein": "쓸개즙 덩굴", + "block.antarchy.creepvine": "크립덩굴", + "block.antarchy.crawling_blight_egg": "크롤링 블라이트 알", + "block.antarchy.skulking_fright_egg": "스컬킹 프라이트 알", + "entity.antarchy.termite": "흰개미", + "entity.antarchy.springbug": "스프링버그", + "entity.antarchy.spit_bug": "침벌레", + "entity.antarchy.stink_bug": "노린재", + "entity.antarchy.rolly_polly": "공벌레", + "entity.antarchy.crawling_blight": "크롤링 블라이트", + "entity.antarchy.skulking_fright": "스컬킹 프라이트", + "entity.antarchy.hercules_beetle": "헤라클레스 비틀", + "entity.antarchy.prince": "더 프린스", + "entity.antarchy.princess": "더 프린세스", + "entity.antarchy.king": "더 킹", + "entity.antarchy.queen": "더 퀸", + "boss.antarchy.king.phase_two": "조여오는 법률", + "boss.antarchy.king.phase_three": "왕가의 심판", + "boss.antarchy.queen.phase_two": "중력의 지배", + "boss.antarchy.queen.phase_three": "시간의 붕괴", + "entity.antarchy.manticore": "만티코어", + "entity.antarchy.royal_black_hole": "특이점", + "entity.antarchy.royal_bolt": "로얄 번개", + "block.antarchy.prince_egg": "더 프린스 알", + "block.antarchy.princess_egg": "더 프린세스 알", + "item.antarchy.springbug_spawn_egg": "스프링버그 생성 알", + "item.antarchy.spit_bug_spawn_egg": "침벌레 생성 알", + "item.antarchy.stink_bug_spawn_egg": "노린재 생성 알", + "item.antarchy.termite_spawn_egg": "흰개미 생성 알", + "item.antarchy.rolly_polly_spawn_egg": "공벌레 생성 알", + "item.antarchy.crawling_blight_spawn_egg": "크롤링 블라이트 생성 알", + "item.antarchy.skulking_fright_spawn_egg": "스컬킹 프라이트 생성 알", + "item.antarchy.hercules_beetle_spawn_egg": "헤라클레스 비틀 생성 알", + "item.antarchy.king_spawn_egg": "더 킹 생성 알", + "item.antarchy.queen_spawn_egg": "더 퀸 생성 알", + "item.antarchy.manticore_spawn_egg": "만티코어 생성 알", + "item.antarchy.prince_spawn_egg": "더 프린스 생성 알", + "item.antarchy.princess_spawn_egg": "더 프린세스 생성 알", + "item.antarchy.chitin": "키틴", + "block.antarchy.polished_broodstone": "매끄러운 브루드스톤", + "block.antarchy.chiseled_broodstone": "조각된 브루드스톤", + "block.antarchy.broodstone_bricks": "브루드스톤 벽돌", + "block.antarchy.broodstone_stairs": "브루드스톤 계단", + "block.antarchy.broodstone_slab": "브루드스톤 반 블록", + "block.antarchy.broodstone_wall": "브루드스톤 담장", + "block.antarchy.polished_broodstone_stairs": "매끄러운 브루드스톤 계단", + "block.antarchy.polished_broodstone_slab": "매끄러운 브루드스톤 반 블록", + "block.antarchy.polished_broodstone_wall": "매끄러운 브루드스톤 담장", + "block.antarchy.broodstone_brick_stairs": "브루드스톤 벽돌 계단", + "block.antarchy.broodstone_brick_slab": "브루드스톤 벽돌 반 블록", + "block.antarchy.broodstone_brick_wall": "브루드스톤 벽돌 담장", + "block.antarchy.broodstone_pillar": "브루드스톤 기둥", + "block.antarchy.myrmite_coal_ore": "미르마이트 석탄 광석", + "block.antarchy.broodstone_uranium_ore": "브루드스톤 우라늄 광석", + "block.antarchy.broodstone_titanium_ore": "브루드스톤 티타늄 광석", + "item.antarchy.raw_bug_meat": "익히지 않은 벌레 고기", + "item.antarchy.cooked_bug_meat": "익힌 벌레 고기", + "item.antarchy.hercules_horn": "헤라클레스의 뿔", + "block.antarchy.hanging_creeproots": "매달린 크립뿌리", + "block.antarchy.glowcap_mushroom": "글로우캡 버섯", + "block.antarchy.potted_glowcap_mushroom": "화분에 담긴 글로우캡 버섯", + "block.antarchy.glowcap_mushroom_block": "글로우캡 버섯 블록", + "block.antarchy.molting_vines": "탈피 덩굴", + "item.antarchy.broodfruit": "브루드열매", + "block.antarchy.springbug_egg": "스프링버그 알", + "block.antarchy.spit_bug_egg": "침벌레 알", + "block.antarchy.jerry_egg": "제리 알", + "entity.antarchy.jerry": "제리", + "item.antarchy.jerry_spawn_egg": "제리 생성 알", + "block.antarchy.biomite": "바이오마이트", + "block.antarchy.biomite_turf": "바이오마이트 잔디", + "block.antarchy.biowart": "바이오사마귀", + "block.antarchy.biowart_tendrils": "바이오사마귀 덩굴손", + "biome.antarchy.biowart_caves": "바이오사마귀 동굴", + "subtitles.antarchy.crawling_blight_growl": "크롤링 블라이트가 으르렁거림", + "subtitles.antarchy.crawling_blight_hurt": "크롤링 블라이트가 다침", + "subtitles.antarchy.crawling_blight_bite": "크롤링 블라이트가 물음", + "subtitles.antarchy.skulking_fright_snarl": "스컬킹 프라이트가 으르렁거림", + "subtitles.antarchy.skulking_fright_hurt": "스컬킹 프라이트가 다침", + "subtitles.antarchy.skulking_fright_bite": "스컬킹 프라이트가 물음", + "subtitles.antarchy.skulking_fright_fly_loop": "스컬킹 프라이트가 날아다님", + "subtitles.antarchy.stink_bug_fart": "노린재가 방귀를 뀜", + "subtitles.antarchy.cavaryn_heartbeat": "카바린이 맥동함", + "subtitles.antarchy.stink_bug_idle": "노린재가 서성거림", + "subtitles.antarchy.rolly_polly_idle": "공벌레가 서성거림", + "subtitles.antarchy.rolly_polly_wheel_mode": "공벌레가 몸을 웅크림", + "subtitles.antarchy.rolly_polly_normal_mode": "공벌레가 몸을 풀음", + "subtitles.antarchy.rolly_polly_roll": "공벌레가 구름", + "subtitles.antarchy.hercules_beetle_idle": "헤라클레스 비틀이 서성거림", + "subtitles.antarchy.hercules_beetle_hurt": "헤라클레스 비틀이 다침", + "subtitles.antarchy.hercules_beetle_attack": "헤라클레스 비틀이 공격함", + "subtitles.antarchy.hercules_beetle_cry": "헤라클레스 비틀이 포효함", + "subtitles.antarchy.hercules_beetle_charge_start": "헤라클레스 비틀이 돌진 충전을 시작함", + "subtitles.antarchy.hercules_beetle_knocked_down": "헤라클레스 비틀이 픽 쓰러짐", + "subtitles.antarchy.springbug_idle": "스프링버그가 서성거림", + "subtitles.antarchy.spit_bug_idle": "침벌레가 서성거림", + "subtitles.antarchy.springbug_hurt": "스프링버그가 다침", + "subtitles.antarchy.springbug_jump": "스프링버그가 도약함", + "subtitles.antarchy.spit_bug_hurt": "침벌레가 다침", + "subtitles.antarchy.spit_bug_spit": "침벌레가 침을 뱉음", + "subtitles.antarchy.brutalfly_spit": "브루탈플라이가 침을 뱉음", + "subtitles.antarchy.jerry_idle": "제리가 지저귐", + "subtitles.antarchy.jerry_hurt": "제리가 다침", + "subtitles.antarchy.jerry_death": "제리가 죽음", + "subtitles.antarchy.jerry_attack": "제리가 공격함", + "subtitles.antarchy.ambient_elythia_ouranwood_forest": "오우란나무 숲이 바스락거림", + "advancements.antarchy.bug_apetit.title": "벌레 맛나게 드세요!", + "advancements.antarchy.bug_apetit.description": "익힌 벌레 고기를 드세요.", + "advancements.antarchy.behavioral_correction.title": "참교육의 시간", + "advancements.antarchy.behavioral_correction.description": "어튜드 어저스터를 흭득하세요.", + "advancements.antarchy.let_it_die.title": "말라 죽게 내버려둬!", + "advancements.antarchy.let_it_die.description": "트러팔로 다발을 획득하세요.", + "advancements.antarchy.let_it_grow.title": "다시 자라나게 해줘!", + "advancements.antarchy.let_it_grow.description": "트러팔로 묘목을 키우세요.", + "advancements.antarchy.beetle_buddies.title": "비틀즈가 된 기분", + "advancements.antarchy.beetle_buddies.description": "헤라클레스 비틀을 길들이세요.", + "advancements.antarchy.herculean_task.title": "헤라클레스의 난제", + "advancements.antarchy.herculean_task.description": "헤라클레스 비틀을 처치하세요.", + "item.antarchy.tigers_eye": "호안석", + "block.antarchy.tigers_eye_block": "호안석 블록", + "item.antarchy.tigers_eye_helmet": "호안석 투구", + "item.antarchy.tigers_eye_chestplate": "호안석 흉갑", + "item.antarchy.tigers_eye_leggings": "호안석 레깅스", + "item.antarchy.tigers_eye_boots": "호안석 부츠", + "trim_material.antarchy.tigers_eye": "Tiger's Eye", + "item.antarchy.tigers_eye_armor.passive": "발각 범위 최대 10% 감소", + "item.antarchy.tigers_eye_armor.full_set": "풀 세트: 적응형 위장", + "item.antarchy.tigers_eye_armor.activate": "%s 누름: 발밑 블록의 모형으로 위장", + "item.antarchy.tigers_eye_armor.active_bonus": "활성화 중 발각 감소율 2배 적용", + "key.antarchy.tigers_eye_camouflage": "적응형 위장", + "key.antarchy.royal_inversion_toggle": "로얄 어세일런트: 반전 전환", + "message.antarchy.tiger_eye_camouflage.activated": "적응형 위장이 활성화되었습니다", + "message.antarchy.tiger_eye_camouflage.disabled": "적응형 위장이 비활성화되었습니다", + "message.antarchy.tiger_eye_camouflage.full_set_required": "호안석 방어구 풀 세트가 필요합니다", + "message.antarchy.tiger_eye_camouflage.invalid_block": "발밑에 위장할 수 있는 적절한 블록이 없습니다", + "music.antarchy.lucid_lullaby": "루시드의 자장가", + "music.antarchy.lucid_lullaby.credit": "hewo_", + "music.antarchy.whistling_void": "휘파람 부는 보이드", + "music.antarchy.whistling_void.credit": "docshrekbot", + "music.antarchy.venenatus": "베네나투스", + "music.antarchy.venenatus.credit": "hewo_", + "music.antarchy.wistful_wanderings": "아쉬운 방랑", + "music.antarchy.wistful_wanderings.credit": "hewo_", + "tooltip.antarchy.lucid_anchor.pyramid": "상단에 안티메탈 신호기 피라미드가 필요합니다", + "tooltip.antarchy.lucid_anchor.path": "아래 세상으로 막힘없는 경로가 확보되면 아래쪽으로 반전 효과를 투사합니다", + "block.antarchy.myrmite_stairs": "미르마이트 계단", + "block.antarchy.myrmite_slab": "미르마이트 반 블록", + "block.antarchy.myrmite_wall": "미르마이트 담장", + "block.antarchy.polished_myrmite": "매끄러운 미르마이트", + "block.antarchy.polished_myrmite_stairs": "매끄러운 미르마이트 계단", + "block.antarchy.polished_myrmite_slab": "매끄러운 미르마이트 반 블록", + "block.antarchy.polished_myrmite_wall": "매끄러운 미르마이트 담장", + "block.antarchy.chiseled_myrmite": "조각된 미르마이트", + "block.antarchy.myrmite_bricks": "미르마이트 벽돌", + "block.antarchy.myrmite_brick_stairs": "미르마이트 벽돌 계단", + "block.antarchy.myrmite_brick_slab": "미르마이트 벽돌 반 블록", + "block.antarchy.myrmite_brick_wall": "미르마이트 벽돌 담장", + "block.antarchy.mossy_myrmite_bricks": "이끼 낀 미르마이트 벽돌", + "block.antarchy.mossy_myrmite_brick_stairs": "이끼 낀 미르마이트 벽돌 계단", + "block.antarchy.mossy_myrmite_brick_slab": "이끼 낀 미르마이트 벽돌 반 블록", + "block.antarchy.mossy_myrmite_brick_wall": "이끼 낀 미르마이트 벽돌 담장", + "block.antarchy.myrmite_pillar": "미르마이트 기둥", + "block.antarchy.mossy_broodstone_bricks": "이끼 낀 브루드스톤 벽돌", + "block.antarchy.mossy_broodstone_brick_stairs": "이끼 낀 브루드스톤 벽돌 계단", + "block.antarchy.mossy_broodstone_brick_slab": "이끼 낀 브루드스톤 벽돌 반 블록", + "block.antarchy.mossy_broodstone_brick_wall": "이끼 낀 브루드스톤 벽돌 담장", + "block.antarchy.mossy_nyxite_bricks": "이끼 낀 닉사이트 벽돌", + "block.antarchy.mossy_nyxite_brick_stairs": "이끼 낀 닉사이트 벽돌 계단", + "block.antarchy.mossy_nyxite_brick_slab": "이끼 낀 닉사이트 벽돌 반 블록", + "block.antarchy.mossy_nyxite_brick_wall": "이끼 낀 닉사이트 벽돌 담장", + "block.antarchy.packed_loam": "굳은 양토", + "block.antarchy.loam_bricks": "양토 벽돌", + "block.antarchy.loam_brick_stairs": "양토 벽돌 계단", + "block.antarchy.loam_brick_slab": "양토 벽돌 반 블록", + "block.antarchy.loam_brick_wall": "양토 벽돌 담장", + "block.antarchy.chiseled_loam_bricks": "조각된 양토 벽돌", + "item.antarchy.cooked_cheep": "익힌 치프", + "item.antarchy.cheep_bucket": "치프 양동이", + "block.antarchy.nadir_nyxium": "나디르 닉시움", + "block.antarchy.verdant_nyxium": "신록의 닉시움", + "block.antarchy.typhonite_pillar": "타이포나이트 기둥", + "block.antarchy.nadir_fern": "나디르 고사리", + "block.antarchy.large_nadir_fern": "키 큰 나디르 고사리", + "block.antarchy.duskbell": "더스크벨", + "block.antarchy.nadir_roots": "나디르 뿌리", + "block.antarchy.verdant_roots": "신록의 뿌리", + "block.antarchy.gorevine": "핏빛 덩굴" + ,"decree.antarchy.the_sky_is_mine": "하늘은 나의 것이다" + ,"decree.antarchy.the_sky_is_mine.subtitle": "땅에 가만히 계십시오." + ,"decree.antarchy.do_not_run": "달리지 마라" + ,"decree.antarchy.do_not_run.subtitle": "달리기를 즉시 멈추십시오.." + ,"decree.antarchy.kneel": "무릎을 꿇어라" + ,"decree.antarchy.kneel.subtitle": "5초 이내에 움웅크리십시오." + ,"decree.antarchy.close_quarters": "근접전이다" + ,"decree.antarchy.close_quarters.subtitle": "6초 이내에 더 킹의 16블록 원 안으로 진입하십시오. 투사체 사용은 금지됩니다." + ,"decree.antarchy.violated": "칙령 위반" + ,"decree.antarchy.violated.subtitle": "30초 동안 체력이 절반으로 감소합니다. 더 킹의 심판을 받으십시오." + ,"effect.antarchy.royal_vitality_penalty": "왕가의 생명력 약화" + ,"decree.antarchy.come_no_closer": "더 이상 접근하지 마라" + ,"decree.antarchy.come_no_closer.subtitle": "더 킹의 내부 반경에 들어가지 마십시오." + ,"decree.antarchy.fight_me_coward": "덤벼라, 겁쟁이 녀석!" + ,"decree.antarchy.fight_me_coward.subtitle": "더 킹에게 접근하십시오." + ,"decree.antarchy.no_respite": "휴식은 없다" + ,"decree.antarchy.no_respite.subtitle": "치유가 봉인됩니다." + ,"decree.antarchy.stand_tall": "당당히 서라" + ,"decree.antarchy.stand_tall.subtitle": "더 킹 앞에서 웅크리지 마십시오" + ,"decree.antarchy.stand_your_ground": "자리를 지켜라" + ,"decree.antarchy.stand_your_ground.subtitle": "지금 서 있는 위치에서 벗어나지 마십시오." + ,"decree.antarchy.hands_off_the_crown": "왕관에 손대지 마라" + ,"decree.antarchy.hands_off_the_crown.subtitle": "더 킹을 공격하고 심판을 받으십시오." + ,"decree.antarchy.show_no_mercy": "자비를 베풀지 마라" + ,"decree.antarchy.show_no_mercy.subtitle": "끊임없이 피해를 입히십시오." + ,"menu.antarchy.royal_judgment": "왕가의 심판" + ,"enchantment.antarchy.feather_rising": "깃털 상승" + ,"enchantment.antarchy.chronosphere": "크로노스피어" + ,"entity.minecraft.villager.antarchy.computer_scientist": "게임 개발자" + ,"entity.minecraft.villager.computer_scientist": "게임 개발자" + ,"block.antarchy.ant_trap": "개미 트랩" + ,"item.antarchy.bug_spray": "벌레 퇴치 스프레이" + ,"entity.minecraft.villager.antarchy.pest_control": "해충 방제사" + ,"entity.minecraft.villager.pest_control": "해충 방제사" + ,"guide.antarchy.category.general": "일반" + ,"guide.antarchy.category.elythia": "엘리시아" + ,"guide.antarchy.category.thoraxis": "소랙시스" + ,"guide.antarchy.category.cavaryn": "카바린" + ,"guide.antarchy.missing_title": "손상된 파일" + ,"guide.antarchy.missing_disk_title": "읽을 수 없는 디스크" + ,"guide.antarchy.disk.toreterror_arena.title": "토레테러 아레나 데이터" + ,"guide.antarchy.disk.high_fructose_corn_syrup.title": "옥수수 시럽 데이터" + ,"guide.antarchy.disk.elythia.title": "엘리시아 접근 기록" + ,"guide.antarchy.disk.flying_squirrel.title": "하늘다람쥐 야외 관찰 기록" + ,"guide.antarchy.disk.basilisk_game.title": "BASILISK.EXE" + ,"guide.antarchy.disk.antman_game.title": "ANTMAN.EXE" + ,"guide.antarchy.disk.cavaryn.title": "카바린 접근 기록" + ,"guide.antarchy.disk.thoraxis.title": "소랙시스 접근 기록" + ,"guide.antarchy.disk.temporal_fields.title": "시간 조작" + ,"guide.antarchy.disk.bloodglass.title": "혈유리 생존 기록" + ,"guide.antarchy.disk.vortex.title": "보텍스" + ,"guide.antarchy.entry.toreterror.title": "토레테러" + ,"guide.antarchy.entry.toreterror_arena.subtitle": "엘리시아 대양 보스 기록" + ,"guide.antarchy.entry.toreterror_arena.description": "거북목(Testudines)에 속하는 강력한 생물입니다. 엘리시아 대양 어딘가에 있는 원형 경기장에 서식하며, 이 기록 보관소를 통해 가장 가까운 경기장의 위치를 추적할 수 있습니다. 좌표는 아래와 같습니다." + ,"guide.antarchy.entry.toreterror_arena.description2": "영역 본능이 매우 강합니다. 등껍질에 장착된 대포는 초고압의 물을 발사하므로 접근 시 상당한 주의가 필요합니다." + ,"guide.antarchy.disk.hercules_beetle.title": "헤라클레스 비틀 야외 관찰 기록" + ,"guide.antarchy.entry.hercules_beetle.title": "헤라클레스 비틀" + ,"guide.antarchy.entry.hercules_beetle.subtitle": "카바린 대형 곤충 기록" + ,"guide.antarchy.entry.hercules_beetle.description": "카바린에 서성거리는 거대한 곤충입니다. 지형을 붕괴시킬 정도로 매우 강력한 돌진 공격을 퍼부을 수 있습니다." + ,"guide.antarchy.entry.hercules_beetle.description2": "시야에 들어오는 즉시 공격성을 띠는 잡식성 생물입니다." + ,"guide.antarchy.entry.hercules_beetle.description3": "전투 중 부상을 입으면 브루드열매로 진정시킬 수 있습니다. 진정되고 나면 전투가 끝난 뒤 먹이를 준 자를 마치 존경하듯 유대감을 형성합니다." + ,"guide.antarchy.entry.brown_ant.title": "갈색 개미" + ,"guide.antarchy.entry.brown_ant.subtitle": "엘리시아로 가는 길" + ,"guide.antarchy.entry.brown_ant.description": "갈색 개미를 우클릭하면 엘리시아로 이동합니다. 이끼 낀 오우란나무 틀 내부에서 개미 한 마리를 제물로 바치면 영구히 활성화되는 포탈을 만들 수 있습니다." + ,"guide.antarchy.entry.brown_ant.description2": "개미집은 오버월드의 숲, 타이가, 평원 및 엘리시아에서 발견됩니다. 갈색 개미는 해를 끼치지 않으며 설탕으로 번식시킬 수 있습니다." + ,"guide.antarchy.entry.brown_ant.description3": "구름 바다는 하늘 높은 곳에서만 형성되며, 약 5개 지역 중 1곳꼴로 존재합니다. 토레테러 아레나는 엘리시아 대양에 위치해 있습니다." + ,"guide.antarchy.entry.termite.title": "흰개미" + ,"guide.antarchy.entry.termite.subtitle": "카바린으로 가는 길" + ,"guide.antarchy.entry.termite.description": "흰개미를 우클릭하면 카바린으로 이동하거나, 미르마이트 틀 안에서 제물로 바쳐 영구 포탈을 활성화할 수 있습니다." + ,"guide.antarchy.entry.termite.description2": "흰개미는 오버월드 숲, 타이가, 평원 및 카바린 자체에 굴을 팁니다. 주변의 목재를 갉아먹으므로 목조 건축물 근처에 두지 마십시오. 촛불 빛을 피하며 목재로 번식합니다." + ,"guide.antarchy.entry.termite.description3": "카바린에서는 한 자리에 머물며 적대적 몹을 죽이거나 알을 깨뜨리면 주의를 끌게 됩니다. 한계치에 다다르면 무리가 몰려옵니다. 다른 곳으로 이동하면 해당 지역의 경계가 가라앉습니다." + ,"guide.antarchy.entry.termite.description4": "글로우캡, 바이오사마귀, 몰웜, 벌레 및 브루딩 터널 지역은 단계별 격상 방식이 다릅니다. 대부분 마지막 웨이브에서 헤라클레스 비틀이 등장합니다." + ,"guide.antarchy.entry.red_ant.title": "붉은 개미" + ,"guide.antarchy.entry.red_ant.subtitle": "소랙시스로 가는 길" + ,"guide.antarchy.entry.red_ant.description": "붉은 개미를 우클릭하면 소랙시스로 이동하거나, 닉사이트 틀 안에서 제물로 바쳐 포탈을 활성화할 수 있습니다. 네더에 굴을 팁니다." + ,"guide.antarchy.entry.red_ant.description2": "소랙시스는 물리 법칙을 따르지 않습니다. 특히 중력이 완전히 뒤틀려 있으며 심지어 반전되어 있습니다. 위로 흐르는 액체인 안티워터와 안티워터 간헐천도 존재합니다." + ,"guide.antarchy.entry.red_ant.description3": "블루스톤은 레드스톤과 유사하지만 거꾸로 작동합니다. 뒤집힌 철도를 만드는 데에도 사용할 수 있습니다." + ,"guide.antarchy.entry.red_ant.description4": "차원의 균열은 서로 연결된 쌍으로 나타납니다. 들어가면 어디서 어떻게 나올지 아무도 모릅니다." + ,"guide.antarchy.gallery.elythia": "엘리시아에서 발견됨" + ,"guide.antarchy.gallery.cavaryn": "카바린에서 발견됨" + ,"guide.antarchy.gallery.thoraxis": "소랙시스에서 발견됨" + ,"guide.antarchy.gallery.drops": "전리품" + ,"guide.antarchy.entry.flying_squirrel.title": "날다람쥐" + ,"guide.antarchy.entry.flying_squirrel.subtitle": "엘리시아 동반자 기록" + ,"guide.antarchy.entry.flying_squirrel.description": "미쳐보고 싶어? 어디 한번 제대로 미쳐보자고." + ,"guide.antarchy.entry.flying_squirrel.description2": "날다람쥐는 견과류와 나무, 그리고 극적인 탈출을 좋아합니다. 먹이를 주어 친해진 뒤 올라탈 수 있는 풍성한 나뭇잎을 제공해 주세요." + ,"guide.antarchy.entry.flying_squirrel.description3": "머리 위에 올려둘 수도 있습니다. 아주 귀엽지만, 위를 올라다보는 게 쓸데없이 복잡해집니다." + ,"guide.antarchy.entry.flying_squirrel.description4": "떨어지더라도 당황하지 마세요. 활공 중일 수도 있으니까요. 당신이 떨어지는 거라면, 패닉에 빠져도 좋습니다." + ,"guide.antarchy.disk.glimmer.title": "글리머 야외 관찰 기록" + ,"guide.antarchy.entry.glimmer.title": "글리머" + ,"guide.antarchy.entry.glimmer.subtitle": "병에 담는 동반자 및 변종 기록" + ,"guide.antarchy.entry.glimmer.description": "글리머는 엘리시아의 글리머링 웅덩이 주변에서 자주 발견되며, 밤이 되면 오우란나무 숲, 엘리시아 초원, 복숭아 숲에서 희귀하게 나타납니다. 웅덩이에서 떨어진 야생 글리머가 낮빛에 노출되면 사라집니다." + ,"guide.antarchy.entry.glimmer.description2": "야생 글리머에게 영혼 사과를 주어 길들일 수 있습니다. 빈손으로 우클릭하면 따라오기, 방랑하기, 앉기 상태를 순환합니다." + ,"guide.antarchy.entry.glimmer.description3": "길들인 글리머는 병에 담을 수 있습니다. 빈 유리병으로 우클릭하면 쿨타임과 상태를 유지한 채 포획됩니다. 어디서든 병을 다시 우클릭하면 해방됩니다." + ,"guide.antarchy.entry.glimmer.description4": "태어난 장소에 따라 변종이 달라집니다. 글리머링 웅덩이에서는 개구리, 오우란나무 사슴, 사과 소가 등장합니다. 오우란나무 숲에서는 개구리와 사슴이, 엘리시아 초원에서는 사과 소가, 복숭아 숲에서는 엘카가 출현합니다. 개미 변종은 특정 서식지에 귀속되지 않고 무작위 확률로만 나타납니다." + ,"guide.antarchy.entry.glimmer.description5": "사과 소: 허기 소모 속도가 25% 감소하며, 허기 수치가 낮아지면 포만감과 재생 효과를 폭발적으로 부여합니다. 오우란나무 사슴: 신속 I 효과를 주며, 돌진하여 부딪힌 적대적 몹을 넉백시킵니다." + ,"guide.antarchy.entry.glimmer.description6": "개구리: 도약 강화 I 효과를 주며, 주변의 적대적 몹을 삼켜 잠시 동안 더 크게 성장하고 강화됩니다. 개미: 공격 사거리가 약간 늘어나며, 대형 개체를 타격하면 힘 II 효과를 폭발적으로 획득합니다." + ,"guide.antarchy.entry.glimmer.description7": "엘카: 혈유리 보호막 II 효과를 부여합니다. 보호막 하트가 깨지면 주변에 충격파를 분출합니다." + ,"guide.antarchy.entry.temporal_fields.title": "시간 조작" + ,"guide.antarchy.entry.temporal_fields.subtitle": "시간 팽창, 수축 및 크로노스피어 가이드" + ,"guide.antarchy.entry.temporal_fields.description": "시간 팽창과 시간 수축은 영향을 받는 개체가 세상의 시간을 얼마나 빠르게 체감하는지 변화시킵니다." + ,"guide.antarchy.entry.temporal_fields.description2": "크로노스피어를 착용하면 자신 주변에 35% 속도의 영구 영역이 생성됩니다. 영역 반경은 1레벨에서 1.5블록, 2레벨에서 2.5블록, 3레벨 이상에서 3.5블록이며, 개체들은 이 반경의 2배 범위까지 영향을 받습니다." + ,"guide.antarchy.entry.temporal_fields.description3": "이 효과는 생명체, 투사체, 떨어진 아이템, 그리고 영역 내부에서 발사된 모든 것에 해당 영역의 속도를 유지시킵니다. 중첩된 영역은 중복되지 않으며 더 느리거나 더 빠른 규칙이 우선 적용됩니다. 더 킹과 더 퀸은 이 효과에 면역입니다." + ,"guide.antarchy.entry.bloodglass.title": "혈유리" + ,"guide.antarchy.entry.bloodglass.subtitle": "반응형 방어 체계" + ,"guide.antarchy.entry.bloodglass.description": "혈수정 방어구는 피해를 한 번 흡수하고 깨진 뒤 재충전되는 혈유리 하트를 부여합니다." + ,"guide.antarchy.entry.bloodglass.description2": "장착한 방어구 부위당 하트가 1개씩 추가되며, 각 하트는 30초의 자체 쿨타임 후 재충전됩니다. 혈수정 사과를 먹으면 방어구 하트 외에 2분간 유지되는 임시 하트 2개를 추가로 얻습니다." + ,"guide.antarchy.entry.bloodglass.description3": "카타나는 보기보다 긴 사거리를 가지며, 돌진 직후 짧은 무적 판정 시간과 함께 다음 돌진까지의 짧은 쿨타임을 가집니다." + ,"guide.antarchy.entry.vortex.title": "보텍스" + ,"guide.antarchy.entry.vortex.subtitle": "보텍스 렌즈 및 폭풍의 눈 가이드" + ,"guide.antarchy.entry.vortex.description": "보텍스 렌즈는 신호에 따라 당기거나 밀어냅니다. 레드스톤 신호는 당기고, 블루스톤 신호는 밀어냅니다." + ,"guide.antarchy.entry.vortex.description2": "신호 세기에 따라 범위가 조절됩니다. 끌어당기는 반경은 1.5~10블록, 높이는 3~20블록입니다. 렌즈 자체는 아무런 피해도 입히지 않습니다." + ,"guide.antarchy.entry.vortex.description3": "폭풍의 눈은 렌즈의 신호 제어 방식과 달리 자체 조건에 따라 상승 기류와 추적 토네이도를 발사합니다." + ,"guide.antarchy.entry.nightmare.title": "나이트메어" + ,"guide.antarchy.entry.nightmare.subtitle": "소랙시스 적대적 개체 기록" + ,"guide.antarchy.entry.nightmare.description": "소랙시스 가장 깊은 지역에서 관측된 생물입니다." + ,"guide.antarchy.entry.nightmare.description2": "플레이어의 체력이 낮을수록 공격이 더욱 강력해지므로, 불리한 전투 상황이 순식간에 악화됩니다." + ,"guide.antarchy.entry.nightmare.description3": "체력이 절반 이하로 떨어지면 공중으로 떠올라 포탈 한 쌍을 열고, 그중 하나로 들어가 플레이어 뒤로 텔레포트하여 습격합니다. 사라진 포탈뿐만 아니라 두 포탈 모두 주시하십시오." + ,"guide.antarchy.entry.high_fructose_corn_syrup.title": "고농도 옥수수 시럽" + ,"guide.antarchy.entry.high_fructose_corn_syrup.subtitle": "의심스러울 정도로 인기 있는 병에 관한 기록" + ,"guide.antarchy.entry.high_fructose_corn_syrup.description": "야생에서 채집하거나 양식한 옥수수를 물병에 넣어 양조할 수 있습니다." + ,"guide.antarchy.entry.high_fructose_corn_syrup.description2": "그대로 마시면 4초 동안 멀미 효과를 일으킵니다. 의사라면 절대" + ,"guide.antarchy.entry.high_fructose_corn_syrup.description3": "제작 제작대에 아무 음식과 함께 사용하면 미국식으로 바뀝니다: 추가 영양가, 추가 포만감, 그리고 재생 효과가 폭발적으로 부여됩니다." + ,"guide.antarchy.entry.rainbow_ant.title": "무지개 개미" + ,"guide.antarchy.entry.rainbow_ant.subtitle": "차원 관문 기록" + ,"guide.antarchy.entry.rainbow_ant.description": "무지개 개미입니다. 평범한 차원 개미처럼 보이지만... 과연 그럴까요? 무지개 설탕에 특별한 친화력을 보이는 것 같습니다." + ,"guide.antarchy.entry.rainbow_ant.description2": "각 무지개 개미는 내부에 고유한 차원을 품고 있습니다. 무지개 개미야말로 다중우주로 향하는 열쇠입니다." + ,"guide.antarchy.disk.rainbow_ant.title": "무지개 개미 야외 관찰 기록" + ,"guide.antarchy.disk.brutalfly.title": "브루탈플라이 야외 관찰 기록" + ,"guide.antarchy.entry.brutalfly.title": "브루탈플라이" + ,"guide.antarchy.entry.brutalfly.subtitle": "엘리시아 적대적 개체 기록" + ,"guide.antarchy.entry.brutalfly.description": "엘리시아산 대형 나비입니다. 더 작은 친척들과 달리 고치에서 나오는 순간 미친 듯이 공격성을 띱니다." + ,"guide.antarchy.entry.brutalfly.description2": "여느 나비와 마찬가지로 브루탈플라이는 고치 상태로 시작합니다. 고치가 손상되지 않는 한 근처에 있어도 비교적 안전합니다." + ,"guide.antarchy.entry.brutalfly.description3": "브루탈플라이가 공격을 시작하면 처리하는 것 외엔 방법이 없습니다." + ,"guide.antarchy.entry.brutalfly.description4": "브루탈플라이는 엘리시아의 숲 지대에서 발견됩니다. 나뭇가지 아래에 매달린 고치를 찾아보세요." + ,"guide.antarchy.entry.easter_bunny.title": "이스터 토끼" + ,"guide.antarchy.entry.easter_bunny.subtitle": "엔티티 기록" + ,"guide.antarchy.entry.easter_bunny.description": "이스터 토끼는 온갖 생물들의 생성 알을 낳습니다! 인생은 이스터 에그와 같아서, 무엇이 나올지 전혀 알 수 없죠." + ,"guide.antarchy.entry.easter_bunny.description2": "당근, 황금 당근, 또는 민들레를 먹이로 주어 보세요." + ,"guide.antarchy.entry.duplicator_tree.title": "복제나무" + ,"guide.antarchy.entry.duplicator_tree.subtitle": "블록 기록" + ,"guide.antarchy.entry.duplicator_tree.description": "다 자란 복제나무는 옆에 비어 있고 지지되는 공간이 있으면 근처의 고체 블록을 복제합니다." + ,"guide.antarchy.entry.duplicator_tree.description2": "유체, 블록 엔티티, 그리고 다른 복제나무 블록은 복제되지 않으며, 정해진 타이머가 아닌 무작위 간격으로 복제가 발생합니다." + ,"guide.antarchy.disk.kraken.title": "크라켄 야외 관찰 기록" + ,"guide.antarchy.entry.kraken.title": "크라켄" + ,"guide.antarchy.entry.kraken.subtitle": "바다의 수호자 기록" + ,"guide.antarchy.entry.kraken.description": "바다의 파수꾼 역할을 하는 터무니없이 거대한 오징어입니다. 날씨와 바다를 거의 완벽하게 지배하며, 다른 두족류들에게 능숙하게 명령을 내립니다." + ,"guide.antarchy.entry.kraken.description2": "운이 안 좋다 싶으면 무슨 짓이든 간에 어린 친척들을 공격하지 마십시오. 불길한 징조 효과를 받은 상태에서 오징어를 죽이면 오징어가 죽은 자리에 크라켄이 소환될 수 있습니다. 불길한 징조 단계당 확률이 약 1%씩 증가합니다." + ,"guide.antarchy.entry.kraken.description3": "인근 물속에서 솟아오르므로 바다 위에서 싸움을 거십시오. 아주 희귀하게, 오징어 한 마리를 죽였을 때 한꺼번에 열 마리가 몰려오는 경우도 있습니다." + ,"guide.antarchy.entry.kraken.description4": "자신을 자극한 자들을 어떠한 수단을 써서라도 끝장내는 대량 살상 생물입니다." + ,"guide.antarchy.entry.king.title": "더 킹" + ,"guide.antarchy.entry.king.subtitle": "엘리시아 왕가 기록" + ,"guide.antarchy.entry.king.description": "더 킹은 한때 자신의 반려와 함께 엘리시아를 통치했으나, 어느 날 그녀를 베어버리고 추방했습니다. 그날 이후 그는 아래 좌표에 위치한 그들의 왕가 나무 곁에 홀로 남아 있습니다." + ,"guide.antarchy.entry.king.description2": "그에게 남은 것은 법과 질서뿐이며, 그는 그것에 집착하고 있습니다. 그는 무뎌지고 가혹해졌으며, 그에게 유일한 위안을 주는 것은 타인을 고통스럽게 하는 것뿐입니다. 그는 공격적이고, 이기적이며, 가학적이고, 강력합니다." + ,"guide.antarchy.entry.king.description3": "시야에 들어오는 즉시 공격해 오며 당신을 장난감처럼 다룰 것입니다. 전투 중에 칙령을 내립니다: 무릎을 꿇어라, 달리지 마라, 더 이상 접근하지 마라, 자비를 베풀지 마라. 그의 말은 곧 법이며, 즉시 복종하기를 기대합니다." + ,"guide.antarchy.entry.king.description4": "칙령을 위반하면 심판을 받는 30초 동안 체력이 절반으로 감소합니다. 그는 뇌전, 빙결, 화염의 원소 힘을 다루어 심판을 집행합니다." + ,"guide.antarchy.entry.king.description5": "그는 자신의 반쪽만큼 강력하진 않지만, 제대로 준비하지 않는다면 당신을 갈갈이 찢어놓을 것입니다." + ,"guide.antarchy.disk.queen.title": "더 퀸의 참화 흔적 야외 관찰 기록" + ,"guide.antarchy.entry.queen.title": "더 퀸" + ,"guide.antarchy.entry.queen.subtitle": "소랙시스 왕가 기록" + ,"guide.antarchy.entry.queen.description": "더 이상 자신의 반쪽 곁에서 모습을 드러내지 않는 그녀는 가혹하고 분노에 찬 존재가 되었습니다. 엘리시아에서 쫓겨난 그녀는 차원을 넘나드는 여정을 거치며 차원 이동 능력을 얻은 것으로 보입니다." + ,"guide.antarchy.entry.queen.description2": "그녀는 강력하고 공격적입니다. 확실한 준비가 되어 있지 않다면 접근하지 마십시오. 더 퀸은 인간에게 원한을 품고 있진 않지만, 자신의 길을 막아선다면 이 세상에서 당신을 흔적도 없이 지워버릴 것입니다." + ,"guide.antarchy.entry.queen.description3": "더 퀸이 당신을 끝장내고 나면, 그녀의 충직한 만티코어들이 남은 잔해를 처리하도록 내버려둘 것입니다." + ,"guide.antarchy.entry.queen.description4": "소랙시스 밑바닥, 아래 좌표에서 그녀를 찾을 수 있습니다. 행운을 빕니다." + ,"guide.antarchy.entry.queen.description5": "그녀는 중력을 사용하여 전투합니다: 퍼져나가는 충격파를 동반한 지면 강타, 중앙으로 끌어당기는 블랙홀, 그리고 현재 중력 방향으로 당신을 짓눌러 고정시키는 압착 영역을 생성합니다." + ,"guide.antarchy.entry.queen.description6": "최종 페이즈에서는 자신만의 시간 팽창 영역을 펼쳐 그 안에 갇힌 모든 이를 느리게 만듭니다." + ,"guide.antarchy.entry.prince.title": "더 프린스" + ,"guide.antarchy.entry.prince.subtitle": "왕가 탈것 기록" + ,"guide.antarchy.entry.prince.description": "더 프린스 알은 작은 더 프린스로 부화하며, 황금 아이템을 먹이면 성장합니다." + ,"guide.antarchy.entry.prince.description2": "다 자란 더 프린스는 길들여 안장을 얹어 비행할 수 있으며, 적들에게 원소 볼트를 발사하고 근처의 적대적 몹들에게 명령을 내릴 수 있습니다. 책임감 있게 먹이를 주십시오. 작은 비행 군주를 키우는 셈이니까요." + ,"guide.antarchy.entry.princess.title": "더 프린세스" + ,"guide.antarchy.entry.princess.subtitle": "왕가 탈것 기록" + ,"guide.antarchy.entry.princess.description": "더 프린세스 알은 작은 더 프린세스로 부화하며, 황금 아이템을 먹이면 성장합니다." + ,"guide.antarchy.entry.princess.description2": "다 자란 더 프린세스는 길들여 안장을 얹어 비행할 수 있으며, 원소 볼트를 발사하고 적들 주변에 시간 팽창 영역을 생성합니다." + ,"subtitles.antarchy.hoverboard_mount": "호버보드가 시동을 켬" + ,"subtitles.antarchy.hoverboard_dismount": "호버보드가 정지함" + ,"subtitles.antarchy.hoverboard_idle": "호버보드가 웅웅거림" , - "entity.antarchy.portal_gun_portal": "포털 건 포털" + "advancements.antarchy.through_the_throat.title": "발밑을 조심해", + "advancements.antarchy.through_the_throat.description": "중력 협곡을 통해 밑바닥으로 추락하세요.", + "advancements.antarchy.underside_castle.title": "거꾸로 선 성", + "advancements.antarchy.underside_castle.description": "밑바닥에 매달려 있는 성을 찾아내세요.", + "advancements.antarchy.hive_awakened.title": "무자비한 모닝콜", + "advancements.antarchy.hive_awakened.description": "카바린 군단을 깨우세요.", + "advancements.antarchy.survived_the_horde.title": "군단은 기억한다", + "advancements.antarchy.survived_the_horde.description": "카바린 군단의 마지막 웨이브까지 살아남아 격퇴하세요.", + "advancements.antarchy.glimmer_keeper.title": "글리머 수집가", + "advancements.antarchy.glimmer_keeper.description": "모든 종류의 글리머를 길들이세요.", + "entity.antarchy.portal_gun_portal": "포탈 건 포탈", + "guide.antarchy.archive_folder.antlas": "안틀라스", + "guide.antarchy.archive_folder.elythia": "엘리시아", + "guide.antarchy.archive_folder.cavaryn": "카바린", + "guide.antarchy.archive_folder.thoraxis": "소랙시스" } diff --git a/common-1.21.1/src/main/resources/data/antarchy/loot_table/spawners/undertrial.json b/common-1.21.1/src/main/resources/data/antarchy/loot_table/spawners/undertrial.json index 6e105225..2a8037fe 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/loot_table/spawners/undertrial.json +++ b/common-1.21.1/src/main/resources/data/antarchy/loot_table/spawners/undertrial.json @@ -27,7 +27,7 @@ { "type": "minecraft:item", "name": "antarchy:cornea_ear", - "weight": 8, + "weight": 5, "functions": [ { "function": "minecraft:set_count", @@ -42,7 +42,7 @@ { "type": "minecraft:item", "name": "antarchy:bluestone", - "weight": 10, + "weight": 6, "functions": [ { "function": "minecraft:set_count", @@ -54,6 +54,36 @@ } ] }, + { + "type": "minecraft:item", + "name": "antarchy:uranium_nugget", + "weight": 4, + "functions": [ + { + "function": "minecraft:set_count", + "count": { + "type": "minecraft:uniform", + "min": 2, + "max": 5 + } + } + ] + }, + { + "type": "minecraft:item", + "name": "antarchy:titanium_nugget", + "weight": 4, + "functions": [ + { + "function": "minecraft:set_count", + "count": { + "type": "minecraft:uniform", + "min": 2, + "max": 5 + } + } + ] + }, { "type": "minecraft:item", "name": "minecraft:diamond", diff --git a/common-1.21.1/src/main/resources/data/antarchy/recipe/blood_crystal_katana.json b/common-1.21.1/src/main/resources/data/antarchy/recipe/blood_crystal_katana.json index 8b8047f2..91b42d97 100644 --- a/common-1.21.1/src/main/resources/data/antarchy/recipe/blood_crystal_katana.json +++ b/common-1.21.1/src/main/resources/data/antarchy/recipe/blood_crystal_katana.json @@ -4,11 +4,11 @@ "pattern": [ " B", " B ", - "N " + "I " ], "key": { - "N": { - "item": "minecraft:netherite_ingot" + "I": { + "item": "minecraft:iron_ingot" }, "B": { "item": "antarchy:blood_crystal_shard" diff --git a/common-1.21.1/src/main/resources/data/antarchy/structure/stampys_house/stampys_house.nbt b/common-1.21.1/src/main/resources/data/antarchy/structure/stampys_house/stampys_house.nbt index 5a52c108..03ce44a4 100644 Binary files a/common-1.21.1/src/main/resources/data/antarchy/structure/stampys_house/stampys_house.nbt and b/common-1.21.1/src/main/resources/data/antarchy/structure/stampys_house/stampys_house.nbt differ diff --git a/fabric-1.20.1/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClient.java b/fabric-1.20.1/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClient.java index c539c854..c130dfdd 100644 --- a/fabric-1.20.1/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClient.java +++ b/fabric-1.20.1/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClient.java @@ -25,7 +25,7 @@ public final class AntarchyFabricClient implements ClientModInitializer { com.craisinlord.antarchy.Antarchy.physicalClient = true; com.craisinlord.antarchy.content.AntarchyAnthologyHooks.registerClient(); ModelLoadingPlugin.register(plugin -> plugin.addModels(SeparateLargeItemModels.all())); - ClientTickEvents.END_CLIENT_TICK.register(client -> QueenMusicHandler.tick(client, AntarchyFabricSounds.THE_QUEEN.get())); + ClientTickEvents.END_CLIENT_TICK.register(client -> QueenMusicHandler.tick(client, AntarchyFabricSounds.THE_QUEEN)); AntarchyFabricClientNetworking.register(); AntarchyFabricClientBootstrap.register(); ResourceManagerHelper.get(PackType.CLIENT_RESOURCES).registerReloadListener(new IdentifiableResourceReloadListener() { diff --git a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClient.java b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClient.java index 625b3584..487ac8a7 100644 --- a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClient.java +++ b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClient.java @@ -26,7 +26,7 @@ public final class AntarchyFabricClient implements ClientModInitializer { com.craisinlord.antarchy.Antarchy.physicalClient = true; com.craisinlord.antarchy.content.AntarchyAnthologyHooks.registerClient(); ModelLoadingPlugin.register(plugin -> plugin.addModels(SeparateLargeItemModels.all())); - ClientTickEvents.END_CLIENT_TICK.register(client -> QueenMusicHandler.tick(client, AntarchyFabricSounds.THE_QUEEN.get())); + ClientTickEvents.END_CLIENT_TICK.register(client -> QueenMusicHandler.tick(client, AntarchyFabricSounds.THE_QUEEN)); AntarchyFabricClientNetworking.register(); AntarchyFabricClientBootstrap.register(); AntarchyComputerGames.register(); diff --git a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyKeyBindings.java b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyKeyBindings.java index 92714e01..60f6b70f 100644 --- a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyKeyBindings.java +++ b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyKeyBindings.java @@ -30,6 +30,19 @@ public final class AntarchyKeyBindings { GLFW.GLFW_KEY_R, CATEGORY ); + public static final KeyMapping MOUNT_BEAM = new KeyMapping( + "key.antarchy.mount_beam", + InputConstants.Type.KEYSYM, + GLFW.GLFW_KEY_H, + CATEGORY + ); + + public static final KeyMapping MOUNT_SIGNATURE = new KeyMapping( + "key.antarchy.mount_signature", + InputConstants.Type.KEYSYM, + GLFW.GLFW_KEY_J, + CATEGORY + ); public static final KeyMapping TIGERS_EYE_CAMOUFLAGE = new KeyMapping( "key.antarchy.tigers_eye_camouflage", InputConstants.Type.KEYSYM, @@ -68,6 +81,8 @@ public final class AntarchyKeyBindings { KeyBindingHelper.registerKeyBinding(BRUTALFLY_FLAP); KeyBindingHelper.registerKeyBinding(MOUNT_SPECIAL); KeyBindingHelper.registerKeyBinding(MOUNT_FLIGHT_TOGGLE); + KeyBindingHelper.registerKeyBinding(MOUNT_BEAM); + KeyBindingHelper.registerKeyBinding(MOUNT_SIGNATURE); KeyBindingHelper.registerKeyBinding(TIGERS_EYE_CAMOUFLAGE); KeyBindingHelper.registerKeyBinding(ROYAL_INVERSION_TOGGLE); KeyBindingHelper.registerKeyBinding(ROYAL_BOUNDARY); @@ -87,6 +102,14 @@ public final class AntarchyKeyBindings { return Minecraft.getInstance().screen == null && MOUNT_FLIGHT_TOGGLE.isDown(); } + public static boolean isMountBeamPressed() { + return Minecraft.getInstance().screen == null && MOUNT_BEAM.isDown(); + } + + public static boolean isMountSignaturePressed() { + return Minecraft.getInstance().screen == null && MOUNT_SIGNATURE.isDown(); + } + public static boolean consumeTigerEyeCamouflagePressed() { return Minecraft.getInstance().screen == null && TIGERS_EYE_CAMOUFLAGE.consumeClick(); } diff --git a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/RoyalMountClientHandler.java b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/RoyalMountClientHandler.java index bd4e64b9..9777466f 100644 --- a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/RoyalMountClientHandler.java +++ b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/client/RoyalMountClientHandler.java @@ -12,6 +12,8 @@ public final class RoyalMountClientHandler { private static boolean wasAttack; private static boolean wasSpecial; private static boolean wasFlightToggle; + private static boolean wasBeam; + private static boolean wasSignature; private static boolean wasAscend; private static boolean wasDescend; private static boolean wasUse; @@ -57,6 +59,18 @@ public final class RoyalMountClientHandler { } wasFlightToggle = flightToggle; + boolean beam = AntarchyKeyBindings.isMountBeamPressed(); + if (beam && !wasBeam) { + ClientPlayNetworking.send(new RoyalMountActionPayload(RoyalMountActionPayload.BEAM)); + } + wasBeam = beam; + + boolean signature = AntarchyKeyBindings.isMountSignaturePressed(); + if (signature && !wasSignature) { + ClientPlayNetworking.send(new RoyalMountActionPayload(RoyalMountActionPayload.SIGNATURE)); + } + wasSignature = signature; + boolean ascend = mc.options.keyJump.isDown(); boolean descend = mc.options.keyShift.isDown(); if (ascend != wasAscend || descend != wasDescend) { @@ -73,6 +87,8 @@ public final class RoyalMountClientHandler { wasAttack = false; wasSpecial = false; wasFlightToggle = false; + wasBeam = false; + wasSignature = false; wasAscend = false; wasDescend = false; } diff --git a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/mixin/infinity/AmendmentRareOresMixin.java b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/mixin/infinity/AmendmentRareOresMixin.java index 0816550f..e7be5675 100644 --- a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/mixin/infinity/AmendmentRareOresMixin.java +++ b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/mixin/infinity/AmendmentRareOresMixin.java @@ -29,5 +29,11 @@ public class AmendmentRareOresMixin { new Amendment.MatchingBlockTagSelector("antarchy:infinity_dimension_rare_ores"), new Amendment.SetValue(0.02) )); + data.computeIfAbsent(ConfigType.EFFECTS, k -> new ArrayList<>()).add(new Amendment( + ConfigType.EFFECTS, + new Amendment.MatchingModSelector("antarchy"), + new Amendment.MatchingSelector("antarchy:paralyzed"), + new Amendment.SetValue(0.0) + )); } } diff --git a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/network/AntarchyFabricNetworking.java b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/network/AntarchyFabricNetworking.java index da1fa06d..e8eca046 100644 --- a/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/network/AntarchyFabricNetworking.java +++ b/fabric-1.21.1/src/main/java/com/craisinlord/antarchy/fabric/network/AntarchyFabricNetworking.java @@ -207,6 +207,8 @@ public final class AntarchyFabricNetworking { case RoyalMountActionPayload.FLIGHT_TOGGLE -> mount.toggleMountedFlight(player); case RoyalMountActionPayload.BITE -> mount.handleMountedBite(player); case RoyalMountActionPayload.SPIT -> mount.handleMountedSpit(player); + case RoyalMountActionPayload.BEAM -> mount.handleMountedBeam(player); + case RoyalMountActionPayload.SIGNATURE -> mount.handleMountedSignature(player); default -> { } } diff --git a/forge-1.20.1/gradle.properties b/forge-1.20.1/gradle.properties index 0dcc5423..cfad7a95 100644 --- a/forge-1.20.1/gradle.properties +++ b/forge-1.20.1/gradle.properties @@ -6,7 +6,7 @@ mod_name=Antarchy mod_description=ANTS! ANTS! ANTS! ANTS! mod_authors=CraisinLord mod_group_id=com.craisinlord -mod_version=2.2.4 +mod_version=2.2.6 mod_license=All Rights Reserved minecraft_version=1.20.1 diff --git a/forge-1.20.1/src/main/java/com/craisinlord/antarchy/forge/client/QueenMusicClientHandler.java b/forge-1.20.1/src/main/java/com/craisinlord/antarchy/forge/client/QueenMusicClientHandler.java index 51d5d0a6..c532459a 100644 --- a/forge-1.20.1/src/main/java/com/craisinlord/antarchy/forge/client/QueenMusicClientHandler.java +++ b/forge-1.20.1/src/main/java/com/craisinlord/antarchy/forge/client/QueenMusicClientHandler.java @@ -18,6 +18,6 @@ public final class QueenMusicClientHandler { public static void onClientTick(TickEvent.ClientTickEvent event) { if (event.phase != TickEvent.Phase.END) return; Minecraft minecraft = Minecraft.getInstance(); - QueenMusicHandler.tick(minecraft, AntarchyForgeSounds.THE_QUEEN.get()); + QueenMusicHandler.tick(minecraft, AntarchyForgeSounds.THE_QUEEN); } } diff --git a/forge-1.20.1/src/main/java/com/craisinlord/antarchy/forge/mixins/compat/DroneFakePlayerConstructionMixin.java b/forge-1.20.1/src/main/java/com/craisinlord/antarchy/forge/mixins/compat/DroneFakePlayerConstructionMixin.java new file mode 100644 index 00000000..532e57a9 --- /dev/null +++ b/forge-1.20.1/src/main/java/com/craisinlord/antarchy/forge/mixins/compat/DroneFakePlayerConstructionMixin.java @@ -0,0 +1,49 @@ +package com.craisinlord.antarchy.forge.mixins.compat; + +import com.mojang.authlib.GameProfile; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.phys.Vec3; +import net.minecraftforge.common.util.FakePlayer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Pseudo; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +/** Protects virtual position calls made before the drone constructor has finished. */ +@Pseudo +@Mixin(targets = "me.desht.pneumaticcraft.common.util.fakeplayer.DroneFakePlayer", remap = false) +public abstract class DroneFakePlayerConstructionMixin extends FakePlayer { + @Unique + private boolean antarchy$droneConstructionComplete; + + protected DroneFakePlayerConstructionMixin(ServerLevel level, GameProfile profile) { + super(level, profile); + } + + @Inject(method = "", at = @At("RETURN"), remap = false) + private void antarchy$finishDroneConstruction(CallbackInfo ci) { + antarchy$droneConstructionComplete = true; + } + + // Explicit Mojmap/SRG selectors: the optional target is unavailable to the + // annotation processor, but its Minecraft overrides are reobfuscated by Forge. + @Inject(method = {"position()Lnet/minecraft/world/phys/Vec3;", "m_20182_()Lnet/minecraft/world/phys/Vec3;"}, + at = @At("HEAD"), cancellable = true, remap = false, require = 0) + private void antarchy$positionDuringConstruction(CallbackInfoReturnable cir) { + if (!antarchy$droneConstructionComplete) { + cir.setReturnValue(super.position()); + } + } + + @Inject(method = {"blockPosition()Lnet/minecraft/core/BlockPos;", "m_20183_()Lnet/minecraft/core/BlockPos;"}, + at = @At("HEAD"), cancellable = true, remap = false, require = 0) + private void antarchy$blockPositionDuringConstruction(CallbackInfoReturnable cir) { + if (!antarchy$droneConstructionComplete) { + cir.setReturnValue(super.blockPosition()); + } + } +} diff --git a/forge-1.20.1/src/main/java/com/craisinlord/antarchy/forge/mixins/infinity/AmendmentRareOresMixin.java b/forge-1.20.1/src/main/java/com/craisinlord/antarchy/forge/mixins/infinity/AmendmentRareOresMixin.java index 4242eef3..81a46d7c 100644 --- a/forge-1.20.1/src/main/java/com/craisinlord/antarchy/forge/mixins/infinity/AmendmentRareOresMixin.java +++ b/forge-1.20.1/src/main/java/com/craisinlord/antarchy/forge/mixins/infinity/AmendmentRareOresMixin.java @@ -24,5 +24,11 @@ public class AmendmentRareOresMixin { new Amendment.MatchingBlockTagSelector("antarchy:infinity_dimension_rare_ores"), new Amendment.SetValue(0.02) )); + data.computeIfAbsent(ConfigType.EFFECTS, k -> new ArrayList<>()).add(new Amendment( + ConfigType.EFFECTS, + new Amendment.MatchingModSelector("antarchy"), + new Amendment.MatchingSelector("antarchy:paralyzed"), + new Amendment.SetValue(0.0) + )); } } diff --git a/forge-1.20.1/src/main/resources/antarchy-forge.mixins.json b/forge-1.20.1/src/main/resources/antarchy-forge.mixins.json index 6f70ad22..25cc1a3c 100644 --- a/forge-1.20.1/src/main/resources/antarchy-forge.mixins.json +++ b/forge-1.20.1/src/main/resources/antarchy-forge.mixins.json @@ -4,6 +4,7 @@ "refmap": "antarchy-forge.mixins.refmap.json", "compatibilityLevel": "JAVA_17", "mixins": [ + "compat.DroneFakePlayerConstructionMixin", "compat.SablePhysicsColliderBlockGetterMixin", "item.BucketItemThoraxisWaterMixin", "entity.ParalyzedMobFreezeMixin", diff --git a/gradle.properties b/gradle.properties index d7169340..f69e0be6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ org.gradle.configureondemand=true minecraft_version_1_21_1=1.21.1 modid=antarchy mod_id=antarchy -mod_version=2.2.5 +mod_version=2.2.6 maven_group=com.craisinlord mixin_version=0.15.4+mixin.0.8.7 diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/client/AntarchyKeyBindings.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/client/AntarchyKeyBindings.java index 1abc6bc4..0cd4fbeb 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/client/AntarchyKeyBindings.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/client/AntarchyKeyBindings.java @@ -36,6 +36,21 @@ public final class AntarchyKeyBindings { InputConstants.KEY_R, CATEGORY ); + public static final KeyMapping MOUNT_BEAM = new KeyMapping( + "key.antarchy.mount_beam", + KeyConflictContext.IN_GAME, + InputConstants.Type.KEYSYM, + InputConstants.KEY_H, + CATEGORY + ); + + public static final KeyMapping MOUNT_SIGNATURE = new KeyMapping( + "key.antarchy.mount_signature", + KeyConflictContext.IN_GAME, + InputConstants.Type.KEYSYM, + InputConstants.KEY_J, + CATEGORY + ); public static final KeyMapping TIGERS_EYE_CAMOUFLAGE = new KeyMapping( "key.antarchy.tigers_eye_camouflage", KeyConflictContext.IN_GAME, @@ -80,6 +95,8 @@ public final class AntarchyKeyBindings { event.register(BRUTALFLY_FLAP); event.register(MOUNT_SPECIAL); event.register(MOUNT_FLIGHT_TOGGLE); + event.register(MOUNT_BEAM); + event.register(MOUNT_SIGNATURE); event.register(TIGERS_EYE_CAMOUFLAGE); event.register(ROYAL_INVERSION_TOGGLE); event.register(ROYAL_BOUNDARY); @@ -91,6 +108,14 @@ public final class AntarchyKeyBindings { return MOUNT_FLIGHT_TOGGLE.isDown(); } + public static boolean isMountBeamPressed() { + return MOUNT_BEAM.isDown(); + } + + public static boolean isMountSignaturePressed() { + return MOUNT_SIGNATURE.isDown(); + } + public static boolean isMountSpecialPressed() { return MOUNT_SPECIAL.isDown(); } diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/client/QueenMusicClientHandler.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/client/QueenMusicClientHandler.java index f03588bd..7a6a07f2 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/client/QueenMusicClientHandler.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/client/QueenMusicClientHandler.java @@ -17,6 +17,6 @@ public final class QueenMusicClientHandler { @SubscribeEvent public static void onClientTick(ClientTickEvent.Post event) { Minecraft minecraft = Minecraft.getInstance(); - QueenMusicHandler.tick(minecraft, AntarchyNeoforgeSounds.THE_QUEEN.get()); + QueenMusicHandler.tick(minecraft, AntarchyNeoforgeSounds.THE_QUEEN); } } diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/client/RoyalMountClientHandler.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/client/RoyalMountClientHandler.java index f71025f7..3f9248ee 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/client/RoyalMountClientHandler.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/client/RoyalMountClientHandler.java @@ -18,6 +18,8 @@ public final class RoyalMountClientHandler { private static boolean wasAttack; private static boolean wasSpecial; private static boolean wasFlightToggle; + private static boolean wasBeam; + private static boolean wasSignature; private static boolean wasAscend; private static boolean wasDescend; private static boolean wasUse; @@ -64,6 +66,18 @@ public final class RoyalMountClientHandler { } wasFlightToggle = flightToggle; + boolean beam = AntarchyKeyBindings.isMountBeamPressed(); + if (beam && !wasBeam) { + PacketDistributor.sendToServer(new RoyalMountActionPayload(RoyalMountActionPayload.BEAM)); + } + wasBeam = beam; + + boolean signature = AntarchyKeyBindings.isMountSignaturePressed(); + if (signature && !wasSignature) { + PacketDistributor.sendToServer(new RoyalMountActionPayload(RoyalMountActionPayload.SIGNATURE)); + } + wasSignature = signature; + boolean ascend = mc.options.keyJump.isDown(); boolean descend = mc.options.keyShift.isDown(); if (ascend != wasAscend || descend != wasDescend) { @@ -80,6 +94,8 @@ public final class RoyalMountClientHandler { wasAttack = false; wasSpecial = false; wasFlightToggle = false; + wasBeam = false; + wasSignature = false; wasAscend = false; wasDescend = false; } diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/mixins/infinity/AmendmentRareOresMixin.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/mixins/infinity/AmendmentRareOresMixin.java index 05459dd0..8769a77b 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/mixins/infinity/AmendmentRareOresMixin.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/mixins/infinity/AmendmentRareOresMixin.java @@ -29,5 +29,11 @@ public class AmendmentRareOresMixin { new Amendment.MatchingBlockTagSelector("antarchy:infinity_dimension_rare_ores"), new Amendment.SetValue(0.02) )); + data.computeIfAbsent(ConfigType.EFFECTS, k -> new ArrayList<>()).add(new Amendment( + ConfigType.EFFECTS, + new Amendment.MatchingModSelector("antarchy"), + new Amendment.MatchingSelector("antarchy:paralyzed"), + new Amendment.SetValue(0.0) + )); } } diff --git a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgePayloadHandlers.java b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgePayloadHandlers.java index 3c1728ad..eec1de75 100644 --- a/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgePayloadHandlers.java +++ b/neoforge-1.21.1/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgePayloadHandlers.java @@ -107,6 +107,8 @@ public class AntarchyNeoforgePayloadHandlers { case com.craisinlord.antarchy.content.network.RoyalMountActionPayload.FLIGHT_TOGGLE -> mount.toggleMountedFlight(player); case com.craisinlord.antarchy.content.network.RoyalMountActionPayload.BITE -> mount.handleMountedBite(player); case com.craisinlord.antarchy.content.network.RoyalMountActionPayload.SPIT -> mount.handleMountedSpit(player); + case com.craisinlord.antarchy.content.network.RoyalMountActionPayload.BEAM -> mount.handleMountedBeam(player); + case com.craisinlord.antarchy.content.network.RoyalMountActionPayload.SIGNATURE -> mount.handleMountedSignature(player); default -> { } }