diff --git a/common/src/main/java/com/craisinlord/antarchy/config/AntarchySettings.java b/common/src/main/java/com/craisinlord/antarchy/config/AntarchySettings.java index 63a49f5f..e3843401 100644 --- a/common/src/main/java/com/craisinlord/antarchy/config/AntarchySettings.java +++ b/common/src/main/java/com/craisinlord/antarchy/config/AntarchySettings.java @@ -90,7 +90,7 @@ public final class AntarchySettings { private static ResourceKey rainbowAntNonInfinityFallbackDimension = dimensionKey("antarchy:elythia"); private static double krakenHealth = 1500.0D; private static double krakenAttackDamage = 45.0D; - private static double octopusBombHealth = 250.0D; + private static double octopusBombHealth = 100.0D; private static double octopusBombAttackDamage = 16.0D; private static double brutalflyHealth = 400.0D; private static double brutalflySwipeDamage = 15.0D; diff --git a/common/src/main/java/com/craisinlord/antarchy/content/AntarchyObjects.java b/common/src/main/java/com/craisinlord/antarchy/content/AntarchyObjects.java index a9050d9d..01232839 100644 --- a/common/src/main/java/com/craisinlord/antarchy/content/AntarchyObjects.java +++ b/common/src/main/java/com/craisinlord/antarchy/content/AntarchyObjects.java @@ -148,6 +148,10 @@ public final class AntarchyObjects { @SuppressWarnings("unchecked") public static Supplier NYXITE_SPIKE = (Supplier) UNBOUND; @SuppressWarnings("unchecked") + public static Supplier CHITEN_BLOCK = (Supplier) UNBOUND; + @SuppressWarnings("unchecked") + public static Supplier CHITEN_SPIKE = (Supplier) UNBOUND; + @SuppressWarnings("unchecked") public static Supplier POTENT_NYXITE = (Supplier) UNBOUND; @SuppressWarnings("unchecked") public static Supplier ANTIMETAL = (Supplier) UNBOUND; @@ -276,6 +280,8 @@ public final class AntarchyObjects { Supplier triffidGooBlock, Supplier paleNyxite, Supplier nyxiteSpike, + Supplier chitenBlock, + Supplier chitenSpike, Supplier potentNyxite, Supplier antimetal, Supplier polishedAntimetal, @@ -364,6 +370,8 @@ public final class AntarchyObjects { TRIFFID_GOO_BLOCK = triffidGooBlock; PALE_NYXITE = paleNyxite; NYXITE_SPIKE = nyxiteSpike; + CHITEN_BLOCK = chitenBlock; + CHITEN_SPIKE = chitenSpike; POTENT_NYXITE = potentNyxite; ANTIMETAL = antimetal; POLISHED_ANTIMETAL = polishedAntimetal; diff --git a/common/src/main/java/com/craisinlord/antarchy/content/AntarchyTags.java b/common/src/main/java/com/craisinlord/antarchy/content/AntarchyTags.java index 4bffaa9a..d2f7ba3e 100644 --- a/common/src/main/java/com/craisinlord/antarchy/content/AntarchyTags.java +++ b/common/src/main/java/com/craisinlord/antarchy/content/AntarchyTags.java @@ -76,6 +76,7 @@ public final class AntarchyTags { public static final TagKey DUCT_TAPE_BLACKLIST = TagKey.create(Registries.ITEM, id("duct_tape_blacklist")); public static final TagKey BROWN_ANT_ACTIVATION_ITEMS = TagKey.create(Registries.ITEM, id("brown_ant_activation_items")); public static final TagKey BROWN_ANT_BREEDING_FOODS = TagKey.create(Registries.ITEM, id("brown_ant_breeding_foods")); + public static final TagKey MULTISHOT_ENCHANTABLE = TagKey.create(Registries.ITEM, id("multishot_enchantable")); public static final TagKey RED_ANT_ACTIVATION_ITEMS = TagKey.create(Registries.ITEM, id("red_ant_activation_items")); public static final TagKey RED_ANT_BREEDING_FOODS = TagKey.create(Registries.ITEM, id("red_ant_breeding_foods")); public static final TagKey RAINBOW_ANT_ACTIVATION_ITEMS = TagKey.create(Registries.ITEM, id("rainbow_ant_activation_items")); @@ -95,6 +96,7 @@ public final class AntarchyTags { public static final class Biomes { public static final TagKey MANTIS_SPAWN_BIOMES = TagKey.create(Registries.BIOME, id("mantis_spawn_biomes")); public static final TagKey MANTIS_OVERWORLD_SPAWN_BIOMES = TagKey.create(Registries.BIOME, id("mantis_overworld_spawn_biomes")); + public static final TagKey ELYTHIA_FIREFLY_PARTICLE_BIOMES = TagKey.create(Registries.BIOME, id("elythia_firefly_particle_biomes")); private Biomes() { } diff --git a/common/src/main/java/com/craisinlord/antarchy/content/block/AmberMossBlock.java b/common/src/main/java/com/craisinlord/antarchy/content/block/AmberMossBlock.java index 0b0a840c..a0489b1b 100644 --- a/common/src/main/java/com/craisinlord/antarchy/content/block/AmberMossBlock.java +++ b/common/src/main/java/com/craisinlord/antarchy/content/block/AmberMossBlock.java @@ -1,6 +1,12 @@ package com.craisinlord.antarchy.content.block; +import com.craisinlord.antarchy.Antarchy; import com.mojang.serialization.MapCodec; +import net.minecraft.core.Holder; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; import net.minecraft.core.BlockPos; import net.minecraft.util.RandomSource; import net.minecraft.world.level.Level; @@ -9,9 +15,14 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.BonemealableBlock; import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; public class AmberMossBlock extends Block implements BonemealableBlock { public static final MapCodec CODEC = Block.simpleCodec(AmberMossBlock::new); + private static final ResourceKey> AMBER_MOSS_PATCH_BONEMEAL = ResourceKey.create( + Registries.CONFIGURED_FEATURE, + ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "amber_moss_patch_bonemeal") + ); public AmberMossBlock(BlockBehaviour.Properties properties) { super(properties); @@ -24,15 +35,19 @@ public class AmberMossBlock extends Block implements BonemealableBlock { @Override public boolean isValidBonemealTarget(LevelReader level, BlockPos pos, BlockState state) { - return false; + return level.getBlockState(pos.above()).isAir(); } @Override public boolean isBonemealSuccess(Level level, RandomSource random, BlockPos pos, BlockState state) { - return false; + return true; } @Override - public void performBonemeal(net.minecraft.server.level.ServerLevel level, RandomSource random, BlockPos pos, BlockState state) { + public void performBonemeal(ServerLevel level, RandomSource random, BlockPos pos, BlockState state) { + Holder.Reference> feature = level.registryAccess() + .lookupOrThrow(Registries.CONFIGURED_FEATURE) + .getOrThrow(AMBER_MOSS_PATCH_BONEMEAL); + feature.value().place(level, level.getChunkSource().getGenerator(), random, pos); } } diff --git a/common/src/main/java/com/craisinlord/antarchy/content/block/ChitenSpikeBlock.java b/common/src/main/java/com/craisinlord/antarchy/content/block/ChitenSpikeBlock.java new file mode 100644 index 00000000..faf02e93 --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/content/block/ChitenSpikeBlock.java @@ -0,0 +1,166 @@ +package com.craisinlord.antarchy.content.block; + +import com.craisinlord.antarchy.content.AntarchyObjects; +import com.mojang.serialization.MapCodec; +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.item.context.BlockPlaceContext; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.PointedDripstoneBlock; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.DripstoneThickness; +import net.minecraft.world.level.material.Fluids; + +public class ChitenSpikeBlock extends PointedDripstoneBlock { + @SuppressWarnings("rawtypes") + public static final MapCodec CODEC = (MapCodec) Block.simpleCodec(ChitenSpikeBlock::new); + + public ChitenSpikeBlock(BlockBehaviour.Properties properties) { + super(properties); + } + + @Override + public MapCodec codec() { + return CODEC; + } + + @Override + public BlockState getStateForPlacement(BlockPlaceContext context) { + LevelAccessor level = context.getLevel(); + BlockPos pos = context.getClickedPos(); + Direction direction = calculateTipDirection(level, pos, context.getNearestLookingVerticalDirection().getOpposite()); + if (direction == null) { + return null; + } + + boolean mergeTips = !context.isSecondaryUseActive(); + DripstoneThickness thickness = calculateDripstoneThickness(level, pos, direction, mergeTips); + if (thickness == null) { + return null; + } + + return this.defaultBlockState() + .setValue(TIP_DIRECTION, direction) + .setValue(THICKNESS, thickness) + .setValue(WATERLOGGED, level.getFluidState(pos).getType() == Fluids.WATER); + } + + @Override + protected BlockState updateShape( + BlockState state, + Direction direction, + BlockState neighborState, + LevelAccessor level, + BlockPos pos, + BlockPos neighborPos + ) { + if (state.getValue(WATERLOGGED)) { + level.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(level)); + } + + if (direction != Direction.UP && direction != Direction.DOWN) { + return state; + } + + Direction tipDirection = state.getValue(TIP_DIRECTION); + if (tipDirection == Direction.DOWN && level.getBlockTicks().hasScheduledTick(pos, this)) { + return state; + } + + if (direction == tipDirection.getOpposite() && !this.canSurvive(state, level, pos)) { + if (tipDirection == Direction.DOWN) { + level.scheduleTick(pos, this, 2); + } else { + level.scheduleTick(pos, this, 1); + } + + return state; + } + + boolean mergeTips = state.getValue(THICKNESS) == DripstoneThickness.TIP_MERGE; + return state.setValue(THICKNESS, calculateDripstoneThickness(level, pos, tipDirection, mergeTips)); + } + + @Override + public boolean canSurvive(BlockState state, LevelReader level, BlockPos pos) { + return isValidPointedDripstonePlacement(level, pos, state.getValue(TIP_DIRECTION)); + } + + @Override + protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { + if (this.canSurvive(state, level, pos)) { + return; + } + + if (state.getValue(TIP_DIRECTION) == Direction.DOWN) { + BlockPos.MutableBlockPos root = pos.mutable(); + while (isChitenSpikeWithDirection(level.getBlockState(root.above()), Direction.DOWN)) { + root.move(Direction.UP); + } + + BlockPos.MutableBlockPos cursor = root.mutable(); + while (isChitenSpikeWithDirection(level.getBlockState(cursor), Direction.DOWN)) { + BlockState fallingState = level.getBlockState(cursor); + if (isChitenSpikeWithDirection(fallingState, Direction.DOWN)) { + net.minecraft.world.entity.item.FallingBlockEntity.fall(level, cursor, fallingState); + } + cursor.move(Direction.DOWN); + } + return; + } + + BlockPos.MutableBlockPos cursor = pos.mutable(); + while (isChitenSpikeWithDirection(level.getBlockState(cursor), Direction.UP)) { + BlockState spikeState = level.getBlockState(cursor); + dropResources(spikeState, level, cursor); + level.removeBlock(cursor, false); + cursor.move(Direction.UP); + } + } + + private static Direction calculateTipDirection(LevelReader level, BlockPos pos, Direction preferredDirection) { + if (isValidPointedDripstonePlacement(level, pos, preferredDirection)) { + return preferredDirection; + } + + Direction opposite = preferredDirection.getOpposite(); + return isValidPointedDripstonePlacement(level, pos, opposite) ? opposite : null; + } + + private static DripstoneThickness calculateDripstoneThickness(LevelReader level, BlockPos pos, Direction direction, boolean mergeTips) { + Direction opposite = direction.getOpposite(); + BlockState forwardState = level.getBlockState(pos.relative(direction)); + if (isChitenSpikeWithDirection(forwardState, opposite)) { + return !mergeTips && forwardState.getValue(THICKNESS) != DripstoneThickness.TIP_MERGE + ? DripstoneThickness.TIP + : DripstoneThickness.TIP_MERGE; + } + + if (!isChitenSpikeWithDirection(forwardState, direction)) { + return DripstoneThickness.TIP; + } + + DripstoneThickness forwardThickness = forwardState.getValue(THICKNESS); + if (forwardThickness != DripstoneThickness.TIP && forwardThickness != DripstoneThickness.TIP_MERGE) { + BlockState backState = level.getBlockState(pos.relative(opposite)); + return !isChitenSpikeWithDirection(backState, direction) ? DripstoneThickness.BASE : DripstoneThickness.MIDDLE; + } + + return DripstoneThickness.FRUSTUM; + } + + private static boolean isValidPointedDripstonePlacement(LevelReader level, BlockPos pos, Direction direction) { + BlockPos supportPos = pos.relative(direction.getOpposite()); + BlockState supportState = level.getBlockState(supportPos); + return supportState.isFaceSturdy(level, supportPos, direction) || isChitenSpikeWithDirection(supportState, direction); + } + + private static boolean isChitenSpikeWithDirection(BlockState state, Direction direction) { + return state.is(AntarchyObjects.CHITEN_SPIKE.get()) && state.getValue(TIP_DIRECTION) == direction; + } +} diff --git a/common/src/main/java/com/craisinlord/antarchy/content/client/particle/OrangeAshParticle.java b/common/src/main/java/com/craisinlord/antarchy/content/client/particle/OrangeAshParticle.java new file mode 100644 index 00000000..560b427f --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/content/client/particle/OrangeAshParticle.java @@ -0,0 +1,54 @@ +package com.craisinlord.antarchy.content.client.particle; + +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.particle.Particle; +import net.minecraft.client.particle.ParticleProvider; +import net.minecraft.client.particle.ParticleRenderType; +import net.minecraft.client.particle.SpriteSet; +import net.minecraft.client.particle.TextureSheetParticle; +import net.minecraft.core.particles.SimpleParticleType; + +public final class OrangeAshParticle extends TextureSheetParticle { + private final SpriteSet sprites; + + private OrangeAshParticle(ClientLevel level, double x, double y, double z, double xd, double yd, double zd, SpriteSet sprites) { + super(level, x, y, z, xd, yd, zd); + this.sprites = sprites; + this.friction = 0.98F; + this.gravity = 0.0025F; + this.speedUpWhenYMotionIsBlocked = false; + this.hasPhysics = false; + this.xd = xd * 0.08D + (this.random.nextDouble() - 0.5D) * 0.01D; + this.yd = yd * 0.02D - 0.01D - this.random.nextDouble() * 0.01D; + this.zd = zd * 0.08D + (this.random.nextDouble() - 0.5D) * 0.01D; + this.quadSize *= 0.75F + this.random.nextFloat() * 0.5F; + this.lifetime = 40 + this.random.nextInt(28); + this.setColor(0.96F, 0.46F, 0.12F); + this.setAlpha(0.72F); + this.pickSprite(sprites); + } + + @Override + public void tick() { + super.tick(); + this.pickSprite(this.sprites); + } + + @Override + public ParticleRenderType getRenderType() { + return ParticleRenderType.PARTICLE_SHEET_OPAQUE; + } + + public static final class Provider implements ParticleProvider { + private final SpriteSet sprites; + + public Provider(SpriteSet sprites) { + this.sprites = sprites; + } + + @Override + public Particle createParticle(SimpleParticleType type, ClientLevel level, double x, double y, double z, double xd, double yd, double zd) { + return new OrangeAshParticle(level, x, y, z, xd, yd, zd, this.sprites); + } + } +} diff --git a/common/src/main/java/com/craisinlord/antarchy/content/client/renderer/CavarynSkyRenderer.java b/common/src/main/java/com/craisinlord/antarchy/content/client/renderer/CavarynSkyRenderer.java new file mode 100644 index 00000000..e0bed5f3 --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/content/client/renderer/CavarynSkyRenderer.java @@ -0,0 +1,155 @@ +package com.craisinlord.antarchy.content.client.renderer; + +import com.craisinlord.antarchy.Antarchy; +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.blaze3d.vertex.BufferUploader; +import com.mojang.blaze3d.vertex.DefaultVertexFormat; +import com.mojang.blaze3d.vertex.MeshData; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.Tesselator; +import com.mojang.blaze3d.vertex.VertexBuffer; +import com.mojang.blaze3d.vertex.VertexFormat; +import java.util.Random; +import net.minecraft.client.Camera; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.Level; + +public final class CavarynSkyRenderer { + public static final ResourceKey CAVARYN = ResourceKey.create( + Registries.DIMENSION, + ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "cavaryn") + ); + + @org.jetbrains.annotations.Nullable + private static VertexBuffer orangeStarBuffer; + + private CavarynSkyRenderer() { + } + + public static boolean shouldRender(ClientLevel level) { + return level.dimension().equals(CAVARYN); + } + + public static void render( + Minecraft minecraft, + ClientLevel level, + PoseStack poseStack, + org.joml.Matrix4f projectionMatrix, + float partialTick, + Camera camera, + boolean isFoggy, + Runnable setupFog, + VertexBuffer skyBuffer, + VertexBuffer darkBuffer + ) { + setupFog.run(); + if (isFoggy || minecraft.gameRenderer.getMainCamera() != camera) { + return; + } + + float red = 0.015F; + float green = 0.085F; + float blue = 0.035F; + + RenderSystem.depthMask(false); + RenderSystem.setShaderColor(red, green, blue, 1.0F); + skyBuffer.bind(); + skyBuffer.drawWithShader(poseStack.last().pose(), projectionMatrix, GameRenderer.getPositionShader()); + VertexBuffer.unbind(); + RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); + + float starBrightness = 0.8F; + if (orangeStarBuffer == null) { + orangeStarBuffer = buildOrangeStarBuffer(); + } + + RenderSystem.enableBlend(); + RenderSystem.defaultBlendFunc(); + RenderSystem.setShaderColor(starBrightness, starBrightness, starBrightness, starBrightness); + orangeStarBuffer.bind(); + orangeStarBuffer.drawWithShader(poseStack.last().pose(), projectionMatrix, GameRenderer.getPositionColorShader()); + VertexBuffer.unbind(); + RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); + RenderSystem.disableBlend(); + + if (camera.getEntity() != null) { + double horizon = camera.getEntity().getEyePosition(partialTick).y - level.getLevelData().getHorizonHeight(level); + if (horizon < 0.0D) { + poseStack.pushPose(); + poseStack.translate(0.0F, 12.0F, 0.0F); + darkBuffer.bind(); + darkBuffer.drawWithShader(poseStack.last().pose(), projectionMatrix, GameRenderer.getPositionShader()); + VertexBuffer.unbind(); + poseStack.popPose(); + } + } + + RenderSystem.depthMask(true); + } + + private static VertexBuffer buildOrangeStarBuffer() { + Random random = new Random(548721L); + BufferBuilder builder = Tesselator.getInstance().begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); + + for (int i = 0; i < 1800; i++) { + double x = random.nextFloat() * 2.0F - 1.0F; + double y = random.nextFloat() * 2.0F - 1.0F; + double z = random.nextFloat() * 2.0F - 1.0F; + double size = 0.12F + random.nextFloat() * 0.12F; + double lenSq = x * x + y * y + z * z; + if (lenSq < 1.0D && lenSq > 0.01D) { + double len = 1.0D / Math.sqrt(lenSq); + x *= len; + y *= len; + z *= len; + double sx = x * 100.0D; + double sy = y * 100.0D; + double sz = z * 100.0D; + double yaw = Math.atan2(x, z); + double sinYaw = Math.sin(yaw); + double cosYaw = Math.cos(yaw); + double pitch = Math.atan2(Math.sqrt(x * x + z * z), y); + double sinPitch = Math.sin(pitch); + double cosPitch = Math.cos(pitch); + double rot = random.nextDouble() * Math.PI * 2.0D; + double sinRot = Math.sin(rot); + double cosRot = Math.cos(rot); + + float[] color = pickStarColor(random); + + for (int j = 0; j < 4; j++) { + double u = (j & 2) - 1; + double v = (j + 1 & 2) - 1; + double px = u * cosRot - v * sinRot; + double py = v * cosRot + u * sinRot; + double qx = px * sinPitch; + double qy = -px * cosPitch; + double rx = qy * sinYaw - py * cosYaw; + double ry = py * sinYaw + qy * cosYaw; + builder.addVertex((float) (sx + rx * size), (float) (sy + qx * size), (float) (sz + ry * size)) + .setColor(color[0], color[1], color[2], 1.0F); + } + } + } + + MeshData mesh = builder.buildOrThrow(); + VertexBuffer buffer = new VertexBuffer(VertexBuffer.Usage.STATIC); + buffer.bind(); + buffer.upload(mesh); + VertexBuffer.unbind(); + return buffer; + } + + private static float[] pickStarColor(Random random) { + float roll = random.nextFloat(); + if (roll < 0.70F) return new float[]{1.00F, 0.55F, 0.14F}; + if (roll < 0.90F) return new float[]{1.00F, 0.70F, 0.24F}; + return new float[]{1.00F, 0.84F, 0.40F}; + } +} diff --git a/common/src/main/java/com/craisinlord/antarchy/content/effect/StinkyMobEffect.java b/common/src/main/java/com/craisinlord/antarchy/content/effect/StinkyMobEffect.java index e8580494..13715363 100644 --- a/common/src/main/java/com/craisinlord/antarchy/content/effect/StinkyMobEffect.java +++ b/common/src/main/java/com/craisinlord/antarchy/content/effect/StinkyMobEffect.java @@ -1,10 +1,23 @@ package com.craisinlord.antarchy.content.effect; +import com.craisinlord.antarchy.content.StinkyBehavior; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffectCategory; +import net.minecraft.world.entity.LivingEntity; public final class StinkyMobEffect extends MobEffect { public StinkyMobEffect() { super(MobEffectCategory.HARMFUL, 0x66773A); } + + @Override + public boolean applyEffectTick(LivingEntity entity, int amplifier) { + StinkyBehavior.tickStinkyTrail(entity); + return true; + } + + @Override + public boolean shouldApplyEffectTickThisTick(int duration, int amplifier) { + return true; + } } diff --git a/common/src/main/java/com/craisinlord/antarchy/content/entity/CreepingHorrorEntity.java b/common/src/main/java/com/craisinlord/antarchy/content/entity/CreepingHorrorEntity.java index e6b15149..12868ec8 100644 --- a/common/src/main/java/com/craisinlord/antarchy/content/entity/CreepingHorrorEntity.java +++ b/common/src/main/java/com/craisinlord/antarchy/content/entity/CreepingHorrorEntity.java @@ -1,11 +1,16 @@ package com.craisinlord.antarchy.content.entity; import com.craisinlord.antarchy.config.AntarchySettings; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.Difficulty; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.MobSpawnType; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.ai.goal.FloatGoal; @@ -18,6 +23,9 @@ import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal; import net.minecraft.world.entity.monster.Monster; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; +import net.minecraft.world.level.ServerLevelAccessor; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; import software.bernie.geckolib.animatable.GeoEntity; import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache; import software.bernie.geckolib.animation.AnimatableManager; @@ -62,6 +70,25 @@ public class CreepingHorrorEntity extends Monster implements GeoEntity { .add(Attributes.FOLLOW_RANGE, 16.0D); } + public static boolean canSpawn(EntityType entityType, ServerLevelAccessor level, MobSpawnType spawnReason, BlockPos pos, RandomSource random) { + if (spawnReason == MobSpawnType.SPAWN_EGG || spawnReason == MobSpawnType.SPAWNER || spawnReason == MobSpawnType.COMMAND) { + return true; + } + + BlockPos belowPos = pos.below(); + BlockState belowState = level.getBlockState(belowPos); + boolean validSupport = !belowState.is(Blocks.BEDROCK) + && belowState.blocksMotion() + && belowState.isFaceSturdy(level, belowPos, Direction.UP) + && belowState.isCollisionShapeFullBlock(level, belowPos); + + return level.getDifficulty() != Difficulty.PEACEFUL + && validSupport + && level.isEmptyBlock(pos) + && level.isEmptyBlock(pos.above()) + && Monster.checkMonsterSpawnRules(entityType, level, spawnReason, pos, random); + } + @Override protected void registerGoals() { this.goalSelector.addGoal(0, new FloatGoal(this)); diff --git a/common/src/main/java/com/craisinlord/antarchy/content/entity/LurkingTerrorEntity.java b/common/src/main/java/com/craisinlord/antarchy/content/entity/LurkingTerrorEntity.java index 9feaf00f..3a44ad3b 100644 --- a/common/src/main/java/com/craisinlord/antarchy/content/entity/LurkingTerrorEntity.java +++ b/common/src/main/java/com/craisinlord/antarchy/content/entity/LurkingTerrorEntity.java @@ -1,8 +1,13 @@ package com.craisinlord.antarchy.content.entity; import com.craisinlord.antarchy.config.AntarchySettings; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.Difficulty; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.MobSpawnType; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.ai.control.FlyingMoveControl; @@ -18,6 +23,9 @@ import net.minecraft.world.entity.ai.navigation.PathNavigation; import net.minecraft.world.entity.monster.Monster; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; +import net.minecraft.world.level.ServerLevelAccessor; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; import software.bernie.geckolib.animatable.GeoEntity; import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache; import software.bernie.geckolib.animation.AnimatableManager; @@ -52,6 +60,25 @@ public class LurkingTerrorEntity extends Monster implements GeoEntity { .add(Attributes.FLYING_SPEED, 0.55D); } + public static boolean canSpawn(EntityType entityType, ServerLevelAccessor level, MobSpawnType spawnReason, BlockPos pos, RandomSource random) { + if (spawnReason == MobSpawnType.SPAWN_EGG || spawnReason == MobSpawnType.SPAWNER || spawnReason == MobSpawnType.COMMAND) { + return true; + } + + BlockPos belowPos = pos.below(); + BlockState belowState = level.getBlockState(belowPos); + boolean validSupport = !belowState.is(Blocks.BEDROCK) + && belowState.blocksMotion() + && belowState.isFaceSturdy(level, belowPos, Direction.UP) + && belowState.isCollisionShapeFullBlock(level, belowPos); + + return level.getDifficulty() != Difficulty.PEACEFUL + && validSupport + && level.isEmptyBlock(pos) + && level.isEmptyBlock(pos.above()) + && Monster.checkMonsterSpawnRules(entityType, level, spawnReason, pos, random); + } + @Override protected PathNavigation createNavigation(Level level) { FlyingPathNavigation nav = new FlyingPathNavigation(this, level); diff --git a/common/src/main/java/com/craisinlord/antarchy/content/entity/OctopusBombEntity.java b/common/src/main/java/com/craisinlord/antarchy/content/entity/OctopusBombEntity.java index b06d9949..527f7513 100644 --- a/common/src/main/java/com/craisinlord/antarchy/content/entity/OctopusBombEntity.java +++ b/common/src/main/java/com/craisinlord/antarchy/content/entity/OctopusBombEntity.java @@ -2,8 +2,7 @@ package com.craisinlord.antarchy.content.entity; import com.craisinlord.antarchy.content.AntarchySoundEvents; import com.craisinlord.antarchy.content.damage.AntarchyDamageSources; -import net.minecraft.core.BlockPos; -import net.minecraft.tags.FluidTags; +import net.minecraft.core.particles.ParticleTypes; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; @@ -11,7 +10,6 @@ import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundEvent; -import net.minecraft.core.particles.ParticleTypes; import net.minecraft.util.Mth; import net.minecraft.util.RandomSource; import net.minecraft.world.DifficultyInstance; @@ -24,6 +22,7 @@ import net.minecraft.world.entity.ai.control.SmoothSwimmingMoveControl; import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal; import net.minecraft.world.entity.ai.goal.RandomLookAroundGoal; import net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal; +import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal; import net.minecraft.world.entity.ai.navigation.FlyingPathNavigation; import net.minecraft.world.entity.ai.navigation.PathNavigation; import net.minecraft.world.entity.ai.navigation.WaterBoundPathNavigation; @@ -46,28 +45,21 @@ import java.util.Objects; public class OctopusBombEntity extends Monster implements GeoEntity { private static final EntityDataAccessor ATTACK_STATE = SynchedEntityData.defineId(OctopusBombEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor ROARING = SynchedEntityData.defineId(OctopusBombEntity.class, EntityDataSerializers.BOOLEAN); private static final EntityDataAccessor ANIMATION_STATE = SynchedEntityData.defineId(OctopusBombEntity.class, EntityDataSerializers.INT); private static final EntityDataAccessor CAN_FLY = SynchedEntityData.defineId(OctopusBombEntity.class, EntityDataSerializers.BOOLEAN); - private static final String ATTACK_COOLDOWN_KEY = "AttackCooldown"; - private static final String ACTION_TICKS_KEY = "ActionTicks"; - private static final String LAST_ATTACK_STATE_KEY = "LastAttackState"; - private static final String AGGRO_TRIGGERED_KEY = "AggroTriggered"; - private static final String GRAB_TARGET_KEY = "GrabTarget"; - private static final String CAN_FLY_KEY = "CanFly"; - private static final String SPAWNED_BY_KRAKEN_KEY = "SpawnedByKraken"; - private static final int ATTACK_NONE = 0; private static final int ATTACK_GRAB = 1; private static final int ATTACK_SWIPE = 2; + private static final int ANIM_IDLE = 0; private static final int ANIM_SWIM = 2; private static final int ANIM_SWIPE = 3; private static final int ANIM_GRAB = 4; private static final int ANIM_DEATH = 5; + private static final int DEATH_ANIM_TICKS = 60; - private static final int INK_SPRAY_RANGE = 6; + private static final int INK_SPRAY_RANGE = 8; private static final int INK_SPRAY_COOLDOWN = 80; private static final RawAnimation IDLE_ANIM = RawAnimation.begin().thenLoop("idle"); @@ -77,16 +69,21 @@ public class OctopusBombEntity extends Monster implements GeoEntity { private static final RawAnimation DEATH_ANIM = RawAnimation.begin().thenPlay("Death"); private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this); + + // Squid-style wander private float wanderDx, wanderDy, wanderDz; private int wanderRetargetTicks; + + // Combat private int attackCooldown; private int actionTicks; private int lastAttackState; - private boolean aggroTriggered; private int grabbedTargetId = -1; private int strafeRetargetTicks; - private int inkSprayCooldown; private float orbitDirection = 1.0F; + private int inkSprayCooldown; + + // Kraken spawn flag private boolean spawnedByKraken; public OctopusBombEntity(EntityType entityType, Level level) { @@ -97,7 +94,7 @@ public class OctopusBombEntity extends Monster implements GeoEntity { public static AttributeSupplier.Builder createAttributes() { return Mob.createMobAttributes() - .add(Attributes.MAX_HEALTH, 250.0D) + .add(Attributes.MAX_HEALTH, 100.0D) .add(Attributes.ATTACK_DAMAGE, 16.0D) .add(Attributes.MOVEMENT_SPEED, 0.28D) .add(Attributes.FLYING_SPEED, 0.28D) @@ -105,15 +102,15 @@ public class OctopusBombEntity extends Monster implements GeoEntity { .add(Attributes.KNOCKBACK_RESISTANCE, 0.4D); } - public static boolean canSpawn(EntityType entityType, ServerLevelAccessor level, MobSpawnType spawnReason, BlockPos pos, RandomSource random) { - return level.getFluidState(pos).is(FluidTags.WATER) && level.getFluidState(pos.above()).is(FluidTags.WATER); + public static boolean canSpawn(EntityType entityType, ServerLevelAccessor level, MobSpawnType spawnReason, net.minecraft.core.BlockPos pos, RandomSource random) { + return level.getFluidState(pos).is(net.minecraft.tags.FluidTags.WATER) + && level.getFluidState(pos.above()).is(net.minecraft.tags.FluidTags.WATER); } @Override protected void defineSynchedData(SynchedEntityData.Builder builder) { super.defineSynchedData(builder); builder.define(ATTACK_STATE, ATTACK_NONE); - builder.define(ROARING, false); builder.define(ANIMATION_STATE, ANIM_IDLE); builder.define(CAN_FLY, false); } @@ -133,12 +130,26 @@ public class OctopusBombEntity extends Monster implements GeoEntity { @Override protected void registerGoals() { - this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 20.0F)); - this.goalSelector.addGoal(7, new RandomLookAroundGoal(this)); + this.goalSelector.addGoal(5, new LookAtPlayerGoal(this, Player.class, 20.0F)); + this.goalSelector.addGoal(6, new RandomLookAroundGoal(this)); - HurtByTargetGoal hurtByTargetGoal = new HurtByTargetGoal(this); - hurtByTargetGoal.setAlertOthers(MissileSquidEntity.class); - this.targetSelector.addGoal(1, hurtByTargetGoal); + // Only retaliate when hit — neutral otherwise + this.targetSelector.addGoal(1, new HurtByTargetGoal(this)); + // When spawned by Kraken and flying, target nearest player + this.targetSelector.addGoal(2, new KrakenSummonTargetGoal(this)); + } + + @Override + protected PathNavigation createNavigation(Level level) { + return new WaterBoundPathNavigation(this, level); + } + + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnReason, @Nullable SpawnGroupData spawnData) { + Objects.requireNonNull(this.getAttribute(Attributes.MAX_HEALTH)).setBaseValue(com.craisinlord.antarchy.config.AntarchySettings.octopusBombHealth()); + this.setHealth((float) com.craisinlord.antarchy.config.AntarchySettings.octopusBombHealth()); + Objects.requireNonNull(this.getAttribute(Attributes.ATTACK_DAMAGE)).setBaseValue(com.craisinlord.antarchy.config.AntarchySettings.octopusBombAttackDamage()); + return super.finalizeSpawn(level, difficulty, spawnReason, spawnData); } @Override @@ -162,19 +173,6 @@ public class OctopusBombEntity extends Monster implements GeoEntity { return this.geoCache; } - @Override - protected PathNavigation createNavigation(Level level) { - return new WaterBoundPathNavigation(this, level); - } - - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor level, DifficultyInstance difficulty, MobSpawnType spawnReason, @Nullable SpawnGroupData spawnData) { - Objects.requireNonNull(this.getAttribute(Attributes.MAX_HEALTH)).setBaseValue(com.craisinlord.antarchy.config.AntarchySettings.octopusBombHealth()); - this.setHealth((float) com.craisinlord.antarchy.config.AntarchySettings.octopusBombHealth()); - Objects.requireNonNull(this.getAttribute(Attributes.ATTACK_DAMAGE)).setBaseValue(com.craisinlord.antarchy.config.AntarchySettings.octopusBombAttackDamage()); - return super.finalizeSpawn(level, difficulty, spawnReason, spawnData); - } - @Override public void baseTick() { int airSupply = this.getAirSupply(); @@ -196,22 +194,17 @@ public class OctopusBombEntity extends Monster implements GeoEntity { return; } - if (this.attackCooldown > 0) { - this.attackCooldown--; - } - if (this.inkSprayCooldown > 0) { - this.inkSprayCooldown--; - } + if (this.attackCooldown > 0) this.attackCooldown--; + if (this.inkSprayCooldown > 0) this.inkSprayCooldown--; + + // Ink spray — always active regardless of aggro state + this.tickInkSpray(); LivingEntity target = this.getTarget(); - this.tickDefensiveInkSpray(); - if (target == null || !target.isAlive()) { this.resetCombatState(); - if (this.isInWater()) { - this.tickWanderMovement(); - } + if (this.isInWater()) this.tickWanderMovement(); this.updateSwimRotation(); this.updateAnimationState(); return; @@ -219,30 +212,15 @@ public class OctopusBombEntity extends Monster implements GeoEntity { this.getLookControl().setLookAt(target, 25.0F, 20.0F); - if (!this.aggroTriggered) { - this.startAggroRoar(); - } - - if (this.isRoaring()) { - this.tickRoarState(target); - this.updateSwimRotation(); - this.updateAnimationState(); - return; - } - if (this.getAttackState() != ATTACK_NONE) { this.tickCurrentAttack(target); - this.updateSwimRotation(); - this.updateAnimationState(); - return; - } - - this.tickPursuitMovement(target); - - if (this.attackCooldown <= 0) { - int nextAttack = this.chooseNextAttack(target); - if (nextAttack != ATTACK_NONE) { - this.startAttack(nextAttack); + } else { + this.tickPursuitMovement(target); + if (this.attackCooldown <= 0) { + int nextAttack = this.chooseNextAttack(target); + if (nextAttack != ATTACK_NONE) { + this.startAttack(nextAttack); + } } } @@ -258,7 +236,6 @@ public class OctopusBombEntity extends Monster implements GeoEntity { this.setDeltaMovement(this.getDeltaMovement().scale(this.isInWater() ? 0.92D : 0.91D)); return; } - super.travel(travelVector); } @@ -296,16 +273,12 @@ public class OctopusBombEntity extends Monster implements GeoEntity { @Override public void addAdditionalSaveData(CompoundTag tag) { super.addAdditionalSaveData(tag); - tag.putInt(ATTACK_COOLDOWN_KEY, this.attackCooldown); - tag.putInt(ACTION_TICKS_KEY, this.actionTicks); - tag.putInt(LAST_ATTACK_STATE_KEY, this.lastAttackState); - tag.putBoolean(AGGRO_TRIGGERED_KEY, this.aggroTriggered); - tag.putBoolean(CAN_FLY_KEY, this.canFly()); - tag.putBoolean(SPAWNED_BY_KRAKEN_KEY, this.spawnedByKraken); - if (this.grabbedTargetId >= 0) { - tag.putInt(GRAB_TARGET_KEY, this.grabbedTargetId); - } - tag.putBoolean("Roaring", this.isRoaring()); + tag.putInt("AttackCooldown", this.attackCooldown); + tag.putInt("ActionTicks", this.actionTicks); + tag.putInt("LastAttackState", this.lastAttackState); + tag.putBoolean("CanFly", this.canFly()); + tag.putBoolean("SpawnedByKraken", this.spawnedByKraken); + if (this.grabbedTargetId >= 0) tag.putInt("GrabTarget", this.grabbedTargetId); tag.putInt("AttackState", this.getAttackState()); tag.putInt("AnimationState", this.getAnimationState()); } @@ -313,27 +286,24 @@ public class OctopusBombEntity extends Monster implements GeoEntity { @Override public void readAdditionalSaveData(CompoundTag tag) { super.readAdditionalSaveData(tag); - this.attackCooldown = tag.getInt(ATTACK_COOLDOWN_KEY); - this.actionTicks = tag.getInt(ACTION_TICKS_KEY); - this.lastAttackState = tag.contains(LAST_ATTACK_STATE_KEY) ? tag.getInt(LAST_ATTACK_STATE_KEY) : ATTACK_NONE; - this.aggroTriggered = tag.getBoolean(AGGRO_TRIGGERED_KEY); - this.setCanFly(tag.getBoolean(CAN_FLY_KEY)); - this.spawnedByKraken = tag.getBoolean(SPAWNED_BY_KRAKEN_KEY); - this.grabbedTargetId = tag.contains(GRAB_TARGET_KEY) ? tag.getInt(GRAB_TARGET_KEY) : -1; - this.entityData.set(ROARING, tag.getBoolean("Roaring")); + this.attackCooldown = tag.getInt("AttackCooldown"); + this.actionTicks = tag.getInt("ActionTicks"); + this.lastAttackState = tag.contains("LastAttackState") ? tag.getInt("LastAttackState") : ATTACK_NONE; + this.setCanFly(tag.getBoolean("CanFly")); + this.spawnedByKraken = tag.getBoolean("SpawnedByKraken"); + this.grabbedTargetId = tag.contains("GrabTarget") ? tag.getInt("GrabTarget") : -1; this.entityData.set(ATTACK_STATE, tag.getInt("AttackState")); this.entityData.set(ANIMATION_STATE, tag.contains("AnimationState") ? tag.getInt("AnimationState") : ANIM_IDLE); - this.updateAnimationState(); - } - - public boolean isRoaring() { - return this.entityData.get(ROARING); } public boolean canFly() { return this.entityData.get(CAN_FLY); } + public void setCanFly(boolean canFly) { + this.entityData.set(CAN_FLY, canFly); + } + public int getAttackState() { return this.entityData.get(ATTACK_STATE); } @@ -342,49 +312,79 @@ public class OctopusBombEntity extends Monster implements GeoEntity { return this.entityData.get(ANIMATION_STATE); } - private void setRoaring(boolean roaring) { - this.entityData.set(ROARING, roaring); + private void setAttackState(int state) { + this.entityData.set(ATTACK_STATE, state); } - public void setCanFly(boolean canFly) { - this.entityData.set(CAN_FLY, canFly); + private void setAnimationState(int state) { + this.entityData.set(ANIMATION_STATE, state); } - public void launchAsProjectile(net.minecraft.world.entity.Entity owner, net.minecraft.world.phys.Vec3 velocity) { + public void launchAsProjectile(net.minecraft.world.entity.Entity owner, Vec3 velocity) { this.spawnedByKraken = true; this.setCanFly(true); this.setDeltaMovement(velocity); } - private void setAttackState(int attackState) { - this.entityData.set(ATTACK_STATE, attackState); - } + // ------------------------------------------------------------------------- + // Squid-style wander + // ------------------------------------------------------------------------- - private void setAnimationState(int animationState) { - this.entityData.set(ANIMATION_STATE, animationState); - } - - private void startAggroRoar() { - this.aggroTriggered = true; - this.actionTicks = 30; - this.setRoaring(true); - this.playSound(AntarchySoundEvents.KRAKEN_ROAR.get(), 1.4F, 1.07F); - this.getNavigation().stop(); - this.setDeltaMovement(this.getDeltaMovement().scale(0.2D)); - this.updateAnimationState(); - } - - private void tickRoarState(LivingEntity target) { - this.getNavigation().stop(); - this.getMoveControl().setWantedPosition(this.getX(), this.getY(), this.getZ(), 0.0D); - this.setDeltaMovement(this.getDeltaMovement().scale(0.6D)); - this.getLookControl().setLookAt(target, 25.0F, 20.0F); - - if (--this.actionTicks <= 0) { - this.actionTicks = 0; - this.setRoaring(false); - this.attackCooldown = 18; + private void tickWanderMovement() { + if (--this.wanderRetargetTicks <= 0) { + this.wanderRetargetTicks = 40 + this.random.nextInt(40); + float angle = this.random.nextFloat() * (float) (Math.PI * 2); + this.wanderDx = Mth.cos(angle) * 0.1f; + this.wanderDy = -0.05f + this.random.nextFloat() * 0.1f; + this.wanderDz = Mth.sin(angle) * 0.1f; } + this.setDeltaMovement(this.getDeltaMovement().add(this.wanderDx, this.wanderDy, this.wanderDz)); + } + + // ------------------------------------------------------------------------- + // Ink spray + // ------------------------------------------------------------------------- + + private void tickInkSpray() { + if (this.inkSprayCooldown > 0 || !(this.level() instanceof ServerLevel serverLevel)) return; + + Player nearbyPlayer = this.level().getNearestPlayer(this, INK_SPRAY_RANGE); + if (nearbyPlayer == null || nearbyPlayer.isCreative() || nearbyPlayer.isSpectator()) return; + + this.inkSprayCooldown = INK_SPRAY_COOLDOWN; + this.playSound(AntarchySoundEvents.KRAKEN_HURT.get(), 1.0F, 1.49F); + + double cx = this.getX(); + double cy = this.getY() + this.getBbHeight() * 0.5D; + double cz = this.getZ(); + serverLevel.sendParticles(ParticleTypes.SQUID_INK, cx, cy, cz, 120, 2.0D, 1.2D, 2.0D, 0.04D); + serverLevel.sendParticles(ParticleTypes.SQUID_INK, cx, cy, cz, 60, 3.5D, 1.8D, 3.5D, 0.02D); + } + + // ------------------------------------------------------------------------- + // Combat + // ------------------------------------------------------------------------- + + private void tickPursuitMovement(LivingEntity target) { + if (this.strafeRetargetTicks-- <= 0) { + this.strafeRetargetTicks = 10 + this.random.nextInt(12); + if (this.random.nextFloat() < 0.4F) this.orbitDirection *= -1.0F; + } + Vec3 attackPoint = this.createCombatTarget(target); + this.getMoveControl().setWantedPosition(attackPoint.x, attackPoint.y, attackPoint.z, 1.1D); + } + + private Vec3 createCombatTarget(LivingEntity target) { + double radius = 9.0D; + double angle = this.tickCount * 0.16D * this.orbitDirection + this.getId() * 0.11D; + double x = target.getX() + Math.cos(angle) * radius; + double z = target.getZ() + Math.sin(angle) * radius; + double y = Mth.clamp( + target.getY() + 1.0D + Math.sin((this.tickCount + this.getId()) * 0.18D), + target.getY() - 3.0D, + target.getY() + 4.0D + ); + return new Vec3(x, y, z); } private void tickCurrentAttack(LivingEntity target) { @@ -402,7 +402,6 @@ public class OctopusBombEntity extends Monster implements GeoEntity { private void startAttack(int attackState) { this.setAttackState(attackState); this.grabbedTargetId = -1; - if (attackState == ATTACK_GRAB) { this.actionTicks = 55; this.playSound(AntarchySoundEvents.KRAKEN_ATTACK.get(), 1.2F, 1.07F); @@ -417,33 +416,26 @@ public class OctopusBombEntity extends Monster implements GeoEntity { this.grabbedTargetId = target.getId(); } - LivingEntity grabbedTarget = this.getGrabbedTarget(); - if (grabbedTarget != null && grabbedTarget.isAlive()) { - this.holdGrabbedTarget(grabbedTarget); + LivingEntity grabbed = this.getGrabbedTarget(); + if (grabbed != null && grabbed.isAlive()) { + this.holdGrabbedTarget(grabbed); if (this.actionTicks <= 45 && this.actionTicks > 10 && this.actionTicks % 10 == 0) { if (this.level() instanceof ServerLevel serverLevel) { - grabbedTarget.hurt(AntarchyDamageSources.krakenMauling(serverLevel, this), 4.0F); + grabbed.hurt(AntarchyDamageSources.krakenMauling(serverLevel, this), 4.0F); } } } if (--this.actionTicks <= 0) { - if (grabbedTarget != null && grabbedTarget.isAlive()) { - this.pullDown(grabbedTarget, 2.5D); - } + if (grabbed != null && grabbed.isAlive()) this.pullDown(grabbed, 2.5D); this.grabbedTargetId = -1; this.finishAttack(); } } private void tickSwipeAttack() { - if (this.actionTicks == 10) { - this.performSwipe(); - } - - if (--this.actionTicks <= 0) { - this.finishAttack(); - } + if (this.actionTicks == 10) this.performSwipe(); + if (--this.actionTicks <= 0) this.finishAttack(); } private void finishAttack() { @@ -453,70 +445,13 @@ public class OctopusBombEntity extends Monster implements GeoEntity { this.attackCooldown = 18; this.grabbedTargetId = -1; this.lastAttackState = finished; - this.updateAnimationState(); - } - - private void tickPursuitMovement(LivingEntity target) { - if (this.strafeRetargetTicks-- <= 0) { - this.strafeRetargetTicks = 10 + this.random.nextInt(12); - if (this.random.nextFloat() < 0.4F) { - this.orbitDirection *= -1.0F; - } - } - - Vec3 attackPoint = this.createCombatTarget(target); - this.getMoveControl().setWantedPosition(attackPoint.x, attackPoint.y, attackPoint.z, 1.1D); - } - - private void resetCombatState() { - this.setAttackState(ATTACK_NONE); - this.setRoaring(false); - this.setTarget(null); - this.actionTicks = 0; - this.grabbedTargetId = -1; - this.aggroTriggered = false; - this.updateAnimationState(); - } - - private void handleAirSupply(int previousAirSupply) { - if (this.isInWaterOrBubble()) { - this.setAirSupply(this.getMaxAirSupply()); - return; - } - - this.setAirSupply(previousAirSupply - 1); - if (this.getAirSupply() <= -20) { - this.setAirSupply(0); - this.hurt(this.damageSources().drown(), 2.0F); - } - } - - private void tickDefensiveInkSpray() { - if (this.inkSprayCooldown > 0 || !(this.level() instanceof ServerLevel serverLevel)) { - return; - } - - Player nearbyPlayer = this.level().getNearestPlayer(this, INK_SPRAY_RANGE); - if (nearbyPlayer == null || nearbyPlayer.isCreative() || nearbyPlayer.isSpectator()) { - return; - } - - this.inkSprayCooldown = INK_SPRAY_COOLDOWN; - this.playSound(AntarchySoundEvents.KRAKEN_HURT.get(), 1.0F, 1.49F); - - double centerY = this.getY() + this.getBbHeight() * 0.5D; - serverLevel.sendParticles(ParticleTypes.SQUID_INK, this.getX(), centerY, this.getZ(), 55, 1.2D, 0.8D, 1.2D, 0.02D); - serverLevel.sendParticles(ParticleTypes.SQUID_INK, this.getX(), centerY, this.getZ(), 35, 2.0D, 1.1D, 2.0D, 0.01D); } private int chooseNextAttack(LivingEntity target) { double distSqr = this.distanceToSqr(target); boolean canGrab = distSqr <= 42.25D; boolean canSwipe = distSqr <= 81.0D && this.isTargetInFront(target, -0.15D); - - if (!canGrab && !canSwipe) { - return ATTACK_NONE; - } + if (!canGrab && !canSwipe) return ATTACK_NONE; int grabWeight = canGrab ? (this.lastAttackState == ATTACK_GRAB ? 1 : 4) : 0; int swipeWeight = canSwipe ? (this.lastAttackState == ATTACK_SWIPE ? 1 : 5) : 0; @@ -524,19 +459,19 @@ public class OctopusBombEntity extends Monster implements GeoEntity { if (total == 0) return ATTACK_NONE; int roll = this.random.nextInt(total); - if (roll < grabWeight) return ATTACK_GRAB; - return ATTACK_SWIPE; + return roll < grabWeight ? ATTACK_GRAB : ATTACK_SWIPE; } private void performSwipe() { AABB hitBox = this.getBoundingBox().inflate(7.0D, 3.0D, 7.0D); - List players = this.level().getEntitiesOfClass(Player.class, hitBox, player -> player.isAlive() && this.isTargetInFront(player, -0.15D)); + List players = this.level().getEntitiesOfClass(Player.class, hitBox, + p -> p.isAlive() && this.isTargetInFront(p, -0.15D)); float damage = (float) this.getAttributeValue(Attributes.ATTACK_DAMAGE); for (Player player : players) { if (this.level() instanceof ServerLevel serverLevel) { player.hurt(AntarchyDamageSources.krakenMauling(serverLevel, this), damage); - Vec3 direction = player.position().subtract(this.position()); - Vec3 horizontal = new Vec3(direction.x, 0.0D, direction.z).normalize().scale(1.75D); + Vec3 dir = player.position().subtract(this.position()); + Vec3 horizontal = new Vec3(dir.x, 0.0D, dir.z).normalize().scale(1.75D); player.push(horizontal.x, 0.3D, horizontal.z); player.hurtMarked = true; } @@ -547,45 +482,49 @@ public class OctopusBombEntity extends Monster implements GeoEntity { Vec3 anchor = this.position().add(0.0D, -this.getBbHeight() * 0.4D, 0.0D); target.setDeltaMovement(anchor.subtract(target.position()).scale(0.35D)); target.resetFallDistance(); - if (target instanceof ServerPlayer serverPlayer) { - serverPlayer.connection.teleport(anchor.x, anchor.y, anchor.z, target.getYRot(), target.getXRot()); + if (target instanceof ServerPlayer sp) { + sp.connection.teleport(anchor.x, anchor.y, anchor.z, target.getYRot(), target.getXRot()); } else { target.moveTo(anchor.x, anchor.y, anchor.z, target.getYRot(), target.getXRot()); } target.hurtMarked = true; } - private void pullDown(LivingEntity target, double downwardStrength) { - target.push(0.0D, -downwardStrength, 0.0D); + private void pullDown(LivingEntity target, double strength) { + target.push(0.0D, -strength, 0.0D); target.hurtMarked = true; } @Nullable private LivingEntity getGrabbedTarget() { - if (this.grabbedTargetId < 0) { - return null; - } - net.minecraft.world.entity.Entity entity = this.level().getEntity(this.grabbedTargetId); - return entity instanceof LivingEntity livingEntity ? livingEntity : null; + if (this.grabbedTargetId < 0) return null; + net.minecraft.world.entity.Entity e = this.level().getEntity(this.grabbedTargetId); + return e instanceof LivingEntity le ? le : null; } - private boolean isTargetInFront(LivingEntity target, double minimumDot) { + private boolean isTargetInFront(LivingEntity target, double minDot) { Vec3 forward = this.getViewVector(1.0F); Vec3 toTarget = target.position().subtract(this.position()).normalize(); - return forward.dot(toTarget) >= minimumDot; + return forward.dot(toTarget) >= minDot; } - private Vec3 createCombatTarget(LivingEntity target) { - double radius = 9.0D; - double angle = this.tickCount * 0.16D * this.orbitDirection + this.getId() * 0.11D; - double x = target.getX() + Math.cos(angle) * radius; - double z = target.getZ() + Math.sin(angle) * radius; - double y = Mth.clamp( - target.getY() + 1.0D + Math.sin((this.tickCount + this.getId()) * 0.18D), - target.getY() - 3.0D, - target.getY() + 4.0D - ); - return new Vec3(x, y, z); + private void resetCombatState() { + this.setAttackState(ATTACK_NONE); + this.setTarget(null); + this.actionTicks = 0; + this.grabbedTargetId = -1; + } + + private void handleAirSupply(int previousAirSupply) { + if (this.isInWaterOrBubble()) { + this.setAirSupply(this.getMaxAirSupply()); + return; + } + this.setAirSupply(previousAirSupply - 1); + if (this.getAirSupply() <= -20) { + this.setAirSupply(0); + this.hurt(this.damageSources().drown(), 2.0F); + } } private void updateSwimRotation() { @@ -596,21 +535,41 @@ public class OctopusBombEntity extends Monster implements GeoEntity { this.yBodyRot = this.getYRot(); this.yHeadRot = this.getYRot(); } - if (velocity.lengthSqr() > 1.0E-4D) { float targetPitch = (float) (-(Mth.atan2(velocity.y, velocity.horizontalDistance()) * (180.0D / Math.PI))); this.setXRot(Mth.approachDegrees(this.getXRot(), targetPitch, 4.0F)); } } + private void updateAnimationState() { + if (this.isDeadOrDying()) { + this.setAnimationState(ANIM_DEATH); + return; + } + switch (this.getAttackState()) { + case ATTACK_GRAB -> { this.setAnimationState(ANIM_GRAB); return; } + case ATTACK_SWIPE -> { this.setAnimationState(ANIM_SWIPE); return; } + default -> {} + } + if (!this.isInWater()) { + this.setAnimationState(ANIM_SWIM); + return; + } + Vec3 vel = this.getDeltaMovement(); + double hSqr = vel.horizontalDistanceSqr(); + double vSqr = vel.y * vel.y; + if (hSqr > 0.03D && hSqr > vSqr * 2.5D) { + this.setAnimationState(ANIM_SWIM); + return; + } + this.setAnimationState(ANIM_IDLE); + } + @Override public void die(DamageSource damageSource) { if (!this.level().isClientSide) { this.setAnimationState(ANIM_DEATH); - this.actionTicks = 0; - this.attackCooldown = 0; this.setAttackState(ATTACK_NONE); - this.setRoaring(false); this.setDeltaMovement(Vec3.ZERO); this.getNavigation().stop(); } @@ -620,65 +579,28 @@ public class OctopusBombEntity extends Monster implements GeoEntity { @Override protected void tickDeath() { this.deathTime++; - - if (this.deathTime == 1) { - this.setAnimationState(ANIM_DEATH); - } - + if (this.deathTime == 1) this.setAnimationState(ANIM_DEATH); if (this.deathTime >= DEATH_ANIM_TICKS) { this.remove(RemovalReason.KILLED); this.dropExperience(this); } } - private void updateAnimationState() { - if (this.isDeadOrDying()) { - this.setAnimationState(ANIM_DEATH); - return; + // ------------------------------------------------------------------------- + // Inner goal: only target players when spawned by Kraken in fly mode + // ------------------------------------------------------------------------- + + private static final class KrakenSummonTargetGoal extends NearestAttackableTargetGoal { + private final OctopusBombEntity octopus; + + KrakenSummonTargetGoal(OctopusBombEntity octopus) { + super(octopus, Player.class, true); + this.octopus = octopus; } - if (this.isRoaring()) { - this.setAnimationState(ANIM_IDLE); - return; + @Override + public boolean canUse() { + return this.octopus.spawnedByKraken && this.octopus.canFly() && super.canUse(); } - - switch (this.getAttackState()) { - case ATTACK_GRAB -> { - this.setAnimationState(ANIM_GRAB); - return; - } - case ATTACK_SWIPE -> { - this.setAnimationState(ANIM_SWIPE); - return; - } - default -> { - } - } - - if (!this.isInWater()) { - this.setAnimationState(ANIM_SWIM); - return; - } - - Vec3 velocity = this.getDeltaMovement(); - double horizontalSpeedSqr = velocity.horizontalDistanceSqr(); - double verticalSpeedSqr = velocity.y * velocity.y; - if (horizontalSpeedSqr > 0.03D && horizontalSpeedSqr > verticalSpeedSqr * 2.5D) { - this.setAnimationState(ANIM_SWIM); - return; - } - - this.setAnimationState(ANIM_IDLE); - } - - private void tickWanderMovement() { - if (--this.wanderRetargetTicks <= 0) { - this.wanderRetargetTicks = 40 + this.random.nextInt(40); - float angle = this.random.nextFloat() * (float) (Math.PI * 2); - this.wanderDx = Mth.cos(angle) * 0.1f; - this.wanderDy = -0.05f + this.random.nextFloat() * 0.1f; - this.wanderDz = Mth.sin(angle) * 0.1f; - } - this.setDeltaMovement(this.getDeltaMovement().add(this.wanderDx, this.wanderDy, this.wanderDz)); } } diff --git a/common/src/main/java/com/craisinlord/antarchy/content/entity/ant/BaseAntEntity.java b/common/src/main/java/com/craisinlord/antarchy/content/entity/ant/BaseAntEntity.java index 464d61f2..5b09bb03 100644 --- a/common/src/main/java/com/craisinlord/antarchy/content/entity/ant/BaseAntEntity.java +++ b/common/src/main/java/com/craisinlord/antarchy/content/entity/ant/BaseAntEntity.java @@ -1230,11 +1230,11 @@ public abstract class BaseAntEntity extends Animal implements GeoEntity { } private boolean shouldPlayAttackAnimation() { - if (!(this instanceof RedAntEntity)) { - return false; - } + return this.shouldUseBiteAnimation() && this.getBiteAnimationTicks() > 0; + } - return this.getBiteAnimationTicks() > 0; + protected boolean shouldUseBiteAnimation() { + return this instanceof RedAntEntity; } private int getBiteAnimationTicks() { @@ -1245,6 +1245,10 @@ public abstract class BaseAntEntity extends Animal implements GeoEntity { this.entityData.set(BITE_ANIM_TICKS, Math.max(0, ticks)); } + protected final void triggerBiteAnimation(int ticks) { + this.setBiteAnimationTicks(ticks); + } + private void syncAttribute(@Nullable AttributeInstance attributeInstance, double desiredValue, boolean rescaleCurrentHealth) { if (attributeInstance == null || Math.abs(attributeInstance.getBaseValue() - desiredValue) < ATTRIBUTE_EPSILON) { return; diff --git a/common/src/main/java/com/craisinlord/antarchy/content/entity/ant/TermiteEntity.java b/common/src/main/java/com/craisinlord/antarchy/content/entity/ant/TermiteEntity.java index 8bab5980..70afc6ff 100644 --- a/common/src/main/java/com/craisinlord/antarchy/content/entity/ant/TermiteEntity.java +++ b/common/src/main/java/com/craisinlord/antarchy/content/entity/ant/TermiteEntity.java @@ -17,6 +17,7 @@ import org.jetbrains.annotations.Nullable; import software.bernie.geckolib.animatable.GeoEntity; public class TermiteEntity extends BaseAntEntity implements GeoEntity { + private static final int WOOD_BITE_ANIMATION_TICKS = 8; private static final int WOOD_SEARCH_INTERVAL_TICKS = 10; private static final int WOOD_REPATH_INTERVAL_TICKS = 6; private static final int WOOD_SEARCH_RADIUS_HORIZONTAL = 12; @@ -88,6 +89,11 @@ public class TermiteEntity extends BaseAntEntity implements GeoEntity { return false; } + @Override + protected boolean shouldUseBiteAnimation() { + return true; + } + @Override protected boolean handlePriorityForaging() { if (!this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { @@ -126,6 +132,7 @@ public class TermiteEntity extends BaseAntEntity implements GeoEntity { } SoundType soundType = targetState.getSoundType(); + this.triggerBiteAnimation(WOOD_BITE_ANIMATION_TICKS); this.level().destroyBlock(targetPos, false, this); this.level().playSound(null, targetPos, soundType.getBreakSound(), this.getSoundSource(), 0.7F, 1.1F); return true; diff --git a/common/src/main/java/com/craisinlord/antarchy/content/fluid/BileLiquidBlock.java b/common/src/main/java/com/craisinlord/antarchy/content/fluid/BileLiquidBlock.java new file mode 100644 index 00000000..81476b5f --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/content/fluid/BileLiquidBlock.java @@ -0,0 +1,42 @@ +package com.craisinlord.antarchy.content.fluid; + +import com.craisinlord.antarchy.content.AntarchyObjects; +import net.minecraft.core.BlockPos; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.tags.EntityTypeTags; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.LiquidBlock; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.FlowingFluid; +import net.minecraft.world.phys.Vec3; + +public class BileLiquidBlock extends LiquidBlock { + private static final int EFFECT_DURATION_TICKS = 100; + private static final Vec3 SLOW_MOVEMENT = new Vec3(0.85D, 0.95D, 0.85D); + + public BileLiquidBlock(FlowingFluid fluid, BlockBehaviour.Properties properties) { + super(fluid, properties); + } + + @Override + public void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { + super.entityInside(state, level, pos, entity); + + if (entity instanceof LivingEntity livingEntity) { + if (!level.isClientSide) { + livingEntity.addEffect(new MobEffectInstance(AntarchyObjects.STINKY_EFFECT.get(), EFFECT_DURATION_TICKS, 0, false, true, true)); + livingEntity.addEffect(new MobEffectInstance(MobEffects.WEAKNESS, EFFECT_DURATION_TICKS, 0, false, true, true)); + } + + if (livingEntity.getType().is(EntityTypeTags.SENSITIVE_TO_BANE_OF_ARTHROPODS)) { + return; + } + } + + entity.makeStuckInBlock(state, SLOW_MOVEMENT); + } +} diff --git a/common/src/main/java/com/craisinlord/antarchy/content/worldgen/cavaryn/CavarynBilePoolFeature.java b/common/src/main/java/com/craisinlord/antarchy/content/worldgen/cavaryn/CavarynBilePoolFeature.java new file mode 100644 index 00000000..f28f4f69 --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/content/worldgen/cavaryn/CavarynBilePoolFeature.java @@ -0,0 +1,150 @@ +package com.craisinlord.antarchy.content.worldgen.cavaryn; + +import com.craisinlord.antarchy.Antarchy; +import com.mojang.serialization.Codec; +import java.util.Optional; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.LiquidBlock; +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; +import net.minecraft.world.level.material.FluidState; + +public final class CavarynBilePoolFeature extends Feature { + private static final ResourceLocation BILE_ID = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "bile"); + private static final int SEARCH_RADIUS = 8; + private static final int SEARCH_ATTEMPTS = 24; + private static final int FLOOR_SCAN_RANGE = 14; + + public CavarynBilePoolFeature(Codec codec) { + super(codec); + } + + @Override + public boolean place(FeaturePlaceContext context) { + Block bileBlock = getBlock(BILE_ID); + if (!(bileBlock instanceof LiquidBlock)) { + return false; + } + + WorldGenLevel level = context.level(); + RandomSource random = context.random(); + BlockPos floorCenter = findPoolFloor(level, context.origin(), random); + if (floorCenter == null) { + return false; + } + + return placePool(level, floorCenter, bileBlock.defaultBlockState(), random); + } + + private static BlockPos findPoolFloor(WorldGenLevel level, BlockPos origin, RandomSource random) { + BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos(); + for (int attempt = 0; attempt < SEARCH_ATTEMPTS; attempt++) { + int x = origin.getX() + random.nextInt(SEARCH_RADIUS * 2 + 1) - SEARCH_RADIUS; + int z = origin.getZ() + random.nextInt(SEARCH_RADIUS * 2 + 1) - SEARCH_RADIUS; + int startY = origin.getY() + random.nextInt(FLOOR_SCAN_RANGE * 2 + 1) - FLOOR_SCAN_RANGE; + startY = Math.max(level.getMinBuildHeight() + 3, Math.min(level.getMaxBuildHeight() - 4, startY)); + + for (int y = startY; y >= Math.max(level.getMinBuildHeight() + 2, startY - FLOOR_SCAN_RANGE); y--) { + mutable.set(x, y, z); + BlockState floorState = level.getBlockState(mutable); + if (!isValidFloor(level, mutable, floorState)) { + continue; + } + + BlockState aboveState = level.getBlockState(mutable.above()); + if (!isOpenBlock(aboveState)) { + continue; + } + + if (countSolidNeighbors(level, mutable) >= 3) { + return mutable.immutable(); + } + } + } + + return null; + } + + private static boolean placePool(WorldGenLevel level, BlockPos center, BlockState bileState, RandomSource random) { + boolean placedAny = false; + int radius = 2 + random.nextInt(3); + BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos(); + + for (int dx = -radius; dx <= radius; dx++) { + for (int dz = -radius; dz <= radius; dz++) { + double normalized = (dx * dx + dz * dz) / (double) Math.max(1, radius * radius); + if (normalized > 1.0D + random.nextDouble() * 0.2D) { + continue; + } + + double density = 1.0D - Math.min(1.0D, normalized); + int localDepth = density > 0.45D || random.nextFloat() < 0.35F ? 2 : 1; + localDepth = Mth.clamp(localDepth, 1, 2); + + for (int depth = 0; depth < localDepth; depth++) { + mutable.set(center.getX() + dx, center.getY() - depth, center.getZ() + dz); + BlockState existing = level.getBlockState(mutable); + FluidState existingFluid = existing.getFluidState(); + if (existing.is(Blocks.BEDROCK)) { + break; + } + if (!existing.canBeReplaced() && existingFluid.isEmpty() && !existing.blocksMotion()) { + continue; + } + + level.setBlock(mutable, bileState, 2); + scheduleFluidTick(level, mutable, bileState); + placedAny = true; + } + } + } + + return placedAny; + } + + private static boolean isValidFloor(WorldGenLevel level, BlockPos pos, BlockState state) { + return !state.isAir() + && !state.is(Blocks.BEDROCK) + && state.getFluidState().isEmpty() + && state.blocksMotion() + && state.isFaceSturdy(level, pos, Direction.UP); + } + + private static boolean isOpenBlock(BlockState state) { + return state.isAir() || state.canBeReplaced() || !state.getFluidState().isEmpty(); + } + + private static int countSolidNeighbors(WorldGenLevel level, BlockPos pos) { + int solidNeighbors = 0; + BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos(); + for (Direction direction : Direction.Plane.HORIZONTAL) { + mutable.setWithOffset(pos, direction); + if (isValidFloor(level, mutable, level.getBlockState(mutable))) { + solidNeighbors++; + } + } + return solidNeighbors; + } + + private static void scheduleFluidTick(WorldGenLevel level, BlockPos pos, BlockState state) { + FluidState fluidState = state.getFluidState(); + if (!fluidState.isEmpty()) { + level.scheduleTick(pos, fluidState.getType(), fluidState.getType().getTickDelay(level)); + } + } + + private static Block getBlock(ResourceLocation id) { + Optional block = BuiltInRegistries.BLOCK.getOptional(id); + return block.orElse(null); + } +} diff --git a/common/src/main/java/com/craisinlord/antarchy/content/worldgen/cavaryn/CavarynCreepvineFeature.java b/common/src/main/java/com/craisinlord/antarchy/content/worldgen/cavaryn/CavarynCreepvineFeature.java new file mode 100644 index 00000000..2086253d --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/content/worldgen/cavaryn/CavarynCreepvineFeature.java @@ -0,0 +1,118 @@ +package com.craisinlord.antarchy.content.worldgen.cavaryn; + +import com.craisinlord.antarchy.Antarchy; +import com.mojang.serialization.Codec; +import java.util.Optional; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.VineBlock; +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 CavarynCreepvineFeature extends Feature { + private static final ResourceLocation CREEPVINE_ID = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "creepvine"); + private static final int SEARCH_RADIUS = 8; + private static final int SEARCH_ATTEMPTS = 24; + private static final int VERTICAL_SCAN = 12; + + public CavarynCreepvineFeature(Codec codec) { + super(codec); + } + + @Override + public boolean place(FeaturePlaceContext context) { + Block creepvineBlock = getBlock(CREEPVINE_ID); + if (!(creepvineBlock instanceof VineBlock vineBlock)) { + return false; + } + + WorldGenLevel level = context.level(); + RandomSource random = context.random(); + Anchor anchor = findAnchor(level, context.origin(), random); + if (anchor == null) { + return false; + } + + return placeVineColumn(level, vineBlock, anchor, random); + } + + private static Anchor findAnchor(WorldGenLevel level, BlockPos origin, RandomSource random) { + BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos(); + for (int attempt = 0; attempt < SEARCH_ATTEMPTS; attempt++) { + int x = origin.getX() + random.nextInt(SEARCH_RADIUS * 2 + 1) - SEARCH_RADIUS; + int z = origin.getZ() + random.nextInt(SEARCH_RADIUS * 2 + 1) - SEARCH_RADIUS; + int startY = origin.getY() + random.nextInt(VERTICAL_SCAN * 2 + 1) - VERTICAL_SCAN; + startY = Math.max(level.getMinBuildHeight() + 3, Math.min(level.getMaxBuildHeight() - 3, startY)); + + for (int y = startY; y >= Math.max(level.getMinBuildHeight() + 1, startY - VERTICAL_SCAN); y--) { + mutable.set(x, y, z); + if (!level.getBlockState(mutable).canBeReplaced()) { + continue; + } + + for (Direction direction : Direction.Plane.HORIZONTAL) { + BlockPos supportPos = mutable.relative(direction); + BlockState supportState = level.getBlockState(supportPos); + if (supportState.isFaceSturdy(level, supportPos, direction.getOpposite())) { + return new Anchor(mutable.immutable(), direction); + } + } + } + } + + return null; + } + + private static boolean placeVineColumn(WorldGenLevel level, VineBlock vineBlock, Anchor anchor, RandomSource random) { + boolean placedAny = false; + int length = 3 + random.nextInt(6); + + for (int offset = 0; offset < length; offset++) { + BlockPos vinePos = anchor.pos().below(offset); + if (vinePos.getY() <= level.getMinBuildHeight()) { + break; + } + + BlockState existing = level.getBlockState(vinePos); + if (!existing.canBeReplaced() && !existing.is(vineBlock)) { + break; + } + + BlockState vineState = createVineState(vineBlock, anchor.supportDirection()); + if (vineState == null || !vineState.canSurvive(level, vinePos)) { + break; + } + + level.setBlock(vinePos, vineState, 3); + placedAny = true; + } + + return placedAny; + } + + private static BlockState createVineState(VineBlock vineBlock, Direction attachedFace) { + BlockState state = vineBlock.defaultBlockState(); + return switch (attachedFace) { + case NORTH -> state.setValue(VineBlock.NORTH, Boolean.TRUE); + case SOUTH -> state.setValue(VineBlock.SOUTH, Boolean.TRUE); + case EAST -> state.setValue(VineBlock.EAST, Boolean.TRUE); + case WEST -> state.setValue(VineBlock.WEST, Boolean.TRUE); + default -> null; + }; + } + + private static Block getBlock(ResourceLocation id) { + Optional block = BuiltInRegistries.BLOCK.getOptional(id); + return block.orElse(null); + } + + private record Anchor(BlockPos pos, Direction supportDirection) { + } +} diff --git a/common/src/main/java/com/craisinlord/antarchy/content/worldgen/cavaryn/CavarynEggPatchFeature.java b/common/src/main/java/com/craisinlord/antarchy/content/worldgen/cavaryn/CavarynEggPatchFeature.java new file mode 100644 index 00000000..f44424c3 --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/content/worldgen/cavaryn/CavarynEggPatchFeature.java @@ -0,0 +1,122 @@ +package com.craisinlord.antarchy.content.worldgen.cavaryn; + +import com.craisinlord.antarchy.content.AntarchyObjects; +import com.craisinlord.antarchy.content.block.CreepingHorrorEggBlock; +import com.craisinlord.antarchy.content.block.LurkingTerrorEggBlock; +import com.mojang.serialization.Codec; +import java.util.List; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +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 CavarynEggPatchFeature extends Feature { + private static final int SEARCH_RADIUS = 8; + private static final int SEARCH_ATTEMPTS = 20; + private static final int FLOOR_SCAN_RANGE = 10; + + public CavarynEggPatchFeature(Codec codec) { + super(codec); + } + + @Override + public boolean place(FeaturePlaceContext context) { + WorldGenLevel level = context.level(); + RandomSource random = context.random(); + BlockPos origin = context.origin(); + + BlockPos surfacePos = findSurfacePos(level, origin, random); + if (surfacePos == null) { + return false; + } + + EggType eggType = random.nextBoolean() ? EggType.CREEPING_HORROR : EggType.LURKING_TERROR; + return placePatch(level, surfacePos, random, eggType); + } + + private static BlockPos findSurfacePos(WorldGenLevel level, BlockPos origin, RandomSource random) { + BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos(); + for (int attempt = 0; attempt < SEARCH_ATTEMPTS; attempt++) { + int x = origin.getX() + random.nextInt(SEARCH_RADIUS * 2 + 1) - SEARCH_RADIUS; + int z = origin.getZ() + random.nextInt(SEARCH_RADIUS * 2 + 1) - SEARCH_RADIUS; + int startY = origin.getY() + random.nextInt(FLOOR_SCAN_RANGE * 2 + 1) - FLOOR_SCAN_RANGE; + startY = Math.max(level.getMinBuildHeight() + 2, Math.min(level.getMaxBuildHeight() - 3, startY)); + + for (int y = startY; y >= Math.max(level.getMinBuildHeight() + 1, startY - FLOOR_SCAN_RANGE); y--) { + mutable.set(x, y, z); + BlockState floorState = level.getBlockState(mutable); + BlockState airState = level.getBlockState(mutable.above()); + if (floorState.getFluidState().isEmpty() + && floorState.blocksMotion() + && floorState.isFaceSturdy(level, mutable, Direction.UP) + && airState.canBeReplaced()) { + return mutable.immutable(); + } + } + } + + return null; + } + + private boolean placePatch(WorldGenLevel level, BlockPos center, RandomSource random, EggType eggType) { + int radius = 2 + random.nextInt(3); + boolean placedAny = false; + List eggSpots = new java.util.ArrayList<>(); + + for (int dx = -radius; dx <= radius; dx++) { + for (int dz = -radius; dz <= radius; dz++) { + double distance = dx * dx + dz * dz; + if (distance > radius * radius + random.nextInt(2)) { + continue; + } + + BlockPos floorPos = center.offset(dx, 0, dz); + BlockState floorState = level.getBlockState(floorPos); + BlockPos eggPos = floorPos.above(); + BlockState aboveState = level.getBlockState(eggPos); + if (!isValidEggFloor(level, floorPos, floorState, aboveState)) { + continue; + } + eggSpots.add(eggPos); + } + } + + if (eggSpots.isEmpty()) { + return placedAny; + } + + int eggCount = Math.min(eggSpots.size(), 2 + random.nextInt(3)); + for (int i = 0; i < eggCount; i++) { + BlockPos eggPos = eggSpots.get(random.nextInt(eggSpots.size())); + if (!level.getBlockState(eggPos).canBeReplaced()) { + continue; + } + + BlockState eggState = eggType == EggType.CREEPING_HORROR + ? AntarchyObjects.CREEPING_HORROR_EGGS.get().defaultBlockState() + : AntarchyObjects.LURKING_TERROR_EGGS.get().defaultBlockState(); + eggState = eggState.setValue(eggType == EggType.CREEPING_HORROR ? CreepingHorrorEggBlock.EGGS : LurkingTerrorEggBlock.EGGS, 1 + random.nextInt(4)); + level.setBlock(eggPos, eggState, 3); + placedAny = true; + } + + return placedAny; + } + + private static boolean isValidEggFloor(WorldGenLevel level, BlockPos floorPos, BlockState floorState, BlockState aboveState) { + return !floorState.isAir() + && floorState.getFluidState().isEmpty() + && floorState.blocksMotion() + && floorState.isFaceSturdy(level, floorPos, Direction.UP) + && aboveState.canBeReplaced(); + } + + private enum EggType { + CREEPING_HORROR, + LURKING_TERROR + } +} diff --git a/common/src/main/java/com/craisinlord/antarchy/content/worldgen/cavaryn/CavarynWallAmberMossFeature.java b/common/src/main/java/com/craisinlord/antarchy/content/worldgen/cavaryn/CavarynWallAmberMossFeature.java new file mode 100644 index 00000000..1a31ea39 --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/content/worldgen/cavaryn/CavarynWallAmberMossFeature.java @@ -0,0 +1,165 @@ +package com.craisinlord.antarchy.content.worldgen.cavaryn; + +import com.craisinlord.antarchy.Antarchy; +import com.mojang.serialization.Codec; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.MultifaceBlock; +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 CavarynWallAmberMossFeature extends Feature { + private static final ResourceLocation AMBER_LICHEN_ID = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "amber_lichen"); + private static final ResourceLocation GLOW_LICHEN_ID = ResourceLocation.withDefaultNamespace("glow_lichen"); + private static final int SEARCH_RADIUS = 8; + private static final int SEARCH_ATTEMPTS = 28; + private static final int VERTICAL_SCAN = 10; + + public CavarynWallAmberMossFeature(Codec codec) { + super(codec); + } + + @Override + public boolean place(FeaturePlaceContext context) { + WorldGenLevel level = context.level(); + RandomSource random = context.random(); + Block amberLichenBlock = getBlock(AMBER_LICHEN_ID); + Block glowLichenBlock = getBlock(GLOW_LICHEN_ID); + if (amberLichenBlock == null || glowLichenBlock == null) { + return false; + } + + Anchor anchor = findAnchor(level, context.origin(), random); + if (anchor == null) { + return false; + } + + List placedPatch = placeWallPatch(level, anchor, amberLichenBlock, random); + if (placedPatch.isEmpty()) { + return false; + } + + placeLichenFringe(level, placedPatch, anchor.supportDirection(), amberLichenBlock, glowLichenBlock, random); + return true; + } + + private static Anchor findAnchor(WorldGenLevel level, BlockPos origin, RandomSource random) { + BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos(); + for (int attempt = 0; attempt < SEARCH_ATTEMPTS; attempt++) { + int x = origin.getX() + random.nextInt(SEARCH_RADIUS * 2 + 1) - SEARCH_RADIUS; + int z = origin.getZ() + random.nextInt(SEARCH_RADIUS * 2 + 1) - SEARCH_RADIUS; + int startY = origin.getY() + random.nextInt(VERTICAL_SCAN * 2 + 1) - VERTICAL_SCAN; + startY = Math.max(level.getMinBuildHeight() + 2, Math.min(level.getMaxBuildHeight() - 3, startY)); + + for (int y = startY; y >= Math.max(level.getMinBuildHeight() + 1, startY - VERTICAL_SCAN); y--) { + mutable.set(x, y, z); + if (!level.getBlockState(mutable).canBeReplaced()) { + continue; + } + + for (Direction direction : Direction.Plane.HORIZONTAL) { + BlockPos supportPos = mutable.relative(direction); + BlockState supportState = level.getBlockState(supportPos); + if (supportState.isFaceSturdy(level, supportPos, direction.getOpposite())) { + return new Anchor(mutable.immutable(), direction); + } + } + } + } + + return null; + } + + private static List placeWallPatch(WorldGenLevel level, Anchor anchor, Block amberLichenBlock, RandomSource random) { + List placed = new ArrayList<>(); + Direction lateral = anchor.supportDirection().getClockWise(); + int width = 1 + random.nextInt(3); + int height = 2 + random.nextInt(4); + + for (int yOffset = 0; yOffset < height; yOffset++) { + for (int lateralOffset = -width; lateralOffset <= width; lateralOffset++) { + if (Math.abs(lateralOffset) == width && random.nextBoolean()) { + continue; + } + + BlockPos pos = anchor.pos().above(yOffset).relative(lateral, lateralOffset); + if (!canPlaceWallMoss(level, pos, anchor.supportDirection())) { + continue; + } + + BlockState state = createLichenState(amberLichenBlock, anchor.supportDirection()); + if (!state.canSurvive(level, pos)) { + continue; + } + + level.setBlock(pos, state, 3); + placed.add(pos.immutable()); + } + } + + return placed; + } + + private static void placeLichenFringe( + WorldGenLevel level, + List patchPositions, + Direction supportDirection, + Block amberLichenBlock, + Block glowLichenBlock, + RandomSource random + ) { + for (BlockPos patchPos : patchPositions) { + for (Direction spread : List.of(Direction.UP, Direction.DOWN, supportDirection.getClockWise(), supportDirection.getCounterClockWise())) { + if (random.nextFloat() > 0.45F) { + continue; + } + + BlockPos targetPos = patchPos.relative(spread); + if (!level.getBlockState(targetPos).canBeReplaced()) { + continue; + } + if (!hasSupport(level, targetPos, supportDirection)) { + continue; + } + + BlockState state = createLichenState(random.nextFloat() < 0.65F ? amberLichenBlock : glowLichenBlock, supportDirection); + if (!state.canSurvive(level, targetPos)) { + continue; + } + + level.setBlock(targetPos, state, 3); + } + } + } + + private static boolean canPlaceWallMoss(WorldGenLevel level, BlockPos pos, Direction supportDirection) { + return level.getBlockState(pos).canBeReplaced() && hasSupport(level, pos, supportDirection); + } + + private static boolean hasSupport(WorldGenLevel level, BlockPos pos, Direction supportDirection) { + BlockPos supportPos = pos.relative(supportDirection); + return level.getBlockState(supportPos).isFaceSturdy(level, supportPos, supportDirection.getOpposite()); + } + + private static BlockState createLichenState(Block lichenBlock, Direction supportDirection) { + return lichenBlock.defaultBlockState().setValue(MultifaceBlock.getFaceProperty(supportDirection), true); + } + + private static Block getBlock(ResourceLocation id) { + Optional block = BuiltInRegistries.BLOCK.getOptional(id); + return block.orElse(null); + } + + private record Anchor(BlockPos pos, Direction supportDirection) { + } +} diff --git a/common/src/main/java/com/craisinlord/antarchy/content/worldgen/cavaryn/ChitenSpikeConfiguration.java b/common/src/main/java/com/craisinlord/antarchy/content/worldgen/cavaryn/ChitenSpikeConfiguration.java new file mode 100644 index 00000000..2160f745 --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/content/worldgen/cavaryn/ChitenSpikeConfiguration.java @@ -0,0 +1,37 @@ +package com.craisinlord.antarchy.content.worldgen.cavaryn; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; + +public record ChitenSpikeConfiguration( + int floorToCeilingSearchRange, + int radius, + int maxColumnHeight, + int heightDeviation, + float chanceOfColumnAtMaxDistanceFromCenter, + int maxDistanceFromCenterAffectingChanceOfColumn, + int maxDistanceFromCenterAffectingHeightBias, + int maxHeightDifference, + float largeVariantChance, + int largeVariantExtraRadius, + int largeVariantExtraHeight, + int largeVariantExtraHeightDeviation, + float largeVariantSurfaceSpikeMultiplier +) implements FeatureConfiguration { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + Codec.intRange(1, 128).fieldOf("floor_to_ceiling_search_range").forGetter(ChitenSpikeConfiguration::floorToCeilingSearchRange), + Codec.intRange(1, 32).fieldOf("radius").forGetter(ChitenSpikeConfiguration::radius), + Codec.intRange(1, 32).fieldOf("max_column_height").forGetter(ChitenSpikeConfiguration::maxColumnHeight), + Codec.intRange(1, 16).fieldOf("height_deviation").forGetter(ChitenSpikeConfiguration::heightDeviation), + Codec.floatRange(0.0F, 1.0F).fieldOf("chance_of_column_at_max_distance_from_center").forGetter(ChitenSpikeConfiguration::chanceOfColumnAtMaxDistanceFromCenter), + Codec.intRange(1, 64).fieldOf("max_distance_from_center_affecting_chance_of_column").forGetter(ChitenSpikeConfiguration::maxDistanceFromCenterAffectingChanceOfColumn), + Codec.intRange(1, 64).fieldOf("max_distance_from_center_affecting_height_bias").forGetter(ChitenSpikeConfiguration::maxDistanceFromCenterAffectingHeightBias), + Codec.intRange(0, 32).fieldOf("max_height_difference").forGetter(ChitenSpikeConfiguration::maxHeightDifference), + Codec.floatRange(0.0F, 1.0F).optionalFieldOf("large_variant_chance", 0.0F).forGetter(ChitenSpikeConfiguration::largeVariantChance), + Codec.intRange(0, 24).optionalFieldOf("large_variant_extra_radius", 0).forGetter(ChitenSpikeConfiguration::largeVariantExtraRadius), + Codec.intRange(0, 32).optionalFieldOf("large_variant_extra_height", 0).forGetter(ChitenSpikeConfiguration::largeVariantExtraHeight), + Codec.intRange(0, 16).optionalFieldOf("large_variant_extra_height_deviation", 0).forGetter(ChitenSpikeConfiguration::largeVariantExtraHeightDeviation), + Codec.floatRange(1.0F, 8.0F).optionalFieldOf("large_variant_surface_spike_multiplier", 1.0F).forGetter(ChitenSpikeConfiguration::largeVariantSurfaceSpikeMultiplier) + ).apply(instance, ChitenSpikeConfiguration::new)); +} diff --git a/common/src/main/java/com/craisinlord/antarchy/content/worldgen/cavaryn/ChitenSpikeFeature.java b/common/src/main/java/com/craisinlord/antarchy/content/worldgen/cavaryn/ChitenSpikeFeature.java new file mode 100644 index 00000000..cd73c28b --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/content/worldgen/cavaryn/ChitenSpikeFeature.java @@ -0,0 +1,253 @@ +package com.craisinlord.antarchy.content.worldgen.cavaryn; + +import com.craisinlord.antarchy.content.AntarchyObjects; +import com.mojang.serialization.Codec; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.OptionalInt; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.PointedDripstoneBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.DripstoneThickness; +import net.minecraft.world.level.levelgen.Column; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; + +public final class ChitenSpikeFeature extends Feature { + private record ResolvedVariant(int radius, int maxColumnHeight, int heightDeviation, int surfaceSpikeAttempts) { + } + + public ChitenSpikeFeature(Codec codec) { + super(codec); + } + + @Override + public boolean place(FeaturePlaceContext context) { + WorldGenLevel level = context.level(); + BlockPos origin = context.origin(); + ChitenSpikeConfiguration config = context.config(); + RandomSource random = context.random(); + + if (!level.getBlockState(origin).isAir()) { + return false; + } + + boolean placedAny = false; + List placedBlocks = new ArrayList<>(); + ResolvedVariant variant = this.resolveVariant(config, random); + int radius = variant.radius(); + for (int dx = -radius; dx <= radius; dx++) { + for (int dz = -radius; dz <= radius; dz++) { + double chance = this.getChanceOfColumn(radius, dx, dz, config); + if (chance <= 0.0D) { + continue; + } + if (this.placeColumn(level, random, origin.offset(dx, 0, dz), dx, dz, chance, config, variant, placedBlocks)) { + placedAny = true; + } + } + } + + if (this.dotSurfaceSpikes(level, random, placedBlocks, config, variant)) { + placedAny = true; + } + return placedAny; + } + + private ResolvedVariant resolveVariant(ChitenSpikeConfiguration config, RandomSource random) { + if (config.largeVariantChance() > 0.0F && random.nextFloat() < config.largeVariantChance()) { + int radius = config.radius() + config.largeVariantExtraRadius(); + int maxColumnHeight = config.maxColumnHeight() + config.largeVariantExtraHeight(); + int heightDeviation = config.heightDeviation() + config.largeVariantExtraHeightDeviation(); + int baseAttempts = Math.max(8, ((radius * 2) + 1) * ((radius * 2) + 1) / 6); + int surfaceSpikeAttempts = Math.max(baseAttempts + 4, Math.round(baseAttempts * config.largeVariantSurfaceSpikeMultiplier())); + return new ResolvedVariant(radius, maxColumnHeight, heightDeviation, surfaceSpikeAttempts); + } + + int radius = config.radius(); + int baseAttempts = Math.max(8, ((radius * 2) + 1) * ((radius * 2) + 1) / 6); + return new ResolvedVariant(radius, config.maxColumnHeight(), config.heightDeviation(), baseAttempts); + } + + private boolean placeColumn( + WorldGenLevel level, + RandomSource random, + BlockPos pos, + int dx, + int dz, + double chance, + ChitenSpikeConfiguration config, + ResolvedVariant variant, + List placedBlocks + ) { + Optional optional = Column.scan(level, pos, config.floorToCeilingSearchRange(), state -> state.isAir(), state -> !state.isAir()); + if (optional.isEmpty()) { + return false; + } + + Column column = optional.get(); + OptionalInt ceiling = column.getCeiling(); + OptionalInt floor = column.getFloor(); + int maxHeight = this.getMaxLength(variant, ceiling, floor); + int downLength = 0; + int upLength = 0; + + if (ceiling.isPresent()) { + downLength = this.getSpikeHeight(random, dx, dz, chance, maxHeight, config.maxDistanceFromCenterAffectingHeightBias(), variant.heightDeviation()); + } + if (floor.isPresent()) { + if (downLength > 0) { + upLength = Mth.clamp( + downLength + Mth.randomBetweenInclusive(random, -config.maxHeightDifference(), config.maxHeightDifference()), + 0, + maxHeight + ); + } else { + upLength = this.getSpikeHeight(random, dx, dz, chance, maxHeight, config.maxDistanceFromCenterAffectingHeightBias(), variant.heightDeviation()); + } + } + + boolean placedAny = false; + if (ceiling.isPresent() && downLength > 0) { + placedAny |= this.growChitenColumn(level, pos.atY(ceiling.getAsInt() - 1), Direction.DOWN, downLength, placedBlocks); + } + if (floor.isPresent() && upLength > 0) { + placedAny |= this.growChitenColumn(level, pos.atY(floor.getAsInt() + 1), Direction.UP, upLength, placedBlocks); + } + return placedAny; + } + + private int getMaxLength(ResolvedVariant variant, OptionalInt ceiling, OptionalInt floor) { + if (ceiling.isPresent() && floor.isPresent()) { + return Math.min(variant.maxColumnHeight(), ceiling.getAsInt() - floor.getAsInt() - 1); + } + return variant.maxColumnHeight(); + } + + private boolean growChitenColumn(WorldGenLevel level, BlockPos rootStart, Direction direction, int length, List placedBlocks) { + boolean placedAny = false; + for (int offset = 0; offset < length; offset++) { + BlockPos spikePos = rootStart.relative(direction, offset); + if (spikePos.getY() < level.getMinBuildHeight() || spikePos.getY() >= level.getMaxBuildHeight()) { + break; + } + + BlockState current = level.getBlockState(spikePos); + if (!current.isAir()) { + break; + } + + BlockState chitenState = AntarchyObjects.CHITEN_BLOCK.get().defaultBlockState(); + level.setBlock(spikePos, chitenState, 3); + placedBlocks.add(spikePos.immutable()); + placedAny = true; + } + return placedAny; + } + + private boolean dotSurfaceSpikes( + WorldGenLevel level, + RandomSource random, + List placedBlocks, + ChitenSpikeConfiguration config, + ResolvedVariant variant + ) { + boolean placedAny = false; + if (placedBlocks.isEmpty()) { + return false; + } + + int attempts = Math.max(variant.surfaceSpikeAttempts(), placedBlocks.size() / 6); + for (int i = 0; i < attempts; i++) { + BlockPos anchor = placedBlocks.get(random.nextInt(placedBlocks.size())); + Direction direction = random.nextBoolean() ? Direction.UP : Direction.DOWN; + int length = 1 + random.nextInt(Math.max(1, config.maxHeightDifference() + 1)); + BlockPos start = anchor.relative(direction); + if (this.growSurfaceSpike(level, start, direction, length)) { + placedAny = true; + } + } + return placedAny; + } + + private boolean growSurfaceSpike(WorldGenLevel level, BlockPos startPos, Direction direction, int length) { + boolean placedAny = false; + for (int offset = 0; offset < length; offset++) { + BlockPos spikePos = startPos.relative(direction, offset); + if (spikePos.getY() < level.getMinBuildHeight() || spikePos.getY() >= level.getMaxBuildHeight()) { + break; + } + if (!level.getBlockState(spikePos).isAir()) { + break; + } + + BlockState spikeState = AntarchyObjects.CHITEN_SPIKE.get().defaultBlockState() + .setValue(PointedDripstoneBlock.TIP_DIRECTION, direction) + .setValue(PointedDripstoneBlock.THICKNESS, getThicknessForRootOffset(offset, length)) + .setValue(PointedDripstoneBlock.WATERLOGGED, false); + if (!spikeState.canSurvive(level, spikePos)) { + break; + } + + level.setBlock(spikePos, spikeState, 3); + placedAny = true; + } + return placedAny; + } + + private static DripstoneThickness getThicknessForRootOffset(int offsetFromRoot, int length) { + if (length <= 1 || offsetFromRoot == length - 1) { + return DripstoneThickness.TIP; + } + if (offsetFromRoot == length - 2) { + return DripstoneThickness.FRUSTUM; + } + if (offsetFromRoot == 0) { + return DripstoneThickness.BASE; + } + return DripstoneThickness.MIDDLE; + } + + private int getSpikeHeight( + RandomSource random, + int dx, + int dz, + double chance, + int maxHeight, + int maxDistanceFromCenterAffectingHeightBias, + int heightDeviation + ) { + if (maxHeight <= 0 || random.nextDouble() > chance) { + return 0; + } + + int distance = Math.abs(dx) + Math.abs(dz); + float mean = (float) Mth.clampedMap( + (double) distance, + 0.0D, + (double) maxDistanceFromCenterAffectingHeightBias, + (double) maxHeight, + 1.0D + ); + int sampled = Math.round((float) (mean + random.nextGaussian() * Math.max(1, Math.min(maxHeight, heightDeviation)))); + return Mth.clamp(sampled, 1, maxHeight); + } + + private double getChanceOfColumn(int radius, int dx, int dz, ChitenSpikeConfiguration config) { + int remainingX = radius - Math.abs(dx); + int remainingZ = radius - Math.abs(dz); + int edgeDistance = Math.min(remainingX, remainingZ); + return Mth.clampedMap( + (double) edgeDistance, + 0.0D, + (double) config.maxDistanceFromCenterAffectingChanceOfColumn(), + (double) config.chanceOfColumnAtMaxDistanceFromCenter(), + 1.0D + ); + } +} diff --git a/common/src/main/java/com/craisinlord/antarchy/content/worldgen/elythia/CoralSpikeFeature.java b/common/src/main/java/com/craisinlord/antarchy/content/worldgen/elythia/CoralSpikeFeature.java new file mode 100644 index 00000000..9fdcf38f --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/content/worldgen/elythia/CoralSpikeFeature.java @@ -0,0 +1,178 @@ +package com.craisinlord.antarchy.content.worldgen.elythia; + +import com.mojang.serialization.Codec; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.SeaPickleBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.levelgen.Heightmap; +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 class CoralSpikeFeature extends Feature { + + private record CoralSet( + net.minecraft.world.level.block.Block block, + net.minecraft.world.level.block.Block coral, + net.minecraft.world.level.block.Block wallFan, + net.minecraft.world.level.block.Block floorFan + ) {} + + private static final CoralSet[] CORAL_SETS = { + new CoralSet(Blocks.TUBE_CORAL_BLOCK, Blocks.TUBE_CORAL, Blocks.TUBE_CORAL_WALL_FAN, Blocks.TUBE_CORAL_FAN), + new CoralSet(Blocks.BRAIN_CORAL_BLOCK, Blocks.BRAIN_CORAL, Blocks.BRAIN_CORAL_WALL_FAN, Blocks.BRAIN_CORAL_FAN), + new CoralSet(Blocks.BUBBLE_CORAL_BLOCK, Blocks.BUBBLE_CORAL, Blocks.BUBBLE_CORAL_WALL_FAN, Blocks.BUBBLE_CORAL_FAN), + new CoralSet(Blocks.FIRE_CORAL_BLOCK, Blocks.FIRE_CORAL, Blocks.FIRE_CORAL_WALL_FAN, Blocks.FIRE_CORAL_FAN), + new CoralSet(Blocks.HORN_CORAL_BLOCK, Blocks.HORN_CORAL, Blocks.HORN_CORAL_WALL_FAN, Blocks.HORN_CORAL_FAN), + }; + + public CoralSpikeFeature(Codec codec) { + super(codec); + } + + @Override + public boolean place(FeaturePlaceContext context) { + WorldGenLevel level = context.level(); + RandomSource random = context.random(); + BlockPos origin = context.origin(); + int seaLevel = level.getSeaLevel(); + + int spikes = 1 + random.nextInt(3); + boolean placed = false; + for (int i = 0; i < spikes; i++) { + int offX = random.nextInt(11) - 5; + int offZ = random.nextInt(11) - 5; + placed |= placeSpike(level, random, origin.offset(offX, 0, offZ), seaLevel); + } + return placed; + } + + private boolean placeSpike(WorldGenLevel level, RandomSource random, BlockPos origin, int seaLevel) { + int floorY = level.getHeight(Heightmap.Types.OCEAN_FLOOR_WG, origin.getX(), origin.getZ()); + if (floorY >= seaLevel) return false; + + CoralSet coral = CORAL_SETS[random.nextInt(CORAL_SETS.length)]; + + int baseRadius = 2 + random.nextInt(2); // 2–3 wide at base + int totalHeight = 20 + random.nextInt(15); // 20–34 blocks tall + + // Curve: lean toward a random horizontal direction, accelerating toward the tip + double curveAngle = random.nextDouble() * Math.PI * 2; + double curveDX = Math.cos(curveAngle); + double curveDZ = Math.sin(curveAngle); + double maxCurve = 4.0 + random.nextDouble() * 5.0; // 4–9 block lean at tip + + boolean placed = false; + + for (int dy = 0; dy < totalHeight; dy++) { + int blockY = floorY + dy; + double progress = (double) dy / totalHeight; + + // Quadratic lean — slow at base, bending hard near tip + double curveOffset = maxCurve * progress * progress; + double centerX = origin.getX() + curveDX * curveOffset; + double centerZ = origin.getZ() + curveDZ * curveOffset; + + // Taper: full width for bottom 25%, then narrows sharply to a point + double taperT = Math.max(0.0, (progress - 0.25) / 0.75); + int radius = (int) Math.max(0, baseRadius * (1.0 - taperT * taperT * 1.3)); + + for (int dx = -(radius + 1); dx <= radius + 1; dx++) { + for (int dz = -(radius + 1); dz <= radius + 1; dz++) { + double dist = Math.sqrt( + (origin.getX() + dx - centerX) * (origin.getX() + dx - centerX) + + (origin.getZ() + dz - centerZ) * (origin.getZ() + dz - centerZ)); + + if (dist > radius + 0.5) continue; + + BlockPos pos = new BlockPos(origin.getX() + dx, blockY, origin.getZ() + dz); + if (!canReplace(level.getBlockState(pos))) continue; + + level.setBlock(pos, coral.block().defaultBlockState(), 2); + placed = true; + + // Coral plants growing off the top of outer-surface blocks + if (dist >= radius - 0.6 && radius > 0) { + BlockPos above = pos.above(); + if (canReplace(level.getBlockState(above))) { + boolean aboveInWater = level.getBlockState(above).is(Blocks.WATER); + if (random.nextFloat() < 0.35f && aboveInWater) { + level.setBlock(above, + coral.coral().defaultBlockState() + .setValue(BlockStateProperties.WATERLOGGED, true), + 2); + } + } + } + + // Wall fans on the outer surface + if (dist >= radius - 0.5) { + for (Direction dir : Direction.Plane.HORIZONTAL) { + if (random.nextFloat() >= 0.4f) continue; + BlockPos fanPos = pos.relative(dir); + BlockState existing = level.getBlockState(fanPos); + if (!existing.isAir() && !existing.is(Blocks.WATER)) continue; + boolean fanInWater = existing.is(Blocks.WATER); + level.setBlock(fanPos, + coral.wallFan().defaultBlockState() + .setValue(BlockStateProperties.HORIZONTAL_FACING, dir) + .setValue(BlockStateProperties.WATERLOGGED, fanInWater), + 2); + } + } + } + } + } + + // Floor scatter: coral plants, fans, and sea pickles around the base + int decorCount = 10 + random.nextInt(12); + for (int i = 0; i < decorCount; i++) { + int fx = origin.getX() + random.nextInt(13) - 6; + int fz = origin.getZ() + random.nextInt(13) - 6; + int fy = level.getHeight(Heightmap.Types.OCEAN_FLOOR_WG, fx, fz); + BlockPos decorPos = new BlockPos(fx, fy, fz); + + if (!canReplace(level.getBlockState(decorPos))) continue; + BlockState below = level.getBlockState(decorPos.below()); + if (below.isAir() || !below.isFaceSturdy(level, decorPos.below(), Direction.UP)) continue; + + boolean decorInWater = level.getBlockState(decorPos).is(Blocks.WATER); + float roll = random.nextFloat(); + CoralSet randomCoral = CORAL_SETS[random.nextInt(CORAL_SETS.length)]; + + if (roll < 0.35f && decorInWater) { + // Coral plant (frond) + BlockState coralState = randomCoral.coral().defaultBlockState() + .setValue(BlockStateProperties.WATERLOGGED, true); + if (coralState.canSurvive(level, decorPos)) { + level.setBlock(decorPos, coralState, 2); + } + } else if (roll < 0.65f) { + // Floor fan + BlockState fanState = randomCoral.floorFan().defaultBlockState() + .setValue(BlockStateProperties.WATERLOGGED, decorInWater); + if (fanState.canSurvive(level, decorPos)) { + level.setBlock(decorPos, fanState, 2); + } + } else { + // Sea pickle cluster + BlockState pickle = Blocks.SEA_PICKLE.defaultBlockState() + .setValue(SeaPickleBlock.PICKLES, 1 + random.nextInt(4)); + if (pickle.canSurvive(level, decorPos)) { + level.setBlock(decorPos, pickle, 2); + } + } + } + + return placed; + } + + private static boolean canReplace(BlockState state) { + return state.isAir() || state.is(Blocks.WATER) || state.canBeReplaced(); + } +} diff --git a/common/src/main/java/com/craisinlord/antarchy/content/worldgen/elythia/ElythiaBiomeSource.java b/common/src/main/java/com/craisinlord/antarchy/content/worldgen/elythia/ElythiaBiomeSource.java index d9155e5a..8940673d 100644 --- a/common/src/main/java/com/craisinlord/antarchy/content/worldgen/elythia/ElythiaBiomeSource.java +++ b/common/src/main/java/com/craisinlord/antarchy/content/worldgen/elythia/ElythiaBiomeSource.java @@ -1,6 +1,7 @@ package com.craisinlord.antarchy.content.worldgen.elythia; import com.craisinlord.antarchy.Antarchy; +import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; @@ -20,10 +21,18 @@ public class ElythiaBiomeSource extends BiomeSource { Registries.BIOME, ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "moleworm_caves") ); + private static final ResourceKey ELYTHIA_LUSH_CAVES = ResourceKey.create( + Registries.BIOME, + ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "elythia_lush_caves") + ); private static final ResourceKey ELYTHIA_OCEAN = ResourceKey.create( Registries.BIOME, ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "elythia_ocean") ); + private static final ResourceKey ELYTHIA_CORAL_SPIKES = ResourceKey.create( + Registries.BIOME, + ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "elythia_coral_spikes") + ); private static final ResourceKey ELYTHIA_BEACH = ResourceKey.create( Registries.BIOME, ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "elythia_beach") @@ -34,7 +43,8 @@ public class ElythiaBiomeSource extends BiomeSource { MultiNoiseBiomeSource.DIRECT_CODEC.forGetter(ElythiaBiomeSource::parameters), 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("ocean_max_y", 85).forGetter(ElythiaBiomeSource::oceanMaxY), + Codec.INT.optionalFieldOf("sea_level", 78).forGetter(ElythiaBiomeSource::seaLevel) ).apply(instance, ElythiaBiomeSource::new)); private final Climate.ParameterList> parameters; @@ -42,36 +52,41 @@ public class ElythiaBiomeSource extends BiomeSource { private final int molewormCavesMaxY; private final int surfaceBiomeSampleY; private final int oceanMaxY; + private final int seaLevel; private final int molewormCavesMaxQuartY; private final int surfaceBiomeSampleQuartY; - private final int oceanMaxQuartY; + private final int seaLevelQuartY; + private final Holder oceanHolder; + private final Holder defaultLandHolder; - public ElythiaBiomeSource(Climate.ParameterList> parameters, int molewormCavesMaxY, int surfaceBiomeSampleY, int oceanMaxY) { + public ElythiaBiomeSource(Climate.ParameterList> parameters, int molewormCavesMaxY, int surfaceBiomeSampleY, int oceanMaxY, int seaLevel) { this.parameters = parameters; this.delegate = MultiNoiseBiomeSource.createFromList(parameters); this.molewormCavesMaxY = molewormCavesMaxY; this.surfaceBiomeSampleY = surfaceBiomeSampleY; this.oceanMaxY = oceanMaxY; + this.seaLevel = seaLevel; this.molewormCavesMaxQuartY = QuartPos.fromBlock(molewormCavesMaxY); this.surfaceBiomeSampleQuartY = QuartPos.fromBlock(surfaceBiomeSampleY); - this.oceanMaxQuartY = QuartPos.fromBlock(oceanMaxY); + this.seaLevelQuartY = QuartPos.fromBlock(seaLevel); + this.oceanHolder = parameters.values().stream() + .map(Pair::getSecond) + .filter(h -> h.is(ELYTHIA_OCEAN)) + .findFirst() + .orElse(null); + this.defaultLandHolder = parameters.values().stream() + .map(Pair::getSecond) + .filter(h -> !isOceanBiome(h) && !h.is(ELYTHIA_BEACH) + && !h.is(MOLEWORM_CAVES) && !h.is(ELYTHIA_LUSH_CAVES)) + .findFirst() + .orElse(null); } - private Climate.ParameterList> parameters() { - return this.parameters; - } - - private int molewormCavesMaxY() { - return this.molewormCavesMaxY; - } - - private int surfaceBiomeSampleY() { - return this.surfaceBiomeSampleY; - } - - private int oceanMaxY() { - return this.oceanMaxY; - } + private Climate.ParameterList> parameters() { return this.parameters; } + private int molewormCavesMaxY() { return this.molewormCavesMaxY; } + private int surfaceBiomeSampleY() { return this.surfaceBiomeSampleY; } + private int oceanMaxY() { return this.oceanMaxY; } + private int seaLevel() { return this.seaLevel; } @Override protected MapCodec codec() { @@ -83,24 +98,53 @@ public class ElythiaBiomeSource extends BiomeSource { return this.delegate.possibleBiomes().stream(); } + // Conservative threshold well inside the ocean entry range (-0.85 to -0.92). + // At continentalness < -0.80 the terrain is reliably below sea level. + // Transition-zone columns (-0.80 to -0.85) are treated as land to avoid + // ocean biome appearing over above-sea-level terrain. + private static final long OCEAN_CONTINENTALNESS_THRESHOLD = Climate.quantizeCoord(-0.80f); + @Override public Holder getNoiseBiome(int x, int y, int z, Climate.Sampler sampler) { Holder biome = this.delegate.getNoiseBiome(x, y, z, sampler); - // Cap moleworm caves below their max Y + // Cap moleworm caves below their max Y — replace with surface biome above it if (biome.is(MOLEWORM_CAVES) && y > this.molewormCavesMaxQuartY) { return resolveSurfaceFallback(x, y, z, sampler, MOLEWORM_CAVES); } - // Cap ocean/beach biomes above sea level — if terrain noise puts these biomes - // too high, replace with whatever surface biome would naturally be there - if ((biome.is(ELYTHIA_OCEAN) || biome.is(ELYTHIA_BEACH)) && y > this.oceanMaxQuartY) { - return resolveSurfaceFallback(x, y, z, sampler, ELYTHIA_OCEAN, ELYTHIA_BEACH); + // Use continentalness (XZ-only noise) to classify the column. + // Ocean columns get the ocean biome at every Y so structures, particles, + // and ambient effects work correctly above the water surface. + Climate.TargetPoint target = sampler.sample(x, this.seaLevelQuartY, z); + if (target.continentalness() < OCEAN_CONTINENTALNESS_THRESHOLD) { + return this.delegate.getNoiseBiome(x, this.seaLevelQuartY, z, sampler); + } + + // Land column below or at sea level: force ocean for any biome not allowed there. + // Use <= so quart 19 (blocks 76-79, partly underwater) is covered. + if (y <= this.seaLevelQuartY && oceanHolder != null && !allowedBelowSeaLevel(biome)) { + return oceanHolder; + } + + // Land column: prevent ocean biomes from bleeding in at any Y + if (isOceanBiome(biome)) { + return resolveLandFallback(x, z, sampler); } return biome; } + private static boolean allowedBelowSeaLevel(Holder biome) { + return biome.is(MOLEWORM_CAVES) || biome.is(ELYTHIA_LUSH_CAVES) + || biome.is(ELYTHIA_OCEAN) || biome.is(ELYTHIA_CORAL_SPIKES); + } + + private static boolean isOceanBiome(Holder biome) { + return biome.is(ELYTHIA_OCEAN) || biome.is(ELYTHIA_CORAL_SPIKES); + } + + // Used for moleworm caves — returns best Y-sample, falls back to whatever the delegate gives @SafeVarargs private Holder resolveSurfaceFallback(int x, int y, int z, Climate.Sampler sampler, ResourceKey... excluded) { Holder fallback = this.delegate.getNoiseBiome(x, this.surfaceBiomeSampleQuartY, z, sampler); @@ -118,6 +162,19 @@ public class ElythiaBiomeSource extends BiomeSource { return fallback; } + // Used when ocean bleeds into a land column — guaranteed to never return an ocean/cave biome + private Holder resolveLandFallback(int x, int z, Climate.Sampler sampler) { + Holder fallback = this.delegate.getNoiseBiome(x, this.surfaceBiomeSampleQuartY, z, sampler); + if (!isOceanOrCave(fallback)) return fallback; + + for (int sampleBlockY : SURFACE_FALLBACK_BLOCK_YS) { + Holder candidate = this.delegate.getNoiseBiome(x, QuartPos.fromBlock(sampleBlockY), z, sampler); + if (!isOceanOrCave(candidate)) return candidate; + } + + return defaultLandHolder != null ? defaultLandHolder : fallback; + } + @SafeVarargs private static boolean isExcluded(Holder biome, ResourceKey... excluded) { for (ResourceKey key : excluded) { @@ -126,10 +183,15 @@ public class ElythiaBiomeSource extends BiomeSource { return false; } + private static boolean isOceanOrCave(Holder biome) { + return isOceanBiome(biome) || biome.is(ELYTHIA_BEACH) + || biome.is(MOLEWORM_CAVES) || biome.is(ELYTHIA_LUSH_CAVES); + } + @Override public void addDebugInfo(java.util.List debug, net.minecraft.core.BlockPos pos, Climate.Sampler sampler) { this.delegate.addDebugInfo(debug, pos, sampler); debug.add("Elythia mole cave cap: y<=" + this.molewormCavesMaxY); - debug.add("Elythia ocean cap: y<=" + this.oceanMaxY); + debug.add("Elythia sea level: " + this.seaLevel); } } diff --git a/common/src/main/java/com/craisinlord/antarchy/mixins/BlockEntitySignMixin.java b/common/src/main/java/com/craisinlord/antarchy/mixins/BlockEntitySignMixin.java new file mode 100644 index 00000000..141359d5 --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/mixins/BlockEntitySignMixin.java @@ -0,0 +1,37 @@ +package com.craisinlord.antarchy.mixins; + +import com.craisinlord.antarchy.Antarchy; +import java.util.Optional; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.state.BlockState; +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.CallbackInfo; + +@Mixin(net.minecraft.world.level.block.entity.BlockEntity.class) +public abstract class BlockEntitySignMixin { + private static final ResourceLocation OURANWOOD_SIGN_ID = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "ouranwood_sign"); + private static final ResourceLocation OURANWOOD_WALL_SIGN_ID = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "ouranwood_wall_sign"); + private static final ResourceLocation OURANWOOD_HANGING_SIGN_ID = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "ouranwood_hanging_sign"); + private static final ResourceLocation OURANWOOD_WALL_HANGING_SIGN_ID = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "ouranwood_wall_hanging_sign"); + + @Inject(method = "validateBlockState", at = @At("HEAD"), cancellable = true) + private static void antarchy$skipOuranwoodSignValidation(BlockState state, CallbackInfo ci) { + if (isOuranwoodSign(state)) { + ci.cancel(); + } + } + + private static boolean isOuranwoodSign(BlockState state) { + return matches(state, OURANWOOD_SIGN_ID) + || matches(state, OURANWOOD_WALL_SIGN_ID) + || matches(state, OURANWOOD_HANGING_SIGN_ID) + || matches(state, OURANWOOD_WALL_HANGING_SIGN_ID); + } + + private static boolean matches(BlockState state, ResourceLocation id) { + return BuiltInRegistries.BLOCK.getOptional(id).map(state::is).orElse(false); + } +} diff --git a/common/src/main/java/com/craisinlord/antarchy/mixins/SquidzookaEnchantMixin.java b/common/src/main/java/com/craisinlord/antarchy/mixins/SquidzookaEnchantMixin.java index cecbfe67..433fd05a 100644 --- a/common/src/main/java/com/craisinlord/antarchy/mixins/SquidzookaEnchantMixin.java +++ b/common/src/main/java/com/craisinlord/antarchy/mixins/SquidzookaEnchantMixin.java @@ -1,72 +1,31 @@ package com.craisinlord.antarchy.mixins; -import com.craisinlord.antarchy.content.item.SquidzookaItem; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.enchantment.Enchantment; +import com.craisinlord.antarchy.content.AntarchyTags; +import net.minecraft.core.HolderGetter; +import net.minecraft.core.HolderSet; +import net.minecraft.tags.ItemTags; +import net.minecraft.tags.TagKey; +import net.minecraft.world.item.Item; import net.minecraft.world.item.enchantment.Enchantments; 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; +import org.spongepowered.asm.mixin.injection.Redirect; -@Mixin(Enchantment.class) +@Mixin(Enchantments.class) public abstract class SquidzookaEnchantMixin { - private static final Registry ENCHANTMENT_REGISTRY = resolveEnchantmentRegistry(); - - @Inject(method = "canEnchant", at = @At("HEAD"), cancellable = true) - private void antarchy$limitSquidzookaCrossbowEnchants(ItemStack stack, CallbackInfoReturnable cir) { - this.antarchy$applySquidzookaEnchantRules(stack, cir); - } - - @Inject(method = "isPrimaryItem", at = @At("HEAD"), cancellable = true) - private void antarchy$limitSquidzookaPrimaryItem(ItemStack stack, CallbackInfoReturnable cir) { - this.antarchy$applySquidzookaEnchantRules(stack, cir); - } - - @Inject(method = "isSupportedItem", at = @At("HEAD"), cancellable = true) - private void antarchy$limitSquidzookaSupportedItem(ItemStack stack, CallbackInfoReturnable cir) { - this.antarchy$applySquidzookaEnchantRules(stack, cir); - } - - private void antarchy$applySquidzookaEnchantRules(ItemStack stack, CallbackInfoReturnable cir) { - if (!(stack.getItem() instanceof SquidzookaItem)) { - return; + @Redirect( + method = "bootstrap", + at = @At(value = "INVOKE", target = "Lnet/minecraft/core/HolderGetter;getOrThrow(Lnet/minecraft/tags/TagKey;)Lnet/minecraft/core/HolderSet$Named;"), + slice = @org.spongepowered.asm.mixin.injection.Slice( + from = @At(value = "FIELD", target = "Lnet/minecraft/world/item/enchantment/Enchantments;MULTISHOT:Lnet/minecraft/resources/ResourceKey;"), + to = @At(value = "FIELD", target = "Lnet/minecraft/world/item/enchantment/Enchantments;QUICK_CHARGE:Lnet/minecraft/resources/ResourceKey;") + ) + ) + private static HolderSet.Named antarchy$allowSquidzookaForMultishot(HolderGetter holderGetter, TagKey tag) { + if (tag.equals(ItemTags.CROSSBOW_ENCHANTABLE)) { + return holderGetter.getOrThrow(AntarchyTags.Items.MULTISHOT_ENCHANTABLE); } - if (ENCHANTMENT_REGISTRY == null) { - return; - } - - Enchantment enchantment = (Enchantment) (Object) this; - ResourceLocation enchantmentId = ENCHANTMENT_REGISTRY.getKey(enchantment); - if (enchantmentId == null) { - return; - } - - if (enchantmentId.equals(Enchantments.MULTISHOT.location())) { - cir.setReturnValue(true); - return; - } - - if (enchantmentId.equals(Enchantments.QUICK_CHARGE.location()) - || enchantmentId.equals(Enchantments.PIERCING.location())) { - cir.setReturnValue(false); - } - } - - @SuppressWarnings("unchecked") - private static Registry resolveEnchantmentRegistry() { - try { - return (Registry) BuiltInRegistries.class.getField("ENCHANTMENT").get(null); - } catch (ReflectiveOperationException primary) { - try { - return (Registry) BuiltInRegistries.class.getField("ENCHANTMENTS").get(null); - } catch (ReflectiveOperationException ignored) { - return null; - } - } + return holderGetter.getOrThrow(tag); } } diff --git a/common/src/main/java/com/craisinlord/antarchy/mixins/SquidzookaMultishotMixin.java b/common/src/main/java/com/craisinlord/antarchy/mixins/SquidzookaMultishotMixin.java new file mode 100644 index 00000000..e8a51510 --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/mixins/SquidzookaMultishotMixin.java @@ -0,0 +1,37 @@ +package com.craisinlord.antarchy.mixins; + +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.enchantment.Enchantment; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(Enchantment.class) +public abstract class SquidzookaMultishotMixin { + @Inject(method = "canEnchant", at = @At("HEAD"), cancellable = true) + private void antarchy$allowSquidzookaForMultishot(ItemStack stack, CallbackInfoReturnable cir) { + if (antarchy$isMultishot() && antarchy$isSquidzooka(stack)) { + cir.setReturnValue(true); + } + } + + @Inject(method = "isPrimaryItem", at = @At("HEAD"), cancellable = true) + private void antarchy$allowSquidzookaAsPrimaryItem(ItemStack stack, CallbackInfoReturnable cir) { + if (antarchy$isMultishot() && antarchy$isSquidzooka(stack)) { + cir.setReturnValue(true); + } + } + + @Unique + private boolean antarchy$isMultishot() { + return "Multishot".equals(((Enchantment) (Object) this).description().getString()); + } + + @Unique + private boolean antarchy$isSquidzooka(ItemStack stack) { + return "squidzooka".equals(BuiltInRegistries.ITEM.getKey(stack.getItem()).getPath()); + } +} diff --git a/common/src/main/java/com/craisinlord/antarchy/mixins/client/CavarynSkyMixin.java b/common/src/main/java/com/craisinlord/antarchy/mixins/client/CavarynSkyMixin.java new file mode 100644 index 00000000..04857183 --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/mixins/client/CavarynSkyMixin.java @@ -0,0 +1,64 @@ +package com.craisinlord.antarchy.mixins.client; + +import com.craisinlord.antarchy.content.client.renderer.CavarynSkyRenderer; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexBuffer; +import net.minecraft.client.Camera; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.renderer.LevelRenderer; +import org.joml.Matrix4f; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(LevelRenderer.class) +public abstract class CavarynSkyMixin { + @Shadow + @Final + private Minecraft minecraft; + + @Shadow + private ClientLevel level; + + @Shadow + @Final + private VertexBuffer skyBuffer; + + @Shadow + @Final + private VertexBuffer darkBuffer; + + @Inject(method = "renderSky", at = @At("HEAD"), cancellable = true) + private void antarchy$renderCavarynSky(Matrix4f modelViewMatrix, Matrix4f projectionMatrix, float partialTick, Camera camera, boolean isFoggy, Runnable setupFog, CallbackInfo ci) { + if (this.level == null || !CavarynSkyRenderer.shouldRender(this.level)) { + return; + } + + PoseStack poseStack = new PoseStack(); + poseStack.mulPose(modelViewMatrix); + CavarynSkyRenderer.render( + this.minecraft, + this.level, + poseStack, + projectionMatrix, + partialTick, + camera, + isFoggy, + setupFog, + this.skyBuffer, + this.darkBuffer + ); + ci.cancel(); + } + + @Inject(method = "renderClouds", at = @At("HEAD"), cancellable = true) + private void antarchy$skipCavarynClouds(PoseStack poseStack, Matrix4f modelViewMatrix, Matrix4f projectionMatrix, float partialTick, double camX, double camY, double camZ, CallbackInfo ci) { + if (this.level != null && CavarynSkyRenderer.shouldRender(this.level)) { + ci.cancel(); + } + } +} diff --git a/common/src/main/java/com/craisinlord/antarchy/mixins/stellaris/DimensionOxygenManagerMixin.java b/common/src/main/java/com/craisinlord/antarchy/mixins/stellaris/DimensionOxygenManagerMixin.java deleted file mode 100644 index 42846ba0..00000000 --- a/common/src/main/java/com/craisinlord/antarchy/mixins/stellaris/DimensionOxygenManagerMixin.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.craisinlord.antarchy.mixins.stellaris; - -import com.st0x0ef.stellaris.common.oxygen.DimensionOxygenManager; -import net.minecraft.core.component.DataComponentType; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.core.registries.Registries; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.tags.TagKey; -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(value = DimensionOxygenManager.class, priority = 2000) -/* - * Tweaks Stellaris oxygen checks for Antarchy dimensions. - */ -public abstract class DimensionOxygenManagerMixin { - @Unique - private static final TagKey ANTARCHY_MARK_39_ARMOR = TagKey.create( - Registries.ITEM, - ResourceLocation.fromNamespaceAndPath("marvel", "iron_man_mark_39_armor") - ); - - @Unique - private static final ResourceLocation ANTARCHY_HELMET_OPEN_ID = - ResourceLocation.fromNamespaceAndPath("marvel", "helmet_open"); - - @Inject(method = "breath", at = @At("HEAD"), cancellable = true) - private void antarchy$allowClosedMark39SuitToBreathe( - LivingEntity entity, - CallbackInfoReturnable cir - ) { - if (antarchy$hasArmor(entity)) { - cir.setReturnValue(true); - } - } - - @Unique - private static boolean antarchy$hasArmor(LivingEntity entity) { - ItemStack helmet = entity.getItemBySlot(EquipmentSlot.HEAD); - boolean hasHelmet = helmet.is(ANTARCHY_MARK_39_ARMOR) && !antarchy$isHelmetOpen(helmet); - boolean hasChestplate = entity.getItemBySlot(EquipmentSlot.CHEST).is(ANTARCHY_MARK_39_ARMOR); - boolean hasLeggings = entity.getItemBySlot(EquipmentSlot.LEGS).is(ANTARCHY_MARK_39_ARMOR); - boolean hasBoots = entity.getItemBySlot(EquipmentSlot.FEET).is(ANTARCHY_MARK_39_ARMOR); - return hasHelmet && hasChestplate && hasLeggings && hasBoots; - } - - @Unique - @SuppressWarnings("unchecked") - private static boolean antarchy$isHelmetOpen(ItemStack helmet) { - DataComponentType componentType = BuiltInRegistries.DATA_COMPONENT_TYPE.get(ANTARCHY_HELMET_OPEN_ID); - if (componentType == null) { - return false; - } - return Boolean.TRUE.equals(helmet.get((DataComponentType) componentType)); - } -} diff --git a/common/src/main/resources/antarchy-common.mixins.json b/common/src/main/resources/antarchy-common.mixins.json index f597f485..6b8422cb 100644 --- a/common/src/main/resources/antarchy-common.mixins.json +++ b/common/src/main/resources/antarchy-common.mixins.json @@ -1,10 +1,12 @@ { "required": true, "package": "com.craisinlord.antarchy.mixins", + "refmap": "antarchy.refmap.json", "plugin": "com.craisinlord.antarchy.mixins.AntarchyMixinPlugin", "compatibilityLevel": "JAVA_21", "mixins": [ "AccessorRangedAttribute", + "BlockEntitySignMixin", "BloodglassMixin", "DreamFireBlockMixin", "DreamSandLowGravityMixin", @@ -13,7 +15,7 @@ "GlowVinesUnderLeavesMixin", "ServerPlayerGameModeMixin", "SquidzookaEnchantMixin", - "StinkyLivingEntityMixin", + "SquidzookaMultishotMixin", "TorchflowerBlockStateMixin", "gravity.AbstractArrowGravityMixin", "gravity.BucketItemGravityMixin", @@ -43,10 +45,10 @@ "gravity.ServerPlayerGravityMixin", "gravity.ThrowableProjectileGravityMixin", "gravity.TrackedEntityAccessor", - "multipart.EntityMultipartLifecycleMixin", - "stellaris.DimensionOxygenManagerMixin" + "multipart.EntityMultipartLifecycleMixin" ], "client": [ + "client.CavarynSkyMixin", "client.ElythiaSkyMixin", "client.ElytraModelAccessor", "client.LightningBoltRendererMixin", diff --git a/common/src/main/resources/assets/antarchy/animations/kraken.animation.json b/common/src/main/resources/assets/antarchy/animations/kraken.animation.json index 4401a478..95d60f28 100644 --- a/common/src/main/resources/assets/antarchy/animations/kraken.animation.json +++ b/common/src/main/resources/assets/antarchy/animations/kraken.animation.json @@ -5524,6 +5524,22 @@ "lerp_mode": "catmullrom" } } + }, + "Kraken": { + "position": { + "0.0": { + "post": { + "vector": [0, 218.48, 0] + }, + "lerp_mode": "catmullrom" + }, + "3.0": { + "post": { + "vector": [0, 218.48, 0] + }, + "lerp_mode": "catmullrom" + } + } } } } diff --git a/common/src/main/resources/assets/antarchy/blockstates/bile.json b/common/src/main/resources/assets/antarchy/blockstates/bile.json new file mode 100644 index 00000000..777d6ac3 --- /dev/null +++ b/common/src/main/resources/assets/antarchy/blockstates/bile.json @@ -0,0 +1,20 @@ +{ + "variants": { + "level=0": { "model": "minecraft:block/water" }, + "level=1": { "model": "minecraft:block/water" }, + "level=2": { "model": "minecraft:block/water" }, + "level=3": { "model": "minecraft:block/water" }, + "level=4": { "model": "minecraft:block/water" }, + "level=5": { "model": "minecraft:block/water" }, + "level=6": { "model": "minecraft:block/water" }, + "level=7": { "model": "minecraft:block/water" }, + "level=8": { "model": "minecraft:block/water" }, + "level=9": { "model": "minecraft:block/water" }, + "level=10": { "model": "minecraft:block/water" }, + "level=11": { "model": "minecraft:block/water" }, + "level=12": { "model": "minecraft:block/water" }, + "level=13": { "model": "minecraft:block/water" }, + "level=14": { "model": "minecraft:block/water" }, + "level=15": { "model": "minecraft:block/water" } + } +} diff --git a/common/src/main/resources/assets/antarchy/blockstates/chiten_spike.json b/common/src/main/resources/assets/antarchy/blockstates/chiten_spike.json new file mode 100644 index 00000000..4cef7a2b --- /dev/null +++ b/common/src/main/resources/assets/antarchy/blockstates/chiten_spike.json @@ -0,0 +1,14 @@ +{ + "variants": { + "thickness=base,vertical_direction=down": { "model": "antarchy:block/chiten_spike_down_base" }, + "thickness=base,vertical_direction=up": { "model": "antarchy:block/chiten_spike_up_base" }, + "thickness=frustum,vertical_direction=down": { "model": "antarchy:block/chiten_spike_down_frustum" }, + "thickness=frustum,vertical_direction=up": { "model": "antarchy:block/chiten_spike_up_frustum" }, + "thickness=middle,vertical_direction=down": { "model": "antarchy:block/chiten_spike_down_middle" }, + "thickness=middle,vertical_direction=up": { "model": "antarchy:block/chiten_spike_up_middle" }, + "thickness=tip,vertical_direction=down": { "model": "antarchy:block/chiten_spike_down_tip" }, + "thickness=tip,vertical_direction=up": { "model": "antarchy:block/chiten_spike_up_tip" }, + "thickness=tip_merge,vertical_direction=down": { "model": "antarchy:block/chiten_spike_down_tip_merge" }, + "thickness=tip_merge,vertical_direction=up": { "model": "antarchy:block/chiten_spike_up_tip_merge" } + } +} diff --git a/common/src/main/resources/assets/antarchy/lang/en_us.json b/common/src/main/resources/assets/antarchy/lang/en_us.json index 1c26892e..95dd34f6 100644 --- a/common/src/main/resources/assets/antarchy/lang/en_us.json +++ b/common/src/main/resources/assets/antarchy/lang/en_us.json @@ -38,6 +38,7 @@ "block.antarchy.chiseled_nyxite": "Chiseled Nyxite", "block.antarchy.nyxite_bricks": "Nyxite Bricks", "block.antarchy.chiten_block": "Chiten Block", + "block.antarchy.chiten_spike": "Chiten Spike", "block.antarchy.shellstone": "Shellstone", "block.antarchy.polished_shellstone": "Polished Shellstone", "block.antarchy.shellstone_bricks": "Shellstone Bricks", @@ -130,6 +131,7 @@ "block.antarchy.uranium_bars": "Uranium Bars", "block.antarchy.titanium_bars": "Titanium Bars", "tooltip.antarchy.signal_saving_bulb": "Toggles on/off. Has light level equal to the signal strength stored on it.", + "block.antarchy.bile": "Bile", "block.antarchy.ichor": "Ichor", "block.antarchy.antiwater": "Antiwater", "entity.antarchy.apple_cow": "Apple Cow", @@ -273,6 +275,7 @@ "item.antarchy.creepvine": "Creepvine", "item.antarchy.chiten": "Chiten", "item.antarchy.chiten_block": "Chiten Block", + "item.antarchy.chiten_spike": "Chiten Spike", "item.antarchy.myrmite": "Myrmite", "item.antarchy.torchflower_bush": "Torchflower Bush", "block.antarchy.torchflower_bush": "Torchflower Bush", @@ -339,6 +342,7 @@ "item.antarchy.ultimate_mace": "Ultimate Mace", "item.antarchy.moggles": "Moggles", "itemGroup.antarchy.antarchy": "Antarchy", + "item.antarchy.bile_bucket": "Bile Bucket", "item.antarchy.ichor_bucket": "Ichor Bucket", "item.antarchy.antiwater_bucket": "Antiwater Bucket", "item.antarchy.reverie_bottle": "Bottle of Reverie", @@ -393,6 +397,7 @@ "biome.antarchy.butterfly_fields": "Butterfly Fields", "biome.antarchy.torchflower_fields": "Torchflower Fields", "biome.antarchy.ouranwood_forest": "Ouranwood Forest", + "biome.antarchy.fungal_ouranwood_forest": "Fungal Ouranwood Forest", "message.antarchy.brown_ant_activated": "The brown ant is ready to open its destination.", "message.antarchy.brown_ant_needs_reagent": "This brown ant needs a reagent before it can open its destination.", "message.antarchy.rainbow_ant_activated": "The rainbow ant hums with a new Infinity destination.", diff --git a/common/src/main/resources/assets/antarchy/models/block/chiten_spike_down_base.json b/common/src/main/resources/assets/antarchy/models/block/chiten_spike_down_base.json new file mode 100644 index 00000000..5bb4d70a --- /dev/null +++ b/common/src/main/resources/assets/antarchy/models/block/chiten_spike_down_base.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/pointed_dripstone", + "textures": { + "cross": "antarchy:block/chiten_spike/chiten_spike_down_base" + } +} diff --git a/common/src/main/resources/assets/antarchy/models/block/chiten_spike_down_frustum.json b/common/src/main/resources/assets/antarchy/models/block/chiten_spike_down_frustum.json new file mode 100644 index 00000000..c94fcdb5 --- /dev/null +++ b/common/src/main/resources/assets/antarchy/models/block/chiten_spike_down_frustum.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/pointed_dripstone", + "textures": { + "cross": "antarchy:block/chiten_spike/chiten_spike_down_frustum" + } +} diff --git a/common/src/main/resources/assets/antarchy/models/block/chiten_spike_down_middle.json b/common/src/main/resources/assets/antarchy/models/block/chiten_spike_down_middle.json new file mode 100644 index 00000000..8cd7d902 --- /dev/null +++ b/common/src/main/resources/assets/antarchy/models/block/chiten_spike_down_middle.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/pointed_dripstone", + "textures": { + "cross": "antarchy:block/chiten_spike/chiten_spike_down_middle" + } +} diff --git a/common/src/main/resources/assets/antarchy/models/block/chiten_spike_down_tip.json b/common/src/main/resources/assets/antarchy/models/block/chiten_spike_down_tip.json new file mode 100644 index 00000000..d8b89d9b --- /dev/null +++ b/common/src/main/resources/assets/antarchy/models/block/chiten_spike_down_tip.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/pointed_dripstone", + "textures": { + "cross": "antarchy:block/chiten_spike/chiten_spike_down_tip" + } +} diff --git a/common/src/main/resources/assets/antarchy/models/block/chiten_spike_down_tip_merge.json b/common/src/main/resources/assets/antarchy/models/block/chiten_spike_down_tip_merge.json new file mode 100644 index 00000000..3941f02d --- /dev/null +++ b/common/src/main/resources/assets/antarchy/models/block/chiten_spike_down_tip_merge.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/pointed_dripstone", + "textures": { + "cross": "antarchy:block/chiten_spike/chiten_spike_down_tip_merge" + } +} diff --git a/common/src/main/resources/assets/antarchy/models/block/chiten_spike_up_base.json b/common/src/main/resources/assets/antarchy/models/block/chiten_spike_up_base.json new file mode 100644 index 00000000..a896ccbb --- /dev/null +++ b/common/src/main/resources/assets/antarchy/models/block/chiten_spike_up_base.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/pointed_dripstone", + "textures": { + "cross": "antarchy:block/chiten_spike/chiten_spike_up_base" + } +} diff --git a/common/src/main/resources/assets/antarchy/models/block/chiten_spike_up_frustum.json b/common/src/main/resources/assets/antarchy/models/block/chiten_spike_up_frustum.json new file mode 100644 index 00000000..e3e84f52 --- /dev/null +++ b/common/src/main/resources/assets/antarchy/models/block/chiten_spike_up_frustum.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/pointed_dripstone", + "textures": { + "cross": "antarchy:block/chiten_spike/chiten_spike_up_frustum" + } +} diff --git a/common/src/main/resources/assets/antarchy/models/block/chiten_spike_up_middle.json b/common/src/main/resources/assets/antarchy/models/block/chiten_spike_up_middle.json new file mode 100644 index 00000000..ba4e46f2 --- /dev/null +++ b/common/src/main/resources/assets/antarchy/models/block/chiten_spike_up_middle.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/pointed_dripstone", + "textures": { + "cross": "antarchy:block/chiten_spike/chiten_spike_up_middle" + } +} diff --git a/common/src/main/resources/assets/antarchy/models/block/chiten_spike_up_tip.json b/common/src/main/resources/assets/antarchy/models/block/chiten_spike_up_tip.json new file mode 100644 index 00000000..25dda590 --- /dev/null +++ b/common/src/main/resources/assets/antarchy/models/block/chiten_spike_up_tip.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/pointed_dripstone", + "textures": { + "cross": "antarchy:block/chiten_spike/chiten_spike_up_tip" + } +} diff --git a/common/src/main/resources/assets/antarchy/models/block/chiten_spike_up_tip_merge.json b/common/src/main/resources/assets/antarchy/models/block/chiten_spike_up_tip_merge.json new file mode 100644 index 00000000..6349e79a --- /dev/null +++ b/common/src/main/resources/assets/antarchy/models/block/chiten_spike_up_tip_merge.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/pointed_dripstone", + "textures": { + "cross": "antarchy:block/chiten_spike/chiten_spike_up_tip_merge" + } +} diff --git a/common/src/main/resources/assets/antarchy/models/block/creeping_horror_egg_1.json b/common/src/main/resources/assets/antarchy/models/block/creeping_horror_egg_1.json index 7a7c5178..f4187644 100644 --- a/common/src/main/resources/assets/antarchy/models/block/creeping_horror_egg_1.json +++ b/common/src/main/resources/assets/antarchy/models/block/creeping_horror_egg_1.json @@ -1,6 +1,6 @@ { "parent": "minecraft:block/template_turtle_egg", "textures": { - "all": "antarchy:block/creeping_horror_eggs/creeping_horror_eggs" + "all": "antarchy:block/creeping_horror_egg/creeping_horror_egg" } } diff --git a/common/src/main/resources/assets/antarchy/models/block/creeping_horror_egg_2.json b/common/src/main/resources/assets/antarchy/models/block/creeping_horror_egg_2.json index 504f83af..d2f9f14d 100644 --- a/common/src/main/resources/assets/antarchy/models/block/creeping_horror_egg_2.json +++ b/common/src/main/resources/assets/antarchy/models/block/creeping_horror_egg_2.json @@ -1,6 +1,6 @@ { "parent": "minecraft:block/template_two_turtle_eggs", "textures": { - "all": "antarchy:block/creeping_horror_eggs/creeping_horror_eggs" + "all": "antarchy:block/creeping_horror_egg/creeping_horror_egg" } } diff --git a/common/src/main/resources/assets/antarchy/models/block/creeping_horror_egg_3.json b/common/src/main/resources/assets/antarchy/models/block/creeping_horror_egg_3.json index 444bdf36..ef956bbe 100644 --- a/common/src/main/resources/assets/antarchy/models/block/creeping_horror_egg_3.json +++ b/common/src/main/resources/assets/antarchy/models/block/creeping_horror_egg_3.json @@ -1,6 +1,6 @@ { "parent": "minecraft:block/template_three_turtle_eggs", "textures": { - "all": "antarchy:block/creeping_horror_eggs/creeping_horror_eggs" + "all": "antarchy:block/creeping_horror_egg/creeping_horror_egg" } } diff --git a/common/src/main/resources/assets/antarchy/models/block/creeping_horror_egg_4.json b/common/src/main/resources/assets/antarchy/models/block/creeping_horror_egg_4.json index f93265b4..af64531c 100644 --- a/common/src/main/resources/assets/antarchy/models/block/creeping_horror_egg_4.json +++ b/common/src/main/resources/assets/antarchy/models/block/creeping_horror_egg_4.json @@ -1,6 +1,6 @@ { "parent": "minecraft:block/template_four_turtle_eggs", "textures": { - "all": "antarchy:block/creeping_horror_eggs/creeping_horror_eggs" + "all": "antarchy:block/creeping_horror_egg/creeping_horror_egg" } } diff --git a/common/src/main/resources/assets/antarchy/models/block/slightly_cracked_creeping_horror_egg_1.json b/common/src/main/resources/assets/antarchy/models/block/slightly_cracked_creeping_horror_egg_1.json index c7684d53..20b6a8ae 100644 --- a/common/src/main/resources/assets/antarchy/models/block/slightly_cracked_creeping_horror_egg_1.json +++ b/common/src/main/resources/assets/antarchy/models/block/slightly_cracked_creeping_horror_egg_1.json @@ -1,6 +1,6 @@ { "parent": "minecraft:block/template_turtle_egg", "textures": { - "all": "antarchy:block/creeping_horror_eggs/creeping_horror_eggs_slightly_cracked" + "all": "antarchy:block/creeping_horror_egg/creeping_horror_egg_slightly_cracked" } } diff --git a/common/src/main/resources/assets/antarchy/models/block/slightly_cracked_creeping_horror_egg_2.json b/common/src/main/resources/assets/antarchy/models/block/slightly_cracked_creeping_horror_egg_2.json index 6ec1173a..cbfa51e2 100644 --- a/common/src/main/resources/assets/antarchy/models/block/slightly_cracked_creeping_horror_egg_2.json +++ b/common/src/main/resources/assets/antarchy/models/block/slightly_cracked_creeping_horror_egg_2.json @@ -1,6 +1,6 @@ { "parent": "minecraft:block/template_two_turtle_eggs", "textures": { - "all": "antarchy:block/creeping_horror_eggs/creeping_horror_eggs_slightly_cracked" + "all": "antarchy:block/creeping_horror_egg/creeping_horror_egg_slightly_cracked" } } diff --git a/common/src/main/resources/assets/antarchy/models/block/slightly_cracked_creeping_horror_egg_3.json b/common/src/main/resources/assets/antarchy/models/block/slightly_cracked_creeping_horror_egg_3.json index ec94e0ff..03be473f 100644 --- a/common/src/main/resources/assets/antarchy/models/block/slightly_cracked_creeping_horror_egg_3.json +++ b/common/src/main/resources/assets/antarchy/models/block/slightly_cracked_creeping_horror_egg_3.json @@ -1,6 +1,6 @@ { "parent": "minecraft:block/template_three_turtle_eggs", "textures": { - "all": "antarchy:block/creeping_horror_eggs/creeping_horror_eggs_slightly_cracked" + "all": "antarchy:block/creeping_horror_egg/creeping_horror_egg_slightly_cracked" } } diff --git a/common/src/main/resources/assets/antarchy/models/block/slightly_cracked_creeping_horror_egg_4.json b/common/src/main/resources/assets/antarchy/models/block/slightly_cracked_creeping_horror_egg_4.json index c1ba4ffb..251150cc 100644 --- a/common/src/main/resources/assets/antarchy/models/block/slightly_cracked_creeping_horror_egg_4.json +++ b/common/src/main/resources/assets/antarchy/models/block/slightly_cracked_creeping_horror_egg_4.json @@ -1,6 +1,6 @@ { "parent": "minecraft:block/template_four_turtle_eggs", "textures": { - "all": "antarchy:block/creeping_horror_eggs/creeping_horror_eggs_slightly_cracked" + "all": "antarchy:block/creeping_horror_egg/creeping_horror_egg_slightly_cracked" } } diff --git a/common/src/main/resources/assets/antarchy/models/block/very_cracked_creeping_horror_egg_1.json b/common/src/main/resources/assets/antarchy/models/block/very_cracked_creeping_horror_egg_1.json index 78cbec5a..4ccfd5ca 100644 --- a/common/src/main/resources/assets/antarchy/models/block/very_cracked_creeping_horror_egg_1.json +++ b/common/src/main/resources/assets/antarchy/models/block/very_cracked_creeping_horror_egg_1.json @@ -1,6 +1,6 @@ { "parent": "minecraft:block/template_turtle_egg", "textures": { - "all": "antarchy:block/creeping_horror_eggs/creeping_horror_eggs_very_cracked" + "all": "antarchy:block/creeping_horror_egg/creeping_horror_egg_very_cracked" } } diff --git a/common/src/main/resources/assets/antarchy/models/block/very_cracked_creeping_horror_egg_2.json b/common/src/main/resources/assets/antarchy/models/block/very_cracked_creeping_horror_egg_2.json index bde1c914..37334cc9 100644 --- a/common/src/main/resources/assets/antarchy/models/block/very_cracked_creeping_horror_egg_2.json +++ b/common/src/main/resources/assets/antarchy/models/block/very_cracked_creeping_horror_egg_2.json @@ -1,6 +1,6 @@ { "parent": "minecraft:block/template_two_turtle_eggs", "textures": { - "all": "antarchy:block/creeping_horror_eggs/creeping_horror_eggs_very_cracked" + "all": "antarchy:block/creeping_horror_egg/creeping_horror_egg_very_cracked" } } diff --git a/common/src/main/resources/assets/antarchy/models/block/very_cracked_creeping_horror_egg_3.json b/common/src/main/resources/assets/antarchy/models/block/very_cracked_creeping_horror_egg_3.json index 4c29c62b..824df80f 100644 --- a/common/src/main/resources/assets/antarchy/models/block/very_cracked_creeping_horror_egg_3.json +++ b/common/src/main/resources/assets/antarchy/models/block/very_cracked_creeping_horror_egg_3.json @@ -1,6 +1,6 @@ { "parent": "minecraft:block/template_three_turtle_eggs", "textures": { - "all": "antarchy:block/creeping_horror_eggs/creeping_horror_eggs_very_cracked" + "all": "antarchy:block/creeping_horror_egg/creeping_horror_egg_very_cracked" } } diff --git a/common/src/main/resources/assets/antarchy/models/block/very_cracked_creeping_horror_egg_4.json b/common/src/main/resources/assets/antarchy/models/block/very_cracked_creeping_horror_egg_4.json index 40ccb68c..d034d949 100644 --- a/common/src/main/resources/assets/antarchy/models/block/very_cracked_creeping_horror_egg_4.json +++ b/common/src/main/resources/assets/antarchy/models/block/very_cracked_creeping_horror_egg_4.json @@ -1,6 +1,6 @@ { "parent": "minecraft:block/template_four_turtle_eggs", "textures": { - "all": "antarchy:block/creeping_horror_eggs/creeping_horror_eggs_very_cracked" + "all": "antarchy:block/creeping_horror_egg/creeping_horror_egg_very_cracked" } } diff --git a/common/src/main/resources/assets/antarchy/models/item/chiten_spike.json b/common/src/main/resources/assets/antarchy/models/item/chiten_spike.json new file mode 100644 index 00000000..0a70c0e9 --- /dev/null +++ b/common/src/main/resources/assets/antarchy/models/item/chiten_spike.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "antarchy:item/chiten_spike" + } +} diff --git a/common/src/main/resources/assets/antarchy/models/item/uranium_bars.json b/common/src/main/resources/assets/antarchy/models/item/uranium_bars.json index 073ce4a9..b41681dd 100644 --- a/common/src/main/resources/assets/antarchy/models/item/uranium_bars.json +++ b/common/src/main/resources/assets/antarchy/models/item/uranium_bars.json @@ -1,6 +1,6 @@ { "parent": "minecraft:item/generated", "textures": { - "layer0": "antarchy:block/uranium/uranium_bars" + "layer0": "antarchy:item/uranium/uranium_bars" } } diff --git a/common/src/main/resources/assets/antarchy/particles/orange_ash.json b/common/src/main/resources/assets/antarchy/particles/orange_ash.json new file mode 100644 index 00000000..ca698ca4 --- /dev/null +++ b/common/src/main/resources/assets/antarchy/particles/orange_ash.json @@ -0,0 +1,5 @@ +{ + "textures": [ + "minecraft:generic_0" + ] +} \ No newline at end of file diff --git a/common/src/main/resources/assets/antarchy/textures/block/bile/bile_flowing.png b/common/src/main/resources/assets/antarchy/textures/block/bile/bile_flowing.png new file mode 100644 index 00000000..68f48de7 Binary files /dev/null and b/common/src/main/resources/assets/antarchy/textures/block/bile/bile_flowing.png differ diff --git a/common/src/main/resources/assets/antarchy/textures/block/bile/bile_flowing.png.mcmeta b/common/src/main/resources/assets/antarchy/textures/block/bile/bile_flowing.png.mcmeta new file mode 100644 index 00000000..1e3d6590 --- /dev/null +++ b/common/src/main/resources/assets/antarchy/textures/block/bile/bile_flowing.png.mcmeta @@ -0,0 +1,6 @@ +{ + "animation": { + "frametime": 3, + "interpolate": true + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/antarchy/textures/block/bile/bile_still.png b/common/src/main/resources/assets/antarchy/textures/block/bile/bile_still.png new file mode 100644 index 00000000..1c5d447a Binary files /dev/null and b/common/src/main/resources/assets/antarchy/textures/block/bile/bile_still.png differ diff --git a/common/src/main/resources/assets/antarchy/textures/block/bile/bile_still.png.mcmeta b/common/src/main/resources/assets/antarchy/textures/block/bile/bile_still.png.mcmeta new file mode 100644 index 00000000..432a3845 --- /dev/null +++ b/common/src/main/resources/assets/antarchy/textures/block/bile/bile_still.png.mcmeta @@ -0,0 +1,6 @@ +{ + "animation": { + "frametime": 4, + "interpolate": true + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_down_base.png b/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_down_base.png new file mode 100644 index 00000000..49c5d6a1 Binary files /dev/null and b/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_down_base.png differ diff --git a/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_down_frustum.png b/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_down_frustum.png new file mode 100644 index 00000000..1660e8e0 Binary files /dev/null and b/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_down_frustum.png differ diff --git a/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_down_middle.png b/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_down_middle.png new file mode 100644 index 00000000..cecd80c1 Binary files /dev/null and b/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_down_middle.png differ diff --git a/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_down_tip.png b/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_down_tip.png new file mode 100644 index 00000000..324c5c8a Binary files /dev/null and b/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_down_tip.png differ diff --git a/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_down_tip_merge.png b/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_down_tip_merge.png new file mode 100644 index 00000000..9c78714d Binary files /dev/null and b/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_down_tip_merge.png differ diff --git a/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_up_base.png b/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_up_base.png new file mode 100644 index 00000000..f9eab88e Binary files /dev/null and b/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_up_base.png differ diff --git a/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_up_frustum.png b/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_up_frustum.png new file mode 100644 index 00000000..a4894a9d Binary files /dev/null and b/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_up_frustum.png differ diff --git a/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_up_middle.png b/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_up_middle.png new file mode 100644 index 00000000..37c8e4d2 Binary files /dev/null and b/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_up_middle.png differ diff --git a/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_up_tip.png b/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_up_tip.png new file mode 100644 index 00000000..9b66fa38 Binary files /dev/null and b/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_up_tip.png differ diff --git a/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_up_tip_merge.png b/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_up_tip_merge.png new file mode 100644 index 00000000..0d9972f2 Binary files /dev/null and b/common/src/main/resources/assets/antarchy/textures/block/chiten_spike/chiten_spike_up_tip_merge.png differ diff --git a/common/src/main/resources/assets/antarchy/textures/item/chiten_spike.png b/common/src/main/resources/assets/antarchy/textures/item/chiten_spike.png new file mode 100644 index 00000000..9b66fa38 Binary files /dev/null and b/common/src/main/resources/assets/antarchy/textures/item/chiten_spike.png differ diff --git a/common/src/main/resources/assets/antarchy/textures/item/uranium/uranium_bars.png b/common/src/main/resources/assets/antarchy/textures/item/uranium/uranium_bars.png new file mode 100644 index 00000000..8efc22c1 Binary files /dev/null and b/common/src/main/resources/assets/antarchy/textures/item/uranium/uranium_bars.png differ diff --git a/common/src/main/resources/assets/antarchy/textures/particle/orange_ash.png b/common/src/main/resources/assets/antarchy/textures/particle/orange_ash.png new file mode 100644 index 00000000..f3cdf989 Binary files /dev/null and b/common/src/main/resources/assets/antarchy/textures/particle/orange_ash.png differ diff --git a/common/src/main/resources/data/antarchy/dimension/elythia.json b/common/src/main/resources/data/antarchy/dimension/elythia.json index 7219060c..77904a56 100644 --- a/common/src/main/resources/data/antarchy/dimension/elythia.json +++ b/common/src/main/resources/data/antarchy/dimension/elythia.json @@ -7,7 +7,7 @@ "type": "antarchy:elythia_biome_source", "moleworm_caves_max_y": 30, "surface_biome_sample_y": 160, - "ocean_max_y": 85, + "ocean_max_y": 75, "biomes": [ { "biome": "antarchy:moleworm_caves", @@ -225,6 +225,30 @@ "offset": 0.0 } }, + { + "biome": "antarchy:fungal_ouranwood_forest", + "parameters": { + "temperature": 0.55, + "humidity": 0.9, + "continentalness": 0.75, + "erosion": 0.0, + "weirdness": 0.85, + "depth": 0.45, + "offset": 0.0 + } + }, + { + "biome": "antarchy:fungal_ouranwood_forest", + "parameters": { + "temperature": 0.55, + "humidity": 0.9, + "continentalness": 0.75, + "erosion": 0.0, + "weirdness": 0.85, + "depth": 0.0, + "offset": 0.0 + } + }, { "biome": "antarchy:torchflower_fields", "parameters": { @@ -398,7 +422,7 @@ "parameters": { "temperature": 0.65, "humidity": 0.90, - "continentalness": -0.50, + "continentalness": -0.88, "erosion": 0.30, "weirdness": 0.0, "depth": 0.0, @@ -410,7 +434,7 @@ "parameters": { "temperature": 0.60, "humidity": 0.88, - "continentalness": -0.55, + "continentalness": -0.92, "erosion": 0.25, "weirdness": -0.40, "depth": 0.0, @@ -422,7 +446,7 @@ "parameters": { "temperature": 0.70, "humidity": 0.92, - "continentalness": -0.45, + "continentalness": -0.85, "erosion": 0.35, "weirdness": 0.40, "depth": 0.0, @@ -434,7 +458,7 @@ "parameters": { "temperature": 0.65, "humidity": 0.90, - "continentalness": -0.50, + "continentalness": -0.88, "erosion": 0.30, "weirdness": 0.0, "depth": 0.5, @@ -446,7 +470,7 @@ "parameters": { "temperature": 0.60, "humidity": 0.88, - "continentalness": -0.55, + "continentalness": -0.92, "erosion": 0.25, "weirdness": -0.40, "depth": 0.5, @@ -454,38 +478,50 @@ } }, { - "biome": "antarchy:elythia_beach", + "biome": "antarchy:elythia_coral_spikes", "parameters": { - "temperature": 0.68, - "humidity": 0.91, - "continentalness": -0.08, - "erosion": 0.50, - "weirdness": 0.0, + "temperature": 0.80, + "humidity": 0.85, + "continentalness": -0.88, + "erosion": 0.20, + "weirdness": 0.60, "depth": 0.0, "offset": 0.0 } }, { - "biome": "antarchy:elythia_beach", + "biome": "antarchy:elythia_coral_spikes", "parameters": { - "temperature": 0.65, - "humidity": 0.89, - "continentalness": -0.05, - "erosion": 0.60, - "weirdness": -0.30, + "temperature": 0.75, + "humidity": 0.82, + "continentalness": -0.90, + "erosion": 0.15, + "weirdness": -0.65, "depth": 0.0, "offset": 0.0 } }, { - "biome": "antarchy:elythia_beach", + "biome": "antarchy:elythia_coral_spikes", "parameters": { - "temperature": 0.70, - "humidity": 0.93, - "continentalness": -0.02, - "erosion": 0.55, - "weirdness": 0.30, - "depth": 0.0, + "temperature": 0.80, + "humidity": 0.85, + "continentalness": -0.88, + "erosion": 0.20, + "weirdness": 0.60, + "depth": 0.5, + "offset": 0.0 + } + }, + { + "biome": "antarchy:elythia_coral_spikes", + "parameters": { + "temperature": 0.75, + "humidity": 0.82, + "continentalness": -0.90, + "erosion": 0.15, + "weirdness": -0.65, + "depth": 0.5, "offset": 0.0 } } diff --git a/common/src/main/resources/data/antarchy/dimension_type/cavaryn.json b/common/src/main/resources/data/antarchy/dimension_type/cavaryn.json index 19af033e..081e44a9 100644 --- a/common/src/main/resources/data/antarchy/dimension_type/cavaryn.json +++ b/common/src/main/resources/data/antarchy/dimension_type/cavaryn.json @@ -1,18 +1,18 @@ { - "ultrawarm": false, + "ultrawarm": true, "natural": false, - "coordinate_scale": 1.0, + "coordinate_scale": 64.0, "bed_works": false, "respawn_anchor_works": false, "min_y": 0, - "height": 256, - "logical_height": 240, + "height": 208, + "logical_height": 192, "infiniburn": "#minecraft:infiniburn_overworld", - "effects": "minecraft:the_end", + "effects": "minecraft:overworld", "ambient_light": 0.0, "piglin_safe": false, "has_raids": false, - "monster_spawn_light_level": 7, + "monster_spawn_light_level": 0, "monster_spawn_block_light_limit": 0, "has_skylight": false, "has_ceiling": true, diff --git a/common/src/main/resources/data/antarchy/loot_table/blocks/chiten_spike.json b/common/src/main/resources/data/antarchy/loot_table/blocks/chiten_spike.json new file mode 100644 index 00000000..b1d9fae3 --- /dev/null +++ b/common/src/main/resources/data/antarchy/loot_table/blocks/chiten_spike.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "antarchy:chiten_spike" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} diff --git a/common/src/main/resources/data/antarchy/loot_table/entities/creeping_horror.json b/common/src/main/resources/data/antarchy/loot_table/entities/creeping_horror.json new file mode 100644 index 00000000..6f31cc60 --- /dev/null +++ b/common/src/main/resources/data/antarchy/loot_table/entities/creeping_horror.json @@ -0,0 +1,39 @@ +{ + "type": "minecraft:entity", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "antarchy:chiten", + "functions": [ + { + "function": "minecraft:set_count", + "count": { + "type": "minecraft:uniform", + "min": 1.0, + "max": 2.0 + } + }, + { + "function": "minecraft:enchanted_count_increase", + "enchantment": "minecraft:looting", + "count": { + "type": "minecraft:uniform", + "min": 0.0, + "max": 1.0 + } + } + ] + } + ], + "conditions": [ + { + "condition": "minecraft:killed_by_player" + } + ] + } + ], + "random_sequence": "antarchy:entities/creeping_horror" +} diff --git a/common/src/main/resources/data/antarchy/loot_table/entities/jumpy_bug.json b/common/src/main/resources/data/antarchy/loot_table/entities/jumpy_bug.json index 7cb9cc54..d206ce93 100644 --- a/common/src/main/resources/data/antarchy/loot_table/entities/jumpy_bug.json +++ b/common/src/main/resources/data/antarchy/loot_table/entities/jumpy_bug.json @@ -28,6 +28,39 @@ ] } ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "antarchy:chiten", + "functions": [ + { + "function": "minecraft:set_count", + "count": { + "type": "minecraft:uniform", + "min": 1.0, + "max": 2.0 + } + }, + { + "function": "minecraft:enchanted_count_increase", + "enchantment": "minecraft:looting", + "count": { + "type": "minecraft:uniform", + "min": 0.0, + "max": 1.0 + } + } + ] + } + ], + "conditions": [ + { + "condition": "minecraft:killed_by_player" + } + ] } ] } diff --git a/common/src/main/resources/data/antarchy/loot_table/entities/lurking_terror.json b/common/src/main/resources/data/antarchy/loot_table/entities/lurking_terror.json new file mode 100644 index 00000000..48b83cfa --- /dev/null +++ b/common/src/main/resources/data/antarchy/loot_table/entities/lurking_terror.json @@ -0,0 +1,39 @@ +{ + "type": "minecraft:entity", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "antarchy:chiten", + "functions": [ + { + "function": "minecraft:set_count", + "count": { + "type": "minecraft:uniform", + "min": 1.0, + "max": 2.0 + } + }, + { + "function": "minecraft:enchanted_count_increase", + "enchantment": "minecraft:looting", + "count": { + "type": "minecraft:uniform", + "min": 0.0, + "max": 1.0 + } + } + ] + } + ], + "conditions": [ + { + "condition": "minecraft:killed_by_player" + } + ] + } + ], + "random_sequence": "antarchy:entities/lurking_terror" +} diff --git a/common/src/main/resources/data/antarchy/loot_table/entities/octopus_bomb.json b/common/src/main/resources/data/antarchy/loot_table/entities/octopus_bomb.json new file mode 100644 index 00000000..c66fab67 --- /dev/null +++ b/common/src/main/resources/data/antarchy/loot_table/entities/octopus_bomb.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:entity", + "pools": [ + { + "rolls": { + "type": "minecraft:uniform", + "min": 5, + "max": 10 + }, + "entries": [ + { + "type": "minecraft:item", + "name": "minecraft:ink_sac" + } + ] + } + ] +} diff --git a/common/src/main/resources/data/antarchy/loot_table/entities/toreterror.json b/common/src/main/resources/data/antarchy/loot_table/entities/toreterror.json index ac06c530..8b8512f1 100644 --- a/common/src/main/resources/data/antarchy/loot_table/entities/toreterror.json +++ b/common/src/main/resources/data/antarchy/loot_table/entities/toreterror.json @@ -17,6 +17,7 @@ }, { "function": "minecraft:enchanted_count_increase", + "enchantment": "minecraft:looting", "count": { "type": "minecraft:uniform", "min": 0.0, @@ -51,7 +52,13 @@ "name": "antarchy:water_cannon" } ], + "conditions": [ + { + "condition": "minecraft:killed_by_player" + } + ], "rolls": 1.0 } - ] + ], + "random_sequence": "antarchy:entities/toreterror" } diff --git a/common/src/main/resources/data/antarchy/recipe/bone_meal_from_chiten.json b/common/src/main/resources/data/antarchy/recipe/bone_meal_from_chiten.json new file mode 100644 index 00000000..9f10eac7 --- /dev/null +++ b/common/src/main/resources/data/antarchy/recipe/bone_meal_from_chiten.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + { + "item": "antarchy:chiten" + } + ], + "result": { + "count": 1, + "id": "minecraft:bone_meal" + } +} diff --git a/common/src/main/resources/data/antarchy/recipe/chiten_block.json b/common/src/main/resources/data/antarchy/recipe/chiten_block.json index 31de72bc..b035961a 100644 --- a/common/src/main/resources/data/antarchy/recipe/chiten_block.json +++ b/common/src/main/resources/data/antarchy/recipe/chiten_block.json @@ -7,8 +7,9 @@ } }, "pattern": [ - "##", - "##" + "###", + "###", + "###" ], "result": { "count": 1, diff --git a/common/src/main/resources/data/antarchy/tags/block/amber_moss_replaceable.json b/common/src/main/resources/data/antarchy/tags/block/amber_moss_replaceable.json new file mode 100644 index 00000000..2300979f --- /dev/null +++ b/common/src/main/resources/data/antarchy/tags/block/amber_moss_replaceable.json @@ -0,0 +1,7 @@ +{ + "values": [ + "#minecraft:moss_replaceable", + "antarchy:myrmite", + "antarchy:amber_moss_block" + ] +} diff --git a/common/src/main/resources/data/antarchy/tags/block/umbral_moss_replaceable.json b/common/src/main/resources/data/antarchy/tags/block/umbral_moss_replaceable.json index 943b3b39..dd3155a9 100644 --- a/common/src/main/resources/data/antarchy/tags/block/umbral_moss_replaceable.json +++ b/common/src/main/resources/data/antarchy/tags/block/umbral_moss_replaceable.json @@ -1,5 +1,6 @@ { "values": [ + "#minecraft:moss_replaceable", "antarchy:nyxite", "minecraft:blackstone", "antarchy:umbral_moss_block" diff --git a/common/src/main/resources/data/antarchy/tags/item/multishot_enchantable.json b/common/src/main/resources/data/antarchy/tags/item/multishot_enchantable.json new file mode 100644 index 00000000..6fd60b67 --- /dev/null +++ b/common/src/main/resources/data/antarchy/tags/item/multishot_enchantable.json @@ -0,0 +1,7 @@ +{ + "replace": false, + "values": [ + "#minecraft:enchantable/crossbow", + "antarchy:squidzooka" + ] +} diff --git a/common/src/main/resources/data/antarchy/tags/worldgen/biome/elythia_firefly_particle_biomes.json b/common/src/main/resources/data/antarchy/tags/worldgen/biome/elythia_firefly_particle_biomes.json new file mode 100644 index 00000000..ff348954 --- /dev/null +++ b/common/src/main/resources/data/antarchy/tags/worldgen/biome/elythia_firefly_particle_biomes.json @@ -0,0 +1,10 @@ +{ + "replace": false, + "values": [ + "antarchy:elythia_meadow", + "antarchy:torchflower_fields", + "antarchy:butterfly_fields", + "antarchy:ouranwood_forest", + "antarchy:sparse_ouranwood_forest" + ] +} diff --git a/common/src/main/resources/data/antarchy/tags/worldgen/biome/has_structure/toreterror_arena_biomes.json b/common/src/main/resources/data/antarchy/tags/worldgen/biome/has_structure/toreterror_arena_biomes.json index 91115ca7..b14f7bed 100644 --- a/common/src/main/resources/data/antarchy/tags/worldgen/biome/has_structure/toreterror_arena_biomes.json +++ b/common/src/main/resources/data/antarchy/tags/worldgen/biome/has_structure/toreterror_arena_biomes.json @@ -1,23 +1,6 @@ { "replace": false, "values": [ - "#minecraft:is_ocean", - "#minecraft:is_deep_ocean", - { - "id": "#neoforge:is_ocean", - "required": false - }, - { - "id": "#c:ocean", - "required": false - }, - { - "id": "#c:shallow_ocean", - "required": false - }, - { - "id": "#c:deep_ocean", - "required": false - } + "#antarchy:is_elythia_ocean" ] } diff --git a/common/src/main/resources/data/antarchy/tags/worldgen/biome/is_elythia.json b/common/src/main/resources/data/antarchy/tags/worldgen/biome/is_elythia.json index c0e9fc48..8e11611d 100644 --- a/common/src/main/resources/data/antarchy/tags/worldgen/biome/is_elythia.json +++ b/common/src/main/resources/data/antarchy/tags/worldgen/biome/is_elythia.json @@ -10,6 +10,7 @@ "antarchy:ouranwood_forest", "antarchy:sparse_ouranwood_forest", "antarchy:elythia_ocean", - "antarchy:elythia_beach" + "antarchy:elythia_coral_spikes", + "antarchy:fungal_ouranwood_forest" ] } diff --git a/common/src/main/resources/data/antarchy/tags/worldgen/biome/is_elythia_ocean.json b/common/src/main/resources/data/antarchy/tags/worldgen/biome/is_elythia_ocean.json new file mode 100644 index 00000000..e5dadf26 --- /dev/null +++ b/common/src/main/resources/data/antarchy/tags/worldgen/biome/is_elythia_ocean.json @@ -0,0 +1,7 @@ +{ + "replace": false, + "values": [ + "antarchy:elythia_ocean", + "antarchy:elythia_coral_spikes" + ] +} diff --git a/common/src/main/resources/data/antarchy/worldgen/biome/cavaryn.json b/common/src/main/resources/data/antarchy/worldgen/biome/cavaryn.json index 163759c3..0a5093bc 100644 --- a/common/src/main/resources/data/antarchy/worldgen/biome/cavaryn.json +++ b/common/src/main/resources/data/antarchy/worldgen/biome/cavaryn.json @@ -9,17 +9,16 @@ "sky_color": 524288, "grass_color": 4211262, "foliage_color": 4211262, - "ambient_sound": "minecraft:ambient.cave", "mood_sound": { "sound": "minecraft:ambient.cave", - "tick_delay": 6000, + "tick_delay": 1200000, "block_search_extent": 8, "offset": 2.0 }, "particle": { "probability": 0.002, "options": { - "type": "minecraft:ash" + "type": "antarchy:orange_ash" } } }, @@ -29,106 +28,39 @@ "liquid": [] }, "features": [ - [ - "minecraft:lake_lava_surface" - ], [], - [ - "minecraft:amethyst_geode" - ], - [ - "minecraft:monster_room", - "minecraft:monster_room_deep" - ], + [], + [], + [], + [], + [], [], [], [ - "minecraft:ore_dirt", - "minecraft:ore_gravel", - "minecraft:ore_granite_upper", - "minecraft:ore_granite_lower", - "minecraft:ore_diorite_upper", - "minecraft:ore_diorite_lower", - "minecraft:ore_andesite_upper", - "minecraft:ore_andesite_lower", - "minecraft:ore_tuff", - "minecraft:ore_coal_upper", - "minecraft:ore_coal_lower", - "minecraft:ore_iron_upper", - "minecraft:ore_iron_middle", - "minecraft:ore_iron_small", - "minecraft:ore_gold", - "minecraft:ore_gold_lower", - "minecraft:ore_redstone", - "minecraft:ore_redstone_lower", - "minecraft:ore_diamond", - "minecraft:ore_diamond_medium", - "minecraft:ore_diamond_large", - "minecraft:ore_diamond_buried", - "minecraft:ore_lapis", - "minecraft:ore_lapis_buried", - "minecraft:ore_copper", - "minecraft:underwater_magma" - ], - [ - "minecraft:large_dripstone", - "minecraft:pointed_dripstone", - "minecraft:glow_lichen" - ], - [ - "minecraft:spring_water", - "minecraft:spring_lava" - ], - [ - "minecraft:brown_mushroom_normal", - "minecraft:red_mushroom_normal" + "antarchy:cavaryn_bile_pools", + "antarchy:cavaryn_amber_moss_patch", + "antarchy:cavaryn_wall_amber_moss", + "antarchy:cavaryn_creepvine", + "minecraft:glow_lichen", + "antarchy:cavaryn_chiten_spikes", + "antarchy:cavaryn_terror_egg_patch" ], [] ], - "creature_spawn_probability": 0.08, + "creature_spawn_probability": 0.06, "spawners": { "monster": [ { - "type": "minecraft:zombie", + "type": "antarchy:creeping_horror", "weight": 95, "minCount": 2, - "maxCount": 4 + "maxCount": 5 }, { - "type": "minecraft:skeleton", - "weight": 90, + "type": "antarchy:lurking_terror", + "weight": 95, "minCount": 2, - "maxCount": 4 - }, - { - "type": "minecraft:creeper", - "weight": 80, - "minCount": 1, - "maxCount": 2 - }, - { - "type": "minecraft:spider", - "weight": 70, - "minCount": 1, - "maxCount": 3 - }, - { - "type": "minecraft:cave_spider", - "weight": 45, - "minCount": 1, - "maxCount": 2 - }, - { - "type": "minecraft:enderman", - "weight": 12, - "minCount": 1, - "maxCount": 2 - }, - { - "type": "minecraft:witch", - "weight": 6, - "minCount": 1, - "maxCount": 1 + "maxCount": 5 } ], "creature": [], diff --git a/common/src/main/resources/data/antarchy/worldgen/biome/elythia_coral_spikes.json b/common/src/main/resources/data/antarchy/worldgen/biome/elythia_coral_spikes.json new file mode 100644 index 00000000..6bcaed9f --- /dev/null +++ b/common/src/main/resources/data/antarchy/worldgen/biome/elythia_coral_spikes.json @@ -0,0 +1,77 @@ +{ + "has_precipitation": false, + "temperature": 0.78, + "downfall": 1.0, + "effects": { + "fog_color": 6245375, + "water_color": 3461580, + "water_fog_color": 1741620, + "sky_color": 8084735, + "foliage_color": 2867501, + "grass_color": 4304168, + "grass_color_modifier": "none", + "mood_sound": { + "sound": "minecraft:ambient.underwater.loop", + "tick_delay": 6000, + "block_search_extent": 8, + "offset": 2.0 + } + }, + "spawn_costs": {}, + "carvers": { + "air": [], + "liquid": [] + }, + "features": [ + [], + [], + [], + [], + [], + [], + [ + "minecraft:ore_coal_upper", + "minecraft:ore_coal_lower", + "minecraft:ore_iron_upper", + "minecraft:ore_iron_middle", + "minecraft:ore_iron_small", + "minecraft:ore_gold", + "minecraft:ore_gold_lower", + "minecraft:ore_redstone", + "minecraft:ore_redstone_lower", + "minecraft:ore_diamond", + "minecraft:ore_diamond_medium", + "minecraft:ore_diamond_large", + "minecraft:ore_diamond_buried", + "minecraft:ore_lapis", + "minecraft:ore_lapis_buried", + "minecraft:ore_copper" + ], + [ + "antarchy:elythia_underground" + ], + [], + [ + "antarchy:elythia_coral_spike" + ], + [] + ], + "creature_spawn_probability": 0.04, + "spawners": { + "monster": [ + { "type": "antarchy:missile_squid", "weight": 12, "minCount": 1, "maxCount": 3 }, + { "type": "antarchy:octopus_bomb", "weight": 4, "minCount": 1, "maxCount": 2 } + ], + "creature": [ + { "type": "minecraft:turtle", "weight": 5, "minCount": 1, "maxCount": 2 } + ], + "ambient": [], + "axolotls": [], + "underground_water_creature": [], + "water_creature": [], + "water_ambient": [ + { "type": "minecraft:tropical_fish", "weight": 20, "minCount": 4, "maxCount": 8 } + ], + "misc": [] + } +} diff --git a/common/src/main/resources/data/antarchy/worldgen/biome/elythia_ocean.json b/common/src/main/resources/data/antarchy/worldgen/biome/elythia_ocean.json index 6d1057ec..1aa23185 100644 --- a/common/src/main/resources/data/antarchy/worldgen/biome/elythia_ocean.json +++ b/common/src/main/resources/data/antarchy/worldgen/biome/elythia_ocean.json @@ -51,18 +51,28 @@ "antarchy:elythia_underground" ], [], - [], + [ + "minecraft:sea_pickle", + "minecraft:warm_ocean_vegetation" + ], [] ], "creature_spawn_probability": 0.04, "spawners": { - "monster": [], - "creature": [], + "monster": [ + { "type": "antarchy:missile_squid", "weight": 12, "minCount": 1, "maxCount": 3 }, + { "type": "antarchy:octopus_bomb", "weight": 4, "minCount": 1, "maxCount": 2 } + ], + "creature": [ + { "type": "minecraft:turtle", "weight": 5, "minCount": 1, "maxCount": 2 } + ], "ambient": [], "axolotls": [], "underground_water_creature": [], "water_creature": [], - "water_ambient": [], + "water_ambient": [ + { "type": "minecraft:tropical_fish", "weight": 20, "minCount": 4, "maxCount": 8 } + ], "misc": [] } } diff --git a/common/src/main/resources/data/antarchy/worldgen/configured_feature/amber_moss_patch_bonemeal.json b/common/src/main/resources/data/antarchy/worldgen/configured_feature/amber_moss_patch_bonemeal.json new file mode 100644 index 00000000..0ba3323d --- /dev/null +++ b/common/src/main/resources/data/antarchy/worldgen/configured_feature/amber_moss_patch_bonemeal.json @@ -0,0 +1,27 @@ +{ + "type": "minecraft:vegetation_patch", + "config": { + "depth": 1, + "extra_bottom_block_chance": 0.0, + "extra_edge_column_chance": 0.75, + "ground_state": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "antarchy:amber_moss_block" + } + }, + "replaceable": "#antarchy:amber_moss_replaceable", + "surface": "floor", + "vegetation_chance": 0.6, + "vegetation_feature": { + "feature": "antarchy:amber_moss_vegetation", + "placement": [] + }, + "vertical_range": 5, + "xz_radius": { + "type": "minecraft:uniform", + "max_inclusive": 2, + "min_inclusive": 1 + } + } +} diff --git a/common/src/main/resources/data/antarchy/worldgen/configured_feature/amber_moss_vegetation.json b/common/src/main/resources/data/antarchy/worldgen/configured_feature/amber_moss_vegetation.json new file mode 100644 index 00000000..f99e9268 --- /dev/null +++ b/common/src/main/resources/data/antarchy/worldgen/configured_feature/amber_moss_vegetation.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:simple_block", + "config": { + "to_place": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "antarchy:amber_moss_carpet", + "Properties": { + "bottom": "true", + "east": "none", + "north": "none", + "south": "none", + "west": "none" + } + } + } + } +} diff --git a/common/src/main/resources/data/antarchy/worldgen/configured_feature/cavaryn_bile_pools.json b/common/src/main/resources/data/antarchy/worldgen/configured_feature/cavaryn_bile_pools.json new file mode 100644 index 00000000..e5a8f052 --- /dev/null +++ b/common/src/main/resources/data/antarchy/worldgen/configured_feature/cavaryn_bile_pools.json @@ -0,0 +1,4 @@ +{ + "type": "antarchy:cavaryn_bile_pools", + "config": {} +} diff --git a/common/src/main/resources/data/antarchy/worldgen/configured_feature/cavaryn_chiten_spikes.json b/common/src/main/resources/data/antarchy/worldgen/configured_feature/cavaryn_chiten_spikes.json new file mode 100644 index 00000000..cb963a90 --- /dev/null +++ b/common/src/main/resources/data/antarchy/worldgen/configured_feature/cavaryn_chiten_spikes.json @@ -0,0 +1,18 @@ +{ + "type": "antarchy:cavaryn_chiten_spikes", + "config": { + "floor_to_ceiling_search_range": 10, + "radius": 4, + "max_column_height": 5, + "height_deviation": 1, + "chance_of_column_at_max_distance_from_center": 0.3, + "max_distance_from_center_affecting_chance_of_column": 4, + "max_distance_from_center_affecting_height_bias": 4, + "max_height_difference": 1, + "large_variant_chance": 0.35, + "large_variant_extra_radius": 3, + "large_variant_extra_height": 4, + "large_variant_extra_height_deviation": 2, + "large_variant_surface_spike_multiplier": 2.5 + } +} diff --git a/common/src/main/resources/data/antarchy/worldgen/configured_feature/cavaryn_creepvine.json b/common/src/main/resources/data/antarchy/worldgen/configured_feature/cavaryn_creepvine.json new file mode 100644 index 00000000..13d7a210 --- /dev/null +++ b/common/src/main/resources/data/antarchy/worldgen/configured_feature/cavaryn_creepvine.json @@ -0,0 +1,4 @@ +{ + "type": "antarchy:cavaryn_creepvine", + "config": {} +} diff --git a/common/src/main/resources/data/antarchy/worldgen/configured_feature/cavaryn_terror_egg_patch.json b/common/src/main/resources/data/antarchy/worldgen/configured_feature/cavaryn_terror_egg_patch.json new file mode 100644 index 00000000..76039ff0 --- /dev/null +++ b/common/src/main/resources/data/antarchy/worldgen/configured_feature/cavaryn_terror_egg_patch.json @@ -0,0 +1,4 @@ +{ + "type": "antarchy:cavaryn_terror_egg_patch", + "config": {} +} diff --git a/common/src/main/resources/data/antarchy/worldgen/configured_feature/cavaryn_wall_amber_moss.json b/common/src/main/resources/data/antarchy/worldgen/configured_feature/cavaryn_wall_amber_moss.json new file mode 100644 index 00000000..f06cc5d9 --- /dev/null +++ b/common/src/main/resources/data/antarchy/worldgen/configured_feature/cavaryn_wall_amber_moss.json @@ -0,0 +1,4 @@ +{ + "type": "antarchy:cavaryn_wall_amber_moss", + "config": {} +} diff --git a/common/src/main/resources/data/antarchy/worldgen/configured_feature/elythia_coral_spike.json b/common/src/main/resources/data/antarchy/worldgen/configured_feature/elythia_coral_spike.json new file mode 100644 index 00000000..066a22b9 --- /dev/null +++ b/common/src/main/resources/data/antarchy/worldgen/configured_feature/elythia_coral_spike.json @@ -0,0 +1,4 @@ +{ + "type": "antarchy:elythia_coral_spike", + "config": {} +} diff --git a/common/src/main/resources/data/antarchy/worldgen/density_function/elythia_surface.json b/common/src/main/resources/data/antarchy/worldgen/density_function/elythia_surface.json index f38e2e03..41e29735 100644 --- a/common/src/main/resources/data/antarchy/worldgen/density_function/elythia_surface.json +++ b/common/src/main/resources/data/antarchy/worldgen/density_function/elythia_surface.json @@ -70,7 +70,7 @@ }, "argument2": { "type": "minecraft:mul", - "argument1": 0.20, + "argument1": 0.30, "argument2": "minecraft:overworld/continents" } } diff --git a/common/src/main/resources/data/antarchy/worldgen/noise_settings/cavaryn.json b/common/src/main/resources/data/antarchy/worldgen/noise_settings/cavaryn.json index ccb3ed01..6a197ae1 100644 --- a/common/src/main/resources/data/antarchy/worldgen/noise_settings/cavaryn.json +++ b/common/src/main/resources/data/antarchy/worldgen/noise_settings/cavaryn.json @@ -5,17 +5,17 @@ "ore_veins_enabled": true, "legacy_random_source": false, "default_block": { - "Name": "minecraft:stone" + "Name": "antarchy:myrmite" }, "default_fluid": { - "Name": "minecraft:water", + "Name": "antarchy:bile", "Properties": { "level": "0" } }, "noise": { "min_y": 0, - "height": 256, + "height": 208, "size_horizontal": 1, "size_vertical": 2 }, @@ -80,8 +80,8 @@ }, "argument2": { "type": "minecraft:y_clamped_gradient", - "from_y": 244, - "to_y": 255, + "from_y": 196, + "to_y": 207, "from_value": -0.5, "to_value": 4 } @@ -93,7 +93,7 @@ "type": "minecraft:range_choice", "input": "minecraft:y", "min_inclusive": 4, - "max_exclusive": 252, + "max_exclusive": 204, "when_in_range": "antarchy:cavaryn_custom", "when_out_of_range": 2 } @@ -105,7 +105,7 @@ "type": "minecraft:range_choice", "input": "minecraft:y", "min_inclusive": 0, - "max_exclusive": 256, + "max_exclusive": 208, "when_in_range": { "type": "minecraft:noise", "noise": "minecraft:ore_veininess", @@ -125,13 +125,13 @@ "argument": { "type": "minecraft:interpolated", "argument": { - "type": "minecraft:range_choice", - "input": "minecraft:y", - "min_inclusive": 0, - "max_exclusive": 256, - "when_in_range": { - "type": "minecraft:noise", - "noise": "minecraft:ore_vein_a", + "type": "minecraft:range_choice", + "input": "minecraft:y", + "min_inclusive": 0, + "max_exclusive": 208, + "when_in_range": { + "type": "minecraft:noise", + "noise": "minecraft:ore_vein_a", "xz_scale": 4, "y_scale": 4 }, @@ -144,13 +144,13 @@ "argument": { "type": "minecraft:interpolated", "argument": { - "type": "minecraft:range_choice", - "input": "minecraft:y", - "min_inclusive": 0, - "max_exclusive": 256, - "when_in_range": { - "type": "minecraft:noise", - "noise": "minecraft:ore_vein_b", + "type": "minecraft:range_choice", + "input": "minecraft:y", + "min_inclusive": 0, + "max_exclusive": 208, + "when_in_range": { + "type": "minecraft:noise", + "noise": "minecraft:ore_vein_b", "xz_scale": 4, "y_scale": 4 }, @@ -249,14 +249,14 @@ "then_run": { "type": "minecraft:block", "result_state": { - "Name": "minecraft:deepslate" + "Name": "antarchy:myrmite" } } }, { "type": "minecraft:block", "result_state": { - "Name": "minecraft:stone" + "Name": "antarchy:myrmite" } } ] diff --git a/common/src/main/resources/data/antarchy/worldgen/noise_settings/elythia.json b/common/src/main/resources/data/antarchy/worldgen/noise_settings/elythia.json index ed8be1a9..0b3e9e86 100644 --- a/common/src/main/resources/data/antarchy/worldgen/noise_settings/elythia.json +++ b/common/src/main/resources/data/antarchy/worldgen/noise_settings/elythia.json @@ -484,7 +484,7 @@ "type": "minecraft:condition", "if_true": { "type": "minecraft:biome", - "biome_is": ["antarchy:elythia_ocean"] + "biome_is": ["antarchy:elythia_ocean", "antarchy:elythia_coral_spikes"] }, "then_run": { "type": "minecraft:sequence", @@ -499,8 +499,26 @@ "surface_type": "floor" }, "then_run": { - "type": "minecraft:block", - "result_state": { "Name": "minecraft:gravel" } + "type": "minecraft:sequence", + "sequence": [ + { + "type": "minecraft:condition", + "if_true": { + "type": "minecraft:water", + "offset": 0, + "surface_depth_multiplier": 0, + "add_stone_depth": false + }, + "then_run": { + "type": "minecraft:block", + "result_state": { "Name": "minecraft:gravel" } + } + }, + { + "type": "minecraft:block", + "result_state": { "Name": "minecraft:sand" } + } + ] } }, { @@ -530,6 +548,10 @@ "type": "minecraft:block", "result_state": { "Name": "antarchy:shellstone" } } + }, + { + "type": "minecraft:block", + "result_state": { "Name": "antarchy:shellstone" } } ] } diff --git a/common/src/main/resources/data/antarchy/worldgen/placed_feature/cavaryn_amber_moss_patch.json b/common/src/main/resources/data/antarchy/worldgen/placed_feature/cavaryn_amber_moss_patch.json new file mode 100644 index 00000000..702f99a5 --- /dev/null +++ b/common/src/main/resources/data/antarchy/worldgen/placed_feature/cavaryn_amber_moss_patch.json @@ -0,0 +1,27 @@ +{ + "feature": "antarchy:amber_moss_patch_bonemeal", + "placement": [ + { + "type": "minecraft:count", + "count": 2 + }, + { + "type": "minecraft:in_square" + }, + { + "type": "minecraft:height_range", + "height": { + "type": "minecraft:uniform", + "min_inclusive": { + "above_bottom": 12 + }, + "max_inclusive": { + "below_top": 12 + } + } + }, + { + "type": "minecraft:biome" + } + ] +} diff --git a/common/src/main/resources/data/antarchy/worldgen/placed_feature/cavaryn_bile_pools.json b/common/src/main/resources/data/antarchy/worldgen/placed_feature/cavaryn_bile_pools.json new file mode 100644 index 00000000..f7f99b3a --- /dev/null +++ b/common/src/main/resources/data/antarchy/worldgen/placed_feature/cavaryn_bile_pools.json @@ -0,0 +1,27 @@ +{ + "feature": "antarchy:cavaryn_bile_pools", + "placement": [ + { + "type": "minecraft:count", + "count": 3 + }, + { + "type": "minecraft:in_square" + }, + { + "type": "minecraft:height_range", + "height": { + "type": "minecraft:uniform", + "min_inclusive": { + "above_bottom": 8 + }, + "max_inclusive": { + "below_top": 16 + } + } + }, + { + "type": "minecraft:biome" + } + ] +} diff --git a/common/src/main/resources/data/antarchy/worldgen/placed_feature/cavaryn_chiten_spikes.json b/common/src/main/resources/data/antarchy/worldgen/placed_feature/cavaryn_chiten_spikes.json new file mode 100644 index 00000000..f4e08187 --- /dev/null +++ b/common/src/main/resources/data/antarchy/worldgen/placed_feature/cavaryn_chiten_spikes.json @@ -0,0 +1,27 @@ +{ + "feature": "antarchy:cavaryn_chiten_spikes", + "placement": [ + { + "type": "minecraft:count", + "count": 3 + }, + { + "type": "minecraft:in_square" + }, + { + "type": "minecraft:height_range", + "height": { + "type": "minecraft:uniform", + "min_inclusive": { + "above_bottom": 12 + }, + "max_inclusive": { + "below_top": 12 + } + } + }, + { + "type": "minecraft:biome" + } + ] +} diff --git a/common/src/main/resources/data/antarchy/worldgen/placed_feature/cavaryn_creepvine.json b/common/src/main/resources/data/antarchy/worldgen/placed_feature/cavaryn_creepvine.json new file mode 100644 index 00000000..2f2740bf --- /dev/null +++ b/common/src/main/resources/data/antarchy/worldgen/placed_feature/cavaryn_creepvine.json @@ -0,0 +1,27 @@ +{ + "feature": "antarchy:cavaryn_creepvine", + "placement": [ + { + "type": "minecraft:count", + "count": 9 + }, + { + "type": "minecraft:in_square" + }, + { + "type": "minecraft:height_range", + "height": { + "type": "minecraft:uniform", + "min_inclusive": { + "above_bottom": 12 + }, + "max_inclusive": { + "below_top": 12 + } + } + }, + { + "type": "minecraft:biome" + } + ] +} diff --git a/common/src/main/resources/data/antarchy/worldgen/placed_feature/cavaryn_terror_egg_patch.json b/common/src/main/resources/data/antarchy/worldgen/placed_feature/cavaryn_terror_egg_patch.json new file mode 100644 index 00000000..053fcd8a --- /dev/null +++ b/common/src/main/resources/data/antarchy/worldgen/placed_feature/cavaryn_terror_egg_patch.json @@ -0,0 +1,27 @@ +{ + "feature": "antarchy:cavaryn_terror_egg_patch", + "placement": [ + { + "type": "minecraft:count", + "count": 2 + }, + { + "type": "minecraft:in_square" + }, + { + "type": "minecraft:height_range", + "height": { + "type": "minecraft:uniform", + "min_inclusive": { + "above_bottom": 8 + }, + "max_inclusive": { + "below_top": 16 + } + } + }, + { + "type": "minecraft:biome" + } + ] +} diff --git a/common/src/main/resources/data/antarchy/worldgen/placed_feature/cavaryn_wall_amber_moss.json b/common/src/main/resources/data/antarchy/worldgen/placed_feature/cavaryn_wall_amber_moss.json new file mode 100644 index 00000000..d7c131c3 --- /dev/null +++ b/common/src/main/resources/data/antarchy/worldgen/placed_feature/cavaryn_wall_amber_moss.json @@ -0,0 +1,27 @@ +{ + "feature": "antarchy:cavaryn_wall_amber_moss", + "placement": [ + { + "type": "minecraft:count", + "count": 10 + }, + { + "type": "minecraft:in_square" + }, + { + "type": "minecraft:height_range", + "height": { + "type": "minecraft:uniform", + "min_inclusive": { + "above_bottom": 12 + }, + "max_inclusive": { + "below_top": 12 + } + } + }, + { + "type": "minecraft:biome" + } + ] +} diff --git a/common/src/main/resources/data/antarchy/worldgen/placed_feature/elythia_coral_spike.json b/common/src/main/resources/data/antarchy/worldgen/placed_feature/elythia_coral_spike.json new file mode 100644 index 00000000..e6757d38 --- /dev/null +++ b/common/src/main/resources/data/antarchy/worldgen/placed_feature/elythia_coral_spike.json @@ -0,0 +1,12 @@ +{ + "feature": "antarchy:elythia_coral_spike", + "placement": [ + { + "type": "minecraft:heightmap", + "heightmap": "OCEAN_FLOOR_WG" + }, + { + "type": "minecraft:biome" + } + ] +} diff --git a/common/src/main/resources/data/antarchy/worldgen/structure/toreterror_arena.json b/common/src/main/resources/data/antarchy/worldgen/structure/toreterror_arena.json index 43c1d56e..834c19a1 100644 --- a/common/src/main/resources/data/antarchy/worldgen/structure/toreterror_arena.json +++ b/common/src/main/resources/data/antarchy/worldgen/structure/toreterror_arena.json @@ -2,7 +2,7 @@ "type": "integrated_api:generic_structure", "start_pool": "antarchy:toreterror_arena/toreterror_arena", "size": 2, - "valid_biome_radius_check": 1, + "valid_biome_radius_check": 5, "biomes": "#antarchy:has_structure/toreterror_arena_biomes", "step": "surface_structures", "terrain_adaptation": "none", diff --git a/common/src/main/resources/data/minecraft/tags/block/mineable/pickaxe.json b/common/src/main/resources/data/minecraft/tags/block/mineable/pickaxe.json index 8cfab94f..71f8d9f6 100644 --- a/common/src/main/resources/data/minecraft/tags/block/mineable/pickaxe.json +++ b/common/src/main/resources/data/minecraft/tags/block/mineable/pickaxe.json @@ -38,6 +38,7 @@ "antarchy:nyxite_brick_wall", "antarchy:myrmite", "antarchy:chiten_block", + "antarchy:chiten_spike", "antarchy:shellstone", "antarchy:polished_shellstone", "antarchy:shellstone_bricks", diff --git a/common/src/main/resources/data/minecraft/tags/item/enchantable/crossbow.json b/common/src/main/resources/data/minecraft/tags/item/enchantable/crossbow.json index 3038abd6..d0458b36 100644 --- a/common/src/main/resources/data/minecraft/tags/item/enchantable/crossbow.json +++ b/common/src/main/resources/data/minecraft/tags/item/enchantable/crossbow.json @@ -1,7 +1,6 @@ { "replace": false, "values": [ - "antarchy:ultimate_crossbow", - "antarchy:squidzooka" + "antarchy:ultimate_crossbow" ] } diff --git a/common/src/main/resources/data/minecraft/tags/worldgen/biome/is_overworld.json b/common/src/main/resources/data/minecraft/tags/worldgen/biome/is_overworld.json deleted file mode 100644 index bf1b47a2..00000000 --- a/common/src/main/resources/data/minecraft/tags/worldgen/biome/is_overworld.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "replace": false, - "values": [ - "antarchy:cavaryn" - ] -} diff --git a/fabric/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabricContent.java b/fabric/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabricContent.java index 6eb1302c..6e6147d5 100644 --- a/fabric/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabricContent.java +++ b/fabric/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabricContent.java @@ -14,10 +14,14 @@ import com.craisinlord.antarchy.content.block.entity.DreamCampfireBlockEntity; import com.craisinlord.antarchy.content.block.entity.HushweedBlockEntity; import com.craisinlord.antarchy.content.block.entity.PotentNyxiteBlockEntity; import com.craisinlord.antarchy.content.block.entity.WaspNestBlockEntity; +import com.craisinlord.antarchy.content.fluid.BileLiquidBlock; import com.craisinlord.antarchy.content.worldgen.ants.BrownAntNestFeature; import com.craisinlord.antarchy.content.worldgen.ants.RainbowAntNestFeature; import com.craisinlord.antarchy.content.worldgen.ants.RedAntNestFeature; import com.craisinlord.antarchy.content.worldgen.ants.TermiteNestFeature; +import com.craisinlord.antarchy.content.worldgen.cavaryn.CavarynBilePoolFeature; +import com.craisinlord.antarchy.content.worldgen.cavaryn.CavarynCreepvineFeature; +import com.craisinlord.antarchy.content.worldgen.cavaryn.CavarynWallAmberMossFeature; import com.craisinlord.antarchy.content.worldgen.thoraxis.NyxiteSpikeConfiguration; import com.craisinlord.antarchy.content.worldgen.thoraxis.AntiwaterSpringsConfiguration; import com.craisinlord.antarchy.content.worldgen.thoraxis.AntiwaterSpringsFeature; @@ -118,6 +122,7 @@ import com.craisinlord.antarchy.content.item.NightmareSwordItem; import com.craisinlord.antarchy.content.item.OuranwoodBoatOnlyItem; import com.craisinlord.antarchy.content.item.OuranwoodChestBoatItem; import com.craisinlord.antarchy.content.item.RainbowSugarItem; +import com.craisinlord.antarchy.content.worldgen.elythia.CoralSpikeFeature; import com.craisinlord.antarchy.content.worldgen.elythia.ElythiaBiomeSource; import com.craisinlord.antarchy.content.worldgen.elythia.ElythiaRiverCarveFunction; import com.craisinlord.antarchy.content.worldgen.elythia.ElythiaFloraFeature; @@ -135,6 +140,9 @@ import com.craisinlord.antarchy.content.worldgen.elythia.OuranwoodCocoonTreeFeat import com.craisinlord.antarchy.content.worldgen.elythia.OuranwoodTreeConfiguration; import com.craisinlord.antarchy.content.worldgen.elythia.OuranwoodTreeFeature; import com.craisinlord.antarchy.content.worldgen.elythia.TriffidPatchFeature; +import com.craisinlord.antarchy.content.worldgen.cavaryn.CavarynEggPatchFeature; +import com.craisinlord.antarchy.content.worldgen.cavaryn.ChitenSpikeConfiguration; +import com.craisinlord.antarchy.content.worldgen.cavaryn.ChitenSpikeFeature; import com.craisinlord.antarchy.content.worldgen.thoraxis.BedBugNestFeature; import com.craisinlord.antarchy.content.worldgen.thoraxis.BedBugSurfaceClusterFeature; import com.craisinlord.antarchy.content.worldgen.thoraxis.CloudSeaCalciteFeature; @@ -584,6 +592,8 @@ public final class AntarchyFabricContent { () -> new Block(nyxiteProperties())); public static final DeferredBlock NYXITE_SPIKE = BLOCKS.register("nyxite_spike", () -> new NyxiteSpikeBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.POINTED_DRIPSTONE))); + public static final DeferredBlock CHITEN_SPIKE = BLOCKS.register("chiten_spike", + () -> new ChitenSpikeBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.POINTED_DRIPSTONE))); public static final DeferredBlock POTENT_NYXITE = BLOCKS.register("potent_nyxite", () -> new PotentNyxiteBlock( AntarchyFabricContent::potentNyxiteBlockEntityType, @@ -619,6 +629,8 @@ public final class AntarchyFabricContent { () -> simpleParticleType()); public static final DeferredHolder, SimpleParticleType> FIREFLY = PARTICLE_TYPES.register("firefly", () -> simpleParticleType()); + public static final DeferredHolder, SimpleParticleType> ORANGE_ASH = PARTICLE_TYPES.register("orange_ash", + () -> simpleParticleType()); public static final DeferredHolder, ParticleType> INVERTED_GEYSER_BASE = PARTICLE_TYPES.register("inverted_geyser_base", () -> particleType(InvertedGeyserBaseParticleOptions::codec, InvertedGeyserBaseParticleOptions::streamCodec)); public static final DeferredHolder, ParticleType> INVERTED_GEYSER_PLUME = PARTICLE_TYPES.register("inverted_geyser_plume", @@ -712,6 +724,29 @@ public final class AntarchyFabricContent { () -> new Potion("growing", new MobEffectInstance(mobEffectHolder(GROWTH_EFFECT), 900, 1))); public static final DeferredHolder EXTREME_GROWING = POTIONS.register("extreme_growing", () -> new Potion("growing", new MobEffectInstance(mobEffectHolder(GROWTH_EFFECT), 600, 2))); + public static final DeferredHolder BILE = FLUIDS.register("bile", + () -> new com.craisinlord.antarchy.fabric.content.fluid.SimpleFluid.Source( + () -> lookupFlowingFluid("bile"), + () -> lookupFlowingFluid("flowing_bile"), + () -> lookupItem("bile_bucket"), + "bile", + 4, + 1, + 5 + )); + public static final DeferredHolder FLOWING_BILE = FLUIDS.register("flowing_bile", + () -> new com.craisinlord.antarchy.fabric.content.fluid.SimpleFluid.Flowing( + () -> lookupFlowingFluid("bile"), + () -> lookupFlowingFluid("flowing_bile"), + () -> lookupItem("bile_bucket"), + "bile", + 4, + 1, + 5 + )); + public static final DeferredBlock BILE_BLOCK = BLOCKS.register("bile", + () -> new BileLiquidBlock((net.minecraft.world.level.material.FlowingFluid) BILE.get(), BlockBehaviour.Properties.ofFullCopy(Blocks.WATER).lightLevel(state -> 5).noLootTable())); + public static final DeferredHolder ICHOR = FLUIDS.register("ichor", () -> new com.craisinlord.antarchy.fabric.content.fluid.SimpleFluid.Source( () -> lookupFlowingFluid("ichor"), @@ -1023,6 +1058,14 @@ public final class AntarchyFabricContent { () -> new ThoraxisSpikeFeature(ThoraxisSpikeConfiguration.CODEC)); public static final DeferredHolder, NyxiteSpikeFeature> NYXITE_SPIKES = FEATURES.register("nyxite_spikes", () -> new NyxiteSpikeFeature(NyxiteSpikeConfiguration.CODEC)); + public static final DeferredHolder, ChitenSpikeFeature> CAVARYN_CHITEN_SPIKES = FEATURES.register("cavaryn_chiten_spikes", + () -> new ChitenSpikeFeature(ChitenSpikeConfiguration.CODEC)); + public static final DeferredHolder, CavarynBilePoolFeature> CAVARYN_BILE_POOLS = FEATURES.register("cavaryn_bile_pools", + () -> new CavarynBilePoolFeature(NoneFeatureConfiguration.CODEC)); + public static final DeferredHolder, CavarynCreepvineFeature> CAVARYN_CREEPVINE = FEATURES.register("cavaryn_creepvine", + () -> new CavarynCreepvineFeature(NoneFeatureConfiguration.CODEC)); + public static final DeferredHolder, CavarynWallAmberMossFeature> CAVARYN_WALL_AMBER_MOSS = FEATURES.register("cavaryn_wall_amber_moss", + () -> new CavarynWallAmberMossFeature(NoneFeatureConfiguration.CODEC)); public static final DeferredHolder, AntiwaterSpringsFeature> ANTIWATER_SPRINGS = FEATURES.register("antiwater_springs", () -> new AntiwaterSpringsFeature(AntiwaterSpringsConfiguration.CODEC)); public static final DeferredHolder, PotentNyxiteFeature> POTENT_NYXITE_FEATURE = FEATURES.register("potent_nyxite", @@ -1035,12 +1078,20 @@ public final class AntarchyFabricContent { () -> new BedBugNestFeature(NoneFeatureConfiguration.CODEC)); public static final DeferredHolder, BedBugSurfaceClusterFeature> BED_BUG_SURFACE_CLUSTER = FEATURES.register("bed_bug_surface_cluster", () -> new BedBugSurfaceClusterFeature(NoneFeatureConfiguration.CODEC)); + public static final DeferredHolder, CavarynEggPatchFeature> CAVARYN_TERROR_EGG_PATCH = FEATURES.register("cavaryn_terror_egg_patch", + () -> new CavarynEggPatchFeature(NoneFeatureConfiguration.CODEC)); public static final DeferredHolder, ThoraxisAntiwaterPoolFeature> THORAXIS_ANTIWATER_POOL = FEATURES.register("thoraxis_antiwater_pool", () -> new ThoraxisAntiwaterPoolFeature(ThoraxisAntiwaterPoolConfiguration.CODEC)); public static final DeferredHolder, LucidAntiwaterPoolFeature> LUCID_ANTIWATER_POOL = FEATURES.register("lucid_antiwater_pool", () -> new LucidAntiwaterPoolFeature(ThoraxisAntiwaterPoolConfiguration.CODEC)); public static final DeferredHolder, ThoraxisDuneFeature> THORAXIS_DUNE = FEATURES.register("thoraxis_dune", () -> new ThoraxisDuneFeature(ThoraxisDuneConfiguration.CODEC)); + public static final DeferredHolder, CoralSpikeFeature> ELYTHIA_CORAL_SPIKE = FEATURES.register("elythia_coral_spike", + () -> new CoralSpikeFeature(NoneFeatureConfiguration.CODEC)); + public static final DeferredHolder, com.craisinlord.antarchy.content.worldgen.elythia.FallenOuranwoodFeature> FALLEN_OURANWOOD_TREE = FEATURES.register("fallen_ouranwood_tree", + () -> new com.craisinlord.antarchy.content.worldgen.elythia.FallenOuranwoodFeature(NoneFeatureConfiguration.CODEC)); + public static final DeferredHolder, com.craisinlord.antarchy.content.worldgen.elythia.FungalMushroomFeature> FUNGAL_MUSHROOM = FEATURES.register("fungal_mushroom", + () -> new com.craisinlord.antarchy.content.worldgen.elythia.FungalMushroomFeature(NoneFeatureConfiguration.CODEC)); public static final DeferredHolder, MapCodec> THORAXIS_BIOME_SOURCE = BIOME_SOURCES.register("thoraxis_biome_source", () -> ThoraxisBiomeSource.CODEC); @@ -1185,6 +1236,8 @@ public final class AntarchyFabricContent { public static final DeferredItem BED_BUG_EGG_ITEM = ITEMS.registerSimpleBlockItem(BED_BUG_EGG); public static final DeferredItem WASP_NEST_ITEM = ITEMS.registerSimpleBlockItem(WASP_NEST); public static final DeferredItem HUSHWEED_ITEM = ITEMS.registerSimpleBlockItem(HUSHWEED); + public static final DeferredItem BILE_BUCKET = ITEMS.register("bile_bucket", + () -> new BucketItem(BILE.get(), new Item.Properties().craftRemainder(Items.BUCKET).stacksTo(1))); public static final DeferredItem ICHOR_BUCKET = ITEMS.register("ichor_bucket", () -> new BucketItem(ICHOR.get(), new Item.Properties().craftRemainder(Items.BUCKET).stacksTo(1))); public static final DeferredItem ANTIWATER_BUCKET = ITEMS.register("antiwater_bucket", @@ -1223,6 +1276,7 @@ public final class AntarchyFabricContent { public static final DeferredItem QUEEN_SCALE = ITEMS.register("queen_scale", () -> new MobComingSoonTooltipItem(new Item.Properties().rarity(Rarity.RARE))); public static final DeferredItem CHITEN = ITEMS.registerSimpleItem("chiten", new Item.Properties().rarity(Rarity.UNCOMMON)); + public static final DeferredItem CHITEN_SPIKE_ITEM = ITEMS.registerSimpleBlockItem(CHITEN_SPIKE); public static final DeferredItem STINK_BUG_ITEM = ITEMS.registerSimpleItem("stink_bug", new Item.Properties().rarity(Rarity.UNCOMMON)); public static final DeferredItem JUMPY_BUG_LEG = ITEMS.registerSimpleItem("jumpy_bug_leg", new Item.Properties().rarity(Rarity.UNCOMMON)); private static final DeferredHolder JUMPY_BOOTS_ARMOR_MATERIAL = ARMOR_MATERIALS.register("jumpy_boots", @@ -1854,6 +1908,8 @@ public final class AntarchyFabricContent { SpawnPlacements.register(BASILISK.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, BasiliskEntity::canSpawn); SpawnPlacements.register(EMPEROR_SCORPION.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EmperorScorpionEntity::canSpawn); SpawnPlacements.register(TORETERROR.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, ToreterrorEntity::canSpawn); + SpawnPlacements.register(CREEPING_HORROR.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, CreepingHorrorEntity::canSpawn); + SpawnPlacements.register(LURKING_TERROR.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, LurkingTerrorEntity::canSpawn); SpawnPlacements.register(TERMITE.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, net.minecraft.world.entity.animal.Animal::checkAnimalSpawnRules); } @@ -1930,7 +1986,7 @@ public final class AntarchyFabricContent { case "blood_crystal_block", "budding_blood_crystal", "small_blood_crystal_bud", "medium_blood_crystal_bud", "large_blood_crystal_bud", "blood_crystal_cluster" -> 7; - case "myrmite", "chiten_block", "amber_moss_block", "amber_moss_carpet" -> 8; + case "myrmite", "chiten_block", "chiten_spike", "amber_moss_block", "amber_moss_carpet" -> 8; case "uranium_ore", "deepslate_uranium_ore", "titanium_ore", "deepslate_titanium_ore", "uranium_block", "titanium_block", "raw_uranium_block", "raw_titanium_block", "cut_uranium", "cut_titanium", "cut_uranium_slab", "cut_titanium_slab", @@ -1939,7 +1995,7 @@ public final class AntarchyFabricContent { "uranium_door", "titanium_door", "uranium_trapdoor", "titanium_trapdoor", "uranium_bars", "titanium_bars" -> 8; case "infested_rooted_dirt", "infested_coarse_dirt", "triffid_goo_block", - "cloud_block" -> 9; + "cloud_block", "creeping_horror_egg", "lurking_terror_egg" -> 9; case "dream_torch", "dream_lantern", "dream_campfire", "dream_fire", "dream_fire_ceiling" -> 10; case "easter_bunny_spawn_egg", "flying_squirrel_spawn_egg", "caterpillar_spawn_egg", "butterfly_spawn_egg", "reverie_spawn_egg", "brutalfly_spawn_egg", @@ -2401,6 +2457,8 @@ public final class AntarchyFabricContent { () -> TRIFFID_GOO_BLOCK.get(), () -> PALE_NYXITE.get(), () -> NYXITE_SPIKE.get(), + () -> CHITEN_BLOCK.get(), + () -> CHITEN_SPIKE.get(), () -> POTENT_NYXITE.get(), () -> ANTIMETAL.get(), () -> POLISHED_ANTIMETAL.get(), diff --git a/fabric/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClientBootstrap.java b/fabric/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClientBootstrap.java index 48130010..bf0241bb 100644 --- a/fabric/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClientBootstrap.java +++ b/fabric/src/main/java/com/craisinlord/antarchy/fabric/client/AntarchyFabricClientBootstrap.java @@ -127,6 +127,17 @@ public final class AntarchyFabricClientBootstrap { } private static void registerFluids() { + FluidRenderHandlerRegistry.INSTANCE.register( + AntarchyFabricContent.BILE.get(), + AntarchyFabricContent.FLOWING_BILE.get(), + new SimpleFluidRenderHandler( + ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "block/bile/bile_still"), + ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "block/bile/bile_flowing"), + ResourceLocation.withDefaultNamespace("block/water_overlay"), + 0xFFFFFFFF + ) + ); + FluidRenderHandlerRegistry.INSTANCE.register( AntarchyFabricContent.ICHOR.get(), AntarchyFabricContent.FLOWING_ICHOR.get(), @@ -179,6 +190,7 @@ public final class AntarchyFabricClientBootstrap { registry.register(AntarchyFabricContent.INVERTED_GEYSER_POOF.get(), InvertedGeyserBaseParticle.Provider::new); registry.register(AntarchyFabricContent.INVERTED_GEYSER_ERUPTION.get(), new InvertedGeyserEruptionParticle.Provider()); registry.register(AntarchyFabricContent.FIREFLY.get(), FireflyParticle.Provider::new); + registry.register(AntarchyFabricContent.ORANGE_ASH.get(), OrangeAshParticle.Provider::new); } private static void registerRenderLayers() { @@ -199,6 +211,7 @@ public final class AntarchyFabricClientBootstrap { BlockRenderLayerMap.INSTANCE.putBlock(AntarchyFabricContent.AMBER_LICHEN.get(), RenderType.cutout()); BlockRenderLayerMap.INSTANCE.putBlock(AntarchyFabricContent.CREEPVINE.get(), RenderType.cutout()); BlockRenderLayerMap.INSTANCE.putBlock(AntarchyFabricContent.NYXITE_SPIKE.get(), RenderType.cutout()); + BlockRenderLayerMap.INSTANCE.putBlock(AntarchyFabricContent.CHITEN_SPIKE.get(), RenderType.cutout()); BlockRenderLayerMap.INSTANCE.putBlock(AntarchyFabricContent.SMALL_BLOOD_CRYSTAL_BUD.get(), RenderType.cutout()); BlockRenderLayerMap.INSTANCE.putBlock(AntarchyFabricContent.MEDIUM_BLOOD_CRYSTAL_BUD.get(), RenderType.cutout()); BlockRenderLayerMap.INSTANCE.putBlock(AntarchyFabricContent.LARGE_BLOOD_CRYSTAL_BUD.get(), RenderType.cutout()); @@ -220,6 +233,8 @@ public final class AntarchyFabricClientBootstrap { BlockRenderLayerMap.INSTANCE.putBlock(AntarchyFabricContent.CLOUD_BLOCK.get(), RenderType.translucent()); BlockRenderLayerMap.INSTANCE.putFluids( RenderType.translucent(), + AntarchyFabricContent.BILE.get(), + AntarchyFabricContent.FLOWING_BILE.get(), AntarchyFabricContent.ICHOR.get(), AntarchyFabricContent.FLOWING_ICHOR.get(), AntarchyFabricContent.ANTIWATER.get(), diff --git a/fabric/src/main/java/com/craisinlord/antarchy/fabric/client/ElythiaFireflyManager.java b/fabric/src/main/java/com/craisinlord/antarchy/fabric/client/ElythiaFireflyManager.java index 1a813793..b436f125 100644 --- a/fabric/src/main/java/com/craisinlord/antarchy/fabric/client/ElythiaFireflyManager.java +++ b/fabric/src/main/java/com/craisinlord/antarchy/fabric/client/ElythiaFireflyManager.java @@ -1,6 +1,7 @@ package com.craisinlord.antarchy.fabric.client; import com.craisinlord.antarchy.config.AntarchySettings; +import com.craisinlord.antarchy.content.AntarchyTags; import com.craisinlord.antarchy.content.AntarchySoundEvents; import com.craisinlord.antarchy.content.client.renderer.ElythiaSkyRenderer; import com.craisinlord.antarchy.fabric.AntarchyFabricContent; @@ -36,8 +37,9 @@ public final class ElythiaFireflyManager { if (dayTime < NIGHT_START || dayTime > NIGHT_END) return; long gameTime = level.getGameTime(); + boolean fireflyBiome = level.getBiome(client.player.blockPosition()).is(AntarchyTags.Biomes.ELYTHIA_FIREFLY_PARTICLE_BIOMES); - if (AntarchySettings.elythiaFireflyParticlesEnabled()) { + if (AntarchySettings.elythiaFireflyParticlesEnabled() && fireflyBiome) { if (gameTime % SPAWN_INTERVAL == 0) { Player player = client.player; int px = (int) player.getX(); diff --git a/fabric/src/main/java/com/craisinlord/antarchy/fabric/client/JumpyBootsClientHandler.java b/fabric/src/main/java/com/craisinlord/antarchy/fabric/client/JumpyBootsClientHandler.java index 9a410f2b..1c3a31a9 100644 --- a/fabric/src/main/java/com/craisinlord/antarchy/fabric/client/JumpyBootsClientHandler.java +++ b/fabric/src/main/java/com/craisinlord/antarchy/fabric/client/JumpyBootsClientHandler.java @@ -53,6 +53,12 @@ public final class JumpyBootsClientHandler { return; } + if (jumpPressed && wasCharging && chargeTicks > 0) { + ClientPlayNetworking.send(new JumpyBootsLaunchPayload(chargeTicks, player.isSprinting())); + reset(); + return; + } + if (sneaking) { chargeTicks = Math.min(chargeTicks + 1, JumpyBootsHelper.CHARGE_TICKS_MAX); wasCharging = true; diff --git a/fabric/src/main/java/com/craisinlord/antarchy/fabric/mixin/ElytraStartFlyingMixin.java b/fabric/src/main/java/com/craisinlord/antarchy/fabric/mixin/ElytraStartFlyingMixin.java index 4ed20662..25421931 100644 --- a/fabric/src/main/java/com/craisinlord/antarchy/fabric/mixin/ElytraStartFlyingMixin.java +++ b/fabric/src/main/java/com/craisinlord/antarchy/fabric/mixin/ElytraStartFlyingMixin.java @@ -16,7 +16,7 @@ public abstract class ElytraStartFlyingMixin { @Shadow public abstract void startFallFlying(); - @Inject(method = "tryToStartFallFlying", at = @At("RETURN"), cancellable = true) + @Inject(method = "tryToStartFallFlying()Z", at = @At("RETURN"), cancellable = true) private void antarchy$allowCustomElytra(CallbackInfoReturnable cir) { if (cir.getReturnValue()) return; Player player = (Player) (Object) this; diff --git a/fabric/src/main/resources/assets/antarchy/models/item/bile_bucket.json b/fabric/src/main/resources/assets/antarchy/models/item/bile_bucket.json new file mode 100644 index 00000000..30a26675 --- /dev/null +++ b/fabric/src/main/resources/assets/antarchy/models/item/bile_bucket.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "antarchy:item/bile_bucket" + } +} diff --git a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyNeoForgeFluidTypes.java b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyNeoForgeFluidTypes.java index fdea9f54..d66a0714 100644 --- a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyNeoForgeFluidTypes.java +++ b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyNeoForgeFluidTypes.java @@ -25,6 +25,16 @@ public final class AntarchyNeoForgeFluidTypes { .density(1000) .viscosity(1000))); + public static final DeferredHolder BILE_TYPE = FLUID_TYPES.register("bile", + () -> new FluidType(FluidType.Properties.create() + .descriptionId("block.antarchy.bile") + .fallDistanceModifier(0.0F) + .supportsBoating(true) + .sound(SoundActions.BUCKET_FILL, SoundEvents.BUCKET_FILL) + .sound(SoundActions.BUCKET_EMPTY, SoundEvents.BUCKET_EMPTY) + .density(1100) + .viscosity(1200))); + public static final DeferredHolder ICHOR_TYPE = FLUID_TYPES.register("ichor", () -> new FluidType(FluidType.Properties.create() .descriptionId("block.antarchy.ichor") diff --git a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyNeoforge.java b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyNeoforge.java index 92e197d5..b8869f66 100644 --- a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyNeoforge.java +++ b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyNeoforge.java @@ -214,6 +214,8 @@ public class AntarchyNeoforge { () -> AntarchyNeoforgeBlocks.TRIFFID_GOO_BLOCK.get(), () -> AntarchyNeoforgeBlocks.PALE_NYXITE.get(), () -> AntarchyNeoforgeBlocks.NYXITE_SPIKE.get(), + () -> AntarchyNeoforgeBlocks.CHITEN_BLOCK.get(), + () -> AntarchyNeoforgeBlocks.CHITEN_SPIKE.get(), () -> AntarchyNeoforgeBlocks.POTENT_NYXITE.get(), () -> AntarchyNeoforgeBlocks.ANTIMETAL.get(), () -> AntarchyNeoforgeBlocks.POLISHED_ANTIMETAL.get(), diff --git a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/client/AntarchyNeoForgeClient.java b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/client/AntarchyNeoForgeClient.java index 3ea56095..aa9aba07 100644 --- a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/client/AntarchyNeoForgeClient.java +++ b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/client/AntarchyNeoForgeClient.java @@ -72,6 +72,8 @@ public final class AntarchyNeoForgeClient { private static final ResourceLocation UNDERWATER_OVERLAY = ResourceLocation.withDefaultNamespace("textures/misc/underwater.png"); private static final ResourceLocation ANTIWATER_STILL = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "block/antiwater_still"); private static final ResourceLocation ANTIWATER_FLOW = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "block/antiwater_flow"); + private static final ResourceLocation BILE_STILL = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "block/bile/bile_still"); + private static final ResourceLocation BILE_FLOW = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "block/bile/bile_flowing"); private AntarchyNeoForgeClient() { } @@ -207,6 +209,7 @@ public final class AntarchyNeoForgeClient { event.registerSpriteSet(AntarchyNeoforgeMisc.INVERTED_GEYSER_POOF.get(), InvertedGeyserBaseParticle.Provider::new); event.registerSpecial(AntarchyNeoforgeMisc.INVERTED_GEYSER_ERUPTION.get(), new InvertedGeyserEruptionParticle.Provider()); event.registerSpriteSet(AntarchyNeoforgeMisc.FIREFLY.get(), FireflyParticle.Provider::new); + event.registerSpriteSet(AntarchyNeoforgeMisc.ORANGE_ASH.get(), OrangeAshParticle.Provider::new); } @SubscribeEvent @@ -284,6 +287,38 @@ public final class AntarchyNeoForgeClient { } }, AntarchyNeoForgeFluidTypes.ICHOR_TYPE.get()); + event.registerFluidType(new IClientFluidTypeExtensions() { + @Override + public ResourceLocation getStillTexture() { + return BILE_STILL; + } + + @Override + public ResourceLocation getFlowingTexture() { + return BILE_FLOW; + } + + @Override + public ResourceLocation getOverlayTexture() { + return WATER_OVERLAY; + } + + @Override + public ResourceLocation getRenderOverlayTexture(Minecraft mc) { + return UNDERWATER_OVERLAY; + } + + @Override + public int getTintColor() { + return 0xFFFFFFFF; + } + + @Override + public int getTintColor(FluidState state, BlockAndTintGetter getter, net.minecraft.core.BlockPos pos) { + return 0xFFFFFFFF; + } + }, AntarchyNeoForgeFluidTypes.BILE_TYPE.get()); + event.registerFluidType(new IClientFluidTypeExtensions() { @Override public ResourceLocation getStillTexture() { @@ -364,6 +399,7 @@ public final class AntarchyNeoForgeClient { ItemBlockRenderTypes.setRenderLayer(AntarchyNeoforgeBlocks.AMBER_LICHEN.get(), RenderType.cutout()); ItemBlockRenderTypes.setRenderLayer(AntarchyNeoforgeBlocks.CREEPVINE.get(), RenderType.cutout()); ItemBlockRenderTypes.setRenderLayer(AntarchyNeoforgeBlocks.NYXITE_SPIKE.get(), RenderType.cutout()); + ItemBlockRenderTypes.setRenderLayer(AntarchyNeoforgeBlocks.CHITEN_SPIKE.get(), RenderType.cutout()); ItemBlockRenderTypes.setRenderLayer(AntarchyNeoforgeBlocks.SMALL_BLOOD_CRYSTAL_BUD.get(), RenderType.cutout()); ItemBlockRenderTypes.setRenderLayer(AntarchyNeoforgeBlocks.MEDIUM_BLOOD_CRYSTAL_BUD.get(), RenderType.cutout()); ItemBlockRenderTypes.setRenderLayer(AntarchyNeoforgeBlocks.LARGE_BLOOD_CRYSTAL_BUD.get(), RenderType.cutout()); diff --git a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/client/ElythiaFireflyManager.java b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/client/ElythiaFireflyManager.java index f0fc69f1..2fa8339b 100644 --- a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/client/ElythiaFireflyManager.java +++ b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/client/ElythiaFireflyManager.java @@ -2,6 +2,7 @@ package com.craisinlord.antarchy.neoforge.client; import com.craisinlord.antarchy.Antarchy; import com.craisinlord.antarchy.config.AntarchySettings; +import com.craisinlord.antarchy.content.AntarchyTags; import com.craisinlord.antarchy.content.AntarchySoundEvents; import com.craisinlord.antarchy.content.client.renderer.ElythiaSkyRenderer; import com.craisinlord.antarchy.neoforge.registry.AntarchyNeoforgeMisc; @@ -42,8 +43,9 @@ public final class ElythiaFireflyManager { if (dayTime < NIGHT_START || dayTime > NIGHT_END) return; long gameTime = level.getGameTime(); + boolean fireflyBiome = level.getBiome(mc.player.blockPosition()).is(AntarchyTags.Biomes.ELYTHIA_FIREFLY_PARTICLE_BIOMES); - if (AntarchySettings.elythiaFireflyParticlesEnabled()) { + if (AntarchySettings.elythiaFireflyParticlesEnabled() && fireflyBiome) { if (gameTime % SPAWN_INTERVAL == 0) { Player player = mc.player; int px = (int) player.getX(); diff --git a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/client/JumpyBootsClientHandler.java b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/client/JumpyBootsClientHandler.java index 048f69a1..be7d4a50 100644 --- a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/client/JumpyBootsClientHandler.java +++ b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/client/JumpyBootsClientHandler.java @@ -62,6 +62,12 @@ public final class JumpyBootsClientHandler { return; } + if (jumpPressed && wasCharging && chargeTicks > 0) { + PacketDistributor.sendToServer(new JumpyBootsLaunchPayload(chargeTicks, player.isSprinting())); + reset(); + return; + } + if (sneaking) { chargeTicks = Math.min(chargeTicks + 1, JumpyBootsHelper.CHARGE_TICKS_MAX); wasCharging = true; diff --git a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeBlocks.java b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeBlocks.java index 6f0bef7a..4f6cd7a1 100644 --- a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeBlocks.java +++ b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeBlocks.java @@ -11,6 +11,7 @@ import com.craisinlord.antarchy.content.block.entity.DreamCampfireBlockEntity; import com.craisinlord.antarchy.content.block.entity.HushweedBlockEntity; import com.craisinlord.antarchy.content.block.entity.PotentNyxiteBlockEntity; import com.craisinlord.antarchy.content.block.entity.WaspNestBlockEntity; +import com.craisinlord.antarchy.content.fluid.BileLiquidBlock; import com.craisinlord.antarchy.neoforge.OuranwoodWoodTypes; import com.craisinlord.antarchy.neoforge.content.fluid.AntiwaterFluidType; import com.mojang.serialization.MapCodec; @@ -173,6 +174,8 @@ public final class AntarchyNeoforgeBlocks { () -> new Block(nyxiteProperties())); public static final DeferredBlock NYXITE_SPIKE = BLOCKS.register("nyxite_spike", () -> new NyxiteSpikeBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.POINTED_DRIPSTONE))); + public static final DeferredBlock CHITEN_SPIKE = BLOCKS.register("chiten_spike", + () -> new ChitenSpikeBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.POINTED_DRIPSTONE))); public static final DeferredBlock POTENT_NYXITE = BLOCKS.register("potent_nyxite", () -> new PotentNyxiteBlock( AntarchyNeoforgeItems::potentNyxiteBlockEntityType, @@ -224,6 +227,8 @@ public final class AntarchyNeoforgeBlocks { () -> new com.craisinlord.antarchy.content.block.OuranwoodSquirrelNestBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.COARSE_DIRT).noLootTable())); public static final DeferredBlock HUSHWEED = BLOCKS.register("hushweed", () -> new HushweedBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.AZALEA).noCollission().noOcclusion())); + public static final DeferredBlock BILE_BLOCK = BLOCKS.register("bile", + () -> new BileLiquidBlock((FlowingFluid) AntarchyNeoforgeMisc.BILE.get(), BlockBehaviour.Properties.ofFullCopy(Blocks.WATER).lightLevel(state -> 5).noLootTable())); public static final DeferredBlock ICHOR_BLOCK = BLOCKS.register("ichor", () -> new LiquidBlock((FlowingFluid) AntarchyNeoforgeMisc.ICHOR.get(), BlockBehaviour.Properties.ofFullCopy(Blocks.WATER).noLootTable())); public static final DeferredBlock ANTIWATER_BLOCK = BLOCKS.register("antiwater", diff --git a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeCreativeModeTabs.java b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeCreativeModeTabs.java index 4fbb93c4..e81c6828 100644 --- a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeCreativeModeTabs.java +++ b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeCreativeModeTabs.java @@ -116,6 +116,7 @@ public class AntarchyNeoforgeCreativeModeTabs { if (event.getTabKey() == CreativeModeTabs.TOOLS_AND_UTILITIES) { event.insertAfter(new ItemStack(Items.SHEARS), new ItemStack(AntarchyNeoforgeItems.DUCT_TAPE_ITEM.get()), CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); event.insertAfter(new ItemStack(Items.MINECART), new ItemStack(AntarchyNeoforgeItems.DIAMOND_MINECART_ITEM.get()), CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); + event.accept(AntarchyNeoforgeItems.BILE_BUCKET.get()); event.accept(AntarchyNeoforgeItems.ICHOR_BUCKET.get()); event.accept(AntarchyNeoforgeItems.ANTIWATER_BUCKET.get()); event.accept(AntarchyNeoforgeItems.CLOUD_BUCKET.get()); @@ -245,6 +246,7 @@ public class AntarchyNeoforgeCreativeModeTabs { event.accept(AntarchyNeoforgeItems.LARGE_BLOOD_CRYSTAL_BUD_ITEM.get()); event.accept(AntarchyNeoforgeItems.MYRMITE_ITEM.get()); event.accept(AntarchyNeoforgeItems.CHITEN_BLOCK_ITEM.get()); + event.accept(AntarchyNeoforgeItems.CHITEN_SPIKE_ITEM.get()); event.accept(AntarchyNeoforgeItems.AMBER_MOSS_BLOCK_ITEM.get()); event.accept(AntarchyNeoforgeItems.AMBER_MOSS_CARPET_ITEM.get()); event.accept(AntarchyNeoforgeItems.URANIUM_BLOCK_ITEM.get()); @@ -397,14 +399,15 @@ public class AntarchyNeoforgeCreativeModeTabs { case "antimetal_scaffolding" -> 13; // 14 - Infested blocks - case "infested_rooted_dirt", "infested_coarse_dirt", "bed_bug_egg" -> 14; + case "infested_rooted_dirt", "infested_coarse_dirt", "bed_bug_egg", + "creeping_horror_egg", "lurking_terror_egg" -> 14; // 15 - Tools case "ultimate_pickaxe", "ultimate_axe", "ultimate_shovel", "ultimate_hoe", "duct_tape", "diamond_minecart", "gravity_sculk_sensor" -> 15; // 16 - Liquid buckets - case "ichor_bucket", "antiwater_bucket", "cloud_bucket" -> 16; + case "bile_bucket", "ichor_bucket", "antiwater_bucket", "cloud_bucket" -> 16; // 17 - Misc wearables / gadgets case "moggles", "brutalfly_elytra", "fallen_king_crown", "jumpy_boots" -> 17; @@ -439,7 +442,7 @@ public class AntarchyNeoforgeCreativeModeTabs { "uranium_ingot", "titanium_ingot", "lucid_eye", "mantis_claw", "jumpy_bug_leg", "brutalfly_wing", "cornea_ear", "primordial_scute", "triffid_goo", "vortex_eye", - "king_scale", "queen_scale", "chiten" -> 22; + "king_scale", "queen_scale", "chiten", "stink_bug" -> 22; // 23 - Arrows (reserved for future arrow types) diff --git a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeItems.java b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeItems.java index 270900c0..d099b76b 100644 --- a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeItems.java +++ b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeItems.java @@ -265,6 +265,7 @@ public final class AntarchyNeoforgeItems { () -> new com.craisinlord.antarchy.content.item.TriffidGooBlockItem(AntarchyNeoforgeBlocks.TRIFFID_GOO_BLOCK.get(), new Item.Properties())); public static final DeferredItem PALE_NYXITE_ITEM = ITEMS.registerSimpleBlockItem(AntarchyNeoforgeBlocks.PALE_NYXITE); public static final DeferredItem NYXITE_SPIKE_ITEM = ITEMS.registerSimpleBlockItem(AntarchyNeoforgeBlocks.NYXITE_SPIKE); + public static final DeferredItem CHITEN_SPIKE_ITEM = ITEMS.registerSimpleBlockItem(AntarchyNeoforgeBlocks.CHITEN_SPIKE); public static final DeferredItem POTENT_NYXITE_ITEM = ITEMS.registerSimpleBlockItem(AntarchyNeoforgeBlocks.POTENT_NYXITE); public static final DeferredItem UMBRAL_MOSS_BLOCK_ITEM = ITEMS.registerSimpleBlockItem(AntarchyNeoforgeBlocks.UMBRAL_MOSS_BLOCK); public static final DeferredItem UMBRAL_MOSS_CARPET_ITEM = ITEMS.registerSimpleBlockItem(AntarchyNeoforgeBlocks.UMBRAL_MOSS_CARPET); @@ -281,6 +282,8 @@ public final class AntarchyNeoforgeItems { public static final DeferredItem LURKING_TERROR_EGG_ITEM = ITEMS.registerSimpleBlockItem(AntarchyNeoforgeBlocks.LURKING_TERROR_EGG); public static final DeferredItem WASP_NEST_ITEM = ITEMS.registerSimpleBlockItem(AntarchyNeoforgeBlocks.WASP_NEST); public static final DeferredItem HUSHWEED_ITEM = ITEMS.registerSimpleBlockItem(AntarchyNeoforgeBlocks.HUSHWEED); + public static final DeferredItem BILE_BUCKET = ITEMS.register("bile_bucket", + () -> new BucketItem(AntarchyNeoforgeMisc.BILE.get(), new Item.Properties().craftRemainder(Items.BUCKET).stacksTo(1))); public static final DeferredItem ICHOR_BUCKET = ITEMS.register("ichor_bucket", () -> new BucketItem(AntarchyNeoforgeMisc.ICHOR.get(), new Item.Properties().craftRemainder(Items.BUCKET).stacksTo(1))); public static final DeferredItem ANTIWATER_BUCKET = ITEMS.register("antiwater_bucket", diff --git a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeMisc.java b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeMisc.java index 3e39984c..85643a47 100644 --- a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeMisc.java +++ b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeMisc.java @@ -13,6 +13,12 @@ import com.craisinlord.antarchy.content.worldgen.ants.BrownAntNestFeature; import com.craisinlord.antarchy.content.worldgen.ants.RainbowAntNestFeature; import com.craisinlord.antarchy.content.worldgen.ants.RedAntNestFeature; import com.craisinlord.antarchy.content.worldgen.ants.TermiteNestFeature; +import com.craisinlord.antarchy.content.worldgen.cavaryn.CavarynBilePoolFeature; +import com.craisinlord.antarchy.content.worldgen.cavaryn.CavarynCreepvineFeature; +import com.craisinlord.antarchy.content.worldgen.cavaryn.CavarynEggPatchFeature; +import com.craisinlord.antarchy.content.worldgen.cavaryn.CavarynWallAmberMossFeature; +import com.craisinlord.antarchy.content.worldgen.cavaryn.ChitenSpikeConfiguration; +import com.craisinlord.antarchy.content.worldgen.cavaryn.ChitenSpikeFeature; import com.craisinlord.antarchy.content.worldgen.elythia.*; import com.craisinlord.antarchy.content.worldgen.thoraxis.*; import com.craisinlord.antarchy.neoforge.content.fluid.AntiwaterFluid; @@ -110,6 +116,15 @@ public final class AntarchyNeoforgeMisc { () -> new Potion("growing", new MobEffectInstance(GROWTH_EFFECT, 600, 2))); // Fluid types + public static final DeferredHolder BILE_TYPE = FLUID_TYPES.register("bile", + () -> new FluidType(FluidType.Properties.create() + .descriptionId("block.antarchy.bile") + .fallDistanceModifier(0.0F) + .supportsBoating(true) + .sound(SoundActions.BUCKET_FILL, SoundEvents.BUCKET_FILL) + .sound(SoundActions.BUCKET_EMPTY, SoundEvents.BUCKET_EMPTY) + .density(1100) + .viscosity(1200))); public static final DeferredHolder ICHOR_TYPE = FLUID_TYPES.register("ichor", () -> new FluidType(FluidType.Properties.create() .descriptionId("block.antarchy.ichor") @@ -131,6 +146,10 @@ public final class AntarchyNeoforgeMisc { .viscosity(1000))); // Fluids + public static final DeferredHolder BILE = FLUIDS.register("bile", + () -> new BaseFlowingFluid.Source(bileProperties())); + public static final DeferredHolder FLOWING_BILE = FLUIDS.register("flowing_bile", + () -> new BaseFlowingFluid.Flowing(bileProperties())); public static final DeferredHolder ICHOR = FLUIDS.register("ichor", () -> new BaseFlowingFluid.Source(ichorProperties())); public static final DeferredHolder FLOWING_ICHOR = FLUIDS.register("flowing_ichor", @@ -155,6 +174,8 @@ public final class AntarchyNeoforgeMisc { () -> new SimpleParticleType(true)); public static final DeferredHolder, SimpleParticleType> FIREFLY = PARTICLE_TYPES.register("firefly", () -> new SimpleParticleType(true)); + public static final DeferredHolder, SimpleParticleType> ORANGE_ASH = PARTICLE_TYPES.register("orange_ash", + () -> new SimpleParticleType(true)); public static final DeferredHolder, ParticleType> INVERTED_GEYSER_BASE = PARTICLE_TYPES.register("inverted_geyser_base", () -> particleType(InvertedGeyserBaseParticleOptions::codec, InvertedGeyserBaseParticleOptions::streamCodec)); public static final DeferredHolder, ParticleType> INVERTED_GEYSER_PLUME = PARTICLE_TYPES.register("inverted_geyser_plume", @@ -213,6 +234,12 @@ public final class AntarchyNeoforgeMisc { () -> new ElythiaTuffBoulderFeature(NoneFeatureConfiguration.CODEC)); public static final DeferredHolder, ElythiaLargeTuffBoulderFeature> ELYTHIA_LARGE_TUFF_BOULDER = FEATURES.register("elythia_large_tuff_boulder", () -> new ElythiaLargeTuffBoulderFeature(NoneFeatureConfiguration.CODEC)); + public static final DeferredHolder, CoralSpikeFeature> ELYTHIA_CORAL_SPIKE = FEATURES.register("elythia_coral_spike", + () -> new CoralSpikeFeature(NoneFeatureConfiguration.CODEC)); + public static final DeferredHolder, FallenOuranwoodFeature> FALLEN_OURANWOOD_TREE = FEATURES.register("fallen_ouranwood_tree", + () -> new FallenOuranwoodFeature(NoneFeatureConfiguration.CODEC)); + public static final DeferredHolder, FungalMushroomFeature> FUNGAL_MUSHROOM = FEATURES.register("fungal_mushroom", + () -> new FungalMushroomFeature(NoneFeatureConfiguration.CODEC)); public static final DeferredHolder, ThoraxisFissureFeature> THORAXIS_FISSURE = FEATURES.register("thoraxis_fissure", () -> new ThoraxisFissureFeature(ThoraxisFissureConfiguration.CODEC)); public static final DeferredHolder, ThoraxisRibColumnsFeature> THORAXIS_RIB_COLUMNS = FEATURES.register("thoraxis_rib_columns", @@ -221,6 +248,14 @@ public final class AntarchyNeoforgeMisc { () -> new ThoraxisSpikeFeature(ThoraxisSpikeConfiguration.CODEC)); public static final DeferredHolder, NyxiteSpikeFeature> NYXITE_SPIKES = FEATURES.register("nyxite_spikes", () -> new NyxiteSpikeFeature(NyxiteSpikeConfiguration.CODEC)); + public static final DeferredHolder, ChitenSpikeFeature> CAVARYN_CHITEN_SPIKES = FEATURES.register("cavaryn_chiten_spikes", + () -> new ChitenSpikeFeature(ChitenSpikeConfiguration.CODEC)); + public static final DeferredHolder, CavarynBilePoolFeature> CAVARYN_BILE_POOLS = FEATURES.register("cavaryn_bile_pools", + () -> new CavarynBilePoolFeature(NoneFeatureConfiguration.CODEC)); + public static final DeferredHolder, CavarynCreepvineFeature> CAVARYN_CREEPVINE = FEATURES.register("cavaryn_creepvine", + () -> new CavarynCreepvineFeature(NoneFeatureConfiguration.CODEC)); + public static final DeferredHolder, CavarynWallAmberMossFeature> CAVARYN_WALL_AMBER_MOSS = FEATURES.register("cavaryn_wall_amber_moss", + () -> new CavarynWallAmberMossFeature(NoneFeatureConfiguration.CODEC)); public static final DeferredHolder, AntiwaterSpringsFeature> ANTIWATER_SPRINGS = FEATURES.register("antiwater_springs", () -> new AntiwaterSpringsFeature(AntiwaterSpringsConfiguration.CODEC)); public static final DeferredHolder, PotentNyxiteFeature> POTENT_NYXITE_FEATURE = FEATURES.register("potent_nyxite", @@ -233,6 +268,8 @@ public final class AntarchyNeoforgeMisc { () -> new BedBugNestFeature(NoneFeatureConfiguration.CODEC)); public static final DeferredHolder, BedBugSurfaceClusterFeature> BED_BUG_SURFACE_CLUSTER = FEATURES.register("bed_bug_surface_cluster", () -> new BedBugSurfaceClusterFeature(NoneFeatureConfiguration.CODEC)); + public static final DeferredHolder, CavarynEggPatchFeature> CAVARYN_TERROR_EGG_PATCH = FEATURES.register("cavaryn_terror_egg_patch", + () -> new CavarynEggPatchFeature(NoneFeatureConfiguration.CODEC)); public static final DeferredHolder, ThoraxisAntiwaterPoolFeature> THORAXIS_ANTIWATER_POOL = FEATURES.register("thoraxis_antiwater_pool", () -> new ThoraxisAntiwaterPoolFeature(ThoraxisAntiwaterPoolConfiguration.CODEC)); public static final DeferredHolder, LucidAntiwaterPoolFeature> LUCID_ANTIWATER_POOL = FEATURES.register("lucid_antiwater_pool", @@ -265,6 +302,15 @@ public final class AntarchyNeoforgeMisc { ATTRIBUTES.register(modEventBus); } + static BaseFlowingFluid.Properties bileProperties() { + return new BaseFlowingFluid.Properties(BILE_TYPE, BILE, FLOWING_BILE) + .bucket(() -> AntarchyNeoforgeItems.BILE_BUCKET.get()) + .block(() -> AntarchyNeoforgeBlocks.BILE_BLOCK.get()) + .slopeFindDistance(4) + .levelDecreasePerBlock(1) + .tickRate(5); + } + static BaseFlowingFluid.Properties ichorProperties() { return new BaseFlowingFluid.Properties(ICHOR_TYPE, ICHOR, FLOWING_ICHOR) .bucket(() -> AntarchyNeoforgeItems.ICHOR_BUCKET.get()) diff --git a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeSpawnPlacements.java b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeSpawnPlacements.java index bc55ca8c..8f4acca4 100644 --- a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeSpawnPlacements.java +++ b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeSpawnPlacements.java @@ -47,6 +47,8 @@ public class AntarchyNeoforgeSpawnPlacements { event.register(AntarchyNeoforgeEntites.SCORPION.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, ScorpionEntity::canSpawn, RegisterSpawnPlacementsEvent.Operation.OR); event.register(AntarchyNeoforgeEntites.BASILISK.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, BasiliskEntity::canSpawn, RegisterSpawnPlacementsEvent.Operation.OR); event.register(AntarchyNeoforgeEntites.EMPEROR_SCORPION.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EmperorScorpionEntity::canSpawn, RegisterSpawnPlacementsEvent.Operation.OR); + event.register(AntarchyNeoforgeEntites.CREEPING_HORROR.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, CreepingHorrorEntity::canSpawn, RegisterSpawnPlacementsEvent.Operation.OR); + event.register(AntarchyNeoforgeEntites.LURKING_TERROR.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, LurkingTerrorEntity::canSpawn, RegisterSpawnPlacementsEvent.Operation.OR); event.register(AntarchyNeoforgeEntites.TERMITE.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, net.minecraft.world.entity.animal.Animal::checkAnimalSpawnRules, RegisterSpawnPlacementsEvent.Operation.OR); } } diff --git a/neoforge/src/main/resources/assets/antarchy/models/item/bile_bucket.json b/neoforge/src/main/resources/assets/antarchy/models/item/bile_bucket.json new file mode 100644 index 00000000..e3943e08 --- /dev/null +++ b/neoforge/src/main/resources/assets/antarchy/models/item/bile_bucket.json @@ -0,0 +1,5 @@ +{ + "parent": "neoforge:item/bucket", + "loader": "neoforge:fluid_container", + "fluid": "antarchy:bile" +}