1.1.0 release

This commit is contained in:
craisinlord committed 2026-08-08 17:00:43 -05:00
1 parent b81dcc3bef
commit de529b54c2
149 files changed
+5623 -2919

No files matched your search

@@ -1,6 +1,8 @@
package com.craisinlord.antarchy.compat.infinity;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.RandomSource;
@@ -23,4 +25,13 @@ public interface InfinityCompatBridge {
default boolean requestWarp(ServerPlayer player, ResourceLocation dimensionId) {
return false;
}
/**
* Converts an already-ignited vanilla Nether portal frame at {@code anyPortalBlockPos} into a real, permanent
* Infinite Dimensions portal to {@code dimensionId}, generating the dimension first if it doesn't exist yet.
* Mirrors what Infinity itself does when a written book is thrown into a lit portal.
*/
default boolean createPhysicalPortal(ServerLevel level, BlockPos anyPortalBlockPos, ResourceLocation dimensionId) {
return false;
}
}
@@ -288,7 +288,7 @@ public final class AntarchySettings {
private static int emperorScorpionWeaknessTicks = 120;
private static int emperorScorpionSummonIntervalTicks = 140;
private static int emperorScorpionMaxSummonedScorpions = 4;
private static int emperorScorpionMaxNearbyScorpions = 3;
private static int emperorScorpionMaxNearbyScorpions = 4;
private static int emperorScorpionHardenCooldownTicks = 2400;
private static double emperorScorpionDamageRange = 80.0D;
private static int emperorScorpionMinDespawnTicks = 6000;
@@ -344,6 +344,7 @@ public final class AntarchySettings {
private static double triffidHealth = 80.0D;
private static double triffidAttackDamage = 10.0D;
private static double triffidGrabDamage = 15.0D;
private static int triffidSweepHitCooldownTicks = 10;
private static double molevoreHealth = 60.0D;
private static double molevoreAttackDamage = 10.0D;
private static double molevoreMovementSpeed = 0.27D;
@@ -2243,6 +2244,9 @@ public final class AntarchySettings {
public static double triffidGrabDamage() { return triffidGrabDamage; }
public static void setTriffidGrabDamage(double value) { triffidGrabDamage = value; }
public static int triffidSweepHitCooldownTicks() { return triffidSweepHitCooldownTicks; }
public static void setTriffidSweepHitCooldownTicks(int value) { triffidSweepHitCooldownTicks = value; }
public static double molevoreHealth() { return molevoreHealth; }
public static void setMolevoreHealth(double value) { molevoreHealth = value; }
@@ -6,7 +6,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
public final class ConfigResetGuard {
public static final int RESET_GENERATION = 5;
public static final int RESET_GENERATION = 6;
private static final String MARKER_FILE_NAME = ".config_generation";
private ConfigResetGuard() {
@@ -108,6 +108,8 @@ public final class AntarchyObjects {
@SuppressWarnings("unchecked")
public static Supplier<EntityType<StinkBugEntity>> STINK_BUG = (Supplier<EntityType<StinkBugEntity>>) UNBOUND;
@SuppressWarnings("unchecked")
public static Supplier<EntityType<com.craisinlord.antarchy.content.entity.RollyPollyEntity>> ROLLY_POLLY = (Supplier<EntityType<com.craisinlord.antarchy.content.entity.RollyPollyEntity>>) UNBOUND;
@SuppressWarnings("unchecked")
public static Supplier<EntityType<com.craisinlord.antarchy.content.entity.CheepEntity>> CHEEP = (Supplier<EntityType<com.craisinlord.antarchy.content.entity.CheepEntity>>) UNBOUND;
@SuppressWarnings("unchecked")
public static Supplier<EntityType<com.craisinlord.antarchy.content.entity.DorrieEntity>> DORRIE = (Supplier<EntityType<com.craisinlord.antarchy.content.entity.DorrieEntity>>) UNBOUND;
@@ -605,6 +607,10 @@ public final class AntarchyObjects {
OURANWOOD_DEER = supplier;
}
public static void setRollyPolly(Supplier<EntityType<com.craisinlord.antarchy.content.entity.RollyPollyEntity>> supplier) {
ROLLY_POLLY = supplier;
}
public static void setGlimmer(Supplier<EntityType<com.craisinlord.antarchy.content.entity.glimmer.GlimmerEntity>> supplier) {
GLIMMER = supplier;
}
@@ -31,6 +31,7 @@ public final class AntarchySoundEvents {
public static Supplier<SoundEvent> BRUTALFLY_IDLE = (Supplier<SoundEvent>) UNBOUND;
public static Supplier<SoundEvent> BRUTALFLY_DEATH = (Supplier<SoundEvent>) UNBOUND;
public static Supplier<SoundEvent> ELYTHIA_FIREFLY_AMBIENT = (Supplier<SoundEvent>) UNBOUND;
public static Supplier<SoundEvent> ELYTHIA_OURANWOOD_FOREST_AMBIENT = (Supplier<SoundEvent>) UNBOUND;
public static Supplier<SoundEvent> MISSILE_SQUID_AMBIENT = (Supplier<SoundEvent>) UNBOUND;
public static Supplier<SoundEvent> MISSILE_SQUID_HURT = (Supplier<SoundEvent>) UNBOUND;
public static Supplier<SoundEvent> MISSILE_SQUID_DEATH = (Supplier<SoundEvent>) UNBOUND;
@@ -195,6 +196,7 @@ public final class AntarchySoundEvents {
Supplier<SoundEvent> brutalflyIdle,
Supplier<SoundEvent> brutalflyDeath,
Supplier<SoundEvent> elythiaFireflyAmbient,
Supplier<SoundEvent> elythiaOuranwoodForestAmbient,
Supplier<SoundEvent> missileSquidAmbient,
Supplier<SoundEvent> missileSquidHurt,
Supplier<SoundEvent> missileSquidDeath,
@@ -355,6 +357,7 @@ public final class AntarchySoundEvents {
BRUTALFLY_IDLE = brutalflyIdle;
BRUTALFLY_DEATH = brutalflyDeath;
ELYTHIA_FIREFLY_AMBIENT = elythiaFireflyAmbient;
ELYTHIA_OURANWOOD_FOREST_AMBIENT = elythiaOuranwoodForestAmbient;
MISSILE_SQUID_AMBIENT = missileSquidAmbient;
MISSILE_SQUID_HURT = missileSquidHurt;
MISSILE_SQUID_DEATH = missileSquidDeath;
@@ -38,6 +38,7 @@ public final class AntarchyTags {
public static final TagKey<Block> ELYTHIA_PORTAL_FRAMES = TagKey.create(Registries.BLOCK, id("elythia_portal_frames"));
public static final TagKey<Block> THORAXIS_PORTAL_FRAMES = TagKey.create(Registries.BLOCK, id("thoraxis_portal_frames"));
public static final TagKey<Block> CAVARYN_PORTAL_FRAMES = TagKey.create(Registries.BLOCK, id("cavaryn_portal_frames"));
public static final TagKey<Block> RAINBOW_PORTAL_FRAMES = TagKey.create(Registries.BLOCK, id("rainbow_portal_frames"));
public static final TagKey<Block> ROLLY_CAVERN_CARVEABLE = TagKey.create(Registries.BLOCK, id("rolly_cavern_carveable"));
public static final TagKey<Block> MINERS_DREAM_CARVABLE = TagKey.create(Registries.BLOCK, id("miners_dream_carvable"));
public static final TagKey<Block> BLUESTONE_COMPONENTS = TagKey.create(Registries.BLOCK, id("bluestone_components"));
@@ -57,6 +57,16 @@ public final class CloudBlock extends Block implements BucketPickup {
return adjacentBlockState.is(this) || super.skipRendering(state, adjacentBlockState, side);
}
@Override
protected boolean propagatesSkylightDown(BlockState state, BlockGetter level, BlockPos pos) {
return true;
}
@Override
protected int getLightBlock(BlockState state, BlockGetter level, BlockPos pos) {
return 0;
}
@Override
public void fallOn(Level level, BlockState state, BlockPos pos, Entity entity, float fallDistance) {
entity.causeFallDamage(fallDistance, 0.0F, level.damageSources().fall());
@@ -0,0 +1,23 @@
package com.craisinlord.antarchy.content.client.model;
import com.craisinlord.antarchy.Antarchy;
import com.craisinlord.antarchy.content.entity.WaterBombEntity;
import net.minecraft.resources.ResourceLocation;
import software.bernie.geckolib.model.GeoModel;
public class WaterBombModel extends GeoModel<WaterBombEntity> {
@Override
public ResourceLocation getModelResource(WaterBombEntity animatable) {
return ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "geo/water_bomb.geo.json");
}
@Override
public ResourceLocation getTextureResource(WaterBombEntity animatable) {
return ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/vfx/water_bomb.png");
}
@Override
public ResourceLocation getAnimationResource(WaterBombEntity animatable) {
return ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "animations/water_bomb.animation.json");
}
}
@@ -3,14 +3,11 @@ package com.craisinlord.antarchy.content.client.renderer;
import com.craisinlord.antarchy.content.client.model.NightmarePortalModel;
import com.craisinlord.antarchy.content.entity.nightmare.NightmarePortalEntity;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.resources.ResourceLocation;
import org.jetbrains.annotations.Nullable;
import software.bernie.geckolib.cache.object.BakedGeoModel;
import software.bernie.geckolib.renderer.GeoEntityRenderer;
public class NightmarePortalRenderer extends GeoEntityRenderer<NightmarePortalEntity> {
@@ -21,17 +18,11 @@ public class NightmarePortalRenderer extends GeoEntityRenderer<NightmarePortalEn
@Override
public void render(NightmarePortalEntity entity, float entityYaw, float partialTick, PoseStack poseStack, MultiBufferSource bufferSource, int packedLight) {
BakedGeoModel model = this.getGeoModel().getBakedModel(this.getGeoModel().getModelResource(entity));
RenderType renderType = RenderType.eyes(NightmarePortalModel.TEXTURE);
VertexConsumer buffer = bufferSource.getBuffer(renderType);
poseStack.pushPose();
poseStack.scale(1.0F, 1.0F, 1.0F);
this.reRender(model, poseStack, bufferSource, entity, renderType, buffer, partialTick, 0xF000F0, OverlayTexture.NO_OVERLAY, 0xFFFFFFFF);
poseStack.popPose();
super.render(entity, entityYaw, partialTick, poseStack, bufferSource, 0xF000F0);
}
@Override
public @Nullable RenderType getRenderType(NightmarePortalEntity animatable, ResourceLocation texture, @Nullable MultiBufferSource bufferSource, float partialTick) {
return RenderType.eyes(NightmarePortalModel.TEXTURE);
return RenderType.entityCutoutNoCull(NightmarePortalModel.TEXTURE);
}
}
@@ -1,61 +1,37 @@
package com.craisinlord.antarchy.content.client.renderer;
import com.craisinlord.antarchy.content.client.model.WaterBombModel;
import com.craisinlord.antarchy.content.entity.WaterBombEntity;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.entity.EntityRenderer;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import org.joml.Matrix4f;
import com.mojang.math.Axis;
import net.minecraft.util.Mth;
import software.bernie.geckolib.renderer.GeoEntityRenderer;
public class WaterBombRenderer extends EntityRenderer<WaterBombEntity> {
private static final ResourceLocation WATER_TEXTURE = ResourceLocation.withDefaultNamespace("textures/block/water_still.png");
public class WaterBombRenderer extends GeoEntityRenderer<WaterBombEntity> {
public WaterBombRenderer(EntityRendererProvider.Context context) {
super(context);
super(context, new WaterBombModel());
this.shadowRadius = 0.0F;
}
@Override
protected int getBlockLightLevel(WaterBombEntity entity, BlockPos pos) {
return 12;
protected void applyRotations(WaterBombEntity animatable, PoseStack poseStack, float ageInTicks, float rotationYaw, float partialTick, float nativeScale) {
float appliedYaw = Mth.rotLerp(partialTick, animatable.yRotO, animatable.getYRot());
float appliedPitch = Mth.lerp(partialTick, animatable.xRotO, animatable.getXRot());
poseStack.mulPose(Axis.YP.rotationDegrees(appliedYaw - 90.0F));
poseStack.mulPose(Axis.XP.rotationDegrees(-appliedPitch));
}
@Override
public void render(WaterBombEntity entity, float entityYaw, float partialTick, PoseStack poseStack, MultiBufferSource buffer, int packedLight) {
poseStack.pushPose();
poseStack.mulPose(this.entityRenderDispatcher.cameraOrientation());
float scale = entity.isHuge() ? 1.5F : 0.5F;
protected float getDeathMaxRotation(WaterBombEntity animatable) {
return 0.0F;
}
@Override
public void preRender(PoseStack poseStack, WaterBombEntity animatable, software.bernie.geckolib.cache.object.BakedGeoModel bakedModel, net.minecraft.client.renderer.MultiBufferSource bufferSource, com.mojang.blaze3d.vertex.VertexConsumer buffer, boolean isReRender, float partialTick, int packedLight, int packedOverlay, int colour) {
float scale = animatable.isHuge() ? 1.5F : 0.5F;
poseStack.scale(scale, scale, scale);
VertexConsumer vertexConsumer = buffer.getBuffer(RenderType.entityTranslucent(WATER_TEXTURE));
PoseStack.Pose pose = poseStack.last();
Matrix4f matrix4f = pose.pose();
addVertex(vertexConsumer, pose, matrix4f, -0.5F, -0.5F, 0.0F, 1.0F, packedLight);
addVertex(vertexConsumer, pose, matrix4f, 0.5F, -0.5F, 1.0F, 1.0F, packedLight);
addVertex(vertexConsumer, pose, matrix4f, 0.5F, 0.5F, 1.0F, 0.0F, packedLight);
addVertex(vertexConsumer, pose, matrix4f, -0.5F, 0.5F, 0.0F, 0.0F, packedLight);
poseStack.popPose();
super.render(entity, entityYaw, partialTick, poseStack, buffer, packedLight);
}
private static void addVertex(VertexConsumer vertexConsumer, PoseStack.Pose pose, Matrix4f matrix4f,
float x, float y, float u, float v, int packedLight) {
vertexConsumer.addVertex(matrix4f, x, y, 0.0F)
.setColor(0.05F, 0.15F, 0.6F, 0.9F)
.setUv(u, v)
.setOverlay(OverlayTexture.NO_OVERLAY)
.setLight(packedLight)
.setNormal(pose, 0.0F, 0.0F, 1.0F);
}
@Override
public ResourceLocation getTextureLocation(WaterBombEntity entity) {
return WATER_TEXTURE;
super.preRender(poseStack, animatable, bakedModel, bufferSource, buffer, isReRender, partialTick, packedLight, packedOverlay, colour);
}
}
@@ -7,7 +7,6 @@ import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectCategory;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.phys.Vec3;
public final class DreadMobEffect extends MobEffect {
public DreadMobEffect() {
@@ -23,8 +22,7 @@ public final class DreadMobEffect extends MobEffect {
int maxTicks = Math.max(minTicks, (int) Math.round(AntarchySettings.dreadHallucinationMobMaxInterval() * 20.0D));
int averageTicks = (minTicks + maxTicks) / 2;
if (player.getRandom().nextInt(averageTicks) == 0) {
Vec3 spawnPos = player.position().add(0.0D, player.getBbHeight() * 0.6D, 0.0D);
NightmareBiteEntity.spawnAt(serverLevel, spawnPos, player.getYRot(), false);
NightmareBiteEntity.spawnAt(serverLevel, player, false);
}
}
return true;
@@ -63,7 +63,12 @@ public class AlphaMantisEntity extends MantisEntity {
@Override
public boolean hurt(DamageSource source, float amount) {
return super.hurt(source, BossCombatUtil.capSingleHitAtHalfHealth(this, amount));
float preHealth = this.getHealth();
boolean hurt = super.hurt(source, amount);
if (hurt) {
BossCombatUtil.clampHalfHealthCrossing(this, preHealth);
}
return hurt;
}
public static boolean checkAlphaMantisSpawnRules(EntityType<AlphaMantisEntity> entityType, ServerLevelAccessor level, MobSpawnType spawnReason, BlockPos pos, RandomSource random) {
@@ -19,6 +19,7 @@ import net.minecraft.server.level.ServerBossEvent;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.world.BossEvent;
import net.minecraft.world.Difficulty;
@@ -34,8 +35,6 @@ import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.ai.goal.FloatGoal;
import net.minecraft.world.entity.ai.goal.Goal;
import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal;
import net.minecraft.world.entity.ai.goal.RandomLookAroundGoal;
import net.minecraft.world.entity.ai.goal.RandomStrollGoal;
import net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal;
import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal;
@@ -81,22 +80,19 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity {
private static final double CLAW_LUNGE_LIFT = 0.02D;
private static final double STING_LUNGE_SPEED = 0.08D;
private static final double STING_LUNGE_LIFT = 0.01D;
private static final double CLAW_RANGE = 5.25D;
private static final double STING_RANGE = 5.75D;
private static final double CLAW_REACH = 5.0D;
private static final double STING_REACH = 6.0D;
private static final double CLAW_HIT_REACH = 6.25D;
private static final double STING_HIT_REACH = 7.5D;
private static final double DIRECT_APPROACH_RANGE = 12.0D;
private static final float DIRECT_APPROACH_TURN_RATE = 10.0F;
private static final float DIRECT_APPROACH_ALIGN_THRESHOLD = 45.0F;
private static final int HARDEN_START_TICKS = 11;
private static final int HARDEN_END_TICKS = 20;
private static final int HARDEN_HEAL_INTERVAL_TICKS = 20;
private static final float HARDEN_HEAL_AMOUNT = 2.0F;
private static final int HARDEN_MIN_DURATION_TICKS = 100;
private static final int HARDEN_MAX_DURATION_TICKS = 200;
private static final double CLAW_VERTICAL_TOLERANCE = 2.5D;
private static final double STING_VERTICAL_TOLERANCE = 3.25D;
private static final double CLAW_FORWARD_DOT = 0.05D;
private static final double STING_FORWARD_DOT = 0.45D;
private static final double CLAW_STRIKE_FORWARD = 2.6D;
private static final double STING_STRIKE_FORWARD = 3.4D;
private static final double CLAW_STRIKE_RADIUS = 2.35D;
private static final double STING_STRIKE_RADIUS = 2.15D;
private static final double ENCOUNTER_HOME_RADIUS = 72.0D;
private static final double ENCOUNTER_LEASH_RADIUS = 96.0D;
private static final double HOME_REACHED_RADIUS = 9.0D;
@@ -133,9 +129,6 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity {
private int hardenHealTicks;
private int hardenSummonedScorpions;
private int disengageTicks;
private float hardenLockedYaw;
private float hardenLockedPitch;
private float attackYaw;
private boolean attackDamageApplied;
private AttackType currentAttack = AttackType.NONE;
private HardenPhase hardenPhase = HardenPhase.NONE;
@@ -181,8 +174,6 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity {
this.goalSelector.addGoal(0, new FloatGoal(this));
this.goalSelector.addGoal(1, new EmperorScorpionCombatGoal());
this.goalSelector.addGoal(5, new RandomStrollGoal(this, 0.8D));
this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 12.0F));
this.goalSelector.addGoal(7, new RandomLookAroundGoal(this));
this.targetSelector.addGoal(1, new HurtByTargetGoal(this));
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true));
}
@@ -197,10 +188,11 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity {
if (this.isHardenedStateActive()) {
return false;
}
amount = BossCombatUtil.capSingleHitAtHalfHealth(this, amount);
float preHealth = this.getHealth();
boolean hurt = super.hurt(source, amount);
if (hurt) {
this.hasTakenDamage = true;
BossCombatUtil.clampHalfHealthCrossing(this, preHealth);
}
return hurt;
}
@@ -244,11 +236,6 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity {
return 1.5F;
}
@Override
public int getMaxHeadYRot() {
return 40;
}
@Override
public void tick() {
super.tick();
@@ -326,7 +313,6 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity {
this.previousAttack = attackType;
this.attackAnimTicks = attackType.animTicks();
this.attackDamageApplied = false;
this.attackYaw = this.getYRot();
this.getNavigation().stop();
if (attackType == AttackType.CLAW) {
this.clawCooldownTicks = AntarchySettings.emperorScorpionClawCooldownTicks();
@@ -345,12 +331,6 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity {
return;
}
if (this.attackAnimTicks > this.currentAttack.commitTick()) {
this.getLookControl().setLookAt(this.attackTarget, 30.0F, 30.0F);
this.attackYaw = this.getYRot();
} else {
this.lockAttackRotation();
}
if (!this.attackDamageApplied
&& this.attackAnimTicks == this.currentAttack.hitTick()
&& this.canHitAttackTarget(this.attackTarget, this.currentAttack)) {
@@ -367,25 +347,8 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity {
if (!target.isAlive() || !this.hasLineOfSight(target)) {
return false;
}
Vec3 origin = this.getStrikeOrigin(attackType);
Vec3 targetCenter = target.position().add(0.0D, target.getBbHeight() * 0.5D, 0.0D);
Vec3 offset = targetCenter.subtract(origin);
double verticalTolerance = attackType == AttackType.STING ? STING_VERTICAL_TOLERANCE : CLAW_VERTICAL_TOLERANCE;
if (Math.abs(offset.y) > verticalTolerance) {
return false;
}
Vec3 horizontal = new Vec3(offset.x, 0.0D, offset.z);
if (horizontal.lengthSqr() < 1.0E-6D) {
return true;
}
Vec3 forward = Vec3.directionFromRotation(0.0F, this.attackYaw);
double forwardDot = horizontal.normalize().dot(new Vec3(forward.x, 0.0D, forward.z).normalize());
double minForwardDot = attackType == AttackType.STING ? STING_FORWARD_DOT : CLAW_FORWARD_DOT;
if (forwardDot < minForwardDot) {
return false;
}
double strikeRadius = attackType == AttackType.STING ? STING_STRIKE_RADIUS : CLAW_STRIKE_RADIUS;
return origin.distanceToSqr(targetCenter) <= strikeRadius * strikeRadius;
double reach = attackType == AttackType.STING ? STING_HIT_REACH : CLAW_HIT_REACH;
return this.distanceToSqr(target) <= reach * reach;
}
private void resetAttackState() {
@@ -395,11 +358,10 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity {
this.attackTarget = null;
}
private Vec3 getStrikeOrigin(AttackType attackType) {
Vec3 forward = Vec3.directionFromRotation(0.0F, this.attackYaw);
double forwardOffset = attackType == AttackType.STING ? STING_STRIKE_FORWARD : CLAW_STRIKE_FORWARD;
double verticalOffset = attackType == AttackType.STING ? this.getBbHeight() * 0.8D : this.getBbHeight() * 0.52D;
return this.position().add(forward.x * forwardOffset, verticalOffset, forward.z * forwardOffset);
private float approachYaw(float current, float target, float maxDeltaPerTick) {
float delta = Mth.wrapDegrees(target - current);
delta = Math.max(-maxDeltaPerTick, Math.min(maxDeltaPerTick, delta));
return current + delta;
}
private void tickHardenState() {
@@ -416,10 +378,6 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity {
switch (this.getHardenPhase()) {
case CASTING -> {
LivingEntity target = this.getTarget();
if (target != null) {
this.getLookControl().setLookAt(target, 20.0F, 20.0F);
}
if (this.hardenCastTicks % this.hardenCastSpawnTicks == 0
&& this.hardenSummonedScorpions < AntarchySettings.emperorScorpionMaxSummonedScorpions()
&& this.countOwnedNearbyScorpionMinions() < AntarchySettings.emperorScorpionMaxNearbyScorpions()) {
@@ -435,13 +393,11 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity {
}
}
case START -> {
this.lockHardenRotation();
if (--this.hardenStateTicks <= 0) {
this.beginHardened();
}
}
case ACTIVE -> {
this.lockHardenRotation();
Vec3 motion = this.getDeltaMovement();
this.setDeltaMovement(0.0D, motion.y, 0.0D);
if (--this.hardenDurationTicks <= 0) {
@@ -454,7 +410,6 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity {
}
}
case END -> {
this.lockHardenRotation();
Vec3 motion = this.getDeltaMovement();
this.setDeltaMovement(0.0D, motion.y, 0.0D);
if (--this.hardenStateTicks <= 0) {
@@ -481,8 +436,6 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity {
private void beginHardening() {
this.setHardenPhase(HardenPhase.START);
this.hardenStateTicks = HARDEN_START_TICKS;
this.hardenLockedYaw = this.getYRot();
this.hardenLockedPitch = this.getXRot();
this.playSound(AntarchySoundEvents.EMPEROR_SCORPION_ROAR.get(), 1.0F, 0.95F + this.random.nextFloat() * 0.05F);
this.setAggressive(false);
}
@@ -540,7 +493,6 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity {
return;
}
horizontal = horizontal.normalize().scale(horizontalSpeed);
this.attackYaw = (float) (net.minecraft.util.Mth.atan2(horizontal.z, horizontal.x) * (180.0D / Math.PI)) - 90.0F;
this.setDeltaMovement(this.getDeltaMovement().add(horizontal.x, verticalSpeed, horizontal.z));
this.hasImpulse = true;
}
@@ -603,27 +555,6 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity {
this.entityData.set(HARDEN_PHASE, phase.ordinal());
}
private void lockAttackRotation() {
this.setYRot(this.attackYaw);
this.setYHeadRot(this.attackYaw);
this.yBodyRot = this.attackYaw;
this.yBodyRotO = this.attackYaw;
this.yHeadRotO = this.attackYaw;
}
private void lockHardenRotation() {
if (!this.isHardenSequenceActive()) {
return;
}
this.setYRot(this.hardenLockedYaw);
this.setYHeadRot(this.hardenLockedYaw);
this.yBodyRot = this.hardenLockedYaw;
this.yBodyRotO = this.hardenLockedYaw;
this.yHeadRotO = this.hardenLockedYaw;
this.setXRot(this.hardenLockedPitch);
this.xRotO = this.hardenLockedPitch;
}
private void updateAnimationState() {
if (this.isDeadOrDying()) {
this.setAnimationState(ANIM_DEATH);
@@ -746,7 +677,6 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity {
this.encounterHome = new BlockPos(tag.getInt("EncounterHomeX"), tag.getInt("EncounterHomeY"), tag.getInt("EncounterHomeZ"));
}
this.resetAttackState();
this.attackYaw = this.getYRot();
if (this.getHardenPhase() == HardenPhase.CASTING) {
this.setHardenPhase(HardenPhase.NONE);
}
@@ -949,7 +879,12 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity {
}
private final class EmperorScorpionCombatGoal extends Goal {
private static final double CHASE_SPEED = 1.1D;
private static final double CHASE_SPEED = 1.15D;
private int repathCooldownTicks;
private double repathTargetX;
private double repathTargetY;
private double repathTargetZ;
private EmperorScorpionCombatGoal() {
this.setFlags(EnumSet.of(Goal.Flag.MOVE, Goal.Flag.LOOK));
@@ -964,12 +899,14 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity {
@Override
public boolean canContinueToUse() {
LivingEntity target = EmperorScorpionEntity.this.getTarget();
return (target != null && target.isAlive()) || EmperorScorpionEntity.this.isAttackLocked();
return EmperorScorpionEntity.this.isAttackLocked()
|| (target != null && target.isAlive() && !EmperorScorpionEntity.this.isHardenSequenceActive());
}
@Override
public void start() {
EmperorScorpionEntity.this.setAggressive(true);
this.repathCooldownTicks = 0;
}
@Override
@@ -980,70 +917,85 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity {
@Override
public void tick() {
if (EmperorScorpionEntity.this.isAttackLocked() || EmperorScorpionEntity.this.isHardenSequenceActive()) {
return;
}
LivingEntity target = EmperorScorpionEntity.this.getTarget();
if (target == null) {
return;
}
if (EmperorScorpionEntity.this.isWithinMeleeAttackRange(target) && EmperorScorpionEntity.this.hasLineOfSight(target)) {
EmperorScorpionEntity.this.getNavigation().stop();
EmperorScorpionEntity.this.setDeltaMovement(0.0D, EmperorScorpionEntity.this.getDeltaMovement().y, 0.0D);
AttackType attackType = EmperorScorpionEntity.this.selectAttack(target);
if (attackType != AttackType.NONE) {
EmperorScorpionEntity.this.beginAttack(target, attackType);
}
return;
}
if (EmperorScorpionEntity.this.isHardenSequenceActive()) {
this.stopMovement();
if (EmperorScorpionEntity.this.distanceToSqr(target) <= DIRECT_APPROACH_RANGE * DIRECT_APPROACH_RANGE
&& EmperorScorpionEntity.this.hasLineOfSight(target)) {
EmperorScorpionEntity.this.getNavigation().stop();
this.approachDirectly(target);
return;
}
EmperorScorpionEntity.this.getLookControl().setLookAt(target, 30.0F, 30.0F);
if (EmperorScorpionEntity.this.isAttackLocked()) {
this.stopMovement();
return;
}
if (!EmperorScorpionEntity.this.hasLineOfSight(target)) {
EmperorScorpionEntity.this.getNavigation().moveTo(target, CHASE_SPEED);
return;
}
if (!EmperorScorpionEntity.this.isWithinMeleeAttackRange(target)) {
EmperorScorpionEntity.this.getNavigation().moveTo(target, CHASE_SPEED);
return;
}
this.stopMovement();
AttackType attackType = EmperorScorpionEntity.this.selectAttack(target);
if (attackType == AttackType.NONE) {
EmperorScorpionEntity.this.getNavigation().moveTo(target, CHASE_SPEED);
return;
}
EmperorScorpionEntity.this.beginAttack(target, attackType);
this.tryRepath(target);
}
private void stopMovement() {
EmperorScorpionEntity.this.getNavigation().stop();
EmperorScorpionEntity.this.setSpeed(0.0F);
EmperorScorpionEntity.this.setZza(0.0F);
private void approachDirectly(LivingEntity target) {
double dx = target.getX() - EmperorScorpionEntity.this.getX();
double dz = target.getZ() - EmperorScorpionEntity.this.getZ();
if (dx * dx + dz * dz < 1.0E-4D) {
return;
}
float targetYaw = (float) (Mth.atan2(dz, dx) * (180.0D / Math.PI)) - 90.0F;
float currentYaw = EmperorScorpionEntity.this.getYRot();
float newYaw = EmperorScorpionEntity.this.approachYaw(currentYaw, targetYaw, DIRECT_APPROACH_TURN_RATE);
EmperorScorpionEntity.this.setYRot(newYaw);
EmperorScorpionEntity.this.setYHeadRot(newYaw);
EmperorScorpionEntity.this.yBodyRot = newYaw;
EmperorScorpionEntity.this.yBodyRotO = newYaw;
Vec3 currentMotion = EmperorScorpionEntity.this.getDeltaMovement();
float headingError = Math.abs(Mth.wrapDegrees(targetYaw - currentYaw));
if (headingError <= DIRECT_APPROACH_ALIGN_THRESHOLD) {
double speed = EmperorScorpionEntity.this.getAttributeValue(Attributes.MOVEMENT_SPEED) * CHASE_SPEED;
Vec3 forward = Vec3.directionFromRotation(0.0F, newYaw).scale(speed);
EmperorScorpionEntity.this.setDeltaMovement(forward.x, currentMotion.y, forward.z);
} else {
EmperorScorpionEntity.this.setDeltaMovement(0.0D, currentMotion.y, 0.0D);
}
}
private void tryRepath(LivingEntity target) {
if (--this.repathCooldownTicks > 0
&& target.distanceToSqr(this.repathTargetX, this.repathTargetY, this.repathTargetZ) < 1.0D) {
return;
}
this.repathTargetX = target.getX();
this.repathTargetY = target.getY();
this.repathTargetZ = target.getZ();
this.repathCooldownTicks = 4 + EmperorScorpionEntity.this.random.nextInt(7);
if (!EmperorScorpionEntity.this.getNavigation().moveTo(target, CHASE_SPEED)) {
this.repathCooldownTicks += 15;
}
}
}
@Override
public boolean isWithinMeleeAttackRange(LivingEntity target) {
if (this.encounterHome != null && target.distanceToSqr(Vec3.atCenterOf(this.encounterHome)) > ENCOUNTER_HOME_RADIUS * ENCOUNTER_HOME_RADIUS) {
return false;
}
return this.distanceToSqr(target) <= STING_RANGE * STING_RANGE;
return this.distanceToSqr(target) <= CLAW_REACH * CLAW_REACH;
}
private AttackType selectAttack(LivingEntity target) {
double horizontalDistance = this.distanceToSqr(target);
boolean inClawRange = this.clawCooldownTicks <= 0 && horizontalDistance <= CLAW_RANGE * CLAW_RANGE;
boolean inStingRange = this.stingCooldownTicks <= 0 && horizontalDistance <= STING_RANGE * STING_RANGE;
boolean canClaw = inClawRange && this.hasLineOfSight(target);
boolean canSting = inStingRange && this.hasLineOfSight(target);
double distSqr = this.distanceToSqr(target);
boolean canClaw = this.clawCooldownTicks <= 0 && distSqr <= CLAW_REACH * CLAW_REACH && this.hasLineOfSight(target);
boolean canSting = this.stingCooldownTicks <= 0 && distSqr <= STING_REACH * STING_REACH && this.hasLineOfSight(target);
if (canClaw && canSting) {
double heightDifference = target.getY() - this.getY();
if (heightDifference > 1.25D || horizontalDistance > CLAW_RANGE * CLAW_RANGE * 0.7D) {
return this.previousAttack == AttackType.STING && this.random.nextFloat() < 0.5F ? AttackType.CLAW : AttackType.STING;
}
return this.previousAttack == AttackType.CLAW && this.random.nextFloat() < 0.55F ? AttackType.STING : AttackType.CLAW;
}
if (canSting) {
@@ -1075,14 +1027,6 @@ public class EmperorScorpionEntity extends Monster implements GeoEntity {
default -> 0;
};
}
private int commitTick() {
return switch (this) {
case CLAW -> Math.max(1, this.hitTick() + 3);
case STING -> Math.max(1, this.hitTick() + 4);
default -> 0;
};
}
}
private enum HardenPhase {
@@ -56,6 +56,8 @@ import net.minecraft.world.entity.ai.goal.RandomLookAroundGoal;
import net.minecraft.world.entity.ai.goal.WaterAvoidingRandomStrollGoal;
import net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal;
import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal;
import net.minecraft.world.entity.ai.goal.target.OwnerHurtByTargetGoal;
import net.minecraft.world.entity.ai.goal.target.OwnerHurtTargetGoal;
import net.minecraft.world.entity.ai.navigation.FlyingPathNavigation;
import net.minecraft.world.entity.ai.navigation.PathNavigation;
import net.minecraft.world.entity.animal.FlyingAnimal;
@@ -141,6 +143,7 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl
private static final int CRY_COOLDOWN_TICKS = 120;
private static final int COMBAT_RESET_TICKS = 60;
private static final int IMPACT_SHAKE_TICKS = 25;
private static final int AIRBORNE_ANIMATION_HYSTERESIS_TICKS = 4;
private static final double FLIGHT_SPEED = 1.38D;
private static final double GROUND_SPEED = 0.34D;
private static final double CHARGE_SPEED = 1.5D;
@@ -250,6 +253,8 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl
&& !this.isKnockedDown()
&& !player.isCreative()
&& !player.isSpectator()));
this.targetSelector.addGoal(3, new OwnerHurtByTargetGoal(this));
this.targetSelector.addGoal(4, new OwnerHurtTargetGoal(this));
}
@Override
@@ -529,12 +534,11 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl
this.setAnimationState(ANIM_KNOCKED_DOWN_IDLE);
return;
}
if (this.isFlying()) {
if (this.isFlying() || this.airborneTicks > AIRBORNE_ANIMATION_HYSTERESIS_TICKS) {
this.setAnimationState(ANIM_FLY);
return;
}
if (!this.onGround()) {
this.setAnimationState(ANIM_IDLE);
return;
}
if (this.getControllingPassenger() instanceof Player rider) {
@@ -594,13 +598,16 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl
amount *= 0.5F;
}
amount = BossCombatUtil.capSingleHitAtHalfHealth(this, amount);
float preHealth = this.getHealth();
if (!this.level().isClientSide && !this.isTame() && !this.isKnockedDown() && !this.isDeadOrDying()) {
float knockThreshold = Math.max(1.0F, this.getMaxHealth() * 0.05F);
if (this.getHealth() - amount <= knockThreshold) {
float allowedDamage = Math.max(0.0F, this.getHealth() - knockThreshold);
boolean hurt = allowedDamage <= 0.0F || super.hurt(source, allowedDamage);
if (hurt) {
BossCombatUtil.clampHalfHealthCrossing(this, preHealth);
}
if (hurt && this.isAlive()) {
this.enterKnockedDown();
}
@@ -608,7 +615,11 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl
}
}
return super.hurt(source, amount);
boolean hurt = super.hurt(source, amount);
if (hurt) {
BossCombatUtil.clampHalfHealthCrossing(this, preHealth);
}
return hurt;
}
@Override
@@ -616,6 +627,9 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl
if (super.isInvulnerableTo(source)) {
return true;
}
if (this.isTame()) {
return false;
}
return BossCombatUtil.isOutOfDamageRange(this, AntarchySettings.herculesBeetleDamageRange());
}
@@ -1227,7 +1241,10 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl
@Override
public boolean canAttack(LivingEntity target) {
if (target instanceof Player player) {
return !this.isTame() && !player.isCreative() && !player.isSpectator() && super.canAttack(target);
if (this.isTame() && this.isOwnedBy(player)) {
return false;
}
return !player.isCreative() && !player.isSpectator() && super.canAttack(target);
}
return super.canAttack(target);
}
@@ -1237,7 +1254,10 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl
return false;
}
if (target instanceof Player player) {
return !player.isCreative() && !player.isSpectator() && !this.isTame();
if (this.isTame() && this.isOwnedBy(player)) {
return false;
}
return !player.isCreative() && !player.isSpectator();
}
return target.canBeSeenAsEnemy();
}
@@ -1402,8 +1422,8 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl
@Override
public boolean canUse() {
return !HerculesBeetleEntity.this.isTame()
&& !HerculesBeetleEntity.this.isKnockedDown()
return !HerculesBeetleEntity.this.isKnockedDown()
&& !HerculesBeetleEntity.this.isVehicle()
&& HerculesBeetleEntity.this.getTarget() != null
&& HerculesBeetleEntity.this.canAttack(HerculesBeetleEntity.this.getTarget());
}
@@ -1413,8 +1433,8 @@ public class HerculesBeetleEntity extends TamableAnimal implements GeoEntity, Fl
LivingEntity target = HerculesBeetleEntity.this.getTarget();
return target != null
&& target.isAlive()
&& !HerculesBeetleEntity.this.isTame()
&& !HerculesBeetleEntity.this.isKnockedDown()
&& !HerculesBeetleEntity.this.isVehicle()
&& HerculesBeetleEntity.this.canAttack(target);
}
@@ -7,6 +7,7 @@ import com.craisinlord.antarchy.content.AntarchySoundEvents;
import java.util.EnumSet;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.particles.ItemParticleOption;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.nbt.CompoundTag;
@@ -21,6 +22,7 @@ import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.Difficulty;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.AgeableMob;
import net.minecraft.world.entity.EntityType;
@@ -108,7 +110,15 @@ public class RollyPollyEntity extends TamableAnimal implements GeoEntity {
return true;
}
return Mob.checkMobSpawnRules(entityType, level, spawnReason, pos, random);
BlockPos belowPos = pos.below();
if (level.getDifficulty() == Difficulty.PEACEFUL) {
return false;
}
return level.getBlockState(pos).isAir()
&& level.getBlockState(pos.above()).isAir()
&& level.getFluidState(pos).isEmpty()
&& level.getFluidState(pos.above()).isEmpty()
&& level.getBlockState(belowPos).isFaceSturdy(level, belowPos, Direction.UP);
}
public static AttributeSupplier.Builder createAttributes() {
@@ -4,9 +4,9 @@ import com.craisinlord.antarchy.content.AntarchyObjects;
import com.craisinlord.antarchy.content.AntarchySoundEvents;
import com.craisinlord.antarchy.content.effect.StinkyBehavior;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.RandomSource;
import net.minecraft.world.Difficulty;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.AgeableMob;
import net.minecraft.world.entity.EntityType;
@@ -25,6 +25,7 @@ import net.minecraft.sounds.SoundEvent;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.ServerLevelAccessor;
import net.minecraft.world.Difficulty;
import org.jetbrains.annotations.Nullable;
import software.bernie.geckolib.animatable.GeoEntity;
import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache;
@@ -68,8 +69,15 @@ public class StinkBugEntity extends Animal implements GeoEntity {
if (spawnReason == MobSpawnType.SPAWN_EGG || spawnReason == MobSpawnType.SPAWNER || spawnReason == MobSpawnType.COMMAND) {
return true;
}
return level.getDifficulty() != Difficulty.PEACEFUL
&& Mob.checkMobSpawnRules(entityType, level, spawnReason, pos, random);
BlockPos belowPos = pos.below();
if (level.getDifficulty() == Difficulty.PEACEFUL) {
return false;
}
return level.getBlockState(pos).isAir()
&& level.getBlockState(pos.above()).isAir()
&& level.getFluidState(pos).isEmpty()
&& level.getFluidState(pos.above()).isEmpty()
&& level.getBlockState(belowPos).isFaceSturdy(level, belowPos, Direction.UP);
}
@Override
@@ -4,9 +4,9 @@ import com.craisinlord.antarchy.config.AntarchySettings;
import com.craisinlord.antarchy.content.AntarchySoundEvents;
import com.craisinlord.antarchy.content.AntarchyTags;
import com.craisinlord.antarchy.content.damage.AntarchyDamageSources;
import java.util.HashSet;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.Map;
import java.util.UUID;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
@@ -78,7 +78,7 @@ public class TriffidEntity extends Monster implements GeoEntity {
private static final RawAnimation DEATH_ANIM = RawAnimation.begin().thenPlayAndHold("death");
private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this);
private final Set<UUID> sweepHitEntities = new HashSet<>();
private final Map<UUID, Integer> sweepHitCooldowns = new HashMap<>();
private int actionTicks;
private int attackCooldown;
@@ -341,7 +341,6 @@ public class TriffidEntity extends Monster implements GeoEntity {
this.actionTicks = SWEEP_TOTAL_TICKS;
this.attackCooldown = SWEEP_COOLDOWN_TICKS;
this.actionStartYaw = this.getAngleTo(target) - 100.0F;
this.sweepHitEntities.clear();
this.setYRot(this.actionStartYaw);
this.playSound(AntarchySoundEvents.TRIFFID_ATTACK.get(), 0.9F, 0.75F);
}
@@ -351,6 +350,7 @@ public class TriffidEntity extends Monster implements GeoEntity {
float progress = elapsed / (float) SWEEP_TOTAL_TICKS;
this.setYRot(this.actionStartYaw + 200.0F * progress);
this.tickSweepHitCooldowns();
if (elapsed >= SWEEP_ACTIVE_START && elapsed <= SWEEP_ACTIVE_END) {
this.applySweepDamage();
}
@@ -358,10 +358,17 @@ public class TriffidEntity extends Monster implements GeoEntity {
this.actionTicks--;
if (this.actionTicks <= 0) {
this.setActionState(ACTION_NONE);
this.sweepHitEntities.clear();
}
}
private void tickSweepHitCooldowns() {
if (this.sweepHitCooldowns.isEmpty()) {
return;
}
this.sweepHitCooldowns.replaceAll((uuid, ticksRemaining) -> ticksRemaining - 1);
this.sweepHitCooldowns.values().removeIf(ticksRemaining -> ticksRemaining <= 0);
}
private void applySweepDamage() {
if (!(this.level() instanceof ServerLevel serverLevel)) {
return;
@@ -374,7 +381,7 @@ public class TriffidEntity extends Monster implements GeoEntity {
);
for (LivingEntity candidate : candidates) {
if (candidate == this || this.sweepHitEntities.contains(candidate.getUUID())) {
if (candidate == this || this.sweepHitCooldowns.containsKey(candidate.getUUID())) {
continue;
}
if (this.distanceTo(candidate) > SWEEP_RANGE) {
@@ -386,9 +393,12 @@ public class TriffidEntity extends Monster implements GeoEntity {
continue;
}
if (candidate.hurt(AntarchyDamageSources.triffidMauling(serverLevel, this), (float) AntarchySettings.triffidAttackDamage())) {
this.sweepHitEntities.add(candidate.getUUID());
}
// Put the entity on cooldown before hurting it, regardless of hurt()'s result: a
// shield or armor effect can absorb the damage and make hurt() return false without
// granting the vanilla invulnerability window, which would otherwise let this attack
// re-attempt damage on the same entity every single tick of the active window.
this.sweepHitCooldowns.put(candidate.getUUID(), AntarchySettings.triffidSweepHitCooldownTicks());
candidate.hurt(AntarchyDamageSources.triffidMauling(serverLevel, this), (float) AntarchySettings.triffidAttackDamage());
}
}
@@ -28,22 +28,35 @@ import net.minecraft.network.syncher.SynchedEntityData;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import software.bernie.geckolib.animatable.GeoEntity;
import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache;
import software.bernie.geckolib.animation.AnimatableManager;
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 class WaterBombEntity extends ThrowableProjectile {
public class WaterBombEntity extends ThrowableProjectile implements GeoEntity {
private static final RawAnimation IDLE_ANIM = RawAnimation.begin().thenLoop("idle");
private static final EntityDataAccessor<Boolean> HUGE = SynchedEntityData.defineId(WaterBombEntity.class, EntityDataSerializers.BOOLEAN);
private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this);
private int lifetimeTicks;
private final Map<UUID, Integer> hitCooldowns = new HashMap<>();
public WaterBombEntity(EntityType<? extends WaterBombEntity> entityType, Level level) {
super(entityType, level);
this.lifetimeTicks = AntarchySettings.waterBombLifetimeTicks();
this.configureProjectile();
}
public WaterBombEntity(Level level, LivingEntity owner) {
super(AntarchyObjects.WATER_BOMB.get(), owner, level);
this.lifetimeTicks = AntarchySettings.waterBombLifetimeTicks();
this.configureProjectile();
}
public WaterBombEntity(Level level, LivingEntity owner, boolean huge) {
@@ -51,6 +64,10 @@ public class WaterBombEntity extends ThrowableProjectile {
this.entityData.set(HUGE, huge);
}
private void configureProjectile() {
this.noCulling = true;
}
@Override
protected void defineSynchedData(SynchedEntityData.Builder builder) {
builder.define(HUGE, false);
@@ -68,6 +85,7 @@ public class WaterBombEntity extends ThrowableProjectile {
@Override
public void tick() {
super.tick();
this.realignToMotion();
this.hitCooldowns.replaceAll((uuid, cd) -> cd - 1);
this.hitCooldowns.entrySet().removeIf(e -> e.getValue() <= 0);
@@ -143,4 +161,29 @@ public class WaterBombEntity extends ThrowableProjectile {
this.lifetimeTicks = tag.contains("LifetimeTicks") ? tag.getInt("LifetimeTicks") : AntarchySettings.waterBombLifetimeTicks();
if (tag.contains("Huge")) this.entityData.set(HUGE, tag.getBoolean("Huge"));
}
private void realignToMotion() {
Vec3 motion = this.getDeltaMovement();
if (motion.lengthSqr() < 1.0E-6D) {
return;
}
double horizontal = Math.sqrt(motion.x * motion.x + motion.z * motion.z);
this.setYRot((float) (net.minecraft.util.Mth.atan2(motion.z, motion.x) * (180.0D / Math.PI)) - 90.0F);
this.setXRot((float) (-(net.minecraft.util.Mth.atan2(motion.y, horizontal) * (180.0D / Math.PI))));
}
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "water_bomb_controller", 0, this::waterBombController));
}
private PlayState waterBombController(AnimationState<WaterBombEntity> state) {
return state.setAndContinue(IDLE_ANIM);
}
@Override
public AnimatableInstanceCache getAnimatableInstanceCache() {
return this.geoCache;
}
}
@@ -4,6 +4,7 @@ import com.craisinlord.antarchy.Antarchy;
import com.craisinlord.antarchy.compat.infinity.InfinityCompat;
import com.craisinlord.antarchy.config.AntarchySettings;
import com.craisinlord.antarchy.content.AntarchyTags;
import com.craisinlord.antarchy.content.portal.RainbowPortalIgniter;
import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
@@ -75,6 +76,31 @@ public class RainbowAntEntity extends BaseAntEntity implements GeoEntity {
return this.hasActiveInfinityDestination() || super.requiresCustomPersistence();
}
/**
* Called on death. If this ant has already been activated (fed its reagent) and Infinity integration is
* enabled, looks for a nearby unlit obsidian Nether-portal frame and, if found, ignites it as a permanent
* physical Infinity Dimensions portal to this ant's assigned dimension.
*/
public boolean tryIgniteInfinityPortalOnDeath() {
if (!this.infinityActivated) {
return false;
}
if (!AntarchySettings.permanentPortalsEnabled() || !AntarchySettings.rainbowAntsLeadToInfinityDimensions()
|| !InfinityCompat.get().isAvailable()) {
return false;
}
if (!(this.level() instanceof ServerLevel serverLevel)) {
return false;
}
ResourceLocation dimensionId = this.resolveDimensionId();
if (dimensionId == null) {
return false;
}
return RainbowPortalIgniter.tryIgnite(serverLevel, this.getBoundingBox(), dimensionId);
}
@Override
public InteractionResult mobInteract(Player player, InteractionHand hand) {
if (!AntTeleportHelper.isRightClickDimensionEnabled(this)) {
@@ -189,6 +215,11 @@ public class RainbowAntEntity extends BaseAntEntity implements GeoEntity {
return child;
}
@Override
public boolean isFood(ItemStack stack) {
return this.infinityActivated && super.isFood(stack);
}
@Override
protected ResourceKey<Level> destinationDimension() {
return AntarchySettings.rainbowAntNonInfinityFallbackDimension();
@@ -384,7 +384,12 @@ public class BrutalflyEntity extends Monster implements GeoEntity {
}
return true;
}
return super.hurt(source, BossCombatUtil.capSingleHitAtHalfHealth(this, amount));
float preHealth = this.getHealth();
boolean hurt = super.hurt(source, amount);
if (hurt) {
BossCombatUtil.clampHalfHealthCrossing(this, preHealth);
}
return hurt;
}
@Override
@@ -138,7 +138,11 @@ public class CloudSharkEntity extends Monster implements GeoEntity {
HurtByTargetGoal hurtByTargetGoal = new HurtByTargetGoal(this);
hurtByTargetGoal.setAlertOthers(CloudSharkEntity.class);
this.targetSelector.addGoal(1, hurtByTargetGoal);
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true));
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, CloudSharkEntity::isTargetablePlayer));
}
private static boolean isTargetablePlayer(LivingEntity target) {
return !(target instanceof Player player) || (!player.isCreative() && !player.isSpectator());
}
@Override
@@ -194,7 +198,7 @@ public class CloudSharkEntity extends Monster implements GeoEntity {
LivingEntity target = this.getTarget();
if ((target == null || !target.isAlive()) && this.tickCount % 10 == 0) {
Player nearbyPlayer = this.level().getNearestPlayer(this, 32.0D);
if (nearbyPlayer != null && this.canAttack(nearbyPlayer)) {
if (nearbyPlayer != null && isTargetablePlayer(nearbyPlayer) && this.canAttack(nearbyPlayer)) {
this.setTarget(nearbyPlayer);
target = nearbyPlayer;
}
@@ -6,7 +6,6 @@ import com.craisinlord.antarchy.content.AntarchyTags;
import com.craisinlord.antarchy.content.AntarchySoundEvents;
import com.craisinlord.antarchy.content.block.OuranwoodAcornBlock;
import com.craisinlord.antarchy.content.block.OuranwoodLeavesBlock;
import com.mojang.logging.LogUtils;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.particles.ItemParticleOption;
@@ -55,14 +54,11 @@ import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache;
import software.bernie.geckolib.animation.*;
import software.bernie.geckolib.animation.AnimationState;
import software.bernie.geckolib.util.GeckoLibUtil;
import org.slf4j.Logger;
import java.util.EnumSet;
import java.util.Optional;
import java.util.UUID;
public class FlyingSquirrelEntity extends TamableAnimal implements GeoEntity {
private static final Logger LOGGER = LogUtils.getLogger();
private static final ResourceKey<Level> ELYTHIA_DIMENSION = ResourceKey.create(
Registries.DIMENSION,
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "elythia")
@@ -405,6 +401,10 @@ public class FlyingSquirrelEntity extends TamableAnimal implements GeoEntity {
this.tickPickupAnimation();
this.tickQuirkAnimation();
this.syncQuirkAnimationTrigger();
if (this.hasActiveQuirkAnimation()) {
this.cancelTravel();
this.setDeltaMovement(Vec3.ZERO);
}
if (this.isClimbingToShoulder()) {
Player shoulderPlayer = this.shoulderPlayerId != null
@@ -812,14 +812,10 @@ public class FlyingSquirrelEntity extends TamableAnimal implements GeoEntity {
int variant = this.random.nextBoolean() ? QUIRK_1 : QUIRK_2;
this.setQuirkVariant(variant);
this.setQuirkTicks(variant == QUIRK_1 ? QUIRK_1_DURATION_TICKS : QUIRK_2_DURATION_TICKS);
LOGGER.info("FlyingSquirrel animation selected={} tick={}", variant == QUIRK_2 ? QUIRK_2_TRIGGER : QUIRK_1_TRIGGER, this.tickCount);
this.quirkCooldownTicks = this.nextQuirkCooldown();
}
private void stopQuirkAnimation() {
if (this.getQuirkVariant() != QUIRK_NONE || this.getQuirkTicks() > 0) {
LOGGER.info("FlyingSquirrel animation state cleared variant={} tick={}", this.getQuirkVariant(), this.tickCount);
}
this.setQuirkTicks(0);
this.setQuirkVariant(QUIRK_NONE);
}
@@ -828,9 +824,6 @@ public class FlyingSquirrelEntity extends TamableAnimal implements GeoEntity {
int quirkVariant = this.getQuirkVariant();
if (quirkVariant != QUIRK_NONE && this.getQuirkTicks() > 0 && this.lastTriggeredQuirkVariant != quirkVariant) {
String triggerName = quirkVariant == QUIRK_2 ? QUIRK_2_TRIGGER : QUIRK_1_TRIGGER;
if (!this.level().isClientSide) {
LOGGER.info("FlyingSquirrel triggerAnim called={} tick={}", triggerName, this.tickCount);
}
this.triggerAnim(QUIRK_CONTROLLER, triggerName);
this.lastTriggeredQuirkVariant = quirkVariant;
return;
@@ -369,7 +369,12 @@ public class KrakenEntity extends Monster implements GeoEntity, MultipartEntityO
return false;
}
return super.hurt(source, BossCombatUtil.capSingleHitAtHalfHealth(this, amount));
float preHealth = this.getHealth();
boolean hurt = super.hurt(source, amount);
if (hurt) {
BossCombatUtil.clampHalfHealthCrossing(this, preHealth);
}
return hurt;
}
@Override
@@ -1,16 +1,22 @@
package com.craisinlord.antarchy.content.entity.nightmare;
import com.craisinlord.antarchy.config.AntarchySettings;
import com.craisinlord.antarchy.content.AntarchySoundEvents;
import com.craisinlord.antarchy.content.AntarchyObjects;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.Nullable;
import software.bernie.geckolib.animatable.GeoEntity;
import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache;
import software.bernie.geckolib.animation.AnimatableManager;
@@ -20,12 +26,26 @@ import software.bernie.geckolib.animation.PlayState;
import software.bernie.geckolib.animation.RawAnimation;
import software.bernie.geckolib.util.GeckoLibUtil;
import java.util.UUID;
public class NightmareBiteEntity extends Entity implements GeoEntity {
private static final EntityDataAccessor<Boolean> PHASE_TWO = SynchedEntityData.defineId(NightmareBiteEntity.class, EntityDataSerializers.BOOLEAN);
private static final RawAnimation BITE_ANIM = RawAnimation.begin().thenPlay("bite");
private static final int LIFETIME_TICKS = 12;
private static final int SOUND_TICK = 7;
private static final int DAMAGE_TICK = 8;
private static final double START_SIDE_OFFSET = 1.35D;
private static final double START_BACK_OFFSET = 1.4D;
private static final double END_SIDE_OFFSET = 0.15D;
private static final double END_BACK_OFFSET = 0.2D;
private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this);
private int ageTicks;
private int approachSide = 1;
private boolean biteSoundPlayed;
private boolean biteDamageApplied;
@Nullable
private UUID targetId;
public NightmareBiteEntity(EntityType<? extends NightmareBiteEntity> entityType, Level level) {
super(entityType, level);
@@ -34,10 +54,12 @@ public class NightmareBiteEntity extends Entity implements GeoEntity {
this.noCulling = true;
}
public static NightmareBiteEntity spawnAt(ServerLevel level, Vec3 pos, float yaw, boolean phaseTwo) {
public static NightmareBiteEntity spawnAt(ServerLevel level, Player target, boolean phaseTwo) {
NightmareBiteEntity bite = new NightmareBiteEntity(AntarchyObjects.NIGHTMARE_BITE.get(), level);
bite.moveTo(pos.x, pos.y, pos.z, yaw, 0.0F);
bite.targetId = target.getUUID();
bite.setPhaseTwo(phaseTwo);
bite.approachSide = target.getRandom().nextBoolean() ? 1 : -1;
bite.updateTrackingPosition(target, 0.0D);
level.addFreshEntity(bite);
return bite;
}
@@ -90,21 +112,90 @@ public class NightmareBiteEntity extends Entity implements GeoEntity {
if (this.level().isClientSide) {
return;
}
if (++this.ageTicks >= 12) {
LivingEntity target = this.resolveTarget();
if (target == null || !target.isAlive() || !target.hasEffect(AntarchyObjects.DREAD.get())) {
this.discard();
return;
}
int nextAge = ++this.ageTicks;
double progress = Math.min(1.0D, nextAge / (double) DAMAGE_TICK);
this.updateTrackingPosition(target, progress);
if (!this.biteSoundPlayed && nextAge >= SOUND_TICK) {
this.biteSoundPlayed = true;
this.level().playSound(null, this.getX(), this.getY(), this.getZ(), AntarchySoundEvents.NIGHTMARE_BITE.get(), SoundSource.HOSTILE, 0.75F, 0.86F + this.random.nextFloat() * 0.1F);
}
if (!this.biteDamageApplied && nextAge >= DAMAGE_TICK) {
this.biteDamageApplied = true;
this.performBite(target);
}
if (nextAge >= LIFETIME_TICKS) {
this.discard();
}
}
@Nullable
private LivingEntity resolveTarget() {
if (!(this.level() instanceof ServerLevel serverLevel) || this.targetId == null) {
return null;
}
Entity entity = serverLevel.getEntity(this.targetId);
return entity instanceof LivingEntity livingEntity ? livingEntity : null;
}
private void updateTrackingPosition(LivingEntity target, double progress) {
Vec3 forward = target.getLookAngle().multiply(1.0D, 0.0D, 1.0D);
if (forward.lengthSqr() < 1.0E-4D) {
forward = this.getViewVector(1.0F).multiply(1.0D, 0.0D, 1.0D);
}
if (forward.lengthSqr() < 1.0E-4D) {
forward = new Vec3(0.0D, 0.0D, 1.0D);
}
forward = forward.normalize();
Vec3 right = new Vec3(-forward.z, 0.0D, forward.x);
double sideOffset = START_SIDE_OFFSET + (END_SIDE_OFFSET - START_SIDE_OFFSET) * progress;
double backOffset = START_BACK_OFFSET + (END_BACK_OFFSET - START_BACK_OFFSET) * progress;
Vec3 desiredPos = target.position()
.add(0.0D, target.getBbHeight() * 0.55D, 0.0D)
.add(right.scale(this.approachSide * sideOffset))
.subtract(forward.scale(backOffset));
Vec3 toTarget = target.getEyePosition().subtract(desiredPos);
this.setPos(desiredPos.x, desiredPos.y, desiredPos.z);
if (toTarget.lengthSqr() > 1.0E-4D) {
float yaw = (float) Math.toDegrees(Math.atan2(toTarget.z, toTarget.x)) - 90.0F;
this.setYRot(yaw);
}
}
private void performBite(LivingEntity target) {
if (target.distanceToSqr(this) > 6.25D) {
return;
}
float damage = (float) Math.max(3.0D, AntarchySettings.nightmareAttackDamage() * 0.35D);
target.hurt(this.damageSources().magic(), damage);
}
@Override
public void addAdditionalSaveData(CompoundTag tag) {
tag.putBoolean("PhaseTwo", this.isPhaseTwo());
tag.putInt("AgeTicks", this.ageTicks);
tag.putInt("ApproachSide", this.approachSide);
tag.putBoolean("BiteSoundPlayed", this.biteSoundPlayed);
tag.putBoolean("BiteDamageApplied", this.biteDamageApplied);
if (this.targetId != null) {
tag.putUUID("TargetId", this.targetId);
}
}
@Override
public void readAdditionalSaveData(CompoundTag tag) {
this.setPhaseTwo(tag.getBoolean("PhaseTwo"));
this.ageTicks = tag.getInt("AgeTicks");
this.approachSide = tag.getInt("ApproachSide");
this.biteSoundPlayed = tag.getBoolean("BiteSoundPlayed");
this.biteDamageApplied = tag.getBoolean("BiteDamageApplied");
if (tag.hasUUID("TargetId")) {
this.targetId = tag.getUUID("TargetId");
}
}
@Override
@@ -5,7 +5,6 @@ import com.craisinlord.antarchy.content.AntarchyObjects;
import com.craisinlord.antarchy.content.AntarchySoundEvents;
import com.craisinlord.antarchy.content.AntarchyTags;
import com.craisinlord.antarchy.content.damage.AntarchyDamageSources;
import com.mojang.logging.LogUtils;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleTypes;
@@ -15,6 +14,8 @@ import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.world.Difficulty;
@@ -54,13 +55,11 @@ import software.bernie.geckolib.animation.AnimationState;
import software.bernie.geckolib.animation.PlayState;
import software.bernie.geckolib.animation.RawAnimation;
import software.bernie.geckolib.util.GeckoLibUtil;
import org.slf4j.Logger;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
public class NightmareEntity extends Monster implements GeoEntity {
private static final Logger LOGGER = LogUtils.getLogger();
private static final EntityDataAccessor<Integer> ANIMATION_STATE = SynchedEntityData.defineId(NightmareEntity.class, EntityDataSerializers.INT);
private static final EntityDataAccessor<Integer> ACTIVE_SPECIAL_ANIMATION = SynchedEntityData.defineId(NightmareEntity.class, EntityDataSerializers.INT);
private static final EntityDataAccessor<Boolean> ROARING = SynchedEntityData.defineId(NightmareEntity.class, EntityDataSerializers.BOOLEAN);
@@ -81,6 +80,7 @@ public class NightmareEntity extends Monster implements GeoEntity {
private static final String PHASE_TWO_TEXTURE_KEY = "PhaseTwoTexture";
private static final String PHASE_TRANSITIONING_KEY = "PhaseTransitioning";
private static final String PHASE_TRANSITION_TICKS_KEY = "PhaseTransitionTicks";
private static final String PENDING_PHASE_TRANSITION_KEY = "PendingPhaseTransition";
private static final String PORTAL_COOLDOWN_KEY = "PortalCooldown";
private static final String PORTAL_ATTACK_TICKS_KEY = "PortalAttackTicks";
private static final String PORTAL_ATTACK_HIT_KEY = "PortalAttackHitApplied";
@@ -115,20 +115,28 @@ public class NightmareEntity extends Monster implements GeoEntity {
private static final int DREAD_TICKS = 160;
private static final int WEAKNESS_TICKS = 100;
private static final int BLOCK_BREAK_TICKS = 10;
private static final int TAKEOFF_COMMIT_TICKS = 8;
private static final int ROAR_FLIGHT_RECOVERY_TICKS = 16;
private static final int FLIGHT_CEILING_CLEARANCE_BLOCKS = 4;
private static final int PHASE_TWO_TRANSITION_TICKS = 80;
private static final int PHASE_TWO_TEXTURE_SWAP_TICKS = 53;
private static final int PORTAL_TOTAL_TICKS = 28;
private static final int PORTAL_TELEPORT_TICK = 12;
private static final int PORTAL_DAMAGE_TICK = 18;
private static final int PORTAL_TRAVEL_INVULNERABLE_TICKS = 8;
private static final int PORTAL_LIFETIME_TICKS = 60;
private static final int PORTAL_TOTAL_TICKS = 74;
private static final int PORTAL_ENTER_TICK = 20;
private static final int PORTAL_HIDE_TICK = 55;
private static final int PORTAL_TELEPORT_TICK = 56;
private static final int PORTAL_REAPPEAR_TICK = 57;
private static final int PORTAL_DAMAGE_TICK = 61;
private static final int PORTAL_TRAVEL_INVULNERABLE_TICKS = PORTAL_REAPPEAR_TICK - PORTAL_HIDE_TICK;
private static final int PORTAL_LIFETIME_TICKS = 84;
private static final double PATROL_SPEED = 0.34D;
private static final double COMBAT_FLIGHT_SPEED = 0.725D;
private static final double GROUND_APPROACH_SPEED = 0.82D;
private static final double ATTACK_START_RANGE_SQR = 42.25D;
private static final double ATTACK_REACH_RADIUS = 2.65D;
private static final double ATTACK_HIT_FORWARD_OFFSET = 1.7D;
private static final double ATTACK_HIT_HALF_WIDTH = 1.85D;
private static final double ATTACK_HIT_MIN_Y_OFFSET = -0.35D;
private static final double ATTACK_HIT_MAX_Y_OFFSET = 2.3D;
private static final double ATTACK_COMMIT_HORIZONTAL_RANGE = 4.2D;
private static final double ATTACK_COMMIT_HORIZONTAL_RANGE_SQR = ATTACK_COMMIT_HORIZONTAL_RANGE * ATTACK_COMMIT_HORIZONTAL_RANGE;
private static final double FLIGHT_ENGAGE_RANGE_SQR = 42.25D;
@@ -136,16 +144,32 @@ public class NightmareEntity extends Monster implements GeoEntity {
private static final double FLIGHT_ATTACK_RANGE_SQR = 49.0D;
private static final double ROAR_RETRY_DISTANCE_SQR = 400.0D;
private static final double PHASE_TWO_HEALTH_FRACTION = 0.5D;
private static final double PORTAL_RANGE = 32.0D;
private static final double PORTAL_RANGE = 72.0D;
private static final double PORTAL_MIN_RANGE_SQR = 49.0D;
private static final double PORTAL_ENTRY_EXIT_MIN_RANGE_SQR = 49.0D;
private static final double PORTAL_EXIT_OFFSET = 2.35D;
private static final double PORTAL_ENTRY_EXIT_MIN_RANGE_SQR = 225.0D;
private static final double PORTAL_EXIT_OFFSET = 15.0D;
private static final double PORTAL_EXIT_SIDE_OFFSET = 4.5D;
private static final double PORTAL_EXIT_AIR_HEIGHT = 3.0D;
private static final double FLYING_APPROACH_STRAFE_OFFSET = 2.1D;
private static final double FLYING_APPROACH_HEIGHT = 0.45D;
private static final double FLYING_APPROACH_HEIGHT_PHASE_TWO = 0.8D;
private static final double FLYING_APPROACH_HEIGHT = 0.0D;
private static final double FLYING_APPROACH_HEIGHT_PHASE_TWO = 0.12D;
private static final double FLYING_APPROACH_TOO_CLOSE_RANGE_SQR = 9.0D;
private static final double FLYING_OVERHEAD_STALL_RANGE_SQR = 4.0D;
private static final double FLYING_OVERHEAD_STALL_HEIGHT = 2.1D;
private static final double FLYING_OVERHEAD_STALL_HEIGHT = 1.35D;
private static final double FLYING_OVERHEAD_RELEASE_HEIGHT = 1.0D;
private static final double LOW_PROFILE_FLIGHT_DISENGAGE_RANGE_SQR = 12.25D;
private static final double LOW_PROFILE_FLIGHT_DISENGAGE_VERTICAL = 1.4D;
private static final double LOW_PROFILE_FLIGHT_DISENGAGE_OVERHEAD = 1.35D;
private static final double FLYING_OVERHEAD_DESCENT_BACK_OFFSET = 2.3D;
private static final double FLYING_OVERHEAD_DESCENT_SIDE_OFFSET = 2.4D;
private static final double FLYING_ATTACK_MAX_OVERHEAD_COMMIT_HEIGHT = 1.2D;
private static final double FLYING_ATTACK_BODY_TARGET_HEIGHT = 0.65D;
private static final double FLYING_ATTACK_MIN_TARGET_HEIGHT = 0.16D;
private static final double LOW_PROFILE_TARGET_MAX_HEIGHT = 1.2D;
private static final double LOW_PROFILE_OVERHEAD_DESCENT_BACK_OFFSET = 2.9D;
private static final double LOW_PROFILE_OVERHEAD_DESCENT_SIDE_OFFSET = 3.0D;
private static final double LOW_PROFILE_TOO_CLOSE_BACK_OFFSET = 3.2D;
private static final double LOW_PROFILE_TOO_CLOSE_STRAFE_SCALE = 0.85D;
private static final double ANIMATION_MOVEMENT_THRESHOLD_SQR = 0.01D;
private static final RawAnimation IDLE_ANIM = RawAnimation.begin().thenLoop("idle");
@@ -165,15 +189,15 @@ public class NightmareEntity extends Monster implements GeoEntity {
private static final String SPECIAL_PHASE_TWO_TRIGGER = "phase2";
private static final String SPECIAL_PORTAL_ENTER_TRIGGER = "portal_enter";
private static final String SPECIAL_PORTAL_EXIT_TRIGGER = "portal_out";
private static final RawAnimation ATTACK_ANIM = RawAnimation.begin().thenPlayAndHold("attack");
private static final RawAnimation ATTACK_P2_ANIM = RawAnimation.begin().thenPlayAndHold("attack_P2");
private static final RawAnimation FLY_ATTACK_ANIM = RawAnimation.begin().thenPlayAndHold("attack2");
private static final RawAnimation FLY_ATTACK_P2_ANIM = RawAnimation.begin().thenPlayAndHold("attack2_P2");
private static final RawAnimation ROAR_ANIM = RawAnimation.begin().thenPlayAndHold("roar");
private static final RawAnimation ROAR_P2_ANIM = RawAnimation.begin().thenPlayAndHold("roar_P2");
private static final RawAnimation PHASE_TWO_TRANSITION_ANIM = RawAnimation.begin().thenPlayAndHold("phase2");
private static final RawAnimation PORTAL_ENTER_ANIM = RawAnimation.begin().thenPlayAndHold("portal_enter");
private static final RawAnimation PORTAL_EXIT_ANIM = RawAnimation.begin().thenPlayAndHold("portal_out");
private static final RawAnimation ATTACK_ANIM = RawAnimation.begin().thenPlay("attack");
private static final RawAnimation ATTACK_P2_ANIM = RawAnimation.begin().thenPlay("attack_P2");
private static final RawAnimation FLY_ATTACK_ANIM = RawAnimation.begin().thenPlay("attack2");
private static final RawAnimation FLY_ATTACK_P2_ANIM = RawAnimation.begin().thenPlay("attack2_P2");
private static final RawAnimation ROAR_ANIM = RawAnimation.begin().thenPlay("roar");
private static final RawAnimation ROAR_P2_ANIM = RawAnimation.begin().thenPlay("roar_P2");
private static final RawAnimation PHASE_TWO_TRANSITION_ANIM = RawAnimation.begin().thenPlay("phase2");
private static final RawAnimation PORTAL_ENTER_ANIM = RawAnimation.begin().thenPlay("portal_enter");
private static final RawAnimation PORTAL_EXIT_ANIM = RawAnimation.begin().thenPlay("portal_out");
private static final RawAnimation DEATH_ANIM = RawAnimation.begin().thenPlayAndHold("death");
private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this);
@@ -192,10 +216,12 @@ public class NightmareEntity extends Monster implements GeoEntity {
private int portalCooldown;
private int portalAttackTicks;
private int portalTravelTicks;
private int takeoffCommitTicks;
private boolean attackHitApplied;
private boolean introRoarUsed;
private boolean flyingToTarget;
private boolean portalAttackHitApplied;
private boolean pendingPhaseTransition;
private int lastTriggeredSpecialAnimation = SPECIAL_NONE;
private Vec3 portalExitPos;
@Nullable
@@ -277,7 +303,7 @@ public class NightmareEntity extends Monster implements GeoEntity {
}
private PlayState mainAnimController(AnimationState<NightmareEntity> state) {
if (this.hasActiveSpecialAnimation()) {
if (this.shouldBlockLocomotionAnimation()) {
return PlayState.STOP;
}
int animState = this.getAnimationState();
@@ -323,7 +349,10 @@ public class NightmareEntity extends Monster implements GeoEntity {
return;
}
this.setNoGravity((this.flyingToTarget || this.portalAttackTicks > 0 || this.portalTravelTicks > 0) && !this.isTooCloseToCeiling());
this.setNoGravity(!this.pendingPhaseTransition
&& !this.isPhaseTransitioning()
&& (this.flyingToTarget || this.portalAttackTicks > 0 || this.portalTravelTicks > 0)
&& !this.isTooCloseToCeiling());
int prevAirborneTicks = this.airborneTicks;
this.airborneTicks = this.onGround() ? 0 : this.airborneTicks + 1;
@@ -337,6 +366,8 @@ public class NightmareEntity extends Monster implements GeoEntity {
if (this.landingCooldown > 0) this.landingCooldown--;
if (this.portalCooldown > 0) this.portalCooldown--;
if (this.portalTravelTicks > 0) this.portalTravelTicks--;
if (this.takeoffCommitTicks > 0) this.takeoffCommitTicks--;
this.setInvisible(this.portalTravelTicks > 0);
LivingEntity target = this.getTarget();
if (!this.canTargetEntity(target)) {
@@ -360,6 +391,10 @@ public class NightmareEntity extends Monster implements GeoEntity {
return;
}
if (this.pendingPhaseTransition) {
this.tickPendingPhaseTransition(target);
}
if (this.isPhaseTransitioning()) {
this.tickPhaseTransition(target);
} else if (this.portalAttackTicks > 0) {
@@ -396,7 +431,7 @@ public class NightmareEntity extends Monster implements GeoEntity {
boolean hurt = clampedAmount > 0.0F && super.hurt(source, clampedAmount);
if (hurt || clampedAmount <= 0.0F) {
this.setHealth(threshold);
this.startPhaseTransition();
this.beginPhaseTransitionSequence();
return true;
}
return false;
@@ -497,6 +532,7 @@ public class NightmareEntity extends Monster implements GeoEntity {
tag.putBoolean(PHASE_TWO_TEXTURE_KEY, this.hasPhaseTwoTexture());
tag.putBoolean(PHASE_TRANSITIONING_KEY, this.isPhaseTransitioning());
tag.putInt(PHASE_TRANSITION_TICKS_KEY, this.phaseTransitionTicks);
tag.putBoolean(PENDING_PHASE_TRANSITION_KEY, this.pendingPhaseTransition);
tag.putInt(PORTAL_COOLDOWN_KEY, this.portalCooldown);
tag.putInt(PORTAL_ATTACK_TICKS_KEY, this.portalAttackTicks);
tag.putBoolean(PORTAL_ATTACK_HIT_KEY, this.portalAttackHitApplied);
@@ -536,6 +572,7 @@ public class NightmareEntity extends Monster implements GeoEntity {
this.setPhaseTwoTexture(tag.contains(PHASE_TWO_TEXTURE_KEY) ? tag.getBoolean(PHASE_TWO_TEXTURE_KEY) : this.isPhaseTwo() && !this.isPhaseTransitioning());
this.setPhaseTransitioning(tag.getBoolean(PHASE_TRANSITIONING_KEY));
this.phaseTransitionTicks = tag.getInt(PHASE_TRANSITION_TICKS_KEY);
this.pendingPhaseTransition = tag.getBoolean(PENDING_PHASE_TRANSITION_KEY);
if (tag.contains(PORTAL_EXIT_X_KEY)) {
this.portalExitPos = new Vec3(tag.getDouble(PORTAL_EXIT_X_KEY), tag.getDouble(PORTAL_EXIT_Y_KEY), tag.getDouble(PORTAL_EXIT_Z_KEY));
} else {
@@ -552,9 +589,13 @@ public class NightmareEntity extends Monster implements GeoEntity {
this.portalAttackTicks = 0;
this.portalTravelTicks = 0;
this.phaseTransitionTicks = 0;
this.pendingPhaseTransition = false;
this.flyingToTarget = false;
this.clearActiveSpecialAnimation();
this.setRoaring(false);
this.setDeltaMovement(Vec3.ZERO);
this.setNoGravity(false);
this.setInvisible(false);
this.getNavigation().stop();
this.clearNightmarePortals();
}
@@ -567,6 +608,14 @@ public class NightmareEntity extends Monster implements GeoEntity {
if (this.deathTime == 1) {
this.selectSpecialAnimation(SPECIAL_DEATH);
}
this.setNoGravity(false);
if (!this.onGround()) {
Vec3 fall = this.getDeltaMovement().multiply(0.6D, 0.0D, 0.6D);
this.setDeltaMovement(fall.x, Math.min(fall.y, 0.0D) - 0.08D, fall.z);
this.hasImpulse = true;
} else {
this.setDeltaMovement(Vec3.ZERO);
}
if (this.deathTime >= DEATH_TICKS) {
this.remove(RemovalReason.KILLED);
this.dropExperience(this);
@@ -635,7 +684,7 @@ public class NightmareEntity extends Monster implements GeoEntity {
private void startRoar() {
this.roarTicks = this.introRoarUsed ? COMBAT_ROAR_TICKS : INTRO_ROAR_TICKS;
this.introRoarUsed = true;
this.roarCooldown = 240 + this.random.nextInt(140);
this.roarCooldown = 420 + this.random.nextInt(180);
this.attackAnimationTicks = 0;
this.attackHitApplied = false;
this.setRoaring(true);
@@ -660,6 +709,9 @@ public class NightmareEntity extends Monster implements GeoEntity {
if (--this.roarTicks <= 0) {
this.roarTicks = 0;
this.setRoaring(false);
this.flyingToTarget = false;
this.takeoffCommitTicks = 0;
this.landingCooldown = Math.max(this.landingCooldown, ROAR_FLIGHT_RECOVERY_TICKS);
this.clearActiveSpecialAnimation();
this.attackCooldown = Math.max(this.attackCooldown, 18);
}
@@ -671,10 +723,23 @@ public class NightmareEntity extends Monster implements GeoEntity {
this.attackCooldown = ATTACK_TOTAL_TICKS + 12;
this.selectSpecialAnimation(this.selectAttackSpecialAnimation());
this.getNavigation().stop();
Vec3 lunge = target.getEyePosition().subtract(this.getEyePosition());
this.faceTowardTarget(target, 180.0F);
Vec3 lungeTarget = this.shouldUseFlyingLocomotion()
? new Vec3(target.getX(), this.getFlyingAttackTargetY(target), target.getZ())
: target.getEyePosition();
Vec3 lunge = lungeTarget.subtract(this.getEyePosition());
if (lunge.lengthSqr() > 1.0E-4D) {
Vec3 normalized = lunge.normalize();
this.setDeltaMovement(this.getDeltaMovement().scale(0.3D).add(normalized.x * 0.85D, normalized.y * 0.18D, normalized.z * 0.85D));
double verticalBoost = this.shouldUseFlyingLocomotion() ? 0.34D : 0.18D;
Vec3 current = this.getDeltaMovement();
double upward = this.shouldUseFlyingLocomotion()
? Math.max(normalized.y * verticalBoost, -0.08D)
: normalized.y * verticalBoost;
this.setDeltaMovement(
normalized.x * 0.85D,
current.y * 0.18D + upward,
normalized.z * 0.85D
);
this.hasImpulse = true;
}
}
@@ -690,7 +755,7 @@ public class NightmareEntity extends Monster implements GeoEntity {
if (!this.attackHitApplied && elapsed >= ATTACK_DAMAGE_TICK) {
this.attackHitApplied = true;
this.playNightmareBiteSound();
this.performAttackHit();
this.performAttackHit(target);
}
if (--this.attackAnimationTicks <= 0) {
this.attackAnimationTicks = 0;
@@ -698,10 +763,37 @@ public class NightmareEntity extends Monster implements GeoEntity {
}
}
private void beginPhaseTransitionSequence() {
this.attackAnimationTicks = 0;
this.portalAttackTicks = 0;
this.portalTravelTicks = 0;
this.attackHitApplied = false;
this.portalAttackHitApplied = false;
this.portalExitPos = null;
this.pendingPhaseTransition = !this.onGround();
this.flyingToTarget = false;
this.clearNightmarePortals();
this.getNavigation().stop();
this.setRoaring(false);
this.setInvisible(false);
this.setNoGravity(false);
this.roarCooldown = Math.max(this.roarCooldown, 80);
this.portalCooldown = Math.max(this.portalCooldown, 140);
if (this.pendingPhaseTransition) {
Vec3 fall = this.getDeltaMovement();
this.setDeltaMovement(fall.x * 0.25D, Math.min(fall.y, 0.0D) - 0.08D, fall.z * 0.25D);
this.clearActiveSpecialAnimation();
return;
}
this.startPhaseTransition();
}
private void startPhaseTransition() {
this.setPhaseTwo(true);
this.setPhaseTwoTexture(false);
this.setPhaseTransitioning(true);
this.pendingPhaseTransition = false;
this.flyingToTarget = false;
this.selectSpecialAnimation(SPECIAL_PHASE_TWO);
this.phaseTransitionTicks = PHASE_TWO_TRANSITION_TICKS;
this.attackAnimationTicks = 0;
@@ -713,14 +805,42 @@ public class NightmareEntity extends Monster implements GeoEntity {
this.clearNightmarePortals();
this.getNavigation().stop();
this.setRoaring(false);
this.setInvisible(false);
this.setDeltaMovement(Vec3.ZERO);
this.setNoGravity(false);
this.roarCooldown = Math.max(this.roarCooldown, 80);
this.portalCooldown = Math.max(this.portalCooldown, 140);
this.playSound(AntarchySoundEvents.NIGHTMARE_ROAR.get(), 2.2F, 0.68F + this.random.nextFloat() * 0.06F);
}
private void tickPendingPhaseTransition(@Nullable LivingEntity target) {
this.getNavigation().stop();
this.setNoGravity(false);
this.flyingToTarget = false;
this.clearActiveSpecialAnimation();
if (target != null) {
this.getLookControl().setLookAt(target, 35.0F, 20.0F);
}
if (!this.onGround()) {
Vec3 fall = this.getDeltaMovement();
this.setDeltaMovement(fall.x * 0.35D, Math.min(fall.y, 0.0D) - 0.08D, fall.z * 0.35D);
this.hasImpulse = true;
return;
}
this.setDeltaMovement(Vec3.ZERO);
this.startPhaseTransition();
}
private void tickPhaseTransition(@Nullable LivingEntity target) {
this.getNavigation().stop();
this.setDeltaMovement(this.getDeltaMovement().scale(0.45D));
this.setNoGravity(false);
if (!this.onGround()) {
Vec3 fall = this.getDeltaMovement();
this.setDeltaMovement(fall.x * 0.2D, Math.min(fall.y, 0.0D) - 0.08D, fall.z * 0.2D);
this.hasImpulse = true;
} else {
this.setDeltaMovement(Vec3.ZERO);
}
this.getMoveControl().setWantedPosition(this.getX(), this.getY(), this.getZ(), 0.0D);
if (target != null) {
this.getLookControl().setLookAt(target, 35.0F, 20.0F);
@@ -762,7 +882,8 @@ public class NightmareEntity extends Monster implements GeoEntity {
this.attackHitApplied = false;
this.attackCooldown = 24;
this.portalCooldown = 180 + this.random.nextInt(100);
this.selectSpecialAnimation(SPECIAL_PORTAL_ENTER);
this.setInvisible(false);
this.clearActiveSpecialAnimation();
this.getNavigation().stop();
this.entryPortal = NightmarePortalEntity.spawnAt(serverLevel, entryPos, this, this.position(), PORTAL_LIFETIME_TICKS);
this.exitPortal = NightmarePortalEntity.spawnAt(serverLevel, exitPos, this, this.position(), PORTAL_LIFETIME_TICKS);
@@ -777,11 +898,41 @@ public class NightmareEntity extends Monster implements GeoEntity {
this.setDeltaMovement(this.getDeltaMovement().scale(0.55D));
if (target != null) {
this.getLookControl().setLookAt(target, 35.0F, 20.0F);
this.faceTowardTarget(target, 12.0F);
}
int elapsed = PORTAL_TOTAL_TICKS - this.portalAttackTicks;
if (elapsed == PORTAL_ENTER_TICK) {
this.selectSpecialAnimation(SPECIAL_PORTAL_ENTER);
this.flyingToTarget = false;
this.setDeltaMovement(Vec3.ZERO);
this.hasImpulse = true;
}
if (elapsed >= PORTAL_ENTER_TICK && elapsed < PORTAL_REAPPEAR_TICK) {
this.flyingToTarget = false;
this.getMoveControl().setWantedPosition(this.getX(), this.getY(), this.getZ(), 0.0D);
this.setDeltaMovement(Vec3.ZERO);
}
if (elapsed == PORTAL_HIDE_TICK) {
this.portalTravelTicks = Math.max(this.portalTravelTicks, PORTAL_TRAVEL_INVULNERABLE_TICKS);
this.setInvisible(true);
this.setDeltaMovement(Vec3.ZERO);
this.hasImpulse = true;
}
if (elapsed == PORTAL_TELEPORT_TICK && this.portalExitPos != null) {
this.executePortalTeleport(target);
}
if (elapsed == PORTAL_REAPPEAR_TICK) {
this.setInvisible(false);
this.flyingToTarget = !this.onGround();
this.selectSpecialAnimation(SPECIAL_PORTAL_EXIT);
if (target != null) {
this.faceTowardTarget(target, 180.0F);
}
this.resumePortalExitFlight(target);
}
if (elapsed > PORTAL_REAPPEAR_TICK && !this.onGround()) {
this.resumePortalExitFlight(target);
}
if (!this.portalAttackHitApplied && elapsed >= PORTAL_DAMAGE_TICK) {
this.portalAttackHitApplied = true;
this.performPortalExitHit();
@@ -791,15 +942,18 @@ public class NightmareEntity extends Monster implements GeoEntity {
this.portalExitPos = null;
this.clearNightmarePortals();
this.clearActiveSpecialAnimation();
this.setInvisible(false);
}
}
private void executePortalTeleport(@Nullable LivingEntity target) {
if (this.portalExitPos == null) return;
this.level().playSound(null, this.getX(), this.getY(), this.getZ(), SoundEvents.PORTAL_TRAVEL, SoundSource.HOSTILE, 0.22F, 0.96F + this.random.nextFloat() * 0.08F);
this.portalTravelTicks = PORTAL_TRAVEL_INVULNERABLE_TICKS;
this.setPortalCooldown();
this.selectSpecialAnimation(SPECIAL_PORTAL_EXIT);
this.setInvisible(true);
this.teleportTo(this.portalExitPos.x, this.portalExitPos.y, this.portalExitPos.z);
this.level().playSound(null, this.getX(), this.getY(), this.getZ(), SoundEvents.ENDERMAN_TELEPORT, SoundSource.HOSTILE, 0.3F, 0.92F + this.random.nextFloat() * 0.08F);
if (target != null) {
this.faceTowardTarget(target, 180.0F);
}
@@ -807,14 +961,59 @@ public class NightmareEntity extends Monster implements GeoEntity {
this.hasImpulse = true;
}
private void performAttackHit() {
AABB hitBox = this.getBoundingBox()
.inflate(ATTACK_REACH_RADIUS, 1.5D, ATTACK_REACH_RADIUS)
.expandTowards(this.getViewVector(1.0F).scale(1.9D));
List<LivingEntity> victims = this.level().getEntitiesOfClass(LivingEntity.class, hitBox, this::canTargetEntity);
private void resumePortalExitFlight(@Nullable LivingEntity target) {
if (this.onGround()) {
this.flyingToTarget = false;
return;
}
Vec3 destination = target != null
? this.getFlightApproachPosition(target)
: this.position().add(this.getViewVector(1.0F).scale(3.0D));
this.getMoveControl().setWantedPosition(destination.x, destination.y, destination.z, COMBAT_FLIGHT_SPEED);
Vec3 current = this.getDeltaMovement();
if (current.lengthSqr() < 0.04D) {
Vec3 launch = destination.subtract(this.position());
if (launch.lengthSqr() < 1.0E-4D) {
launch = this.getViewVector(1.0F);
}
if (launch.lengthSqr() > 1.0E-4D) {
Vec3 normalized = launch.normalize();
this.setDeltaMovement(normalized.x * 0.42D, Math.max(normalized.y * 0.22D, -0.02D), normalized.z * 0.42D);
this.hasImpulse = true;
}
}
}
private void performAttackHit(@Nullable LivingEntity target) {
Vec3 forward = this.getViewVector(1.0F).multiply(1.0D, 0.0D, 1.0D);
if (forward.lengthSqr() < 1.0E-4D) {
float yawRadians = this.getYRot() * Mth.DEG_TO_RAD;
forward = new Vec3(-Mth.sin(yawRadians), 0.0D, Mth.cos(yawRadians));
}
if (forward.lengthSqr() < 1.0E-4D) {
forward = new Vec3(0.0D, 0.0D, 1.0D);
}
forward = forward.normalize();
Vec3 strikeOrigin = this.position()
.add(0.0D, this.getBbHeight() * 0.55D, 0.0D)
.add(forward.scale(0.4D));
Vec3 strikeCenter = strikeOrigin
.add(forward.scale(ATTACK_HIT_FORWARD_OFFSET));
AABB hitBox = new AABB(
Math.min(strikeOrigin.x, strikeCenter.x) - ATTACK_HIT_HALF_WIDTH,
this.getBoundingBox().minY + ATTACK_HIT_MIN_Y_OFFSET,
Math.min(strikeOrigin.z, strikeCenter.z) - ATTACK_HIT_HALF_WIDTH,
Math.max(strikeOrigin.x, strikeCenter.x) + ATTACK_HIT_HALF_WIDTH,
this.getBoundingBox().minY + ATTACK_HIT_MAX_Y_OFFSET,
Math.max(strikeOrigin.z, strikeCenter.z) + ATTACK_HIT_HALF_WIDTH
);
List<LivingEntity> victims = new ArrayList<>(this.level().getEntitiesOfClass(LivingEntity.class, hitBox, this::canTargetEntity));
if (target != null && this.canTargetEntity(target) && !victims.contains(target) && this.canConnectAttackTo(target, forward, hitBox)) {
victims.add(0, target);
}
float damage = (float) this.getAttributeValue(Attributes.ATTACK_DAMAGE);
for (LivingEntity victim : victims) {
if (!this.isInFront(victim.position(), -0.25D)) continue;
if (!this.canConnectAttackTo(victim, forward, hitBox)) continue;
if (victim.hurt(this.nightmareDamageSource(), damage)) {
this.applyNightmareStrikeEffects(victim);
this.knockAway(victim, 1.15D, 0.3D);
@@ -826,6 +1025,31 @@ public class NightmareEntity extends Monster implements GeoEntity {
}
}
private boolean canConnectAttackTo(LivingEntity victim, Vec3 forward, AABB hitBox) {
if (!this.hasLineOfSight(victim)) {
return false;
}
Vec3 victimCenter = victim.getBoundingBox().getCenter();
if (!this.isInFront(victimCenter, -0.42D)) {
return false;
}
if (victim.getBoundingBox().inflate(0.1D).intersects(hitBox)) {
return true;
}
Vec3 toVictim = victimCenter.subtract(this.position()).multiply(1.0D, 0.0D, 1.0D);
double forwardDistance = toVictim.dot(forward);
if (forwardDistance < 0.15D || forwardDistance > ATTACK_HIT_FORWARD_OFFSET + 1.25D) {
return false;
}
Vec3 lateral = toVictim.subtract(forward.scale(forwardDistance));
if (lateral.lengthSqr() > (ATTACK_HIT_HALF_WIDTH + 0.55D) * (ATTACK_HIT_HALF_WIDTH + 0.55D)) {
return false;
}
double minY = this.getBoundingBox().minY + ATTACK_HIT_MIN_Y_OFFSET;
double maxY = this.getBoundingBox().minY + ATTACK_HIT_MAX_Y_OFFSET + 0.4D;
return victim.getBoundingBox().maxY >= minY && victim.getBoundingBox().minY <= maxY;
}
private void performPortalExitHit() {
if (this.portalExitPos == null) return;
AABB hitBox = this.getBoundingBox().move(this.portalExitPos.subtract(this.position())).inflate(1.7D, 1.2D, 1.7D);
@@ -906,6 +1130,12 @@ public class NightmareEntity extends Monster implements GeoEntity {
if (!this.hasLineOfSight(target) || this.distanceToSqr(target) > ATTACK_START_RANGE_SQR) return false;
double hdSqr = this.horizontalDistanceToSqr(target);
double verticalDistance = Math.abs(target.getEyeY() - this.getEyeY());
if (this.shouldUseFlyingLocomotion()) {
double overheadGap = this.getY() - target.getY();
return hdSqr <= ATTACK_COMMIT_HORIZONTAL_RANGE_SQR
&& verticalDistance <= 2.5D
&& overheadGap <= FLYING_ATTACK_MAX_OVERHEAD_COMMIT_HEIGHT;
}
return hdSqr <= ATTACK_COMMIT_HORIZONTAL_RANGE_SQR && verticalDistance <= 4.0D;
}
@@ -913,10 +1143,29 @@ public class NightmareEntity extends Monster implements GeoEntity {
if (target == null || this.isTooCloseToCeiling()) {
return false;
}
boolean lowProfileTarget = this.isLowProfileFlightTarget(target);
if (this.flyingToTarget && this.takeoffCommitTicks > 0) {
return true;
}
double distanceSqr = this.distanceToSqr(target);
double verticalDistance = Math.abs(target.getEyeY() - this.getEyeY());
double horizontalDistanceSqr = this.horizontalDistanceToSqr(target);
double overheadGap = this.getY() - target.getY();
if (lowProfileTarget
&& horizontalDistanceSqr <= LOW_PROFILE_FLIGHT_DISENGAGE_RANGE_SQR
&& verticalDistance <= LOW_PROFILE_FLIGHT_DISENGAGE_VERTICAL
&& overheadGap <= LOW_PROFILE_FLIGHT_DISENGAGE_OVERHEAD) {
return false;
}
if (this.flyingToTarget) {
return distanceSqr > ATTACK_COMMIT_HORIZONTAL_RANGE_SQR || verticalDistance > 1.25D;
if (horizontalDistanceSqr <= ATTACK_COMMIT_HORIZONTAL_RANGE_SQR
&& verticalDistance <= FLYING_OVERHEAD_RELEASE_HEIGHT
&& overheadGap <= FLYING_ATTACK_MAX_OVERHEAD_COMMIT_HEIGHT) {
return false;
}
return distanceSqr > ATTACK_COMMIT_HORIZONTAL_RANGE_SQR
|| verticalDistance > 1.0D
|| overheadGap > FLYING_ATTACK_MAX_OVERHEAD_COMMIT_HEIGHT;
}
if (distanceSqr >= FLIGHT_ENGAGE_RANGE_SQR) {
return true;
@@ -941,15 +1190,52 @@ public class NightmareEntity extends Monster implements GeoEntity {
double height = this.isPhaseTwo() ? FLYING_APPROACH_HEIGHT_PHASE_TWO : FLYING_APPROACH_HEIGHT;
double horizontalDistanceSqr = this.horizontalDistanceToSqr(target);
double overheadGap = this.getY() - target.getY();
Vec3 anchor = target.position().subtract(forward.scale(1.4D)).add(right.scale(strafe));
boolean lowProfileTarget = this.isLowProfileFlightTarget(target);
double attackTargetY = this.getFlyingAttackTargetY(target);
Vec3 anchor = target.position().subtract(forward.scale(1.8D)).add(right.scale(strafe));
if (horizontalDistanceSqr <= FLYING_OVERHEAD_STALL_RANGE_SQR && overheadGap >= FLYING_OVERHEAD_STALL_HEIGHT) {
anchor = target.position().add(right.scale(strafe * 1.4D)).subtract(forward.scale(0.6D));
return new Vec3(anchor.x, target.getEyeY() + 0.15D, anchor.z);
double sideOffset = lowProfileTarget ? LOW_PROFILE_OVERHEAD_DESCENT_SIDE_OFFSET : FLYING_OVERHEAD_DESCENT_SIDE_OFFSET;
double backOffset = lowProfileTarget ? LOW_PROFILE_OVERHEAD_DESCENT_BACK_OFFSET : FLYING_OVERHEAD_DESCENT_BACK_OFFSET;
anchor = target.position()
.add(right.scale(strafe > 0.0D ? sideOffset : -sideOffset))
.subtract(forward.scale(backOffset));
return new Vec3(anchor.x, attackTargetY, anchor.z);
}
if (horizontalDistanceSqr <= FLYING_APPROACH_TOO_CLOSE_RANGE_SQR) {
anchor = target.position().subtract(forward.scale(2.4D));
double backOffset = lowProfileTarget ? LOW_PROFILE_TOO_CLOSE_BACK_OFFSET : 2.8D;
double strafeScale = lowProfileTarget ? LOW_PROFILE_TOO_CLOSE_STRAFE_SCALE : 0.6D;
anchor = target.position().subtract(forward.scale(backOffset)).add(right.scale(strafe * strafeScale));
}
return new Vec3(anchor.x, target.getEyeY() + height, anchor.z);
return new Vec3(anchor.x, attackTargetY + height, anchor.z);
}
private Vec3 getFlightDescentPosition(LivingEntity target) {
Vec3 toTarget = target.position().subtract(this.position()).multiply(1.0D, 0.0D, 1.0D);
if (toTarget.lengthSqr() < 1.0E-4D) {
toTarget = this.getViewVector(1.0F).multiply(1.0D, 0.0D, 1.0D);
}
if (toTarget.lengthSqr() < 1.0E-4D) {
toTarget = new Vec3(0.0D, 0.0D, 1.0D);
}
Vec3 forward = toTarget.normalize();
Vec3 right = new Vec3(-forward.z, 0.0D, forward.x);
double side = this.tickCount % 20 < 10 ? 1.0D : -1.0D;
boolean lowProfileTarget = this.isLowProfileFlightTarget(target);
double sideOffset = lowProfileTarget ? 1.15D : 0.9D;
double backOffset = lowProfileTarget ? 1.2D : 0.9D;
Vec3 anchor = target.position()
.subtract(forward.scale(backOffset))
.add(right.scale(side * sideOffset));
return new Vec3(anchor.x, this.getFlyingAttackTargetY(target), anchor.z);
}
private boolean isLowProfileFlightTarget(LivingEntity target) {
return target.getBbHeight() <= LOW_PROFILE_TARGET_MAX_HEIGHT;
}
private double getFlyingAttackTargetY(LivingEntity target) {
double targetHeight = Mth.clamp(target.getBbHeight() * 0.4D, FLYING_ATTACK_MIN_TARGET_HEIGHT, FLYING_ATTACK_BODY_TARGET_HEIGHT);
return target.getY() + targetHeight;
}
private double horizontalDistanceToSqr(LivingEntity target) {
@@ -1006,9 +1292,11 @@ public class NightmareEntity extends Monster implements GeoEntity {
Vec3 right = new Vec3(-forward.z, 0.0D, forward.x);
Vec3[] candidates = new Vec3[] {
target.position().subtract(forward.scale(PORTAL_EXIT_OFFSET)),
target.position().subtract(forward.scale(1.4D)).add(right.scale(2.25D)),
target.position().subtract(forward.scale(1.4D)).subtract(right.scale(2.25D)),
target.position().add(forward.scale(2.4D))
target.position().subtract(forward.scale(PORTAL_EXIT_OFFSET)).add(0.0D, PORTAL_EXIT_AIR_HEIGHT, 0.0D),
target.position().subtract(forward.scale(PORTAL_EXIT_OFFSET)).add(right.scale(PORTAL_EXIT_SIDE_OFFSET)),
target.position().subtract(forward.scale(PORTAL_EXIT_OFFSET)).subtract(right.scale(PORTAL_EXIT_SIDE_OFFSET)),
target.position().subtract(forward.scale(PORTAL_EXIT_OFFSET)).add(right.scale(PORTAL_EXIT_SIDE_OFFSET)).add(0.0D, PORTAL_EXIT_AIR_HEIGHT, 0.0D),
target.position().subtract(forward.scale(PORTAL_EXIT_OFFSET)).subtract(right.scale(PORTAL_EXIT_SIDE_OFFSET)).add(0.0D, PORTAL_EXIT_AIR_HEIGHT, 0.0D)
};
for (Vec3 candidate : candidates) {
Vec3 adjusted = this.findValidPortalPosition(candidate);
@@ -1024,7 +1312,7 @@ public class NightmareEntity extends Monster implements GeoEntity {
@Nullable
private Vec3 findValidPortalPosition(Vec3 base) {
EntityDimensions dimensions = this.getType().getDimensions();
for (int yOffset = 1; yOffset >= -1; yOffset--) {
for (int yOffset = 4; yOffset >= -3; yOffset--) {
Vec3 candidate = new Vec3(base.x, base.y + yOffset, base.z);
AABB box = dimensions.makeBoundingBox(candidate);
if (this.level().noCollision(this, box)) {
@@ -1081,9 +1369,11 @@ public class NightmareEntity extends Monster implements GeoEntity {
return;
}
if (this.hasActiveSpecialAnimation()) {
this.groundMoveTicks = 0;
this.tickWingFlapSound();
return;
if (this.shouldBlockLocomotionAnimation()) {
this.groundMoveTicks = 0;
this.tickWingFlapSound();
return;
}
}
if (this.flyingToTarget) {
this.groundMoveTicks = 0;
@@ -1091,7 +1381,7 @@ public class NightmareEntity extends Monster implements GeoEntity {
this.tickWingFlapSound();
return;
}
if (this.isNoGravity() || this.airborneTicks >= MIN_AIRBORNE_TICKS_FOR_FLY_ANIM) {
if (this.shouldUseFlyingLocomotion()) {
this.groundMoveTicks = 0;
this.setAnimationState(ANIM_FLY);
this.tickWingFlapSound();
@@ -1131,8 +1421,29 @@ public class NightmareEntity extends Monster implements GeoEntity {
return this.getActiveSpecialAnimation() != SPECIAL_NONE;
}
private boolean shouldBlockLocomotionAnimation() {
int specialAnimation = this.getActiveSpecialAnimation();
if (specialAnimation == SPECIAL_NONE) {
return false;
}
if (specialAnimation == SPECIAL_ROAR || specialAnimation == SPECIAL_ROAR_P2) {
return false;
}
if (specialAnimation == SPECIAL_PORTAL_EXIT) {
return false;
}
if (specialAnimation == SPECIAL_PHASE_TWO) {
return true;
}
return true;
}
private boolean shouldUseFlyingLocomotion() {
return this.flyingToTarget || this.isNoGravity() || !this.onGround() || this.airborneTicks >= MIN_AIRBORNE_TICKS_FOR_FLY_ANIM;
}
private int selectAttackSpecialAnimation() {
boolean flyingAttack = this.isNoGravity() || this.airborneTicks >= MIN_AIRBORNE_TICKS_FOR_FLY_ANIM || this.flyingToTarget;
boolean flyingAttack = this.shouldUseFlyingLocomotion();
if (flyingAttack) {
return this.isPhaseTwo() ? SPECIAL_FLY_ATTACK_P2 : SPECIAL_FLY_ATTACK;
}
@@ -1141,16 +1452,9 @@ public class NightmareEntity extends Monster implements GeoEntity {
private void selectSpecialAnimation(int specialAnimation) {
this.setActiveSpecialAnimation(specialAnimation);
if (!this.level().isClientSide) {
LOGGER.info("Nightmare animation selected={} tick={}", this.specialAnimationName(specialAnimation), this.tickCount);
}
}
private void clearActiveSpecialAnimation() {
int specialAnimation = this.getActiveSpecialAnimation();
if (specialAnimation != SPECIAL_NONE && !this.level().isClientSide) {
LOGGER.info("Nightmare animation state cleared={} tick={}", this.specialAnimationName(specialAnimation), this.tickCount);
}
this.setActiveSpecialAnimation(SPECIAL_NONE);
}
@@ -1159,9 +1463,6 @@ public class NightmareEntity extends Monster implements GeoEntity {
if (activeSpecialAnimation != SPECIAL_NONE && this.lastTriggeredSpecialAnimation != activeSpecialAnimation) {
String triggerName = this.specialAnimationTrigger(activeSpecialAnimation);
if (triggerName != null) {
if (!this.level().isClientSide) {
LOGGER.info("Nightmare triggerAnim called={} tick={}", triggerName, this.tickCount);
}
this.triggerAnim(SPECIAL_CONTROLLER, triggerName);
}
this.lastTriggeredSpecialAnimation = activeSpecialAnimation;
@@ -1189,11 +1490,6 @@ public class NightmareEntity extends Monster implements GeoEntity {
};
}
private String specialAnimationName(int specialAnimation) {
String triggerName = this.specialAnimationTrigger(specialAnimation);
return triggerName != null ? triggerName : "none";
}
private final class NightmarePhaseTransitionGoal extends Goal {
NightmarePhaseTransitionGoal() {
this.setFlags(EnumSet.of(Flag.MOVE, Flag.LOOK, Flag.JUMP));
@@ -1280,6 +1576,7 @@ public class NightmareEntity extends Monster implements GeoEntity {
&& NightmareEntity.this.landingCooldown <= 0
&& NightmareEntity.this.shouldUseFlightPressure(target)
&& !NightmareEntity.this.isPhaseTransitioning()
&& !NightmareEntity.this.isRoaring()
&& NightmareEntity.this.portalAttackTicks <= 0;
}
@@ -1288,12 +1585,14 @@ public class NightmareEntity extends Monster implements GeoEntity {
LivingEntity target = NightmareEntity.this.getTarget();
return target != null
&& NightmareEntity.this.shouldUseFlightPressure(target)
&& !NightmareEntity.this.isRoaring()
&& NightmareEntity.this.portalAttackTicks <= 0;
}
@Override
public void start() {
NightmareEntity.this.flyingToTarget = true;
NightmareEntity.this.takeoffCommitTicks = TAKEOFF_COMMIT_TICKS;
}
@Override
@@ -1316,6 +1615,27 @@ public class NightmareEntity extends Monster implements GeoEntity {
NightmareEntity.this.setDeltaMovement(NightmareEntity.this.getDeltaMovement().add(0.0D, 0.38D, 0.0D));
NightmareEntity.this.hasImpulse = true;
}
double horizontalDistanceSqr = NightmareEntity.this.horizontalDistanceToSqr(target);
double overheadGap = NightmareEntity.this.getY() - target.getY();
if (horizontalDistanceSqr <= ATTACK_COMMIT_HORIZONTAL_RANGE_SQR
&& overheadGap > FLYING_ATTACK_MAX_OVERHEAD_COMMIT_HEIGHT) {
Vec3 descentPos = NightmareEntity.this.getFlightDescentPosition(target);
NightmareEntity.this.faceTowardTarget(target, 14.0F);
NightmareEntity.this.getMoveControl().setWantedPosition(
descentPos.x,
descentPos.y,
descentPos.z,
COMBAT_FLIGHT_SPEED * 1.08D
);
return;
}
if (horizontalDistanceSqr <= FLYING_OVERHEAD_STALL_RANGE_SQR
&& overheadGap >= FLYING_OVERHEAD_STALL_HEIGHT
&& NightmareEntity.this.attackCooldown <= 0
&& NightmareEntity.this.canStartAttackOn(target)) {
NightmareEntity.this.startAttack(target);
return;
}
if (NightmareEntity.this.attackCooldown <= 0 && NightmareEntity.this.canStartAttackOn(target)) {
NightmareEntity.this.startAttack(target);
return;
@@ -6,6 +6,8 @@ import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
@@ -23,8 +25,11 @@ import software.bernie.geckolib.util.GeckoLibUtil;
import java.util.UUID;
public class NightmarePortalEntity extends Entity implements GeoEntity {
private static final int OPEN_TICKS = 10;
private static final int CLOSE_TICKS = 10;
private static final EntityDataAccessor<Boolean> CLOSING = SynchedEntityData.defineId(NightmarePortalEntity.class, EntityDataSerializers.BOOLEAN);
private static final RawAnimation OPEN_ANIM = RawAnimation.begin().thenPlay("open").thenLoop("idle");
private static final RawAnimation OPEN_ANIM = RawAnimation.begin().thenPlay("open");
private static final RawAnimation IDLE_ANIM = RawAnimation.begin().thenLoop("idle");
private static final RawAnimation CLOSE_ANIM = RawAnimation.begin().thenPlay("close");
private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this);
@@ -48,6 +53,7 @@ public class NightmarePortalEntity extends Entity implements GeoEntity {
portal.fallbackDestination = fallbackDestination;
portal.lifetimeTicks = lifetimeTicks;
level.addFreshEntity(portal);
level.playSound(null, pos.x, pos.y, pos.z, SoundEvents.END_PORTAL_SPAWN, SoundSource.HOSTILE, 0.22F, 0.95F + owner.getRandom().nextFloat() * 0.1F);
return portal;
}
@@ -88,12 +94,12 @@ public class NightmarePortalEntity extends Entity implements GeoEntity {
@Override
public void tick() {
super.tick();
this.ageTicks++;
if (this.level().isClientSide) {
return;
}
this.ageTicks++;
if (this.ageTicks >= this.lifetimeTicks - 10) {
if (this.ageTicks >= this.lifetimeTicks - CLOSE_TICKS) {
this.entityData.set(CLOSING, true);
}
if (this.ageTicks >= this.lifetimeTicks) {
@@ -145,7 +151,14 @@ public class NightmarePortalEntity extends Entity implements GeoEntity {
}
private PlayState portalController(AnimationState<NightmarePortalEntity> state) {
return state.setAndContinue(this.isClosing() ? CLOSE_ANIM : OPEN_ANIM);
state.getController().setAnimationSpeed(this.isClosing() || this.ageTicks < OPEN_TICKS ? 4.0D : 1.0D);
if (this.isClosing()) {
return state.setAndContinue(CLOSE_ANIM);
}
if (this.ageTicks < OPEN_TICKS) {
return state.setAndContinue(OPEN_ANIM);
}
return state.setAndContinue(IDLE_ANIM);
}
@Override
@@ -7,7 +7,7 @@ public class PeachItem extends Item {
public PeachItem() {
super(new Item.Properties().food(new FoodProperties.Builder()
.nutrition(4)
.saturationModifier(2.4F)
.saturationModifier(1.4F)
.build()));
}
}
@@ -4,6 +4,7 @@ import com.craisinlord.antarchy.content.AntarchyObjects;
import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.Component;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
@@ -24,6 +25,8 @@ public class SpiritAppleItem extends Item {
ItemStack result = super.finishUsingItem(stack, level, livingEntity);
if (!level.isClientSide()) {
livingEntity.addEffect(new MobEffectInstance(AntarchyObjects.GLIMMERING_EFFECT.get(), GLIMMERING_DURATION_TICKS, 0, false, false, true));
livingEntity.addEffect(new MobEffectInstance(MobEffects.SLOW_FALLING, GLIMMERING_DURATION_TICKS, 0, false, false, true));
livingEntity.addEffect(new MobEffectInstance(MobEffects.JUMP, GLIMMERING_DURATION_TICKS, 0, false, false, true));
}
return result;
}
@@ -21,14 +21,16 @@ public final class PermanentPortalShape {
public static final int MAX_SIZE = 21;
public static final int ACTIVE_SEARCH_RADIUS = 24;
private final PermanentPortalType type;
private final TagKey<Block> frameTag;
private final Block portalBlock;
private final Direction.Axis axis;
private final BlockPos bottomLeft;
private final int width;
private final int height;
private PermanentPortalShape(PermanentPortalType type, Direction.Axis axis, BlockPos bottomLeft, int width, int height) {
this.type = type;
private PermanentPortalShape(TagKey<Block> frameTag, Block portalBlock, Direction.Axis axis, BlockPos bottomLeft, int width, int height) {
this.frameTag = frameTag;
this.portalBlock = portalBlock;
this.axis = axis;
this.bottomLeft = bottomLeft;
this.width = width;
@@ -36,21 +38,26 @@ public final class PermanentPortalShape {
}
@Nullable
public static PermanentPortalShape findInactive(BlockGetter level, BlockPos interiorPos, PermanentPortalType type, Direction.Axis axis) {
return find(level, interiorPos, type, axis, state -> state.isAir());
public static PermanentPortalShape findInactive(BlockGetter level, BlockPos interiorPos, TagKey<Block> frameTag, Block portalBlock, Direction.Axis axis) {
return find(level, interiorPos, frameTag, portalBlock, axis, state -> state.isAir());
}
@Nullable
public static PermanentPortalShape findInactiveNear(BlockGetter level, BlockPos center, PermanentPortalType type) {
public static PermanentPortalShape findInactive(BlockGetter level, BlockPos interiorPos, PermanentPortalType type, Direction.Axis axis) {
return findInactive(level, interiorPos, type.frameTag(), type.portalBlock(), axis);
}
@Nullable
public static PermanentPortalShape findInactiveNear(BlockGetter level, BlockPos center, TagKey<Block> frameTag, Block portalBlock) {
for (int x = center.getX() - 2; x <= center.getX() + 2; x++) {
for (int y = center.getY() - 2; y <= center.getY() + 2; y++) {
for (int z = center.getZ() - 2; z <= center.getZ() + 2; z++) {
BlockPos candidate = new BlockPos(x, y, z);
PermanentPortalShape xShape = findInactive(level, candidate, type, Direction.Axis.X);
PermanentPortalShape xShape = findInactive(level, candidate, frameTag, portalBlock, Direction.Axis.X);
if (xShape != null) {
return xShape;
}
PermanentPortalShape zShape = findInactive(level, candidate, type, Direction.Axis.Z);
PermanentPortalShape zShape = findInactive(level, candidate, frameTag, portalBlock, Direction.Axis.Z);
if (zShape != null) {
return zShape;
}
@@ -60,10 +67,15 @@ public final class PermanentPortalShape {
return null;
}
@Nullable
public static PermanentPortalShape findInactiveNear(BlockGetter level, BlockPos center, PermanentPortalType type) {
return findInactiveNear(level, center, type.frameTag(), type.portalBlock());
}
@Nullable
public static PermanentPortalShape findActive(BlockGetter level, BlockPos interiorPos, PermanentPortalType type, Direction.Axis axis) {
Block portalBlock = type.portalBlock();
return find(level, interiorPos, type, axis, state -> state.is(portalBlock));
return find(level, interiorPos, type.frameTag(), portalBlock, axis, state -> state.is(portalBlock));
}
@Nullable
@@ -90,7 +102,8 @@ public final class PermanentPortalShape {
private static PermanentPortalShape find(
BlockGetter level,
BlockPos interiorPos,
PermanentPortalType type,
TagKey<Block> frameTag,
Block portalBlock,
Direction.Axis axis,
Predicate<BlockState> interiorPredicate
) {
@@ -110,17 +123,17 @@ public final class PermanentPortalShape {
cursor = cursor.relative(leftDirection);
}
int width = measureWidth(level, cursor, widthDirection, type.frameTag(), interiorPredicate);
int width = measureWidth(level, cursor, widthDirection, frameTag, interiorPredicate);
if (width < MIN_WIDTH) {
return null;
}
int height = measureHeight(level, cursor, widthDirection, width, type.frameTag(), interiorPredicate);
int height = measureHeight(level, cursor, widthDirection, width, frameTag, interiorPredicate);
if (height < MIN_HEIGHT) {
return null;
}
return new PermanentPortalShape(type, axis, cursor.immutable(), width, height);
return new PermanentPortalShape(frameTag, portalBlock, axis, cursor.immutable(), width, height);
}
private static int measureWidth(
@@ -197,7 +210,7 @@ public final class PermanentPortalShape {
}
public void fill(ServerLevel level) {
BlockState portalState = this.type.portalBlock().defaultBlockState().setValue(BlockStateProperties.HORIZONTAL_AXIS, this.axis);
BlockState portalState = this.portalBlock.defaultBlockState().setValue(BlockStateProperties.HORIZONTAL_AXIS, this.axis);
this.forEachInterior(pos -> level.setBlock(pos, portalState, Block.UPDATE_ALL));
}
@@ -226,7 +239,7 @@ public final class PermanentPortalShape {
}
}
return new PermanentPortalShape(type, axis, bottomLeft.immutable(), 2, 3);
return new PermanentPortalShape(type.frameTag(), type.portalBlock(), axis, bottomLeft.immutable(), 2, 3);
}
private static boolean canCreate(BlockGetter level, BlockPos bottomLeft, PermanentPortalType type, Direction.Axis axis) {
@@ -27,6 +27,20 @@ public final class CustomBrewingRecipes {
return !getOutput(input, ingredient).isEmpty();
}
public static boolean isCustomIngredient(ItemStack stack) {
return stack.is(cornItem())
|| stack.is(ROOTS)
|| stack.is(AntarchyTags.Items.GLIMMER_AUGMENT_APPLE_COW)
|| stack.is(AntarchyTags.Items.GLIMMER_AUGMENT_OURANWOOD_DEER)
|| stack.is(AntarchyTags.Items.GLIMMER_AUGMENT_FROG)
|| stack.is(AntarchyTags.Items.GLIMMER_AUGMENT_ANT)
|| stack.is(AntarchyTags.Items.GLIMMER_AUGMENT_ELKA);
}
public static boolean isCustomContainer(ItemStack stack) {
return stack.is(highFructoseCornSyrupItem()) || stack.is(AntarchyObjects.GLIMMER_BOTTLE.get());
}
public static ItemStack getOutput(ItemStack input, ItemStack ingredient) {
if (input.isEmpty() || ingredient.isEmpty()) {
return ItemStack.EMPTY;
@@ -6,7 +6,6 @@ public enum ThoraxisWeatherKind {
NONE("none"),
INVERSION_STORM("inversion_storm"),
BLOOD_RAIN("blood_rain"),
SHARKNADO("sharknado"),
SANDSTORM("sandstorm");
private final String id;
@@ -5,14 +5,11 @@ import com.craisinlord.antarchy.content.AntarchyObjects;
import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi;
import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection;
import com.craisinlord.antarchy.content.gravity.AntarchyGravityTransition;
import com.craisinlord.antarchy.content.entity.cloud_shark.CloudSharkEntity;
import com.craisinlord.antarchy.content.entity.cloud_shark.SharknadoManager;
import net.minecraft.core.BlockPos;
import net.minecraft.core.particles.BlockParticleOption;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvents;
@@ -44,10 +41,6 @@ public final class ThoraxisWeatherManager {
net.minecraft.core.registries.Registries.BIOME,
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "lucid_pools")
);
private static final ResourceKey<Biome> CLOUD_SEA = ResourceKey.create(
net.minecraft.core.registries.Registries.BIOME,
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "cloud_sea")
);
private static final int WEATHER_RECHECK_MIN_TICKS = 400;
private static final int WEATHER_RECHECK_MAX_TICKS = 900;
private static final int STORM_MIN_TICKS = 600;
@@ -141,7 +134,6 @@ public final class ThoraxisWeatherManager {
switch (state.kind) {
case INVERSION_STORM -> tickInversionStorm(level, state, now);
case BLOOD_RAIN -> tickBloodRain(level, state, now);
case SHARKNADO -> tickSharknadoWeather(level, state, now);
case SANDSTORM -> tickSandstorm(level, state, now);
default -> {
}
@@ -233,55 +225,6 @@ public final class ThoraxisWeatherManager {
);
}
private static void tickSharknadoWeather(ServerLevel level, WeatherState state, long now) {
if (now == state.startedAt) {
seedSharknado(level, state.anchor);
}
if (now % WEATHER_PARTICLE_INTERVAL != 0L) {
return;
}
level.sendParticles(
ParticleTypes.CLOUD,
state.anchor.getX() + 0.5D,
state.anchor.getY() + 8.0D,
state.anchor.getZ() + 0.5D,
26,
10.0D,
8.0D,
10.0D,
0.12D
);
}
private static void seedSharknado(ServerLevel level, BlockPos anchor) {
SharknadoManager manager = SharknadoManager.get(level);
for (int i = 0; i < 4; i++) {
CloudSharkEntity shark = createCloudShark(level);
if (shark == null) {
continue;
}
double x = anchor.getX() + level.getRandom().nextDouble() * 10.0D - 5.0D;
double y = anchor.getY() + 6.0D + level.getRandom().nextDouble() * 6.0D;
double z = anchor.getZ() + level.getRandom().nextDouble() * 10.0D - 5.0D;
shark.moveTo(x, y, z, level.getRandom().nextFloat() * 360.0F, 0.0F);
level.addFreshEntity(shark);
manager.tryFormOrJoin(shark, level);
}
}
private static CloudSharkEntity createCloudShark(ServerLevel level) {
EntityType<?> entityType = BuiltInRegistries.ENTITY_TYPE.getOptional(ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "cloud_shark"))
.orElse(null);
if (entityType == null) {
return null;
}
return entityType.create(level) instanceof CloudSharkEntity cloudShark ? cloudShark : null;
}
private static WeatherKindSelection chooseWeather(ServerLevel level, RandomSource random) {
var players = level.players();
if (players.isEmpty()) {
@@ -296,10 +239,6 @@ public final class ThoraxisWeatherManager {
return new WeatherKindSelection(ThoraxisWeatherKind.SANDSTORM, anchor);
}
if (biome.is(CLOUD_SEA)) {
return new WeatherKindSelection(ThoraxisWeatherKind.SHARKNADO, anchor);
}
if (biome.is(LUCID_POOLS)) {
return random.nextFloat() < 0.35F
? new WeatherKindSelection(ThoraxisWeatherKind.BLOOD_RAIN, anchor)
@@ -57,6 +57,10 @@ public class ElythiaBiomeSource extends BiomeSource {
Registries.BIOME,
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "glimmering_pools")
);
private static final ResourceKey<Biome> CLOUD_SEA = ResourceKey.create(
Registries.BIOME,
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "cloud_sea")
);
private static final int[] SURFACE_FALLBACK_BLOCK_YS = new int[]{192, 160, 128, 96, 64, 32, 0};
private static final class ColumnBiomeCache {
@@ -77,7 +81,8 @@ public class ElythiaBiomeSource extends BiomeSource {
Codec.INT.optionalFieldOf("moleworm_caves_max_y", 72).forGetter(ElythiaBiomeSource::molewormCavesMaxY),
Codec.INT.optionalFieldOf("surface_biome_sample_y", 160).forGetter(ElythiaBiomeSource::surfaceBiomeSampleY),
Codec.INT.optionalFieldOf("ocean_max_y", 85).forGetter(ElythiaBiomeSource::oceanMaxY),
Codec.INT.optionalFieldOf("sea_level", 78).forGetter(ElythiaBiomeSource::seaLevel)
Codec.INT.optionalFieldOf("sea_level", 78).forGetter(ElythiaBiomeSource::seaLevel),
Codec.INT.optionalFieldOf("cloud_sea_min_y", 360).forGetter(ElythiaBiomeSource::cloudSeaMinY)
).apply(instance, ElythiaBiomeSource::new));
private final Climate.ParameterList<Holder<Biome>> parameters;
@@ -86,28 +91,33 @@ public class ElythiaBiomeSource extends BiomeSource {
private final int surfaceBiomeSampleY;
private final int oceanMaxY;
private final int seaLevel;
private final int cloudSeaMinY;
private final int molewormCavesMaxQuartY;
private final int surfaceBiomeSampleQuartY;
private final int oceanMaxQuartY;
private final int seaLevelQuartY;
private final int undergroundGuardMaxQuartY;
private final int cloudSeaMinQuartY;
private final Holder<Biome> oceanHolder;
private final Holder<Biome> defaultLandHolder;
private final Holder<Biome> glimmeringPoolsHolder;
private final Holder<Biome> ouranwoodForestHolder;
private final Holder<Biome> cloudSeaHolder;
public ElythiaBiomeSource(Climate.ParameterList<Holder<Biome>> parameters, int molewormCavesMaxY, int surfaceBiomeSampleY, int oceanMaxY, int seaLevel) {
public ElythiaBiomeSource(Climate.ParameterList<Holder<Biome>> parameters, int molewormCavesMaxY, int surfaceBiomeSampleY, int oceanMaxY, int seaLevel, int cloudSeaMinY) {
this.parameters = parameters;
this.delegate = MultiNoiseBiomeSource.createFromList(parameters);
this.molewormCavesMaxY = molewormCavesMaxY;
this.surfaceBiomeSampleY = surfaceBiomeSampleY;
this.oceanMaxY = oceanMaxY;
this.seaLevel = seaLevel;
this.cloudSeaMinY = cloudSeaMinY;
this.molewormCavesMaxQuartY = QuartPos.fromBlock(molewormCavesMaxY);
this.surfaceBiomeSampleQuartY = QuartPos.fromBlock(surfaceBiomeSampleY);
this.oceanMaxQuartY = QuartPos.fromBlock(oceanMaxY);
this.seaLevelQuartY = QuartPos.fromBlock(seaLevel);
this.undergroundGuardMaxQuartY = QuartPos.fromBlock(molewormCavesMaxY + 40);
this.cloudSeaMinQuartY = QuartPos.fromBlock(cloudSeaMinY);
this.oceanHolder = parameters.values().stream()
.map(Pair::getSecond)
.filter(h -> h.is(ELYTHIA_OCEAN))
@@ -130,6 +140,11 @@ public class ElythiaBiomeSource extends BiomeSource {
&& !h.is(GLIMMERING_POOLS))
.findFirst()
.orElse(null);
this.cloudSeaHolder = parameters.values().stream()
.map(Pair::getSecond)
.filter(h -> h.is(CLOUD_SEA))
.findFirst()
.orElse(null);
}
private Climate.ParameterList<Holder<Biome>> parameters() { return this.parameters; }
@@ -137,6 +152,7 @@ public class ElythiaBiomeSource extends BiomeSource {
private int surfaceBiomeSampleY() { return this.surfaceBiomeSampleY; }
private int oceanMaxY() { return this.oceanMaxY; }
private int seaLevel() { return this.seaLevel; }
private int cloudSeaMinY() { return this.cloudSeaMinY; }
@Override
protected MapCodec<? extends BiomeSource> codec() {
@@ -148,11 +164,29 @@ public class ElythiaBiomeSource extends BiomeSource {
return this.delegate.possibleBiomes().stream();
}
private static final long OCEAN_CONTINENTALNESS_THRESHOLD = Climate.quantizeCoord(-0.87f);
private static final int CLOUD_SEA_CELL_SIZE = 96;
private static final long CLOUD_SEA_CHANCE_DENOMINATOR = 5L; // 1-in-5 columns == ~20%
@Override
public Holder<Biome> getNoiseBiome(int x, int y, int z, Climate.Sampler sampler) {
// Only some sky columns are the cloud sea — everywhere else, altitude above the cloud
// floor just falls through to whatever biome would normally be there. Decided before
// touching the (expensive) delegate at all, both for correctness (multi-noise has no
// real notion of raw Y to gate a biome on) and as a speed win for the common case.
if (this.cloudSeaHolder != null && y >= this.cloudSeaMinQuartY && isCloudSeaColumn(x, z)) {
return this.cloudSeaHolder;
}
Holder<Biome> biome = this.delegate.getNoiseBiome(x, y, z, sampler);
// Defensive: cloud_sea's multi-noise parameter point is reserved far off in "offset"
// so it shouldn't win nearest-neighbor on its own, but if it ever does for a query
// below the cloud floor, treat it like any other biome that has no business at that
// altitude and fall back to a real land biome instead of leaking clouds into terrain.
if (biome.is(CLOUD_SEA)) {
return resolveLandFallback(x, z, sampler);
}
if (biome.is(MOLEWORM_CAVES) && y > this.molewormCavesMaxQuartY) {
return resolveSurfaceFallback(x, z, sampler, this.molewormSurfaceFallbackCache, MOLEWORM_CAVES, GLIMMERING_POOLS);
}
@@ -229,6 +263,13 @@ public class ElythiaBiomeSource extends BiomeSource {
return gate <= 3L;
}
private static boolean isCloudSeaColumn(int x, int z) {
long cellX = Math.floorDiv(x, CLOUD_SEA_CELL_SIZE);
long cellZ = Math.floorDiv(z, CLOUD_SEA_CELL_SIZE);
long gate = Math.floorMod(cellX * 668265263L + cellZ * 2246822519L, CLOUD_SEA_CHANCE_DENOMINATOR);
return gate == 0L;
}
private static boolean isSparseOuranwoodCandidate(Climate.TargetPoint target, int x, int z) {
if (target.temperature() > Climate.quantizeCoord(0.24F)) {
return false;
@@ -312,7 +353,7 @@ public class ElythiaBiomeSource extends BiomeSource {
private static boolean isOceanOrCave(Holder<Biome> biome) {
return isOceanBiome(biome) || biome.is(ELYTHIA_BEACH)
|| biome.is(MOLEWORM_CAVES) || biome.is(ELYTHIA_LUSH_CAVES)
|| biome.is(GLIMMERING_POOLS);
|| biome.is(GLIMMERING_POOLS) || biome.is(CLOUD_SEA);
}
@Override
@@ -323,5 +364,6 @@ public class ElythiaBiomeSource extends BiomeSource {
}
debug.add("Elythia mole cave cap: y<=" + this.molewormCavesMaxY);
debug.add("Elythia sea level: " + this.seaLevel);
debug.add("Elythia cloud sea: y>=" + this.cloudSeaMinY + " in ~1/" + CLOUD_SEA_CHANCE_DENOMINATOR + " columns");
}
}
@@ -1,87 +0,0 @@
package com.craisinlord.antarchy.content.worldgen.thoraxis;
import com.craisinlord.antarchy.content.AntarchyObjects;
import com.mojang.serialization.Codec;
import net.minecraft.core.BlockPos;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.feature.Feature;
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
public final class CloudSeaCalciteFeature extends Feature<NoneFeatureConfiguration> {
public CloudSeaCalciteFeature(Codec<NoneFeatureConfiguration> codec) {
super(codec);
}
@Override
public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> context) {
WorldGenLevel level = context.level();
BlockPos origin = context.origin();
RandomSource random = context.random();
int banks = 2 + random.nextInt(3);
boolean placedAny = false;
for (int i = 0; i < banks; i++) {
BlockPos center = origin.offset(random.nextInt(25) - 12, random.nextInt(17) - 8, random.nextInt(25) - 12);
int radiusX = 3 + random.nextInt(4);
int radiusY = 1 + random.nextInt(3);
int radiusZ = 3 + random.nextInt(4);
placedAny |= placeBank(level, center, radiusX, radiusY, radiusZ, random);
}
return placedAny;
}
private boolean placeBank(WorldGenLevel level, BlockPos center, int radiusX, int radiusY, int radiusZ, RandomSource random) {
boolean placedAny = false;
int xRange = Math.max(1, radiusX);
int yRange = Math.max(1, radiusY);
int zRange = Math.max(1, radiusZ);
BlockState cloud = AntarchyObjects.CLOUD_BLOCK.get().defaultBlockState();
for (int x = -xRange; x <= xRange; x++) {
for (int y = -yRange; y <= yRange; y++) {
for (int z = -zRange; z <= zRange; z++) {
double normalized = (x * x) / (double) (xRange * xRange)
+ (y * y) / (double) (yRange * yRange)
+ (z * z) / (double) (zRange * zRange);
if (normalized > 1.0D + random.nextDouble() * 0.18D) {
continue;
}
boolean hollowCore = normalized < 0.58D;
if (hollowCore && random.nextFloat() < 0.72F) {
BlockPos target = center.offset(x, y, z);
BlockState current = level.getBlockState(target);
if (current.is(Blocks.BEDROCK)) {
continue;
}
if (current.isAir() || current.canBeReplaced() || !current.getFluidState().isEmpty()) {
level.setBlock(target, Blocks.AIR.defaultBlockState(), 2);
placedAny = true;
}
continue;
}
if (Math.abs(y) == yRange && random.nextFloat() < 0.55F) {
continue;
}
BlockPos target = center.offset(x, y, z);
BlockState current = level.getBlockState(target);
if (current.is(Blocks.BEDROCK) || (!current.isAir() && !current.canBeReplaced() && current.getFluidState().isEmpty())) {
continue;
}
level.setBlock(target, cloud, 2);
placedAny = true;
}
}
}
return placedAny;
}
}
@@ -39,10 +39,6 @@ public final class ThoraxisBiomeSource extends BiomeSource {
Registries.BIOME,
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "lucid_pools")
);
private static final ResourceKey<Biome> CLOUD_SEA = ResourceKey.create(
Registries.BIOME,
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "cloud_sea")
);
public static final MapCodec<ThoraxisBiomeSource> CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(
MultiNoiseBiomeSource.DIRECT_CODEC.forGetter(ThoraxisBiomeSource::parameters),
@@ -64,10 +60,7 @@ public final class ThoraxisBiomeSource extends BiomeSource {
private Holder<Biome> dreamDunesBiome;
private Holder<Biome> umbralHillsBiome;
private Holder<Biome> lucidPoolsBiome;
private Holder<Biome> cloudSeaBiome;
private static final ThreadLocal<Long2DoubleOpenHashMap> CLOUD_SEA_CACHE =
ThreadLocal.withInitial(() -> new Long2DoubleOpenHashMap(512));
private static final ThreadLocal<Long2DoubleOpenHashMap> REGION_CACHE =
ThreadLocal.withInitial(() -> new Long2DoubleOpenHashMap(512));
private static final ThreadLocal<Long2DoubleOpenHashMap> VERTICAL_CACHE =
@@ -96,7 +89,6 @@ public final class ThoraxisBiomeSource extends BiomeSource {
this.dreamDunesBiome = this.findBiome(DREAM_DUNES);
this.umbralHillsBiome = this.findBiome(UMBRAL_HILLS);
this.lucidPoolsBiome = this.findBiome(LUCID_POOLS);
this.cloudSeaBiome = this.findBiome(CLOUD_SEA);
this.biomesResolved = true;
}
}
@@ -130,10 +122,6 @@ public final class ThoraxisBiomeSource extends BiomeSource {
@Override
public Holder<Biome> getNoiseBiome(int x, int y, int z, Climate.Sampler sampler) {
this.resolveBiomesIfNeeded();
if (this.cloudSeaBiome != null && cachedIsCloudSeaZone(x, z)) {
return this.cloudSeaBiome;
}
if (y >= this.lucidPoolsMinQuartY && this.lucidPoolsBiome != null) {
return this.lucidPoolsBiome;
}
@@ -160,7 +148,6 @@ public final class ThoraxisBiomeSource extends BiomeSource {
this.delegate.addDebugInfo(debug, pos, sampler);
debug.add("Thoraxis selector: mixed vertical/region noise");
debug.add("Thoraxis Lucid Pools: y>=" + this.lucidPoolsMinY);
debug.add("Thoraxis Cloud Sea: widened noise-selected");
}
private Holder<Biome> findBiome(ResourceKey<Biome> key) {
@@ -170,18 +157,6 @@ public final class ThoraxisBiomeSource extends BiomeSource {
.orElse(null);
}
private boolean cachedIsCloudSeaZone(int quartX, int quartZ) {
long key = net.minecraft.world.level.ChunkPos.asLong(quartX, quartZ);
Long2DoubleOpenHashMap cache = CLOUD_SEA_CACHE.get();
if (cache.containsKey(key)) {
return cache.get(key) > 0.0D;
}
boolean result = isCloudSeaZone(quartX, quartZ);
if (cache.size() >= 512) cache.clear();
cache.put(key, result ? 1.0D : -1.0D);
return result;
}
private double cachedRegionNoise(int quartX, int quartZ) {
long key = net.minecraft.world.level.ChunkPos.asLong(quartX, quartZ);
Long2DoubleOpenHashMap cache = REGION_CACHE.get();
@@ -206,13 +181,6 @@ public final class ThoraxisBiomeSource extends BiomeSource {
return result;
}
private static boolean isCloudSeaZone(int quartX, int quartZ) {
double primary = sampleNoise(quartX, quartZ, 56);
double secondary = sampleNoise(quartX + 137, quartZ - 211, 24);
double combined = primary * 0.72D + secondary * 0.28D;
return (combined >= 0.892D && combined <= 0.952D) || (combined >= 0.962D && combined <= 0.992D);
}
private static double sampleRegionNoise(int quartX, int quartZ) {
double broad = sampleNoise(quartX, quartZ, REGION_NOISE_SCALE);
double detail = sampleNoise(quartX + 311, quartZ - 197, REGION_DETAIL_SCALE);
@@ -4,6 +4,7 @@ import com.craisinlord.antarchy.content.item.MantisClawItem;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.LivingEntity;
@@ -22,11 +23,15 @@ public abstract class MantisClawWallClimbMixin extends LivingEntity {
@Unique
private static final int antarchy$MANTIS_CLAW_CLIMB_DURABILITY_INTERVAL = 20;
@Unique
private static final int antarchy$MANTIS_CLAW_FALL_RESET_GRACE_TICKS = 10;
@Unique
private boolean antarchy$mantisClinging;
@Unique
private int antarchy$mantisWallJumpCooldown;
@Unique
private int antarchy$mantisClingDurabilityTicks;
@Unique
private int antarchy$mantisFallResetTicks;
protected MantisClawWallClimbMixin(EntityType<? extends LivingEntity> entityType, Level level) {
super(entityType, level);
@@ -37,6 +42,10 @@ public abstract class MantisClawWallClimbMixin extends LivingEntity {
if (this.antarchy$mantisWallJumpCooldown > 0) {
this.antarchy$mantisWallJumpCooldown--;
}
if (this.antarchy$mantisFallResetTicks > 0) {
this.antarchy$mantisFallResetTicks--;
this.fallDistance = 0.0F;
}
if (!this.antarchy$canMantisCling()) {
this.antarchy$mantisClinging = false;
@@ -62,10 +71,21 @@ public abstract class MantisClawWallClimbMixin extends LivingEntity {
this.setDeltaMovement(motion.x, clampedY, motion.z);
this.hasImpulse = true;
this.fallDistance = 0.0F;
this.antarchy$mantisFallResetTicks = antarchy$MANTIS_CLAW_FALL_RESET_GRACE_TICKS;
this.antarchy$mantisClinging = true;
this.antarchy$damageMantisClawsWhileClimbing();
}
@Inject(method = "causeFallDamage", at = @At("HEAD"), cancellable = true)
private void antarchy$preventFallDamageWhileMantisClimbing(float fallDistance, float multiplier, DamageSource source, org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable<Boolean> cir) {
if (!this.antarchy$shouldSuppressMantisFallDamage()) {
return;
}
this.fallDistance = 0.0F;
cir.setReturnValue(false);
}
@Unique
private boolean antarchy$canMantisCling() {
Player player = (Player) (Object) this;
@@ -121,4 +141,9 @@ public abstract class MantisClawWallClimbMixin extends LivingEntity {
serverPlayer.containerMenu.broadcastChanges();
}
}
@Unique
private boolean antarchy$shouldSuppressMantisFallDamage() {
return this.antarchy$mantisClinging || this.antarchy$mantisFallResetTicks > 0 || this.antarchy$canMantisCling();
}
}
@@ -10,6 +10,13 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(PotionBrewing.class)
public abstract class PotionBrewingMixin {
@Inject(method = "isIngredient", at = @At("HEAD"), cancellable = true)
private void antarchy$isCustomIngredient(ItemStack stack, CallbackInfoReturnable<Boolean> cir) {
if (CustomBrewingRecipes.isCustomIngredient(stack)) {
cir.setReturnValue(true);
}
}
@Inject(method = "hasMix", at = @At("HEAD"), cancellable = true)
private void antarchy$hasCustomMix(ItemStack input, ItemStack ingredient, CallbackInfoReturnable<Boolean> cir) {
if (CustomBrewingRecipes.hasMix(input, ingredient)) {
@@ -0,0 +1,38 @@
package com.craisinlord.antarchy.mixins.client;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.Music;
import net.minecraft.world.level.biome.Biome;
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(Minecraft.class)
public abstract class DimensionMusicMixin {
private static final ResourceLocation CAVARYN_DIMENSION =
ResourceLocation.fromNamespaceAndPath("antarchy", "cavaryn");
private static final ResourceLocation THORAXIS_DIMENSION =
ResourceLocation.fromNamespaceAndPath("antarchy", "thoraxis");
@Inject(method = "getSituationalMusic", at = @At("HEAD"), cancellable = true)
private void antarchy$useDimensionBiomeMusic(CallbackInfoReturnable<Music> cir) {
Minecraft minecraft = (Minecraft) (Object) this;
ClientLevel level = minecraft.level;
if (level == null) {
return;
}
ResourceLocation dimensionId = level.dimension().location();
if (!dimensionId.equals(CAVARYN_DIMENSION) && !dimensionId.equals(THORAXIS_DIMENSION)) {
return;
}
BlockPos musicPos = minecraft.player != null ? minecraft.player.blockPosition() : BlockPos.containing(minecraft.gameRenderer.getMainCamera().getPosition());
Biome biome = level.getBiome(musicPos).value();
biome.getBackgroundMusic().ifPresent(cir::setReturnValue);
}
}
@@ -78,6 +78,7 @@
"client.AbstractMinecartRendererMixin",
"client.EntityLightProbeMixin",
"client.CustomBossBarMixin",
"client.DimensionMusicMixin",
"client.CavarynSkyMixin",
"client.CavarynHordeFogMixin",
"client.CavarynHordeLightTextureMixin",
File diff suppressed because it is too large. Load diff
@@ -9115,110 +9115,110 @@
"vector": [0, 0, 0]
},
"0.125": {
"vector": [0, 0, 0]
"vector": [2.5, 0, 0]
},
"0.2917": {
"pre": {
"vector": [17.5, 0, 0]
"vector": [10, 0, 0]
},
"post": {
"vector": [17.5, 0, 0]
"vector": [10, 0, 0]
},
"lerp_mode": "catmullrom"
},
"0.4167": {
"post": {
"vector": [22.5, 0, 0]
"vector": [12.5, 0, 0]
},
"lerp_mode": "catmullrom"
},
"0.5": {
"vector": [0, 0, 0]
"vector": [5, 0, 0]
},
"0.625": {
"vector": [0, 0, 0]
"vector": [5, 0, 0]
},
"0.7917": {
"pre": {
"vector": [17.5, 0, 0]
"vector": [10, 0, 0]
},
"post": {
"vector": [17.5, 0, 0]
"vector": [10, 0, 0]
},
"lerp_mode": "catmullrom"
},
"0.9167": {
"post": {
"vector": [22.5, 0, 0]
"vector": [12.5, 0, 0]
},
"lerp_mode": "catmullrom"
},
"1.0": {
"vector": [0, 0, 0]
"vector": [5, 0, 0]
},
"1.125": {
"vector": [0, 0, 0]
"vector": [2.5, 0, 0]
},
"1.2917": {
"pre": {
"vector": [17.5, 0, 0]
"vector": [10, 0, 0]
},
"post": {
"vector": [17.5, 0, 0]
"vector": [10, 0, 0]
},
"lerp_mode": "catmullrom"
},
"1.4167": {
"post": {
"vector": [30, 0, 0]
"vector": [12.5, 0, 0]
},
"lerp_mode": "catmullrom"
},
"1.6667": {
"post": {
"vector": ["35-math.cos(q.anim_time*90*32-50)*5", 0, 0]
"vector": ["13-math.cos(query.anim_time*90*16-50)*1.5", 0, 0]
},
"lerp_mode": "catmullrom"
},
"1.875": {
"post": {
"vector": ["35-math.cos(q.anim_time*90*32-50)*5", 0, 0]
"vector": ["13-math.cos(query.anim_time*90*16-50)*1.5", 0, 0]
},
"lerp_mode": "catmullrom"
},
"2.125": {
"post": {
"vector": [30, 0, 0]
"vector": [12.5, 0, 0]
},
"lerp_mode": "catmullrom"
},
"2.5": {
"post": {
"vector": [0, 0, 0]
"vector": [5, 0, 0]
},
"lerp_mode": "catmullrom"
},
"2.5833": {
"post": {
"vector": [0, 0, 0]
"vector": [5, 0, 0]
},
"lerp_mode": "catmullrom"
},
"2.6667": {
"post": {
"vector": [32.5, 0, 0]
"vector": [12.5, 0, 0]
},
"lerp_mode": "catmullrom"
},
"2.75": {
"post": {
"vector": [37.5, 0, 0]
"vector": [15, 0, 0]
},
"lerp_mode": "catmullrom"
},
"3.125": {
"post": {
"vector": [37.5, 0, 0]
"vector": [12.5, 0, 0]
},
"lerp_mode": "catmullrom"
},
@@ -9229,7 +9229,7 @@
"lerp_mode": "catmullrom"
},
"3.8333": {
"vector": [0, 0, 0]
"vector": [2.5, 0, 0]
}
}
},
@@ -11936,4 +11936,4 @@
}
}
}
}
}
@@ -847,7 +847,6 @@
"biome.antarchy.umbral_hills": "Umbralhügel",
"biome.antarchy.lucid_pools": "Luzide Teiche",
"biome.antarchy.dream_dunes": "Traumdünen",
"biome.antarchy.cloud_sea": "Wolkenmeer",
"block.antarchy.wild_corn": "Wild Mais",
"trim_material.antarchy.blood_crystal": "Blutkristall",
"trim_material.antarchy.nightmare_scale": "Albtraum-Schuppe",
@@ -532,6 +532,7 @@
"item.antarchy.alpha_mantis_spawn_egg": "Alpha Mantis Spawn Egg",
"biome.antarchy.moleworm_caves": "Moleworm Caves",
"biome.antarchy.elythia_meadow": "Elythian Meadows",
"biome.antarchy.elythia_ocean": "Elythian Ocean",
"biome.antarchy.butterfly_fields": "Butterfly Fields",
"biome.antarchy.ouranwood_forest": "Ouranwood Forest",
"biome.antarchy.glimmering_pools": "Glimmering Pools",
@@ -583,7 +584,7 @@
"effect.antarchy.bloodglass_ward": "Bloodglass Ward",
"effect.antarchy.bloodglass_ward.description": "Gives hearts that shatter, absorbing an entire hit of damage. They regenerate over time.",
"effect.antarchy.glimmering": "Glimmering",
"effect.antarchy.glimmering.description": "Passes through entities and attacks unharmed, like a spirit.",
"effect.antarchy.glimmering.description": "Passes through entities and attacks unharmed, like a spirit. Grants a lighter step and a higher jump.",
"death.attack.triffid_mauling": "%1$s was mauled to death by a plant",
"death.attack.triffid_mauling.player": "%1$s was mauled to death by a plant",
"death.attack.triffid_swallow": "%1$s was swallowed by a triffid",
@@ -621,6 +622,10 @@
"advancements.antarchy.visit_cavaryn.description": "Enter the infested dimension of Cavaryn.",
"advancements.antarchy.fallen_kingdom_castle.title": "I Used to Rule the World...",
"advancements.antarchy.fallen_kingdom_castle.description": "Discover the Fallen Kingdom Castle.",
"advancements.antarchy.a_lovely_world.title": "A Lovely World",
"advancements.antarchy.a_lovely_world.description": "You found a strangely familiar house in Elythia.",
"advancements.antarchy.cops_n_robbers.title": "Cops N Robbers!",
"advancements.antarchy.cops_n_robbers.description": "This is just a nostalgic structure, no affiliation with Sky :)",
"advancements.antarchy.fallen_king_crown.title": "Chunks would load when I gave the word...",
"advancements.antarchy.fallen_king_crown.description": "Obtain the Fallen King\u0027s Crown.",
"advancements.antarchy.the_lab.title": "Hey everyone, Dan here",
@@ -1019,6 +1024,7 @@
"subtitles.antarchy.jerry_hurt": "Jerry hurts",
"subtitles.antarchy.jerry_death": "Jerry dies",
"subtitles.antarchy.jerry_attack": "Jerry attacks",
"subtitles.antarchy.ambient_elythia_ouranwood_forest": "Ouranwood Forest Rustles",
"advancements.antarchy.bug_apetit.title": "Bug Apétit",
"advancements.antarchy.bug_apetit.description": "Eat Cooked Bug Meat.",
"advancements.antarchy.behavioral_correction.title": "Behavioral Correction",
@@ -847,7 +847,6 @@
"biome.antarchy.umbral_hills": "Colinas umbrías",
"biome.antarchy.lucid_pools": "Pozas lúcidas",
"biome.antarchy.dream_dunes": "Dunas de ensueño",
"biome.antarchy.cloud_sea": "Mar de nubes",
"block.antarchy.wild_corn": "Maíz silvestre",
"trim_material.antarchy.blood_crystal": "Cristal de sangre",
"trim_material.antarchy.nightmare_scale": "Escama de Pesadilla",
@@ -847,7 +847,6 @@
"biome.antarchy.umbral_hills": "Collines ombrales",
"biome.antarchy.lucid_pools": "Bassins lucides",
"biome.antarchy.dream_dunes": "Dunes oniriques",
"biome.antarchy.cloud_sea": "Mer de nuages",
"block.antarchy.wild_corn": "Maïs sauvage",
"trim_material.antarchy.blood_crystal": "Cristal de sang",
"trim_material.antarchy.nightmare_scale": "Écaille de Cauchemar",
@@ -847,7 +847,6 @@
"biome.antarchy.umbral_hills": "Colline ombrose",
"biome.antarchy.lucid_pools": "Pozze di Lucid",
"biome.antarchy.dream_dunes": "Dune dei sogni",
"biome.antarchy.cloud_sea": "Mare di nuvole",
"block.antarchy.wild_corn": "Mais selvatico",
"trim_material.antarchy.blood_crystal": "Cristallo di sangue",
"trim_material.antarchy.nightmare_scale": "Scaglia dell’Incubo",
@@ -847,7 +847,6 @@
"biome.antarchy.umbral_hills": "アンブラルの丘",
"biome.antarchy.lucid_pools": "ルーシッドの池",
"biome.antarchy.dream_dunes": "夢の砂丘",
"biome.antarchy.cloud_sea": "雲海",
"block.antarchy.wild_corn": "野生のトウモロコシ",
"trim_material.antarchy.blood_crystal": "血の結晶",
"trim_material.antarchy.nightmare_scale": "ナイトメアの鱗",
@@ -847,7 +847,6 @@
"biome.antarchy.umbral_hills": "그늘진 언덕",
"biome.antarchy.lucid_pools": "루시드 웅덩이",
"biome.antarchy.dream_dunes": "꿈의 사구",
"biome.antarchy.cloud_sea": "구름 바다",
"block.antarchy.wild_corn": "야생 옥수수",
"trim_material.antarchy.blood_crystal": "혈수정",
"trim_material.antarchy.nightmare_scale": "악몽 비늘",
@@ -847,7 +847,6 @@
"biome.antarchy.umbral_hills": "Colinas Umbrais",
"biome.antarchy.lucid_pools": "Poças Lúcidas",
"biome.antarchy.dream_dunes": "Dunas dos Sonhos",
"biome.antarchy.cloud_sea": "Mar de Nuvens",
"block.antarchy.wild_corn": "Milho silvestre",
"trim_material.antarchy.blood_crystal": "Cristal de Sangue",
"trim_material.antarchy.nightmare_scale": "Escama de Pesadelo",
@@ -820,7 +820,6 @@
"biome.antarchy.umbral_hills": "Теневые холмы",
"biome.antarchy.lucid_pools": "Пруды люцидов",
"biome.antarchy.dream_dunes": "Дюны сновидений",
"biome.antarchy.cloud_sea": "Облачное море",
"block.antarchy.wild_corn": "Дикая кукуруза",
"trim_material.antarchy.blood_crystal": "Кровавый кристалл",
"trim_material.antarchy.nightmare_scale": "Чешуя кошмара",
@@ -847,7 +847,6 @@
"biome.antarchy.umbral_hills": "幽影丘陵",
"biome.antarchy.lucid_pools": "清醒池",
"biome.antarchy.dream_dunes": "梦境沙丘",
"biome.antarchy.cloud_sea": "云海",
"block.antarchy.wild_corn": "野生玉米",
"trim_material.antarchy.blood_crystal": "血晶",
"trim_material.antarchy.nightmare_scale": "梦魇鳞片",
@@ -847,7 +847,6 @@
"biome.antarchy.umbral_hills": "幽影丘陵",
"biome.antarchy.lucid_pools": "清醒池",
"biome.antarchy.dream_dunes": "夢境沙丘",
"biome.antarchy.cloud_sea": "雲海",
"block.antarchy.wild_corn": "野生玉米",
"trim_material.antarchy.blood_crystal": "血晶",
"trim_material.antarchy.nightmare_scale": "夢魘鱗片",
@@ -928,6 +928,7 @@
"sounds": [
{
"name": "antarchy:lucid_lullaby",
"type": "event",
"stream": true
}
]
@@ -944,6 +945,7 @@
"sounds": [
{
"name": "antarchy:venenatus",
"type": "event",
"stream": true
}
]
@@ -960,6 +962,7 @@
"sounds": [
{
"name": "antarchy:wistful_wanderings",
"type": "event",
"stream": true
}
]
@@ -1878,6 +1881,35 @@
}
]
},
"ambient.elythia.ouranwood_forest": {
"subtitle": "subtitles.antarchy.ambient_elythia_ouranwood_forest",
"sounds": [
{
"name": "antarchy:ambient/elythia/ouranwood_forest/ouranwoodforest1",
"stream": false
},
{
"name": "antarchy:ambient/elythia/ouranwood_forest/ouranwoodforest2",
"stream": false
},
{
"name": "antarchy:ambient/elythia/ouranwood_forest/ouranwoodforest3",
"stream": false
},
{
"name": "antarchy:ambient/elythia/ouranwood_forest/ouranwoodforest4",
"stream": false
},
{
"name": "antarchy:ambient/elythia/ouranwood_forest/ouranwoodforest5",
"stream": false
},
{
"name": "antarchy:ambient/elythia/ouranwood_forest/ouranwoodforest6",
"stream": false
}
]
},
"cavaryn_heartbeat": {
"subtitle": "subtitles.antarchy.cavaryn_heartbeat",
"sounds": [
@@ -0,0 +1,42 @@
{
"parent": "minecraft:adventure/root",
"criteria": {
"discover_ruined_prison": {
"conditions": {
"player": [
{
"condition": "minecraft:entity_properties",
"entity": "this",
"predicate": {
"location": {
"structures": "antarchy:ruined_prison"
}
}
}
]
},
"trigger": "minecraft:location"
}
},
"display": {
"announce_to_chat": true,
"description": {
"translate": "advancements.antarchy.cops_n_robbers.description"
},
"frame": "task",
"icon": {
"count": 1,
"id": "minecraft:iron_bars"
},
"show_toast": true,
"title": {
"translate": "advancements.antarchy.cops_n_robbers.title"
}
},
"requirements": [
[
"discover_ruined_prison"
]
],
"sends_telemetry_event": true
}
@@ -1,34 +0,0 @@
{
"parent": "minecraft:adventure/root",
"criteria": {
"kill_molevore": {
"conditions": {
"entity": {
"type": "antarchy:molevore"
}
},
"trigger": "minecraft:player_killed_entity"
}
},
"display": {
"announce_to_chat": true,
"description": {
"translate": "advancements.antarchy.kill_molevore.description"
},
"frame": "task",
"icon": {
"count": 1,
"id": "antarchy:molevore_nose"
},
"show_toast": true,
"title": {
"translate": "advancements.antarchy.kill_molevore.title"
}
},
"requirements": [
[
"kill_molevore"
]
],
"sends_telemetry_event": true
}
@@ -14,7 +14,7 @@
],
"humidity": [
-1.0,
0.55
0.1
],
"continentalness": [
-1.0,
@@ -43,7 +43,7 @@
1.0
],
"humidity": [
0.5,
0.1,
1.0
],
"continentalness": [
@@ -55,8 +55,8 @@
1.0
],
"weirdness": [
-0.45,
0.45
-0.55,
0.55
],
"depth": [
-2.0,
@@ -73,8 +73,8 @@
1.0
],
"humidity": [
0.15,
0.85
0.1,
1.0
],
"continentalness": [
-1.0,
@@ -85,7 +85,37 @@
1.0
],
"weirdness": [
0.45,
-0.85,
-0.45
],
"depth": [
-2.0,
-0.1
],
"offset": 0.0
},
"biome": "antarchy:glowcap_caves"
},
{
"parameters": {
"temperature": [
-1.0,
1.0
],
"humidity": [
0.1,
1.0
],
"continentalness": [
-1.0,
1.0
],
"erosion": [
-1.0,
1.0
],
"weirdness": [
0.35,
1.0
],
"depth": [
@@ -103,7 +133,7 @@
1.0
],
"humidity": [
0.15,
0.1,
1.0
],
"continentalness": [
@@ -115,11 +145,41 @@
1.0
],
"weirdness": [
-0.25,
0.65
0.65,
1.0
],
"depth": [
0.35,
-2.0,
-0.1
],
"offset": 0.0
},
"biome": "antarchy:biowart_caves"
},
{
"parameters": {
"temperature": [
-1.0,
1.0
],
"humidity": [
-0.15,
1.0
],
"continentalness": [
-1.0,
1.0
],
"erosion": [
-1.0,
1.0
],
"weirdness": [
-0.6,
0.9
],
"depth": [
0.15,
2.0
],
"offset": 0.0
@@ -134,7 +194,7 @@
],
"humidity": [
-1.0,
1.0
-0.15
],
"continentalness": [
-1.0,
@@ -155,6 +215,66 @@
"offset": 0.0
},
"biome": "antarchy:brooding_tunnels"
},
{
"parameters": {
"temperature": [
-1.0,
1.0
],
"humidity": [
-0.15,
1.0
],
"continentalness": [
-1.0,
1.0
],
"erosion": [
-1.0,
1.0
],
"weirdness": [
-1.0,
-0.6
],
"depth": [
-0.1,
2.0
],
"offset": 0.0
},
"biome": "antarchy:brooding_tunnels"
},
{
"parameters": {
"temperature": [
-1.0,
1.0
],
"humidity": [
-0.15,
1.0
],
"continentalness": [
-1.0,
1.0
],
"erosion": [
-1.0,
1.0
],
"weirdness": [
0.9,
1.0
],
"depth": [
-0.1,
2.0
],
"offset": 0.0
},
"biome": "antarchy:brooding_tunnels"
}
]
}
@@ -40,7 +40,7 @@
"temperature": 0.75,
"humidity": 0.96,
"continentalness": 0.64,
"erosion": 0.10,
"erosion": 0.1,
"weirdness": 0.65,
"depth": 0.3,
"offset": 0.27
@@ -63,7 +63,7 @@
"parameters": {
"temperature": 0.68,
"humidity": 0.99,
"continentalness": 0.60,
"continentalness": 0.6,
"erosion": 0.28,
"weirdness": 0.42,
"depth": 0.4,
@@ -73,11 +73,11 @@
{
"biome": "antarchy:elythia_meadow",
"parameters": {
"temperature": 0.70,
"temperature": 0.7,
"humidity": 0.94,
"continentalness": 0.55,
"erosion": 0.22,
"weirdness": -0.30,
"weirdness": -0.3,
"depth": 0.3,
"offset": 0.0
}
@@ -161,7 +161,7 @@
"humidity": 0.93,
"continentalness": 0.54,
"erosion": 0.25,
"weirdness": -0.50,
"weirdness": -0.5,
"depth": 0.45,
"offset": 0.0
}
@@ -172,8 +172,8 @@
"temperature": 0.67,
"humidity": 0.93,
"continentalness": 0.54,
"erosion": 0.20,
"weirdness": -0.40,
"erosion": 0.2,
"weirdness": -0.4,
"depth": 0.45,
"offset": 0.0
}
@@ -229,7 +229,7 @@
{
"biome": "antarchy:sparse_ouranwood_forest",
"parameters": {
"temperature": 0.20,
"temperature": 0.2,
"humidity": 0.62,
"continentalness": 0.95,
"erosion": -0.35,
@@ -279,7 +279,7 @@
"parameters": {
"temperature": 0.74,
"humidity": 0.99,
"continentalness": 0.60,
"continentalness": 0.6,
"erosion": 0.17,
"weirdness": 0.28,
"depth": 0.0,
@@ -353,7 +353,7 @@
"humidity": 0.96,
"continentalness": 0.62,
"erosion": 0.13,
"weirdness": 0.20,
"weirdness": 0.2,
"depth": 0.0,
"offset": 0.0
}
@@ -361,11 +361,11 @@
{
"biome": "antarchy:butterfly_fields",
"parameters": {
"temperature": 0.70,
"temperature": 0.7,
"humidity": 0.97,
"continentalness": 0.64,
"erosion": 0.15,
"weirdness": 0.10,
"weirdness": 0.1,
"depth": 0.0,
"offset": 0.0
}
@@ -389,7 +389,7 @@
"humidity": 0.96,
"continentalness": 0.62,
"erosion": 0.13,
"weirdness": 0.20,
"weirdness": 0.2,
"depth": 0.85,
"offset": 0.0
}
@@ -398,9 +398,9 @@
"biome": "antarchy:elythia_ocean",
"parameters": {
"temperature": 0.65,
"humidity": 0.90,
"humidity": 0.9,
"continentalness": -0.88,
"erosion": 0.30,
"erosion": 0.3,
"weirdness": 0.0,
"depth": 0.0,
"offset": 0.0
@@ -409,11 +409,11 @@
{
"biome": "antarchy:elythia_ocean",
"parameters": {
"temperature": 0.60,
"temperature": 0.6,
"humidity": 0.88,
"continentalness": -0.92,
"erosion": 0.25,
"weirdness": -0.40,
"weirdness": -0.4,
"depth": 0.0,
"offset": 0.0
}
@@ -421,11 +421,11 @@
{
"biome": "antarchy:elythia_ocean",
"parameters": {
"temperature": 0.70,
"temperature": 0.7,
"humidity": 0.92,
"continentalness": -0.85,
"erosion": 0.35,
"weirdness": 0.40,
"weirdness": 0.4,
"depth": 0.0,
"offset": 0.0
}
@@ -434,9 +434,9 @@
"biome": "antarchy:elythia_ocean",
"parameters": {
"temperature": 0.65,
"humidity": 0.90,
"humidity": 0.9,
"continentalness": -0.88,
"erosion": 0.30,
"erosion": 0.3,
"weirdness": 0.0,
"depth": 0.5,
"offset": 0.0
@@ -445,11 +445,11 @@
{
"biome": "antarchy:elythia_ocean",
"parameters": {
"temperature": 0.60,
"temperature": 0.6,
"humidity": 0.88,
"continentalness": -0.92,
"erosion": 0.25,
"weirdness": -0.40,
"weirdness": -0.4,
"depth": 0.5,
"offset": 0.0
}
@@ -457,11 +457,11 @@
{
"biome": "antarchy:elythia_coral_spikes",
"parameters": {
"temperature": 0.80,
"temperature": 0.8,
"humidity": 0.85,
"continentalness": -0.88,
"erosion": 0.20,
"weirdness": 0.50,
"erosion": 0.2,
"weirdness": 0.5,
"depth": 0.0,
"offset": 0.0
}
@@ -471,7 +471,7 @@
"parameters": {
"temperature": 0.75,
"humidity": 0.82,
"continentalness": -0.90,
"continentalness": -0.9,
"erosion": 0.15,
"weirdness": -0.55,
"depth": 0.0,
@@ -481,11 +481,11 @@
{
"biome": "antarchy:elythia_coral_spikes",
"parameters": {
"temperature": 0.80,
"temperature": 0.8,
"humidity": 0.85,
"continentalness": -0.88,
"erosion": 0.20,
"weirdness": 0.50,
"erosion": 0.2,
"weirdness": 0.5,
"depth": 0.5,
"offset": 0.0
}
@@ -495,14 +495,45 @@
"parameters": {
"temperature": 0.75,
"humidity": 0.82,
"continentalness": -0.90,
"continentalness": -0.9,
"erosion": 0.15,
"weirdness": -0.55,
"depth": 0.5,
"offset": 0.0
}
},
{
"biome": "antarchy:cloud_sea",
"parameters": {
"temperature": [
-1.0,
1.0
],
"humidity": [
-1.0,
1.0
],
"continentalness": [
-1.0,
1.0
],
"erosion": [
-1.0,
1.0
],
"weirdness": [
-1.0,
1.0
],
"depth": [
0.0,
1.0
],
"offset": 0.999
}
}
]
],
"cloud_sea_min_y": 360
}
}
}
@@ -11,136 +11,244 @@
"biomes": [
{
"parameters": {
"temperature": [-1.0, 1.0],
"humidity": [-1.0, 1.0],
"continentalness": [-1.0, 1.0],
"erosion": [-1.0, 1.0],
"weirdness": [-1.0, 1.0],
"depth": [0.0, 1.0],
"temperature": [
-1.0,
1.0
],
"humidity": [
-1.0,
1.0
],
"continentalness": [
-1.0,
1.0
],
"erosion": [
-1.0,
1.0
],
"weirdness": [
-1.0,
1.0
],
"depth": [
0.0,
1.0
],
"offset": 0.0
},
"biome": "antarchy:dream_dunes"
},
{
"parameters": {
"temperature": [-1.0, 1.0],
"humidity": [-1.0, 1.0],
"continentalness": [-1.0, 1.0],
"erosion": [-1.0, 1.0],
"weirdness": [-1.0, 1.0],
"depth": [0.0, 1.0],
"temperature": [
-1.0,
1.0
],
"humidity": [
-1.0,
1.0
],
"continentalness": [
-1.0,
1.0
],
"erosion": [
-1.0,
1.0
],
"weirdness": [
-1.0,
1.0
],
"depth": [
0.0,
1.0
],
"offset": 0.02
},
"biome": "antarchy:umbral_hills"
},
{
"parameters": {
"temperature": [-1.0, 1.0],
"humidity": [-1.0, 1.0],
"continentalness": [-1.0, 1.0],
"erosion": [-1.0, 1.0],
"weirdness": [-1.0, 1.0],
"depth": [0.0, 1.0],
"temperature": [
-1.0,
1.0
],
"humidity": [
-1.0,
1.0
],
"continentalness": [
-1.0,
1.0
],
"erosion": [
-1.0,
1.0
],
"weirdness": [
-1.0,
1.0
],
"depth": [
0.0,
1.0
],
"offset": 0.0
},
"biome": "antarchy:nightmare_wastes"
},
{
"parameters": {
"temperature": [-1.0, 1.0],
"humidity": [-1.0, 1.0],
"continentalness": [-1.0, 1.0],
"erosion": [-1.0, 1.0],
"weirdness": [-1.0, 1.0],
"depth": [0.0, 1.0],
"temperature": [
-1.0,
1.0
],
"humidity": [
-1.0,
1.0
],
"continentalness": [
-1.0,
1.0
],
"erosion": [
-1.0,
1.0
],
"weirdness": [
-1.0,
1.0
],
"depth": [
0.0,
1.0
],
"offset": 0.04
},
"biome": "antarchy:nightmare_wastes"
},
{
"parameters": {
"temperature": [-1.0, 1.0],
"humidity": [-1.0, 1.0],
"continentalness": [-1.0, 1.0],
"erosion": [-1.0, 1.0],
"weirdness": [-1.0, 1.0],
"depth": [0.0, 1.0],
"temperature": [
-1.0,
1.0
],
"humidity": [
-1.0,
1.0
],
"continentalness": [
-1.0,
1.0
],
"erosion": [
-1.0,
1.0
],
"weirdness": [
-1.0,
1.0
],
"depth": [
0.0,
1.0
],
"offset": 0.12
},
"biome": "antarchy:nightmare_wastes"
},
{
"parameters": {
"temperature": [-1.0, 1.0],
"humidity": [-1.0, 1.0],
"continentalness": [-1.0, 1.0],
"erosion": [-1.0, 1.0],
"weirdness": [-1.0, 1.0],
"depth": [0.0, 1.0],
"temperature": [
-1.0,
1.0
],
"humidity": [
-1.0,
1.0
],
"continentalness": [
-1.0,
1.0
],
"erosion": [
-1.0,
1.0
],
"weirdness": [
-1.0,
1.0
],
"depth": [
0.0,
1.0
],
"offset": 0.18
},
"biome": "antarchy:nightmare_wastes"
},
{
"parameters": {
"temperature": [-1.0, 1.0],
"humidity": [-1.0, 1.0],
"continentalness": [-1.0, 1.0],
"erosion": [-1.0, 1.0],
"weirdness": [-1.0, 1.0],
"depth": [0.0, 1.0],
"temperature": [
-1.0,
1.0
],
"humidity": [
-1.0,
1.0
],
"continentalness": [
-1.0,
1.0
],
"erosion": [
-1.0,
1.0
],
"weirdness": [
-1.0,
1.0
],
"depth": [
0.0,
1.0
],
"offset": 0.24
},
"biome": "antarchy:nightmare_wastes"
},
{
"parameters": {
"temperature": [-1.0, 1.0],
"humidity": [-1.0, 1.0],
"continentalness": [-1.0, 1.0],
"erosion": [-1.0, 1.0],
"weirdness": [-1.0, 1.0],
"depth": [0.0, 1.0],
"temperature": [
-1.0,
1.0
],
"humidity": [
-1.0,
1.0
],
"continentalness": [
-1.0,
1.0
],
"erosion": [
-1.0,
1.0
],
"weirdness": [
-1.0,
1.0
],
"depth": [
0.0,
1.0
],
"offset": 0.6
},
"biome": "antarchy:lucid_pools"
},
{
"parameters": {
"temperature": [-1.0, 1.0],
"humidity": [-1.0, 1.0],
"continentalness": [-1.0, 1.0],
"erosion": [-1.0, 1.0],
"weirdness": [-1.0, 1.0],
"depth": [0.0, 1.0],
"offset": 0.965
},
"biome": "antarchy:cloud_sea"
},
{
"parameters": {
"temperature": [-1.0, 1.0],
"humidity": [-1.0, 1.0],
"continentalness": [-1.0, 1.0],
"erosion": [-1.0, 1.0],
"weirdness": [-1.0, 1.0],
"depth": [0.0, 1.0],
"offset": 0.93
},
"biome": "antarchy:cloud_sea"
},
{
"parameters": {
"temperature": [-1.0, 1.0],
"humidity": [-1.0, 1.0],
"continentalness": [-1.0, 1.0],
"erosion": [-1.0, 1.0],
"weirdness": [-1.0, 1.0],
"depth": [0.0, 1.0],
"offset": 0.985
},
"biome": "antarchy:cloud_sea"
}
}
]
}
}
@@ -5,8 +5,8 @@
"bed_works": true,
"respawn_anchor_works": false,
"min_y": -64,
"height": 384,
"logical_height": 384,
"height": 512,
"logical_height": 512,
"infiniburn": "#minecraft:infiniburn_overworld",
"effects": "minecraft:overworld",
"ambient_light": 0.0,
@@ -3,19 +3,38 @@
"pools": [
{
"rolls": 1.0,
"conditions": [
{
"condition": "minecraft:block_state_property",
"block": "antarchy:corn_crop",
"properties": {
"half": "lower"
}
}
],
"entries": [
{
"type": "minecraft:item",
"name": "antarchy:corn"
"type": "minecraft:alternatives",
"children": [
{
"type": "minecraft:item",
"name": "antarchy:corn",
"conditions": [
{
"condition": "minecraft:block_state_property",
"block": "antarchy:corn_crop",
"properties": {
"half": "lower",
"age": "3"
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:corn_seeds",
"conditions": [
{
"condition": "minecraft:block_state_property",
"block": "antarchy:corn_crop",
"properties": {
"half": "lower"
}
}
]
}
]
}
]
},
@@ -0,0 +1,240 @@
{
"type": "minecraft:chest",
"pools": [
{
"entries": [
{
"type": "minecraft:item",
"name": "minecraft:bread",
"weight": 14,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 5.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:rotten_flesh",
"weight": 16,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 7.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:bone",
"weight": 14,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 6.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:chain",
"weight": 12,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 4.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:iron_ingot",
"weight": 10,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 4.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:arrow",
"weight": 12,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 8.0,
"max": 20.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:torch",
"weight": 12,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 12.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:string",
"weight": 10,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 6.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:coal",
"weight": 10,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 6.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:experience_bottle",
"weight": 6,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 3.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:potion",
"weight": 6,
"functions": [
{
"function": "minecraft:set_components",
"components": {
"minecraft:potion_contents": {
"potion": "minecraft:healing"
}
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:emerald",
"weight": 6,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 3.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:duct_tape",
"weight": 5,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 3.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:uranium_nugget",
"weight": 8,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 3.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:titanium_nugget",
"weight": 8,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 3.0
}
}
]
}
],
"rolls": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 7.0
}
}
],
"random_sequence": "antarchy:chests/ruined_prison/generic"
}
@@ -0,0 +1,282 @@
{
"type": "minecraft:chest",
"pools": [
{
"entries": [
{
"type": "minecraft:item",
"name": "minecraft:iron_sword",
"weight": 14,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 10.0,
"max": 22.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:crossbow",
"weight": 14,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 10.0,
"max": 22.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:shield",
"weight": 10
},
{
"type": "minecraft:item",
"name": "minecraft:arrow",
"weight": 16,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 12.0,
"max": 28.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:spectral_arrow",
"weight": 8,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 12.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:chainmail_chestplate",
"weight": 8,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 8.0,
"max": 20.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:chainmail_leggings",
"weight": 8,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 8.0,
"max": 20.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:experience_bottle",
"weight": 10,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 5.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:potion",
"weight": 8,
"functions": [
{
"function": "minecraft:set_components",
"components": {
"minecraft:potion_contents": {
"potion": "minecraft:strength"
}
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:potion",
"weight": 8,
"functions": [
{
"function": "minecraft:set_components",
"components": {
"minecraft:potion_contents": {
"potion": "minecraft:healing"
}
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:book",
"weight": 6,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 16.0,
"max": 28.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:golden_apple",
"weight": 6
},
{
"type": "minecraft:item",
"name": "minecraft:diamond",
"weight": 4,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 2.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:uranium_nugget",
"weight": 18,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 5.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:titanium_nugget",
"weight": 18,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 5.0
}
}
]
}
],
"rolls": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 7.0
}
},
{
"entries": [
{
"type": "minecraft:item",
"name": "minecraft:diamond_sword",
"weight": 4,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 20.0,
"max": 30.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:crossbow",
"weight": 4,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 20.0,
"max": 30.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:book",
"weight": 6,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 20.0,
"max": 30.0
},
"options": "#minecraft:on_random_loot"
}
]
}
],
"rolls": {
"type": "minecraft:uniform",
"min": 0.0,
"max": 1.0
}
}
],
"random_sequence": "antarchy:chests/ruined_prison/warden_cache"
}
@@ -0,0 +1,176 @@
{
"type": "minecraft:chest",
"pools": [
{
"entries": [
{
"type": "minecraft:item",
"name": "minecraft:white_wool",
"weight": 14,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 6.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:orange_wool",
"weight": 14,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 6.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:candle",
"weight": 12,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 4.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:paper",
"weight": 12,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 7.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:feather",
"weight": 10,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 6.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:book",
"weight": 10,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 8.0,
"max": 20.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:music_disc_cat",
"weight": 2
},
{
"type": "minecraft:item",
"name": "minecraft:bone",
"weight": 8,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 6.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:emerald",
"weight": 6,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 3.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:amethyst_shard",
"weight": 8,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 6.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:rainbow_sugar",
"weight": 10
},
{
"type": "minecraft:item",
"name": "antarchy:duct_tape",
"weight": 4,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 3.0
}
}
]
}
],
"rolls": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 7.0
}
}
],
"random_sequence": "antarchy:chests/stampys_house/bedroom"
}
@@ -0,0 +1,165 @@
{
"type": "minecraft:chest",
"pools": [
{
"entries": [
{
"type": "minecraft:item",
"name": "antarchy:peach",
"weight": 18,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 3.0,
"max": 8.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:peach_pie",
"weight": 10,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 3.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:popcorn",
"weight": 12,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 6.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:cornbread",
"weight": 10,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 5.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:root_beer",
"weight": 8,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 3.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:rainbow_sugar",
"weight": 8,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 4.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:cookie",
"weight": 12,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 3.0,
"max": 8.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:milk_bucket",
"weight": 6
},
{
"type": "minecraft:item",
"name": "minecraft:cake",
"weight": 3
},
{
"type": "minecraft:item",
"name": "minecraft:apple",
"weight": 10,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 5.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:bread",
"weight": 12,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 5.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:mud_pie",
"weight": 4
}
],
"rolls": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 7.0
}
}
],
"random_sequence": "antarchy:chests/stampys_house/kitchen"
}
@@ -0,0 +1,176 @@
{
"type": "minecraft:chest",
"pools": [
{
"entries": [
{
"type": "minecraft:item",
"name": "antarchy:peach_planks",
"weight": 16,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 6.0,
"max": 16.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:peach_slab",
"weight": 12,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 12.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:ladder",
"weight": 14,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 12.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:torch",
"weight": 14,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 12.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:redstone",
"weight": 12,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 12.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:lever",
"weight": 10,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 4.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:stick",
"weight": 14,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 12.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:string",
"weight": 10,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 8.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:fishing_rod",
"weight": 8
},
{
"type": "minecraft:item",
"name": "minecraft:bow",
"weight": 6,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 6.0,
"max": 18.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:duct_tape",
"weight": 6,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 4.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:golden_apple",
"weight": 3
}
],
"rolls": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 8.0
}
}
],
"random_sequence": "antarchy:chests/stampys_house/storage"
}
@@ -0,0 +1,274 @@
{
"type": "minecraft:chest",
"pools": [
{
"entries": [
{
"type": "minecraft:item",
"name": "minecraft:diamond_sword",
"weight": 10,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 24.0,
"max": 30.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:crossbow",
"weight": 10,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 24.0,
"max": 30.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:shield",
"weight": 8
},
{
"type": "minecraft:item",
"name": "minecraft:arrow",
"weight": 18,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 24.0,
"max": 48.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:spectral_arrow",
"weight": 12,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 12.0,
"max": 24.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:experience_bottle",
"weight": 12,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 5.0,
"max": 10.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:potion",
"weight": 8,
"functions": [
{
"function": "minecraft:set_components",
"components": {
"minecraft:potion_contents": {
"potion": "minecraft:strength"
}
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:potion",
"weight": 8,
"functions": [
{
"function": "minecraft:set_components",
"components": {
"minecraft:potion_contents": {
"potion": "minecraft:regeneration"
}
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:book",
"weight": 10,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 24.0,
"max": 30.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:golden_apple",
"weight": 10
},
{
"type": "minecraft:item",
"name": "minecraft:diamond",
"weight": 6,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 4.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:uranium_nugget",
"weight": 40,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 8.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:titanium_nugget",
"weight": 40,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 8.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:uranium_ingot",
"weight": 2
},
{
"type": "minecraft:item",
"name": "antarchy:titanium_ingot",
"weight": 2
}
],
"rolls": {
"type": "minecraft:uniform",
"min": 5.0,
"max": 8.0
}
},
{
"entries": [
{
"type": "minecraft:item",
"name": "minecraft:crossbow",
"weight": 8,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 24.0,
"max": 30.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:book",
"weight": 10,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 25.0,
"max": 30.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:netherite_scrap",
"weight": 4,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 2.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:diamond",
"weight": 6,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 3.0
}
}
]
}
],
"rolls": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 2.0
}
}
],
"random_sequence": "antarchy:spawners/ruined_prison/hard"
}
@@ -0,0 +1,248 @@
{
"type": "minecraft:chest",
"pools": [
{
"entries": [
{
"type": "minecraft:item",
"name": "minecraft:iron_sword",
"weight": 18,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 8.0,
"max": 20.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:crossbow",
"weight": 16,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 10.0,
"max": 22.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:shield",
"weight": 12
},
{
"type": "minecraft:item",
"name": "minecraft:arrow",
"weight": 20,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 16.0,
"max": 36.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:spectral_arrow",
"weight": 8,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 6.0,
"max": 14.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:experience_bottle",
"weight": 10,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 3.0,
"max": 7.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:potion",
"weight": 8,
"functions": [
{
"function": "minecraft:set_components",
"components": {
"minecraft:potion_contents": {
"potion": "minecraft:strength"
}
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:potion",
"weight": 8,
"functions": [
{
"function": "minecraft:set_components",
"components": {
"minecraft:potion_contents": {
"potion": "minecraft:healing"
}
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:emerald",
"weight": 10,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 5.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:iron_ingot",
"weight": 8,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 6.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:chain",
"weight": 8,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 6.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:uranium_nugget",
"weight": 32,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 6.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:titanium_nugget",
"weight": 32,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 6.0
}
}
]
}
],
"rolls": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 7.0
}
},
{
"entries": [
{
"type": "minecraft:item",
"name": "minecraft:diamond_sword",
"weight": 4,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 20.0,
"max": 30.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:book",
"weight": 6,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 20.0,
"max": 30.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:golden_apple",
"weight": 6
}
],
"rolls": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 1.0
}
}
],
"random_sequence": "antarchy:spawners/ruined_prison/medium"
}
@@ -0,0 +1,231 @@
{
"type": "minecraft:chest",
"pools": [
{
"entries": [
{
"type": "minecraft:item",
"name": "minecraft:diamond",
"weight": 8,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 4.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:gold_ingot",
"weight": 14,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 6.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:emerald",
"weight": 12,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 4.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:copper_ingot",
"weight": 14,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 8.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:book",
"weight": 8,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 15.0,
"max": 30.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:crossbow",
"weight": 10,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 15.0,
"max": 30.0
},
"options": "#minecraft:on_random_loot"
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:arrow",
"weight": 14,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 12.0,
"max": 32.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:duct_tape",
"weight": 10,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 3.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:torch",
"weight": 8,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 12.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:bread",
"weight": 12,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 6.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:mud_pie",
"weight": 4
}
],
"rolls": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 7.0
}
},
{
"entries": [
{
"type": "minecraft:item",
"name": "antarchy:fallen_king_crown",
"weight": 6,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 1.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:uranium_nugget",
"weight": 9,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 2.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:titanium_nugget",
"weight": 9,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 2.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:golden_apple",
"weight": 9
}
],
"rolls": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 2.0
}
}
],
"random_sequence": "antarchy:spawners/stampys_house/trail_chamber/hard"
}
@@ -0,0 +1,260 @@
{
"type": "minecraft:chest",
"pools": [
{
"entries": [
{
"type": "minecraft:item",
"name": "minecraft:bread",
"weight": 18,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 6.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:iron_ingot",
"weight": 12,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 4.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:copper_ingot",
"weight": 14,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 2.0,
"max": 8.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:gold_ingot",
"weight": 10,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 4.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:arrow",
"weight": 14,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 8.0,
"max": 24.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:torch",
"weight": 10,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 4.0,
"max": 12.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:duct_tape",
"weight": 10,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 3.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:potion",
"weight": 6,
"functions": [
{
"function": "minecraft:set_components",
"components": {
"minecraft:potion_contents": {
"potion": "antarchy:shrinking"
}
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:potion",
"weight": 6,
"functions": [
{
"function": "minecraft:set_components",
"components": {
"minecraft:potion_contents": {
"potion": "antarchy:growing"
}
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:emerald",
"weight": 6,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 3.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:mud_pie",
"weight": 4
}
],
"rolls": {
"type": "minecraft:uniform",
"min": 3.0,
"max": 6.0
}
},
{
"entries": [
{
"type": "minecraft:item",
"name": "antarchy:fallen_king_crown",
"weight": 4,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 1.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:uranium_nugget",
"weight": 7,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 2.0
}
}
]
},
{
"type": "minecraft:item",
"name": "antarchy:titanium_nugget",
"weight": 7,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 2.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:golden_apple",
"weight": 7
},
{
"type": "minecraft:item",
"name": "minecraft:diamond",
"weight": 4,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 2.0
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:book",
"weight": 4,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 10.0,
"max": 25.0
},
"options": "#minecraft:on_random_loot"
}
]
}
],
"rolls": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 2.0
}
}
],
"random_sequence": "antarchy:spawners/stampys_house/trail_chamber/medium"
}
@@ -0,0 +1,20 @@
{
"type": "minecraft:crafting_shaped",
"category": "building",
"pattern": [
"MD",
"DM"
],
"key": {
"M": {
"item": "minecraft:mud"
},
"D": {
"item": "antarchy:myrmite"
}
},
"result": {
"count": 1,
"id": "antarchy:loam"
}
}
@@ -1,6 +1,6 @@
{
"replace": false,
"values": [
"minecraft:sugar"
"antarchy:rainbow_sugar"
]
}
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"antarchy:elythia_meadow"
]
}
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"antarchy:elythia_meadow"
]
}
@@ -24,8 +24,8 @@
},
"music": {
"sound": "antarchy:music.game.cavaryn",
"min_delay": 12000,
"max_delay": 24000,
"min_delay": 600,
"max_delay": 1800,
"replace_current_music": true
}
},
@@ -63,7 +63,7 @@
],
[]
],
"creature_spawn_probability": 0.08,
"creature_spawn_probability": 0.98,
"spawners": {
"monster": [
{
@@ -76,15 +76,15 @@
"creature": [
{
"type": "antarchy:rolly_polly",
"weight": 25,
"minCount": 1,
"maxCount": 3
"weight": 320,
"minCount": 4,
"maxCount": 8
},
{
"type": "antarchy:stink_bug",
"weight": 35,
"minCount": 2,
"maxCount": 4
"weight": 420,
"minCount": 4,
"maxCount": 8
}
],
"ambient": [],
@@ -23,8 +23,8 @@
},
"music": {
"sound": "antarchy:music.game.cavaryn",
"min_delay": 12000,
"max_delay": 24000,
"min_delay": 600,
"max_delay": 1800,
"replace_current_music": true
}
},
@@ -60,22 +60,22 @@
"antarchy:spit_bug_egg_patch"
]
],
"creature_spawn_probability": 0.12,
"creature_spawn_probability": 0.98,
"spawners": {
"monster": [
],
"creature": [
{
"type": "antarchy:rolly_polly",
"weight": 25,
"minCount": 1,
"maxCount": 3
"weight": 300,
"minCount": 4,
"maxCount": 8
},
{
"type": "antarchy:stink_bug",
"weight": 35,
"minCount": 2,
"maxCount": 4
"weight": 450,
"minCount": 4,
"maxCount": 8
}],
"ambient": [
],
@@ -18,13 +18,12 @@
},
"music": {
"sound": "antarchy:music.game.elythia",
"min_delay": 12000,
"max_delay": 24000,
"min_delay": 600,
"max_delay": 1800,
"replace_current_music": true
}
},
"spawn_costs": {
},
"spawn_costs": {},
"carvers": {
"air": [],
"liquid": []
@@ -70,10 +69,9 @@
],
[]
],
"creature_spawn_probability": 0.20,
"creature_spawn_probability": 0.2,
"spawners": {
"monster": [
],
"monster": [],
"creature": [
{
"type": "antarchy:caterpillar",
@@ -23,8 +23,8 @@
},
"music": {
"sound": "antarchy:music.game.cavaryn",
"min_delay": 12000,
"max_delay": 24000,
"min_delay": 600,
"max_delay": 1800,
"replace_current_music": true
}
},
@@ -64,22 +64,22 @@
"antarchy:cavaryn_hanging_creeproots"
]
],
"creature_spawn_probability": 0.06,
"creature_spawn_probability": 0.98,
"spawners": {
"monster": [
],
"creature": [
{
"type": "antarchy:rolly_polly",
"weight": 25,
"minCount": 1,
"maxCount": 3
"weight": 320,
"minCount": 4,
"maxCount": 8
},
{
"type": "antarchy:stink_bug",
"weight": 35,
"minCount": 2,
"maxCount": 4
"weight": 420,
"minCount": 4,
"maxCount": 8
}],
"ambient": [
],
@@ -18,8 +18,8 @@
},
"music": {
"sound": "antarchy:music.game.cavaryn",
"min_delay": 12000,
"max_delay": 24000,
"min_delay": 600,
"max_delay": 1800,
"replace_current_music": true
}
},
@@ -59,7 +59,7 @@
],
[]
],
"creature_spawn_probability": 0.08,
"creature_spawn_probability": 0.9,
"spawners": {
"monster": [
{
@@ -75,13 +75,26 @@
"maxCount": 4
}
],
"creature": [],
"creature": [
{
"type": "antarchy:rolly_polly",
"weight": 220,
"minCount": 3,
"maxCount": 7
},
{
"type": "antarchy:stink_bug",
"weight": 300,
"minCount": 4,
"maxCount": 8
}
],
"ambient": [
{
"type": "minecraft:bat",
"weight": 12,
"minCount": 4,
"maxCount": 8
"weight": 1,
"minCount": 1,
"maxCount": 2
}
],
"axolotls": [],
@@ -1,23 +1,32 @@
{
"has_precipitation": false,
"temperature": 2.0,
"downfall": 0.0,
"temperature": 0.82,
"downfall": 1.0,
"effects": {
"fog_color": 983040,
"water_color": 327680,
"water_fog_color": 0,
"sky_color": 524288,
"particle": {
"probability": 0.02,
"options": {
"type": "minecraft:cloud"
}
"fog_color": 8084735,
"water_color": 5021432,
"water_fog_color": 736368,
"sky_color": 8084735,
"foliage_color": 2867501,
"grass_color": 4304168,
"grass_color_modifier": "none",
"mood_sound": {
"sound": "minecraft:ambient.basalt_deltas.mood",
"tick_delay": 8000,
"block_search_extent": 8,
"offset": 2.0
},
"music": {
"sound": "antarchy:music.game.elythia",
"min_delay": 600,
"max_delay": 1800,
"replace_current_music": true
}
},
"spawn_costs": {
"antarchy:cloud_shark": {
"energy_budget": 0.2,
"charge": 9
"energy_budget": 0.15,
"charge": 22
}
},
"carvers": {
@@ -30,26 +39,27 @@
[],
[],
[
"antarchy:cloud_sea_calcite_banks"
"antarchy:elythia_clouds"
],
[],
[],
[],
[],
[],
[]
],
"creature_spawn_probability": 0.03,
"spawners": {
"creature": [],
"ambient": [],
"monster": [
{
"type": "antarchy:cloud_shark",
"weight": 40,
"minCount": 2,
"maxCount": 5
"weight": 10,
"minCount": 1,
"maxCount": 2
}
],
"creature": [],
"ambient": [],
"axolotls": [],
"underground_water_creature": [],
"water_creature": [],
@@ -26,8 +26,8 @@
},
"music": {
"sound": "antarchy:music.game.thoraxis",
"min_delay": 12000,
"max_delay": 24000,
"min_delay": 600,
"max_delay": 1800,
"replace_current_music": true
}
},
@@ -57,8 +57,7 @@
],
[
"antarchy:nyxite_spikes",
"antarchy:patch_ceiling_fire",
"antarchy:patch_ceiling_antigravel"
"antarchy:patch_ceiling_fire"
],
[
"antarchy:cornea_stalk_patch",
@@ -18,8 +18,8 @@
},
"music": {
"sound": "antarchy:music.game.elythia",
"min_delay": 12000,
"max_delay": 24000,
"min_delay": 600,
"max_delay": 1800,
"replace_current_music": true
}
},
@@ -18,8 +18,8 @@
},
"music": {
"sound": "antarchy:music.game.elythia",
"min_delay": 12000,
"max_delay": 24000,
"min_delay": 600,
"max_delay": 1800,
"replace_current_music": true
}
},
@@ -65,19 +65,39 @@
"creature_spawn_probability": 0.04,
"spawners": {
"monster": [
{ "type": "antarchy:missile_squid", "weight": 12, "minCount": 1, "maxCount": 3 }
{
"type": "antarchy:missile_squid",
"weight": 12,
"minCount": 1,
"maxCount": 3
}
],
"creature": [
{ "type": "minecraft:turtle", "weight": 5, "minCount": 1, "maxCount": 2 }
{
"type": "minecraft:turtle",
"weight": 5,
"minCount": 1,
"maxCount": 2
}
],
"ambient": [],
"axolotls": [],
"underground_water_creature": [],
"water_creature": [
{ "type": "antarchy:octopus_bomb", "weight": 4, "minCount": 1, "maxCount": 2 }
{
"type": "antarchy:octopus_bomb",
"weight": 4,
"minCount": 1,
"maxCount": 2
}
],
"water_ambient": [
{ "type": "minecraft:tropical_fish", "weight": 20, "minCount": 4, "maxCount": 8 }
{
"type": "minecraft:tropical_fish",
"weight": 20,
"minCount": 4,
"maxCount": 8
}
],
"misc": []
}
@@ -24,8 +24,8 @@
},
"music": {
"sound": "antarchy:music.game.elythia",
"min_delay": 12000,
"max_delay": 24000,
"min_delay": 600,
"max_delay": 1800,
"replace_current_music": true
}
},
@@ -18,8 +18,8 @@
},
"music": {
"sound": "antarchy:music.game.elythia",
"min_delay": 12000,
"max_delay": 24000,
"min_delay": 600,
"max_delay": 1800,
"replace_current_music": true
}
},
@@ -156,8 +156,18 @@
}
],
"water_ambient": [
{ "type": "antarchy:cheep", "weight": 10, "minCount": 3, "maxCount": 6 },
{ "type": "minecraft:tropical_fish", "weight": 20, "minCount": 4, "maxCount": 8 }
{
"type": "antarchy:cheep",
"weight": 10,
"minCount": 3,
"maxCount": 6
},
{
"type": "minecraft:tropical_fish",
"weight": 20,
"minCount": 4,
"maxCount": 8
}
],
"misc": []
}
@@ -18,8 +18,8 @@
},
"music": {
"sound": "antarchy:music.game.elythia",
"min_delay": 12000,
"max_delay": 24000,
"min_delay": 600,
"max_delay": 1800,
"replace_current_music": true
}
},
@@ -68,18 +68,38 @@
"creature_spawn_probability": 0.15,
"spawners": {
"monster": [
{ "type": "antarchy:missile_squid", "weight": 12, "minCount": 1, "maxCount": 3 }
],
"creature": [
{
"type": "antarchy:missile_squid",
"weight": 12,
"minCount": 1,
"maxCount": 3
}
],
"creature": [],
"ambient": [],
"axolotls": [],
"underground_water_creature": [],
"water_creature": [
{ "type": "antarchy:octopus_bomb", "weight": 4, "minCount": 1, "maxCount": 2 }],
{
"type": "antarchy:octopus_bomb",
"weight": 4,
"minCount": 1,
"maxCount": 2
}
],
"water_ambient": [
{ "type": "antarchy:cheep", "weight": 10, "minCount": 3, "maxCount": 6 },
{ "type": "minecraft:tropical_fish", "weight": 20, "minCount": 4, "maxCount": 8 }
{
"type": "antarchy:cheep",
"weight": 10,
"minCount": 3,
"maxCount": 6
},
{
"type": "minecraft:tropical_fish",
"weight": 20,
"minCount": 4,
"maxCount": 8
}
],
"misc": []
}
@@ -18,8 +18,8 @@
},
"music": {
"sound": "antarchy:music.game.elythia",
"min_delay": 12000,
"max_delay": 24000,
"min_delay": 600,
"max_delay": 1800,
"replace_current_music": true
}
},
@@ -16,6 +16,7 @@
"type": "minecraft:spore_blossom_air"
}
},
"ambient_sound": "antarchy:ambient.elythia.ouranwood_forest",
"mood_sound": {
"sound": "minecraft:ambient.crimson_forest.mood",
"tick_delay": 6000,
@@ -24,8 +25,8 @@
},
"music": {
"sound": "antarchy:music.game.elythia",
"min_delay": 12000,
"max_delay": 24000,
"min_delay": 600,
"max_delay": 1800,
"replace_current_music": true
}
},
@@ -18,8 +18,8 @@
},
"music": {
"sound": "antarchy:music.game.elythia",
"min_delay": 12000,
"max_delay": 24000,
"min_delay": 600,
"max_delay": 1800,
"replace_current_music": true
}
},
@@ -83,8 +83,7 @@
"maxCount": 1
}
],
"ambient": [
],
"ambient": [],
"axolotls": [],
"underground_water_creature": [
{
@@ -24,8 +24,8 @@
},
"music": {
"sound": "antarchy:music.game.cavaryn",
"min_delay": 12000,
"max_delay": 24000,
"min_delay": 600,
"max_delay": 1800,
"replace_current_music": true
}
},
@@ -53,22 +53,22 @@
],
[]
],
"creature_spawn_probability": 0.09,
"creature_spawn_probability": 0.98,
"spawners": {
"monster": [
],
"creature": [
{
"type": "antarchy:rolly_polly",
"weight": 25,
"minCount": 1,
"maxCount": 3
"weight": 280,
"minCount": 4,
"maxCount": 8
},
{
"type": "antarchy:stink_bug",
"weight": 40,
"minCount": 2,
"maxCount": 4
"weight": 380,
"minCount": 4,
"maxCount": 8
}],
"ambient": [
],
@@ -26,8 +26,8 @@
},
"music": {
"sound": "antarchy:music.game.thoraxis",
"min_delay": 12000,
"max_delay": 24000,
"min_delay": 600,
"max_delay": 1800,
"replace_current_music": true
}
},
@@ -62,8 +62,7 @@
"antarchy:red_ant_nest_magma",
"antarchy:nyxite_spikes",
"antarchy:patch_fire_sparse",
"antarchy:patch_ceiling_fire",
"antarchy:patch_ceiling_antigravel"
"antarchy:patch_ceiling_fire"
],
[],
[
@@ -18,8 +18,8 @@
},
"music": {
"sound": "antarchy:music.game.elythia",
"min_delay": 12000,
"max_delay": 24000,
"min_delay": 600,
"max_delay": 1800,
"replace_current_music": true
}
},
@@ -26,8 +26,8 @@
},
"music": {
"sound": "antarchy:music.game.thoraxis",
"min_delay": 12000,
"max_delay": 24000,
"min_delay": 600,
"max_delay": 1800,
"replace_current_music": true
}
},
@@ -64,8 +64,7 @@
"antarchy:bed_bug_nest",
"antarchy:nyxite_spikes",
"antarchy:patch_fire_sparse",
"antarchy:patch_ceiling_fire",
"antarchy:patch_ceiling_antigravel"
"antarchy:patch_ceiling_fire"
],
[
"antarchy:cornea_stalk_patch",
@@ -16,6 +16,7 @@
"type": "minecraft:spore_blossom_air"
}
},
"ambient_sound": "antarchy:ambient.elythia.ouranwood_forest",
"mood_sound": {
"sound": "minecraft:ambient.crimson_forest.mood",
"tick_delay": 6000,
@@ -24,21 +25,21 @@
},
"music": {
"sound": "antarchy:music.game.elythia",
"min_delay": 12000,
"max_delay": 24000,
"min_delay": 600,
"max_delay": 1800,
"replace_current_music": true
}
},
"spawn_costs": {
"antarchy:basilisk": {
"energy_budget": 0.1,
"charge": 14.0
},
"antarchy:glimmer": {
"energy_budget": 0.1,
"charge": 9
}
"antarchy:basilisk": {
"energy_budget": 0.1,
"charge": 14.0
},
"antarchy:glimmer": {
"energy_budget": 0.1,
"charge": 9
}
},
"carvers": {
"air": [],
"liquid": []
@@ -126,8 +127,7 @@
"maxCount": 1
}
],
"ambient": [
],
"ambient": [],
"axolotls": [],
"underground_water_creature": [],
"water_creature": [
@@ -136,10 +136,22 @@
"weight": 2,
"minCount": 1,
"maxCount": 1
}],
}
],
"water_ambient": [
{ "type": "antarchy:cheep", "weight": 10, "minCount": 3, "maxCount": 6 },
{ "type": "minecraft:tropical_fish", "weight": 20, "minCount": 4, "maxCount": 8 }],
{
"type": "antarchy:cheep",
"weight": 10,
"minCount": 3,
"maxCount": 6
},
{
"type": "minecraft:tropical_fish",
"weight": 20,
"minCount": 4,
"maxCount": 8
}
],
"misc": []
}
}
Loaded 100 of 149 files, more files were not shown because too many files have changed in this diff. Show more