diff --git a/common/src/main/java/com/craisinlord/antarchy/content/AntarchySoundEvents.java b/common/src/main/java/com/craisinlord/antarchy/content/AntarchySoundEvents.java index ee33fc27..3ad471a1 100644 --- a/common/src/main/java/com/craisinlord/antarchy/content/AntarchySoundEvents.java +++ b/common/src/main/java/com/craisinlord/antarchy/content/AntarchySoundEvents.java @@ -122,6 +122,14 @@ public final class AntarchySoundEvents { public static Supplier BOMBER_WALK = (Supplier) UNBOUND; public static Supplier BOMBER_KNOCK = (Supplier) UNBOUND; public static Supplier BOMBER_EXPLODE = (Supplier) UNBOUND; + public static Supplier STINKY_FLY = (Supplier) UNBOUND; + public static Supplier CREEPING_HORROR_GROWL = (Supplier) UNBOUND; + public static Supplier CREEPING_HORROR_HURT = (Supplier) UNBOUND; + public static Supplier CREEPING_HORROR_BITE = (Supplier) UNBOUND; + public static Supplier LURKING_TERROR_SNARL = (Supplier) UNBOUND; + public static Supplier LURKING_TERROR_HURT = (Supplier) UNBOUND; + public static Supplier LURKING_TERROR_BITE = (Supplier) UNBOUND; + public static Supplier LURKING_TERROR_FLY_LOOP = (Supplier) UNBOUND; public static Supplier DUCT_TAPE_USE = (Supplier) UNBOUND; private AntarchySoundEvents() { @@ -241,6 +249,14 @@ public final class AntarchySoundEvents { Supplier bomberWalk, Supplier bomberKnock, Supplier bomberExplode, + Supplier stinkyFly, + Supplier creepingHorrorGrowl, + Supplier creepingHorrorHurt, + Supplier creepingHorrorBite, + Supplier lurkingTerrorSnarl, + Supplier lurkingTerrorHurt, + Supplier lurkingTerrorBite, + Supplier lurkingTerrorFlyLoop, Supplier ductTapeUse ) { SQUIDZOOKA_FIRE = squidzookaFire; @@ -356,6 +372,14 @@ public final class AntarchySoundEvents { BOMBER_WALK = bomberWalk; BOMBER_KNOCK = bomberKnock; BOMBER_EXPLODE = bomberExplode; + STINKY_FLY = stinkyFly; + CREEPING_HORROR_GROWL = creepingHorrorGrowl; + CREEPING_HORROR_HURT = creepingHorrorHurt; + CREEPING_HORROR_BITE = creepingHorrorBite; + LURKING_TERROR_SNARL = lurkingTerrorSnarl; + LURKING_TERROR_HURT = lurkingTerrorHurt; + LURKING_TERROR_BITE = lurkingTerrorBite; + LURKING_TERROR_FLY_LOOP = lurkingTerrorFlyLoop; DUCT_TAPE_USE = ductTapeUse; } } diff --git a/common/src/main/java/com/craisinlord/antarchy/content/block/CreepingHorrorEggBlock.java b/common/src/main/java/com/craisinlord/antarchy/content/block/CreepingHorrorEggBlock.java index ea6bb9b0..5d2077aa 100644 --- a/common/src/main/java/com/craisinlord/antarchy/content/block/CreepingHorrorEggBlock.java +++ b/common/src/main/java/com/craisinlord/antarchy/content/block/CreepingHorrorEggBlock.java @@ -3,6 +3,7 @@ package com.craisinlord.antarchy.content.block; import com.craisinlord.antarchy.content.AntarchyObjects; import com.craisinlord.antarchy.content.entity.CreepingHorrorEntity; import com.craisinlord.antarchy.content.block.AmberMossBlock; +import com.craisinlord.antarchy.content.block.LurkingTerrorEggBlock; import com.mojang.serialization.MapCodec; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -127,6 +128,30 @@ public class CreepingHorrorEggBlock extends Block { public void playerDestroy(Level level, Player player, BlockPos pos, BlockState state, BlockEntity blockEntity, net.minecraft.world.item.ItemStack stack) { super.playerDestroy(level, player, pos, state, blockEntity, stack); this.decreaseEggs(level, pos, state); + if (level instanceof ServerLevel serverLevel) { + panicHatchNearby(serverLevel, pos); + } + } + + private static void panicHatchNearby(ServerLevel level, BlockPos origin) { + int radius = 6; + BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos(); + for (int dx = -radius; dx <= radius; dx++) { + for (int dy = -radius; dy <= radius; dy++) { + for (int dz = -radius; dz <= radius; dz++) { + if (dx == 0 && dy == 0 && dz == 0) continue; + mutable.set(origin.getX() + dx, origin.getY() + dy, origin.getZ() + dz); + if (level.random.nextFloat() >= 0.4f) continue; + BlockState nearby = level.getBlockState(mutable); + BlockPos immutable = mutable.immutable(); + if (nearby.getBlock() instanceof CreepingHorrorEggBlock b) { + b.hatchEggs(level, immutable, nearby, level.random); + } else if (nearby.getBlock() instanceof LurkingTerrorEggBlock b) { + b.hatchEggs(level, immutable, nearby, level.random); + } + } + } + } } @Override @@ -150,7 +175,7 @@ public class CreepingHorrorEggBlock extends Block { this.decreaseEggs(level, pos, state); } - private void hatchEggs(ServerLevel level, BlockPos pos, BlockState state, RandomSource random) { + void hatchEggs(ServerLevel level, BlockPos pos, BlockState state, RandomSource random) { level.removeBlock(pos, false); level.playSound(null, pos, SoundEvents.TURTLE_EGG_HATCH, SoundSource.BLOCKS, 0.75F, 0.95F + random.nextFloat() * 0.1F); diff --git a/common/src/main/java/com/craisinlord/antarchy/content/block/LurkingTerrorEggBlock.java b/common/src/main/java/com/craisinlord/antarchy/content/block/LurkingTerrorEggBlock.java index c99b4e7f..4c0d4417 100644 --- a/common/src/main/java/com/craisinlord/antarchy/content/block/LurkingTerrorEggBlock.java +++ b/common/src/main/java/com/craisinlord/antarchy/content/block/LurkingTerrorEggBlock.java @@ -3,6 +3,7 @@ package com.craisinlord.antarchy.content.block; import com.craisinlord.antarchy.content.AntarchyObjects; import com.craisinlord.antarchy.content.entity.LurkingTerrorEntity; import com.craisinlord.antarchy.content.block.AmberMossBlock; +import com.craisinlord.antarchy.content.block.CreepingHorrorEggBlock; import com.mojang.serialization.MapCodec; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -127,6 +128,30 @@ public class LurkingTerrorEggBlock extends Block { public void playerDestroy(Level level, Player player, BlockPos pos, BlockState state, BlockEntity blockEntity, net.minecraft.world.item.ItemStack stack) { super.playerDestroy(level, player, pos, state, blockEntity, stack); this.decreaseEggs(level, pos, state); + if (level instanceof ServerLevel serverLevel) { + panicHatchNearby(serverLevel, pos); + } + } + + private static void panicHatchNearby(ServerLevel level, BlockPos origin) { + int radius = 6; + BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos(); + for (int dx = -radius; dx <= radius; dx++) { + for (int dy = -radius; dy <= radius; dy++) { + for (int dz = -radius; dz <= radius; dz++) { + if (dx == 0 && dy == 0 && dz == 0) continue; + mutable.set(origin.getX() + dx, origin.getY() + dy, origin.getZ() + dz); + if (level.random.nextFloat() >= 0.4f) continue; + BlockState nearby = level.getBlockState(mutable); + BlockPos immutable = mutable.immutable(); + if (nearby.getBlock() instanceof LurkingTerrorEggBlock b) { + b.hatchEggs(level, immutable, nearby, level.random); + } else if (nearby.getBlock() instanceof CreepingHorrorEggBlock b) { + b.hatchEggs(level, immutable, nearby, level.random); + } + } + } + } } @Override @@ -150,7 +175,7 @@ public class LurkingTerrorEggBlock extends Block { this.decreaseEggs(level, pos, state); } - private void hatchEggs(ServerLevel level, BlockPos pos, BlockState state, RandomSource random) { + void hatchEggs(ServerLevel level, BlockPos pos, BlockState state, RandomSource random) { level.removeBlock(pos, false); level.playSound(null, pos, SoundEvents.TURTLE_EGG_HATCH, SoundSource.BLOCKS, 0.75F, 0.95F + random.nextFloat() * 0.1F); diff --git a/common/src/main/java/com/craisinlord/antarchy/content/client/model/SpitBugModel.java b/common/src/main/java/com/craisinlord/antarchy/content/client/model/SpitBugModel.java new file mode 100644 index 00000000..a051572b --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/content/client/model/SpitBugModel.java @@ -0,0 +1,23 @@ +package com.craisinlord.antarchy.content.client.model; + +import com.craisinlord.antarchy.Antarchy; +import com.craisinlord.antarchy.content.entity.SpitBugEntity; +import net.minecraft.resources.ResourceLocation; +import software.bernie.geckolib.model.GeoModel; + +public class SpitBugModel extends GeoModel { + @Override + public ResourceLocation getModelResource(SpitBugEntity animatable) { + return ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "geo/spit_bug.geo.json"); + } + + @Override + public ResourceLocation getTextureResource(SpitBugEntity animatable) { + return ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/entity/spit_bug.png"); + } + + @Override + public ResourceLocation getAnimationResource(SpitBugEntity animatable) { + return ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "animations/spit_bug.animation.json"); + } +} diff --git a/common/src/main/java/com/craisinlord/antarchy/content/client/renderer/AntCarriedFoodGeoLayer.java b/common/src/main/java/com/craisinlord/antarchy/content/client/renderer/AntCarriedFoodGeoLayer.java index cddb1908..6ec997a2 100644 --- a/common/src/main/java/com/craisinlord/antarchy/content/client/renderer/AntCarriedFoodGeoLayer.java +++ b/common/src/main/java/com/craisinlord/antarchy/content/client/renderer/AntCarriedFoodGeoLayer.java @@ -35,11 +35,10 @@ public class AntCarriedFoodGeoLayer extends BlockAndItemGeoLayer @Override protected void renderStackForBone(PoseStack poseStack, GeoBone bone, ItemStack stack, BaseAntEntity animatable, MultiBufferSource bufferSource, float partialTick, int packedLight, int packedOverlay) { - double yOffset = animatable.isDancing() ? -0.055D : -0.04D; - poseStack.translate(0.0D, yOffset, -0.42D); - poseStack.mulPose(Axis.XP.rotationDegrees(90.0F)); - poseStack.mulPose(Axis.ZP.rotationDegrees(180.0F)); - poseStack.scale(0.4F, 0.4F, 0.4F); + double yOffset = animatable.isDancing() ? 0.58D : 0.15D; + poseStack.translate(0.0D, yOffset, -0.50D); + poseStack.mulPose(Axis.YP.rotationDegrees(90.0F)); + poseStack.scale(0.5F, 0.5F, 0.5F); super.renderStackForBone(poseStack, bone, stack, animatable, bufferSource, partialTick, packedLight, packedOverlay); } } diff --git a/common/src/main/java/com/craisinlord/antarchy/content/client/renderer/AntCarriedFoodLayer.java b/common/src/main/java/com/craisinlord/antarchy/content/client/renderer/AntCarriedFoodLayer.java deleted file mode 100644 index 2197e1a6..00000000 --- a/common/src/main/java/com/craisinlord/antarchy/content/client/renderer/AntCarriedFoodLayer.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.craisinlord.antarchy.content.client.renderer; - -import com.craisinlord.antarchy.content.entity.ant.BaseAntEntity; -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.math.Axis; -import net.minecraft.client.model.SilverfishModel; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.entity.ItemRenderer; -import net.minecraft.client.renderer.entity.RenderLayerParent; -import net.minecraft.client.renderer.entity.layers.RenderLayer; -import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.world.item.ItemDisplayContext; -import net.minecraft.world.item.ItemStack; - -public class AntCarriedFoodLayer extends RenderLayer> { - private final ItemRenderer itemRenderer; - - public AntCarriedFoodLayer(RenderLayerParent> renderer, ItemRenderer itemRenderer) { - super(renderer); - this.itemRenderer = itemRenderer; - } - - @Override - public void render( - PoseStack poseStack, - MultiBufferSource buffer, - int packedLight, - T ant, - float limbSwing, - float limbSwingAmount, - float partialTick, - float ageInTicks, - float netHeadYaw, - float headPitch - ) { - ItemStack carriedFood = ant.getCarriedFood(); - if (carriedFood.isEmpty()) { - return; - } - - poseStack.pushPose(); - poseStack.translate(0.0F, 0.08F, -0.06F); - poseStack.mulPose(Axis.XP.rotationDegrees(90.0F)); - poseStack.mulPose(Axis.ZP.rotationDegrees(180.0F)); - poseStack.scale(0.22F, 0.22F, 0.22F); - this.itemRenderer.renderStatic( - ant, - carriedFood, - ItemDisplayContext.FIXED, - false, - poseStack, - buffer, - ant.level(), - packedLight, - OverlayTexture.NO_OVERLAY, - ant.getId() - ); - poseStack.popPose(); - } -} diff --git a/common/src/main/java/com/craisinlord/antarchy/content/client/renderer/SpitBugProjectileRenderer.java b/common/src/main/java/com/craisinlord/antarchy/content/client/renderer/SpitBugProjectileRenderer.java new file mode 100644 index 00000000..7b9fbedd --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/content/client/renderer/SpitBugProjectileRenderer.java @@ -0,0 +1,73 @@ +package com.craisinlord.antarchy.content.client.renderer; + +import com.craisinlord.antarchy.content.entity.SpitBugProjectileEntity; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.entity.EntityRenderer; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceLocation; +import org.joml.Matrix4f; + +public class SpitBugProjectileRenderer extends EntityRenderer { + private static final ResourceLocation PROJECTILE_TEXTURE = + ResourceLocation.withDefaultNamespace("textures/entity/enderdragon/dragon_fireball.png"); + + public SpitBugProjectileRenderer(EntityRendererProvider.Context context) { + super(context); + } + + @Override + protected int getBlockLightLevel(SpitBugProjectileEntity entity, BlockPos pos) { + return 15; + } + + @Override + public void render(SpitBugProjectileEntity entity, float entityYaw, float partialTick, PoseStack poseStack, MultiBufferSource buffer, int packedLight) { + poseStack.pushPose(); + poseStack.mulPose(this.entityRenderDispatcher.cameraOrientation()); + + float scale = entity.getRenderScale(partialTick); + poseStack.scale(scale, scale, scale); + + VertexConsumer vertexConsumer = buffer.getBuffer(RenderType.entityTranslucent(PROJECTILE_TEXTURE)); + PoseStack.Pose pose = poseStack.last(); + Matrix4f matrix4f = pose.pose(); + float alpha = entity.isLingering() ? 0.78F : 0.95F; + + addVertex(vertexConsumer, pose, matrix4f, -0.5F, -0.5F, 0.0F, 1.0F, alpha, packedLight); + addVertex(vertexConsumer, pose, matrix4f, 0.5F, -0.5F, 1.0F, 1.0F, alpha, packedLight); + addVertex(vertexConsumer, pose, matrix4f, 0.5F, 0.5F, 1.0F, 0.0F, alpha, packedLight); + addVertex(vertexConsumer, pose, matrix4f, -0.5F, 0.5F, 0.0F, 0.0F, alpha, packedLight); + + poseStack.popPose(); + super.render(entity, entityYaw, partialTick, poseStack, buffer, packedLight); + } + + private static void addVertex( + VertexConsumer vertexConsumer, + PoseStack.Pose pose, + Matrix4f matrix4f, + float x, + float y, + float u, + float v, + float alpha, + int packedLight + ) { + vertexConsumer.addVertex(matrix4f, x, y, 0.0F) + .setColor(0.55F, 1.0F, 0.35F, alpha) + .setUv(u, v) + .setOverlay(OverlayTexture.NO_OVERLAY) + .setLight(packedLight) + .setNormal(pose, 0.0F, 0.0F, 1.0F); + } + + @Override + public ResourceLocation getTextureLocation(SpitBugProjectileEntity entity) { + return PROJECTILE_TEXTURE; + } +} diff --git a/common/src/main/java/com/craisinlord/antarchy/content/client/renderer/SpitBugRenderer.java b/common/src/main/java/com/craisinlord/antarchy/content/client/renderer/SpitBugRenderer.java new file mode 100644 index 00000000..34bae797 --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/content/client/renderer/SpitBugRenderer.java @@ -0,0 +1,14 @@ +package com.craisinlord.antarchy.content.client.renderer; + +import com.craisinlord.antarchy.content.client.model.SpitBugModel; +import com.craisinlord.antarchy.content.entity.SpitBugEntity; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import software.bernie.geckolib.renderer.GeoEntityRenderer; + +public class SpitBugRenderer extends GeoEntityRenderer { + public SpitBugRenderer(EntityRendererProvider.Context context) { + super(context, new SpitBugModel()); + this.shadowRadius = 1.6F; + this.withScale(0.85F); + } +} diff --git a/common/src/main/java/com/craisinlord/antarchy/content/entity/BomberEntity.java b/common/src/main/java/com/craisinlord/antarchy/content/entity/BomberEntity.java index b725f3dd..b2398d8e 100644 --- a/common/src/main/java/com/craisinlord/antarchy/content/entity/BomberEntity.java +++ b/common/src/main/java/com/craisinlord/antarchy/content/entity/BomberEntity.java @@ -67,6 +67,8 @@ public class BomberEntity extends Monster implements GeoEntity { private static final int DEFAULT_FUSE_TICKS = 120; private static final int EXPLODE_ANIM_START_TICKS = 25; private static final int FLASH_INTERVAL_TICKS = 5; + private static final double KNOCKBACK_MULTIPLIER = 3.0D; + private static final float EXPLOSION_RADIUS_MULTIPLIER = 0.45F; private static final RawAnimation IDLE_ANIM = RawAnimation.begin().thenLoop("idle"); private static final RawAnimation WALK_ANIM = RawAnimation.begin().thenLoop("walk"); @@ -152,7 +154,13 @@ public class BomberEntity extends Monster implements GeoEntity { this.primeFuse(); } - return super.hurt(source, amount); + this.pushAwayFrom(source); + return false; + } + + @Override + public void knockback(double strength, double x, double z) { + super.knockback(strength * KNOCKBACK_MULTIPLIER, x, z); } @Override @@ -205,6 +213,11 @@ public class BomberEntity extends Monster implements GeoEntity { public void tick() { super.tick(); + if (this.detonating && this.fuseTicks <= EXPLODE_ANIM_START_TICKS) { + this.getNavigation().stop(); + this.setDeltaMovement(Vec3.ZERO); + } + if (!this.level().isClientSide && this.detonating) { if (this.fuseTicks > 0) { this.fuseTicks--; @@ -268,7 +281,7 @@ public class BomberEntity extends Monster implements GeoEntity { double x = this.getX(); double y = this.getY(0.0625D); double z = this.getZ(); - float radius = (float) AntarchySettings.bomberExplosionRadius(); + float radius = (float) (AntarchySettings.bomberExplosionRadius() * EXPLOSION_RADIUS_MULTIPLIER); serverLevel.playSound(null, x, y, z, SoundEvents.GENERIC_EXPLODE.value(), SoundSource.HOSTILE, 0.55F, 1.0F); serverLevel.explode( this, @@ -306,6 +319,26 @@ public class BomberEntity extends Monster implements GeoEntity { this.discard(); } + private void pushAwayFrom(DamageSource source) { + Entity sourceEntity = source.getDirectEntity(); + if (sourceEntity == null) { + sourceEntity = source.getEntity(); + } + if (sourceEntity == null || sourceEntity == this) { + return; + } + + double dx = this.getX() - sourceEntity.getX(); + double dz = this.getZ() - sourceEntity.getZ(); + double distance = Math.sqrt(dx * dx + dz * dz); + if (distance < 1.0E-4D) { + return; + } + + double strength = 0.4D * KNOCKBACK_MULTIPLIER; + this.push(dx / distance * strength, 0.08D, dz / distance * strength); + } + private boolean isMovingForAnimation() { return this.getDeltaMovement().horizontalDistanceSqr() > 1.0E-4D || this.getNavigation().isInProgress(); } @@ -317,12 +350,12 @@ public class BomberEntity extends Monster implements GeoEntity { @Override public boolean canUse() { - return super.canUse(); + return !BomberEntity.this.isDetonating() || BomberEntity.this.getFuseTicks() > EXPLODE_ANIM_START_TICKS && super.canUse(); } @Override public boolean canContinueToUse() { - return super.canContinueToUse(); + return !BomberEntity.this.isDetonating() || BomberEntity.this.getFuseTicks() > EXPLODE_ANIM_START_TICKS && super.canContinueToUse(); } } } 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 12868ec8..f2139e87 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,10 +1,12 @@ package com.craisinlord.antarchy.content.entity; import com.craisinlord.antarchy.config.AntarchySettings; +import com.craisinlord.antarchy.content.AntarchySoundEvents; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.util.RandomSource; import net.minecraft.world.Difficulty; +import net.minecraft.sounds.SoundEvent; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; @@ -133,12 +135,28 @@ public class CreepingHorrorEntity extends Monster implements GeoEntity { public boolean doHurtTarget(net.minecraft.world.entity.Entity target) { boolean result = super.doHurtTarget(target); if (result) { + this.playSound(AntarchySoundEvents.CREEPING_HORROR_BITE.get(), 1.0F, 0.95F + this.random.nextFloat() * 0.1F); attackAnimTicks = 20; this.level().broadcastEntityEvent(this, ATTACK_ANIM_EVENT); } return result; } + @Override + protected SoundEvent getAmbientSound() { + return AntarchySoundEvents.CREEPING_HORROR_GROWL.get(); + } + + @Override + protected SoundEvent getHurtSound(net.minecraft.world.damagesource.DamageSource source) { + return AntarchySoundEvents.CREEPING_HORROR_HURT.get(); + } + + @Override + protected SoundEvent getDeathSound() { + return AntarchySoundEvents.CREEPING_HORROR_HURT.get(); + } + @Override public void handleEntityEvent(byte id) { if (id == ATTACK_ANIM_EVENT) { 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 bd99d51f..7ae6a44e 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,6 +1,7 @@ package com.craisinlord.antarchy.content.entity; import com.craisinlord.antarchy.config.AntarchySettings; +import com.craisinlord.antarchy.content.AntarchySoundEvents; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.util.RandomSource; @@ -22,6 +23,7 @@ import net.minecraft.world.entity.ai.navigation.FlyingPathNavigation; import net.minecraft.world.entity.ai.navigation.PathNavigation; import net.minecraft.world.entity.monster.Monster; import net.minecraft.world.entity.player.Player; +import net.minecraft.sounds.SoundEvent; import net.minecraft.world.level.Level; import net.minecraft.world.level.ServerLevelAccessor; import net.minecraft.world.level.block.Blocks; @@ -129,12 +131,28 @@ public class LurkingTerrorEntity extends Monster implements GeoEntity { public boolean doHurtTarget(net.minecraft.world.entity.Entity target) { boolean result = super.doHurtTarget(target); if (result) { + this.playSound(AntarchySoundEvents.LURKING_TERROR_BITE.get(), 1.0F, 0.95F + this.random.nextFloat() * 0.1F); attackAnimTicks = 20; this.level().broadcastEntityEvent(this, ATTACK_ANIM_EVENT); } return result; } + @Override + protected SoundEvent getAmbientSound() { + return AntarchySoundEvents.LURKING_TERROR_SNARL.get(); + } + + @Override + protected SoundEvent getHurtSound(net.minecraft.world.damagesource.DamageSource source) { + return AntarchySoundEvents.LURKING_TERROR_HURT.get(); + } + + @Override + protected SoundEvent getDeathSound() { + return AntarchySoundEvents.LURKING_TERROR_HURT.get(); + } + @Override public void handleEntityEvent(byte id) { if (id == ATTACK_ANIM_EVENT) { @@ -147,6 +165,9 @@ public class LurkingTerrorEntity extends Monster implements GeoEntity { @Override public void tick() { super.tick(); + if (!this.level().isClientSide() && !this.onGround() && this.tickCount % 40 == 0) { + this.playSound(AntarchySoundEvents.LURKING_TERROR_FLY_LOOP.get(), 0.45F, 0.95F + this.random.nextFloat() * 0.1F); + } if (attackAnimTicks > 0) attackAnimTicks--; } diff --git a/common/src/main/java/com/craisinlord/antarchy/content/entity/SpitBugEntity.java b/common/src/main/java/com/craisinlord/antarchy/content/entity/SpitBugEntity.java new file mode 100644 index 00000000..71bf9ef6 --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/content/entity/SpitBugEntity.java @@ -0,0 +1,265 @@ +package com.craisinlord.antarchy.content.entity; + +import com.craisinlord.antarchy.Antarchy; +import net.minecraft.core.BlockPos; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.network.syncher.EntityDataSerializers; +import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.util.RandomSource; +import net.minecraft.world.Difficulty; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +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; +import net.minecraft.world.entity.ai.goal.Goal; +import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal; +import net.minecraft.world.entity.ai.goal.MeleeAttackGoal; +import net.minecraft.world.entity.ai.goal.RandomLookAroundGoal; +import net.minecraft.world.entity.ai.goal.WaterAvoidingRandomStrollGoal; +import net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal; +import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal; +import net.minecraft.world.entity.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.state.BlockState; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.phys.Vec3; +import software.bernie.geckolib.animatable.GeoEntity; +import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache; +import software.bernie.geckolib.animation.AnimatableManager; +import software.bernie.geckolib.animation.AnimationController; +import software.bernie.geckolib.animation.AnimationState; +import software.bernie.geckolib.animation.PlayState; +import software.bernie.geckolib.animation.RawAnimation; +import software.bernie.geckolib.util.GeckoLibUtil; + +import java.util.EnumSet; + +public class SpitBugEntity extends Monster implements GeoEntity { + private static final EntityDataAccessor SPIT_ANIM_TICKS = + SynchedEntityData.defineId(SpitBugEntity.class, EntityDataSerializers.INT); + private static final RawAnimation IDLE_ANIM = RawAnimation.begin().thenLoop("idle"); + private static final RawAnimation WALK_ANIM = RawAnimation.begin().thenLoop("walk"); + private static final RawAnimation SPIT_ANIM = RawAnimation.begin().thenPlay("spit"); + + private static final double MAX_HEALTH = 30.0D; + private static final double MOVEMENT_SPEED = 0.23D; + private static final double ATTACK_DAMAGE = 5.0D; + private static final double FOLLOW_RANGE = 24.0D; + private static final double SPIT_RANGE_SQR = 14.0D * 14.0D; + private static final double MELEE_RANGE_SQR = 3.5D * 3.5D; + private static final int SPIT_COOLDOWN_TICKS = 55; + private static final int SPIT_ANIMATION_TICKS = 18; + private static final int SPIT_RELEASE_TICKS = 8; + + private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this); + + private int spitCooldownTicks; + private int spitAnimationTicks; + private int spitReleaseTicks; + + public SpitBugEntity(EntityType entityType, Level level) { + super(entityType, level); + this.xpReward = 10; + } + + public static AttributeSupplier.Builder createAttributes() { + return Mob.createMobAttributes() + .add(Attributes.MAX_HEALTH, MAX_HEALTH) + .add(Attributes.MOVEMENT_SPEED, MOVEMENT_SPEED) + .add(Attributes.ATTACK_DAMAGE, ATTACK_DAMAGE) + .add(Attributes.FOLLOW_RANGE, FOLLOW_RANGE) + .add(Attributes.ARMOR, 4.0D) + .add(Attributes.KNOCKBACK_RESISTANCE, 0.2D); + } + + 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; + } + + return level.getDifficulty() != Difficulty.PEACEFUL + && level.isEmptyBlock(pos) + && level.isEmptyBlock(pos.above()) + && Monster.checkMonsterSpawnRules(entityType, level, spawnReason, pos, random); + } + + @Override + protected void defineSynchedData(SynchedEntityData.Builder builder) { + super.defineSynchedData(builder); + builder.define(SPIT_ANIM_TICKS, 0); + } + + @Override + protected void registerGoals() { + this.goalSelector.addGoal(0, new FloatGoal(this)); + this.goalSelector.addGoal(1, new SpitAttackGoal()); + this.goalSelector.addGoal(2, new MeleeAttackGoal(this, 1.0D, false)); + this.goalSelector.addGoal(3, new WaterAvoidingRandomStrollGoal(this, 0.9D)); + this.goalSelector.addGoal(4, new LookAtPlayerGoal(this, Player.class, 12.0F)); + this.goalSelector.addGoal(5, new RandomLookAroundGoal(this)); + this.targetSelector.addGoal(1, new HurtByTargetGoal(this)); + this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true)); + } + + @Override + public void registerControllers(AnimatableManager.ControllerRegistrar controllers) { + controllers.add(new AnimationController<>(this, "main_controller", 2, this::mainAnimController)); + } + + @Override + public AnimatableInstanceCache getAnimatableInstanceCache() { + return this.geoCache; + } + + @Override + public void tick() { + super.tick(); + if (this.level().isClientSide) { + return; + } + + if (this.spitCooldownTicks > 0) { + this.spitCooldownTicks--; + } + + if (this.spitAnimationTicks > 0) { + this.spitAnimationTicks--; + this.entityData.set(SPIT_ANIM_TICKS, this.spitAnimationTicks); + if (this.spitReleaseTicks > 0 && --this.spitReleaseTicks == 0) { + this.fireSpitProjectile(); + } + } + } + + @Override + public boolean doHurtTarget(net.minecraft.world.entity.Entity target) { + boolean hurt = super.doHurtTarget(target); + if (hurt) { + this.playSound(SoundEvents.SPIDER_HURT, 0.7F, 0.8F + this.random.nextFloat() * 0.2F); + } + return hurt; + } + + @Override + protected SoundEvent getAmbientSound() { + return SoundEvents.SPIDER_AMBIENT; + } + + @Override + protected SoundEvent getHurtSound(DamageSource damageSource) { + return SoundEvents.SPIDER_HURT; + } + + @Override + protected SoundEvent getDeathSound() { + return SoundEvents.SPIDER_DEATH; + } + + @Override + protected void playStepSound(BlockPos pos, BlockState blockState) { + this.playSound(SoundEvents.SPIDER_STEP, 0.18F, 0.95F); + } + + private PlayState mainAnimController(AnimationState state) { + if (this.entityData.get(SPIT_ANIM_TICKS) > 0) { + return state.setAndContinue(SPIT_ANIM); + } + return state.setAndContinue(state.isMoving() ? WALK_ANIM : IDLE_ANIM); + } + + private boolean canSpitAt(LivingEntity target) { + return this.spitCooldownTicks <= 0 + && this.spitAnimationTicks <= 0 + && this.hasLineOfSight(target) + && this.distanceToSqr(target) <= SPIT_RANGE_SQR + && this.distanceToSqr(target) > MELEE_RANGE_SQR; + } + + private void startSpitAttack() { + this.spitCooldownTicks = SPIT_COOLDOWN_TICKS; + this.spitAnimationTicks = SPIT_ANIMATION_TICKS; + this.spitReleaseTicks = SPIT_RELEASE_TICKS; + this.entityData.set(SPIT_ANIM_TICKS, this.spitAnimationTicks); + } + + @SuppressWarnings("unchecked") + private void fireSpitProjectile() { + if (!(this.level() instanceof ServerLevel serverLevel)) { + return; + } + + LivingEntity target = this.getTarget(); + if (target == null || !target.isAlive()) { + return; + } + + EntityType projectileType = (EntityType) BuiltInRegistries.ENTITY_TYPE.getOptional( + ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "spit_bug_projectile") + ).orElse(null); + if (projectileType == null) { + return; + } + + SpitBugProjectileEntity projectile = new SpitBugProjectileEntity(projectileType, this, serverLevel); + Vec3 origin = this.position() + .add(0.0D, this.getBbHeight() * 0.55D, 0.0D) + .add(this.getViewVector(0.0F).scale(1.35D)); + Vec3 aimPoint = target.getEyePosition().add(target.getDeltaMovement().scale(0.45D)); + Vec3 direction = aimPoint.subtract(origin).normalize(); + + projectile.setPos(origin.x, origin.y, origin.z); + projectile.shoot(direction.x, direction.y, direction.z, 1.05F, 0.0F); + serverLevel.addFreshEntity(projectile); + this.playSound(SoundEvents.SLIME_ATTACK, 1.0F, 0.85F + this.random.nextFloat() * 0.15F); + } + + private final class SpitAttackGoal extends Goal { + SpitAttackGoal() { + this.setFlags(EnumSet.of(Flag.MOVE, Flag.LOOK)); + } + + @Override + public boolean canUse() { + LivingEntity target = SpitBugEntity.this.getTarget(); + return target != null && target.isAlive(); + } + + @Override + public boolean canContinueToUse() { + return this.canUse(); + } + + @Override + public void tick() { + LivingEntity target = SpitBugEntity.this.getTarget(); + if (target == null) { + return; + } + + SpitBugEntity.this.getLookControl().setLookAt(target, 30.0F, 30.0F); + + if (SpitBugEntity.this.canSpitAt(target)) { + SpitBugEntity.this.getNavigation().stop(); + SpitBugEntity.this.startSpitAttack(); + return; + } + + if (SpitBugEntity.this.distanceToSqr(target) > 36.0D || !SpitBugEntity.this.hasLineOfSight(target)) { + SpitBugEntity.this.getNavigation().moveTo(target, 1.0D); + } else { + SpitBugEntity.this.getNavigation().stop(); + } + } + } +} diff --git a/common/src/main/java/com/craisinlord/antarchy/content/entity/SpitBugProjectileEntity.java b/common/src/main/java/com/craisinlord/antarchy/content/entity/SpitBugProjectileEntity.java new file mode 100644 index 00000000..34211277 --- /dev/null +++ b/common/src/main/java/com/craisinlord/antarchy/content/entity/SpitBugProjectileEntity.java @@ -0,0 +1,172 @@ +package com.craisinlord.antarchy.content.entity; + +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.network.syncher.EntityDataSerializers; +import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.projectile.ThrowableItemProjectile; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.EntityHitResult; +import net.minecraft.world.phys.Vec3; + +public class SpitBugProjectileEntity extends ThrowableItemProjectile { + private static final EntityDataAccessor LINGERING = + SynchedEntityData.defineId(SpitBugProjectileEntity.class, EntityDataSerializers.BOOLEAN); + private static final int MAX_FLIGHT_TICKS = 100; + private static final int LINGER_DURATION_TICKS = 300; + private static final int DIRECT_HIT_DAMAGE = 8; + private static final float LINGER_RADIUS = 1.65F; + + private boolean lingering; + private int lingeringTicks; + + public SpitBugProjectileEntity(EntityType entityType, Level level) { + super(entityType, level); + } + + public SpitBugProjectileEntity(EntityType entityType, LivingEntity owner, Level level) { + super(entityType, owner, level); + } + + @Override + protected void defineSynchedData(SynchedEntityData.Builder builder) { + super.defineSynchedData(builder); + builder.define(LINGERING, false); + } + + @Override + protected Item getDefaultItem() { + return Items.SLIME_BALL; + } + + @Override + protected double getDefaultGravity() { + return 0.03D; + } + + @Override + public boolean canBeCollidedWith() { + return false; + } + + @Override + public boolean isAttackable() { + return false; + } + + public boolean isLingering() { + return this.entityData.get(LINGERING); + } + + public float getRenderScale(float partialTick) { + if (!this.isLingering()) { + return 0.65F; + } + float progress = Math.min(1.0F, (this.lingeringTicks + partialTick) / 8.0F); + return 0.6F + progress * 0.5F; + } + + @Override + public void tick() { + if (this.isLingering()) { + this.tickLingering(); + return; + } + + super.tick(); + if (this.tickCount > MAX_FLIGHT_TICKS) { + this.discard(); + return; + } + + if (this.level().isClientSide) { + this.level().addParticle(ParticleTypes.ITEM_SLIME, this.getX(), this.getY(), this.getZ(), 0.0D, 0.0D, 0.0D); + } + } + + private void tickLingering() { + this.lingeringTicks++; + this.setDeltaMovement(Vec3.ZERO); + + if (this.level().isClientSide) { + double radius = 0.4D + this.random.nextDouble() * 0.45D; + this.level().addParticle( + ParticleTypes.ITEM_SLIME, + this.getX() + (this.random.nextDouble() - 0.5D) * radius, + this.getY() + 0.04D, + this.getZ() + (this.random.nextDouble() - 0.5D) * radius, + 0.0D, + 0.0D, + 0.0D + ); + return; + } + + if (this.lingeringTicks % 4 == 0) { + this.applyLingeringSpit(); + } + + if (this.lingeringTicks >= LINGER_DURATION_TICKS) { + this.discard(); + } + } + + private void applyLingeringSpit() { + for (LivingEntity target : this.level().getEntitiesOfClass( + LivingEntity.class, + this.getBoundingBox().inflate(LINGER_RADIUS, 0.6D, LINGER_RADIUS), + entity -> entity.isAlive() && entity != this.getOwner() + )) { + target.addEffect(new MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, 30, 3, false, true, true)); + target.makeStuckInBlock(Blocks.HONEY_BLOCK.defaultBlockState(), new Vec3(0.2D, 0.0D, 0.2D)); + } + + if (this.level() instanceof ServerLevel serverLevel) { + serverLevel.sendParticles(ParticleTypes.ITEM_SLIME, this.getX(), this.getY() + 0.05D, this.getZ(), 3, 0.45D, 0.02D, 0.45D, 0.0D); + } + } + + @Override + protected void onHitEntity(EntityHitResult result) { + if (!this.level().isClientSide && result.getEntity() instanceof LivingEntity livingTarget) { + Entity owner = this.getOwner(); + if (owner instanceof LivingEntity livingOwner) { + livingTarget.hurt(this.damageSources().mobProjectile(this, livingOwner), DIRECT_HIT_DAMAGE); + } else { + livingTarget.hurt(this.damageSources().magic(), DIRECT_HIT_DAMAGE); + } + livingTarget.addEffect(new MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, 80, 3, false, true, true)); + livingTarget.makeStuckInBlock(Blocks.HONEY_BLOCK.defaultBlockState(), new Vec3(0.25D, 0.0D, 0.25D)); + } + + this.beginLingering(result.getLocation()); + } + + @Override + protected void onHitBlock(BlockHitResult result) { + this.beginLingering(result.getLocation()); + } + + private void beginLingering(Vec3 location) { + if (this.isLingering()) { + return; + } + + this.lingering = true; + this.entityData.set(LINGERING, true); + this.lingeringTicks = 0; + this.noPhysics = true; + this.setPos(location.x, location.y + 0.05D, location.z); + this.setDeltaMovement(Vec3.ZERO); + } +} 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 index f8596dd0..1a6de863 100644 --- a/common/src/main/java/com/craisinlord/antarchy/content/fluid/BileLiquidBlock.java +++ b/common/src/main/java/com/craisinlord/antarchy/content/fluid/BileLiquidBlock.java @@ -3,6 +3,7 @@ package com.craisinlord.antarchy.content.fluid; import com.craisinlord.antarchy.Antarchy; import com.craisinlord.antarchy.content.AntarchyObjects; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.effect.MobEffectInstance; @@ -11,34 +12,69 @@ 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.Block; 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.FluidState; import net.minecraft.world.level.material.FlowingFluid; +import net.minecraft.world.level.material.Fluids; public class BileLiquidBlock extends LiquidBlock { private static final ResourceLocation BILE_ID = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "bile"); private static final ResourceLocation FLOWING_BILE_ID = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "flowing_bile"); + private static final ResourceLocation BROODSTONE_ID = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "broodstone"); + private static final ResourceLocation MYRMITE_ID = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "myrmite"); private static final int EFFECT_DURATION_TICKS = 100; public BileLiquidBlock(FlowingFluid fluid, BlockBehaviour.Properties properties) { super(fluid, properties); } + @Override + protected void neighborChanged(BlockState state, Level level, BlockPos pos, Block neighborBlock, BlockPos neighborPos, boolean movedByPiston) { + super.neighborChanged(state, level, pos, neighborBlock, neighborPos, movedByPiston); + if (!level.isClientSide) { + reactWithWater(state, level, pos); + } + } + + @Override + protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean movedByPiston) { + super.onPlace(state, level, pos, oldState, movedByPiston); + if (!level.isClientSide) { + reactWithWater(state, level, pos); + } + } + + private void reactWithWater(BlockState state, Level level, BlockPos pos) { + for (Direction dir : Direction.values()) { + FluidState neighbor = level.getFluidState(pos.relative(dir)); + if (neighbor.is(Fluids.WATER) || neighbor.is(Fluids.FLOWING_WATER)) { + boolean isSource = state.getFluidState().isSource(); + ResourceLocation resultId = isSource ? BROODSTONE_ID : MYRMITE_ID; + Block resultBlock = BuiltInRegistries.BLOCK.getOptional(resultId).orElse(null); + if (resultBlock != null) { + level.setBlock(pos, resultBlock.defaultBlockState(), 3); + level.levelEvent(1501, pos, 0); + } + return; + } + } + } + @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) { + if (livingEntity.getType().is(EntityTypeTags.SENSITIVE_TO_BANE_OF_ARTHROPODS)) { + return; + } 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; - } } } 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 3b9d1ab1..3b88db8e 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 @@ -126,11 +126,10 @@ public class ElythiaBiomeSource extends BiomeSource { return oceanHolder != null ? oceanHolder : seaLevelBiome; } - // Land column in the shallow-underwater zone: force ocean for surface biomes that - // ended up below sea level (e.g. meadow in a depression). Only applies within - // 6 quarts (~24 blocks) of sea level — deep underground is unaffected. - if (y >= this.seaLevelQuartY - 6 && y <= this.seaLevelQuartY - && oceanHolder != null && !allowedBelowSeaLevel(biome)) { + // Land column below sea level: force any non-allowed surface biome to ocean. + // Cave sand/decorations are prevented by above_preliminary_surface in the + // surface rules, so this is safe to apply unconditionally. + if (y <= this.seaLevelQuartY && oceanHolder != null && !allowedBelowSeaLevel(biome)) { return oceanHolder; } diff --git a/common/src/main/resources/assets/antarchy/animations/bomber.animation.json b/common/src/main/resources/assets/antarchy/animations/bomber.animation.json index 4bd766fb..de1fdc78 100644 --- a/common/src/main/resources/assets/antarchy/animations/bomber.animation.json +++ b/common/src/main/resources/assets/antarchy/animations/bomber.animation.json @@ -66,7 +66,7 @@ "animation_length": 0.5, "sound_effects": { "0.0": { - "effect": "antarchy:bomber_walk|0.9|1.0" + "effect": "antarchy:bomber_walk|1.5|1.0" } }, "bones": { 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 ca6c9f4f..72b2fc94 100644 --- a/common/src/main/resources/assets/antarchy/lang/en_us.json +++ b/common/src/main/resources/assets/antarchy/lang/en_us.json @@ -159,6 +159,7 @@ "entity.antarchy.bed_bug": "Bed Bug", "entity.antarchy.stink_bug": "Stink Bug", "entity.antarchy.jumpy_bug": "Jumpy Bug", + "entity.antarchy.spit_bug": "Spit Bug", "entity.antarchy.wasp": "Wasp", "entity.antarchy.bomber": "Bomber", "entity.antarchy.moleworm": "Moleworm", @@ -180,6 +181,7 @@ "item.antarchy.wasp_spawn_egg": "Wasp Spawn Egg", "item.antarchy.bomber_spawn_egg": "Bomber Spawn Egg", "item.antarchy.jumpy_bug_spawn_egg": "Jumpy Bug Spawn Egg", + "item.antarchy.spit_bug_spawn_egg": "Spit Bug Spawn Egg", "item.antarchy.big_bertha_blade": "Big Bertha Blade", "item.antarchy.big_bertha_handle": "Big Bertha Handle", "item.antarchy.big_bertha_hilt": "Big Bertha Hilt", @@ -652,6 +654,14 @@ "subtitles.antarchy.bomber_walk": "Bomber walks", "subtitles.antarchy.bomber_knock": "Bomber gets hit", "subtitles.antarchy.bomber_explode": "Bomber fuse hisses", + "subtitles.antarchy.creeping_horror_growl": "Creeping Horror growls", + "subtitles.antarchy.creeping_horror_hurt": "Creeping Horror hurts", + "subtitles.antarchy.creeping_horror_bite": "Creeping Horror bites", + "subtitles.antarchy.lurking_terror_snarl": "Lurking Terror snarls", + "subtitles.antarchy.lurking_terror_hurt": "Lurking Terror hurts", + "subtitles.antarchy.lurking_terror_bite": "Lurking Terror bites", + "subtitles.antarchy.lurking_terror_fly_loop": "Lurking Terror flies", + "subtitles.antarchy.stinky_fly": "Stinky flies buzz", "item.minecraft.potion.effect.inversion": "Potion of Inversion", "item.minecraft.potion.effect.long_inversion": "Potion of Inversion", "item.minecraft.splash_potion.effect.inversion": "Splash Potion of Inversion", diff --git a/common/src/main/resources/assets/antarchy/models/item/spit_bug_spawn_egg.json b/common/src/main/resources/assets/antarchy/models/item/spit_bug_spawn_egg.json new file mode 100644 index 00000000..ddd15597 --- /dev/null +++ b/common/src/main/resources/assets/antarchy/models/item/spit_bug_spawn_egg.json @@ -0,0 +1,3 @@ +{ + "parent": "minecraft:item/template_spawn_egg" +} diff --git a/common/src/main/resources/assets/antarchy/sounds.json b/common/src/main/resources/assets/antarchy/sounds.json index 100a1def..579b758f 100644 --- a/common/src/main/resources/assets/antarchy/sounds.json +++ b/common/src/main/resources/assets/antarchy/sounds.json @@ -466,6 +466,103 @@ } ] }, + "creeping_horror_growl": { + "subtitle": "subtitles.antarchy.creeping_horror_growl", + "sounds": [ + { + "name": "antarchy:mob/creeping_horror/creeping_horror_growl1" + }, + { + "name": "antarchy:mob/creeping_horror/creeping_horror_growl2" + } + ] + }, + "creeping_horror_hurt": { + "subtitle": "subtitles.antarchy.creeping_horror_hurt", + "sounds": [ + { + "name": "antarchy:mob/creeping_horror/creeping_horror_hurt1" + }, + { + "name": "antarchy:mob/creeping_horror/creeping_horror_hurt2" + } + ] + }, + "creeping_horror_bite": { + "subtitle": "subtitles.antarchy.creeping_horror_bite", + "sounds": [ + { + "name": "antarchy:mob/creeping_horror/creeping_horror_bite" + } + ] + }, + "lurking_terror_snarl": { + "subtitle": "subtitles.antarchy.lurking_terror_snarl", + "sounds": [ + { + "name": "antarchy:mob/lurking_terror/lurking_terror_snarl1" + }, + { + "name": "antarchy:mob/lurking_terror/lurking_terror_snarl2" + } + ] + }, + "lurking_terror_hurt": { + "subtitle": "subtitles.antarchy.lurking_terror_hurt", + "sounds": [ + { + "name": "antarchy:mob/lurking_terror/lurking_terror_hurt1" + }, + { + "name": "antarchy:mob/lurking_terror/lurking_terror_hurt2" + } + ] + }, + "lurking_terror_bite": { + "subtitle": "subtitles.antarchy.lurking_terror_bite", + "sounds": [ + { + "name": "antarchy:mob/lurking_terror/lurking_terror_bite1" + } + ] + }, + "lurking_terror_fly_loop": { + "subtitle": "subtitles.antarchy.lurking_terror_fly_loop", + "sounds": [ + { + "name": "antarchy:mob/lurking_terror/lurking_terror_fly_loop" + } + ] + }, + "stinky_fly": { + "subtitle": "subtitles.antarchy.stinky_fly", + "sounds": [ + { + "name": "antarchy:effect/stinky/stinky_flies1" + }, + { + "name": "antarchy:effect/stinky/stinky_flies2" + }, + { + "name": "antarchy:effect/stinky/stinky_flies3" + }, + { + "name": "antarchy:effect/stinky/stinky_flies4" + }, + { + "name": "antarchy:effect/stinky/stinky_flies5" + }, + { + "name": "antarchy:effect/stinky/stinky_flies6" + }, + { + "name": "antarchy:effect/stinky/stinky_flies7" + }, + { + "name": "antarchy:effect/stinky/stinky_flies8" + } + ] + }, "thoraxis_nightmare_wastes_ambient": { "subtitle": "subtitles.antarchy.thoraxis_nightmare_wastes_ambient", "sounds": [ diff --git a/common/src/main/resources/assets/antarchy/sounds/effect/stinky/stinky_flies1.ogg b/common/src/main/resources/assets/antarchy/sounds/effect/stinky/stinky_flies1.ogg new file mode 100644 index 00000000..7f0e4752 Binary files /dev/null and b/common/src/main/resources/assets/antarchy/sounds/effect/stinky/stinky_flies1.ogg differ diff --git a/common/src/main/resources/assets/antarchy/sounds/effect/stinky/stinky_flies2.ogg b/common/src/main/resources/assets/antarchy/sounds/effect/stinky/stinky_flies2.ogg new file mode 100644 index 00000000..aedbdfd1 Binary files /dev/null and b/common/src/main/resources/assets/antarchy/sounds/effect/stinky/stinky_flies2.ogg differ diff --git a/common/src/main/resources/assets/antarchy/sounds/effect/stinky/stinky_flies3.ogg b/common/src/main/resources/assets/antarchy/sounds/effect/stinky/stinky_flies3.ogg new file mode 100644 index 00000000..a7eab4a5 Binary files /dev/null and b/common/src/main/resources/assets/antarchy/sounds/effect/stinky/stinky_flies3.ogg differ diff --git a/common/src/main/resources/assets/antarchy/sounds/effect/stinky/stinky_flies4.ogg b/common/src/main/resources/assets/antarchy/sounds/effect/stinky/stinky_flies4.ogg new file mode 100644 index 00000000..999c8b5f Binary files /dev/null and b/common/src/main/resources/assets/antarchy/sounds/effect/stinky/stinky_flies4.ogg differ diff --git a/common/src/main/resources/assets/antarchy/sounds/effect/stinky/stinky_flies5.ogg b/common/src/main/resources/assets/antarchy/sounds/effect/stinky/stinky_flies5.ogg new file mode 100644 index 00000000..4d744f46 Binary files /dev/null and b/common/src/main/resources/assets/antarchy/sounds/effect/stinky/stinky_flies5.ogg differ diff --git a/common/src/main/resources/assets/antarchy/sounds/effect/stinky/stinky_flies6.ogg b/common/src/main/resources/assets/antarchy/sounds/effect/stinky/stinky_flies6.ogg new file mode 100644 index 00000000..19c373b1 Binary files /dev/null and b/common/src/main/resources/assets/antarchy/sounds/effect/stinky/stinky_flies6.ogg differ diff --git a/common/src/main/resources/assets/antarchy/sounds/effect/stinky/stinky_flies7.ogg b/common/src/main/resources/assets/antarchy/sounds/effect/stinky/stinky_flies7.ogg new file mode 100644 index 00000000..add34ab4 Binary files /dev/null and b/common/src/main/resources/assets/antarchy/sounds/effect/stinky/stinky_flies7.ogg differ diff --git a/common/src/main/resources/assets/antarchy/sounds/effect/stinky/stinky_flies8.ogg b/common/src/main/resources/assets/antarchy/sounds/effect/stinky/stinky_flies8.ogg new file mode 100644 index 00000000..16fad7fd Binary files /dev/null and b/common/src/main/resources/assets/antarchy/sounds/effect/stinky/stinky_flies8.ogg differ diff --git a/common/src/main/resources/assets/antarchy/sounds/mob/creeping_horror/creeping_horror_bite.ogg b/common/src/main/resources/assets/antarchy/sounds/mob/creeping_horror/creeping_horror_bite.ogg new file mode 100644 index 00000000..b1aa509a Binary files /dev/null and b/common/src/main/resources/assets/antarchy/sounds/mob/creeping_horror/creeping_horror_bite.ogg differ diff --git a/common/src/main/resources/assets/antarchy/sounds/mob/creeping_horror/creeping_horror_growl1.ogg b/common/src/main/resources/assets/antarchy/sounds/mob/creeping_horror/creeping_horror_growl1.ogg new file mode 100644 index 00000000..746f4f3a Binary files /dev/null and b/common/src/main/resources/assets/antarchy/sounds/mob/creeping_horror/creeping_horror_growl1.ogg differ diff --git a/common/src/main/resources/assets/antarchy/sounds/mob/creeping_horror/creeping_horror_growl2.ogg b/common/src/main/resources/assets/antarchy/sounds/mob/creeping_horror/creeping_horror_growl2.ogg new file mode 100644 index 00000000..a60677ea Binary files /dev/null and b/common/src/main/resources/assets/antarchy/sounds/mob/creeping_horror/creeping_horror_growl2.ogg differ diff --git a/common/src/main/resources/assets/antarchy/sounds/mob/creeping_horror/creeping_horror_hurt1.ogg b/common/src/main/resources/assets/antarchy/sounds/mob/creeping_horror/creeping_horror_hurt1.ogg new file mode 100644 index 00000000..1ad6f0ec Binary files /dev/null and b/common/src/main/resources/assets/antarchy/sounds/mob/creeping_horror/creeping_horror_hurt1.ogg differ diff --git a/common/src/main/resources/assets/antarchy/sounds/mob/creeping_horror/creeping_horror_hurt2.ogg b/common/src/main/resources/assets/antarchy/sounds/mob/creeping_horror/creeping_horror_hurt2.ogg new file mode 100644 index 00000000..e1f10239 Binary files /dev/null and b/common/src/main/resources/assets/antarchy/sounds/mob/creeping_horror/creeping_horror_hurt2.ogg differ diff --git a/common/src/main/resources/assets/antarchy/sounds/mob/lurking_terror/lurking_terror_bite1.ogg b/common/src/main/resources/assets/antarchy/sounds/mob/lurking_terror/lurking_terror_bite1.ogg new file mode 100644 index 00000000..a72b530e Binary files /dev/null and b/common/src/main/resources/assets/antarchy/sounds/mob/lurking_terror/lurking_terror_bite1.ogg differ diff --git a/common/src/main/resources/assets/antarchy/sounds/mob/lurking_terror/lurking_terror_hurt1.ogg b/common/src/main/resources/assets/antarchy/sounds/mob/lurking_terror/lurking_terror_hurt1.ogg new file mode 100644 index 00000000..1ad6f0ec Binary files /dev/null and b/common/src/main/resources/assets/antarchy/sounds/mob/lurking_terror/lurking_terror_hurt1.ogg differ diff --git a/common/src/main/resources/assets/antarchy/sounds/mob/lurking_terror/lurking_terror_hurt2.ogg b/common/src/main/resources/assets/antarchy/sounds/mob/lurking_terror/lurking_terror_hurt2.ogg new file mode 100644 index 00000000..e1f10239 Binary files /dev/null and b/common/src/main/resources/assets/antarchy/sounds/mob/lurking_terror/lurking_terror_hurt2.ogg differ diff --git a/common/src/main/resources/assets/antarchy/sounds/mob/lurking_terror/lurking_terror_snarl1.ogg b/common/src/main/resources/assets/antarchy/sounds/mob/lurking_terror/lurking_terror_snarl1.ogg new file mode 100644 index 00000000..669bbdc8 Binary files /dev/null and b/common/src/main/resources/assets/antarchy/sounds/mob/lurking_terror/lurking_terror_snarl1.ogg differ diff --git a/common/src/main/resources/assets/antarchy/sounds/mob/lurking_terror/lurking_terror_snarl2.ogg b/common/src/main/resources/assets/antarchy/sounds/mob/lurking_terror/lurking_terror_snarl2.ogg new file mode 100644 index 00000000..1305bb04 Binary files /dev/null and b/common/src/main/resources/assets/antarchy/sounds/mob/lurking_terror/lurking_terror_snarl2.ogg differ diff --git a/common/src/main/resources/data/antarchy/dimension/cavaryn.json b/common/src/main/resources/data/antarchy/dimension/cavaryn.json index 71098217..5a96e0a7 100644 --- a/common/src/main/resources/data/antarchy/dimension/cavaryn.json +++ b/common/src/main/resources/data/antarchy/dimension/cavaryn.json @@ -13,7 +13,7 @@ "continentalness": [-1.0, 1.0], "erosion": [-1.0, 1.0], "weirdness": [-1.0, 1.0], - "depth": [-2.0, 0.7], + "depth": [-2.0, -0.1], "offset": 0.0 }, "biome": "antarchy:cavaryn" @@ -25,7 +25,7 @@ "continentalness": [-1.0, 1.0], "erosion": [-1.0, 1.0], "weirdness": [-1.0, 1.0], - "depth": [0.7, 2.0], + "depth": [-0.1, 2.0], "offset": 0.0 }, "biome": "antarchy:brooding_tunnels" diff --git a/common/src/main/resources/data/antarchy/dimension/elythia.json b/common/src/main/resources/data/antarchy/dimension/elythia.json index ccccf713..34edaa91 100644 --- a/common/src/main/resources/data/antarchy/dimension/elythia.json +++ b/common/src/main/resources/data/antarchy/dimension/elythia.json @@ -7,8 +7,8 @@ "type": "antarchy:elythia_biome_source", "moleworm_caves_max_y": 30, "surface_biome_sample_y": 160, - "ocean_max_y": 67, - "sea_level": 70, + "ocean_max_y": 62, + "sea_level": 65, "biomes": [ { "biome": "antarchy:moleworm_caves", diff --git a/common/src/main/resources/data/antarchy/loot_table/entities/spit_bug.json b/common/src/main/resources/data/antarchy/loot_table/entities/spit_bug.json new file mode 100644 index 00000000..bed1a754 --- /dev/null +++ b/common/src/main/resources/data/antarchy/loot_table/entities/spit_bug.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/spit_bug" +} diff --git a/common/src/main/resources/data/antarchy/structure/toreterror_arena/toreterror_arena.nbt b/common/src/main/resources/data/antarchy/structure/toreterror_arena/toreterror_arena.nbt index ec30c888..f36059d3 100644 Binary files a/common/src/main/resources/data/antarchy/structure/toreterror_arena/toreterror_arena.nbt and b/common/src/main/resources/data/antarchy/structure/toreterror_arena/toreterror_arena.nbt differ diff --git a/common/src/main/resources/data/antarchy/structure/toreterror_arena/toreterror_arena_bottom.nbt b/common/src/main/resources/data/antarchy/structure/toreterror_arena/toreterror_arena_bottom.nbt index b82ec575..c02c9e2f 100644 Binary files a/common/src/main/resources/data/antarchy/structure/toreterror_arena/toreterror_arena_bottom.nbt and b/common/src/main/resources/data/antarchy/structure/toreterror_arena/toreterror_arena_bottom.nbt differ 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 79a55585..32b4ea7d 100644 --- a/common/src/main/resources/data/antarchy/worldgen/biome/cavaryn.json +++ b/common/src/main/resources/data/antarchy/worldgen/biome/cavaryn.json @@ -38,13 +38,13 @@ [], [ "antarchy:cavaryn_bile_veins", - "antarchy:cavaryn_wall_amber_moss", + "antarchy:cavaryn_bile_cysts", "antarchy:cavaryn_chiten_spikes", "antarchy:cavaryn_terror_egg_patch", + "antarchy:cavaryn_wall_amber_moss", "antarchy:cavaryn_creepvine" ], [ - "antarchy:cavaryn_bile_cysts" ] ], "creature_spawn_probability": 0.06, diff --git a/common/src/main/resources/data/antarchy/worldgen/biome/sparse_ouranwood_forest.json b/common/src/main/resources/data/antarchy/worldgen/biome/sparse_ouranwood_forest.json index cfa7f932..55655a56 100644 --- a/common/src/main/resources/data/antarchy/worldgen/biome/sparse_ouranwood_forest.json +++ b/common/src/main/resources/data/antarchy/worldgen/biome/sparse_ouranwood_forest.json @@ -62,7 +62,8 @@ [ "antarchy:ouranwood_trees_sparse", "antarchy:elythia_forest_flora", - "antarchy:elythia_brown_ant_nests" + "antarchy:elythia_brown_ant_nests", + "antarchy:termite_nest" ], [] ], diff --git a/common/src/main/resources/data/antarchy/worldgen/configured_feature/termite_nest.json b/common/src/main/resources/data/antarchy/worldgen/configured_feature/termite_nest.json new file mode 100644 index 00000000..f777d3bb --- /dev/null +++ b/common/src/main/resources/data/antarchy/worldgen/configured_feature/termite_nest.json @@ -0,0 +1,14 @@ +{ + "type": "antarchy:termite_nest", + "config": { + "to_place": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "antarchy:termite_nest", + "Properties": { + "facing": "north" + } + } + } + } +} 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 b2212c26..9a4a7d46 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 @@ -1,5 +1,5 @@ { - "sea_level": 70, + "sea_level": 65, "disable_mob_generation": false, "aquifers_enabled": true, "ore_veins_enabled": false, @@ -487,73 +487,77 @@ "biome_is": ["antarchy:elythia_ocean", "antarchy:elythia_coral_spikes"] }, "then_run": { - "type": "minecraft:sequence", - "sequence": [ - { - "type": "minecraft:condition", - "if_true": { - "type": "minecraft:stone_depth", - "add_surface_depth": false, - "offset": 0, - "secondary_depth_range": 0, - "surface_type": "floor" - }, - "then_run": { - "type": "minecraft:sequence", - "sequence": [ - { - "type": "minecraft:condition", - "if_true": { - "type": "minecraft:water", - "offset": 0, - "surface_depth_multiplier": 0, - "add_stone_depth": false + "type": "minecraft:condition", + "if_true": { "type": "minecraft:above_preliminary_surface" }, + "then_run": { + "type": "minecraft:sequence", + "sequence": [ + { + "type": "minecraft:condition", + "if_true": { + "type": "minecraft:stone_depth", + "add_surface_depth": false, + "offset": 0, + "secondary_depth_range": 0, + "surface_type": "floor" + }, + "then_run": { + "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:sand" } + } }, - "then_run": { + { "type": "minecraft:block", "result_state": { "Name": "minecraft:sand" } } - }, - { - "type": "minecraft:block", - "result_state": { "Name": "minecraft:sand" } - } - ] - } - }, - { - "type": "minecraft:condition", - "if_true": { - "type": "minecraft:stone_depth", - "add_surface_depth": false, - "offset": 0, - "secondary_depth_range": 4, - "surface_type": "floor" + ] + } }, - "then_run": { + { + "type": "minecraft:condition", + "if_true": { + "type": "minecraft:stone_depth", + "add_surface_depth": false, + "offset": 0, + "secondary_depth_range": 4, + "surface_type": "floor" + }, + "then_run": { + "type": "minecraft:block", + "result_state": { "Name": "antarchy:shellstone" } + } + }, + { + "type": "minecraft:condition", + "if_true": { + "type": "minecraft:stone_depth", + "add_surface_depth": true, + "offset": 0, + "secondary_depth_range": 0, + "surface_type": "floor" + }, + "then_run": { + "type": "minecraft:block", + "result_state": { "Name": "antarchy:shellstone" } + } + }, + { "type": "minecraft:block", "result_state": { "Name": "antarchy:shellstone" } } - }, - { - "type": "minecraft:condition", - "if_true": { - "type": "minecraft:stone_depth", - "add_surface_depth": true, - "offset": 0, - "secondary_depth_range": 0, - "surface_type": "floor" - }, - "then_run": { - "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_creepvine.json b/common/src/main/resources/data/antarchy/worldgen/placed_feature/cavaryn_creepvine.json index 2f2740bf..f81d4998 100644 --- 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 @@ -3,7 +3,7 @@ "placement": [ { "type": "minecraft:count", - "count": 9 + "count": 18 }, { "type": "minecraft:in_square" diff --git a/common/src/main/resources/data/antarchy/worldgen/placed_feature/termite_nest.json b/common/src/main/resources/data/antarchy/worldgen/placed_feature/termite_nest.json new file mode 100644 index 00000000..70a93fad --- /dev/null +++ b/common/src/main/resources/data/antarchy/worldgen/placed_feature/termite_nest.json @@ -0,0 +1,19 @@ +{ + "feature": "antarchy:termite_nest", + "placement": [ + { + "type": "minecraft:rarity_filter", + "chance": 88 + }, + { + "type": "minecraft:in_square" + }, + { + "type": "minecraft:heightmap", + "heightmap": "WORLD_SURFACE_WG" + }, + { + "type": "minecraft:biome" + } + ] +} diff --git a/common/src/main/resources/data/minecraft/tags/entity_type/arthropod.json b/common/src/main/resources/data/minecraft/tags/entity_type/arthropod.json index 59b9fd2d..23a5c7e0 100644 --- a/common/src/main/resources/data/minecraft/tags/entity_type/arthropod.json +++ b/common/src/main/resources/data/minecraft/tags/entity_type/arthropod.json @@ -9,6 +9,7 @@ "antarchy:bed_bug", "antarchy:mantis", "antarchy:jumpy_bug", + "antarchy:spit_bug", "antarchy:stink_bug", "antarchy:creeping_horror", "antarchy:lurking_terror", 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 5519915f..cd39cd98 100644 --- a/fabric/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabricContent.java +++ b/fabric/src/main/java/com/craisinlord/antarchy/fabric/AntarchyFabricContent.java @@ -84,6 +84,8 @@ import com.craisinlord.antarchy.content.entity.MolevoreEntity; import com.craisinlord.antarchy.content.entity.MolewormEntity; import com.craisinlord.antarchy.content.entity.BomberEntity; import com.craisinlord.antarchy.content.entity.SizeRayProjectileEntity; +import com.craisinlord.antarchy.content.entity.SpitBugEntity; +import com.craisinlord.antarchy.content.entity.SpitBugProjectileEntity; import com.craisinlord.antarchy.content.entity.TriffidEntity; import com.craisinlord.antarchy.content.entity.WaspEntity; import com.craisinlord.antarchy.content.entity.ant.BaseAntEntity; @@ -392,6 +394,14 @@ public final class AntarchyFabricContent { public static final DeferredHolder BOMBER_WALK = registerSoundEvent("bomber_walk"); public static final DeferredHolder BOMBER_KNOCK = registerSoundEvent("bomber_knock"); public static final DeferredHolder BOMBER_EXPLODE = registerSoundEvent("bomber_explode"); + public static final DeferredHolder STINKY_FLY_SOUND = registerSoundEvent("stinky_fly"); + public static final DeferredHolder CREEPING_HORROR_GROWL = registerSoundEvent("creeping_horror_growl"); + public static final DeferredHolder CREEPING_HORROR_HURT = registerSoundEvent("creeping_horror_hurt"); + public static final DeferredHolder CREEPING_HORROR_BITE = registerSoundEvent("creeping_horror_bite"); + public static final DeferredHolder LURKING_TERROR_SNARL = registerSoundEvent("lurking_terror_snarl"); + public static final DeferredHolder LURKING_TERROR_HURT = registerSoundEvent("lurking_terror_hurt"); + public static final DeferredHolder LURKING_TERROR_BITE = registerSoundEvent("lurking_terror_bite"); + public static final DeferredHolder LURKING_TERROR_FLY_LOOP = registerSoundEvent("lurking_terror_fly_loop"); public static final DeferredHolder DUCT_TAPE_USE = registerSoundEvent("duct_tape_use"); public static final DeferredHolder POTENT_NYXITE_HYPNOTIC_GAS = registerSoundEvent("potent_nyxite_hypnotic_gas"); public static final DeferredHolder POTENT_NYXITE_GEYSER_ERUPTION_START = registerSoundEvent("potent_nyxite_geyser_eruption_start"); @@ -852,6 +862,17 @@ public final class AntarchyFabricContent { .sized(3.0F, 3.0F) .clientTrackingRange(8) .build("jumpy_bug")); + public static final DeferredHolder, EntityType> SPIT_BUG = ENTITY_TYPES.register("spit_bug", + () -> EntityType.Builder.of(SpitBugEntity::new, MobCategory.MONSTER) + .sized(2.5F, 3.0F) + .clientTrackingRange(10) + .build("spit_bug")); + public static final DeferredHolder, EntityType> SPIT_BUG_PROJECTILE = ENTITY_TYPES.register("spit_bug_projectile", + () -> EntityType.Builder.of(SpitBugProjectileEntity::new, MobCategory.MISC) + .sized(0.5F, 0.5F) + .clientTrackingRange(8) + .updateInterval(1) + .build("spit_bug_projectile")); public static final DeferredHolder, EntityType> SHRINK_RAY_PROJECTILE = ENTITY_TYPES.register("shrink_ray_projectile", () -> EntityType.Builder.of(SizeRayProjectileEntity::createShrink, MobCategory.MISC) .sized(0.5F, 0.5F) @@ -1715,6 +1736,8 @@ public final class AntarchyFabricContent { () -> new DeferredSpawnEggItem(BOMBER, 0x7A7A7A, 0xB32020, new Item.Properties())); public static final DeferredItem JUMPY_BUG_SPAWN_EGG = ITEMS.register("jumpy_bug_spawn_egg", () -> new DeferredSpawnEggItem(JUMPY_BUG, 0x0A1636, 0x8A3E00, new Item.Properties())); + public static final DeferredItem SPIT_BUG_SPAWN_EGG = ITEMS.register("spit_bug_spawn_egg", + () -> new DeferredSpawnEggItem(SPIT_BUG, 0x6B4A2B, 0x7ED957, new Item.Properties())); public static final DeferredItem STINK_BUG_SPAWN_EGG = ITEMS.register("stink_bug_spawn_egg", () -> new DeferredSpawnEggItem(STINK_BUG, 0x111111, 0xFF7A00, new Item.Properties())); public static final DeferredItem CLOUD_SHARK_SPAWN_EGG = ITEMS.register("cloud_shark_spawn_egg", @@ -1861,6 +1884,7 @@ public final class AntarchyFabricContent { FabricDefaultAttributeRegistry.register(WASP.get(), WaspEntity.createAttributes().build()); FabricDefaultAttributeRegistry.register(BOMBER.get(), BomberEntity.createAttributes().build()); FabricDefaultAttributeRegistry.register(JUMPY_BUG.get(), JumpyBugEntity.createAttributes().build()); + FabricDefaultAttributeRegistry.register(SPIT_BUG.get(), SpitBugEntity.createAttributes().build()); FabricDefaultAttributeRegistry.register(MANTIS.get(), MantisEntity.createAttributes().build()); FabricDefaultAttributeRegistry.register(TRIFFID.get(), TriffidEntity.createAttributes().build()); FabricDefaultAttributeRegistry.register(LUCID.get(), LucidEntity.createAttributes().build()); @@ -1908,6 +1932,7 @@ public final class AntarchyFabricContent { SpawnPlacements.register(WASP.get(), SpawnPlacementTypes.NO_RESTRICTIONS, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, WaspEntity::canSpawn); SpawnPlacements.register(BOMBER.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, BomberEntity::canSpawn); SpawnPlacements.register(JUMPY_BUG.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, JumpyBugEntity::canSpawn); + SpawnPlacements.register(SPIT_BUG.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, SpitBugEntity::canSpawn); SpawnPlacements.register(KRAKEN.get(), SpawnPlacementTypes.IN_WATER, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, KrakenEntity::canSpawn); SpawnPlacements.register(MISSILE_SQUID.get(), SpawnPlacementTypes.IN_WATER, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, MissileSquidEntity::canSpawn); SpawnPlacements.register(OCTOPUS_BOMB.get(), SpawnPlacementTypes.IN_WATER, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, OctopusBombEntity::canSpawn); @@ -2018,7 +2043,7 @@ public final class AntarchyFabricContent { "moleworm_spawn_egg", "mantis_spawn_egg", "molevore_spawn_egg", "triffid_spawn_egg", "apple_cow_spawn_egg", "golden_apple_cow_spawn_egg", "enchanted_golden_apple_cow_spawn_egg", "honeyed_apple_cow_spawn_egg", "dr_trayaurus_spawn_egg", "wasp_spawn_egg", - "bomber_spawn_egg", "jumpy_bug_spawn_egg", "stink_bug_spawn_egg", "cloud_shark_spawn_egg", "kraken_spawn_egg", "missile_squid_spawn_egg", "octopus_bomb_spawn_egg", + "bomber_spawn_egg", "jumpy_bug_spawn_egg", "spit_bug_spawn_egg", "stink_bug_spawn_egg", "cloud_shark_spawn_egg", "kraken_spawn_egg", "missile_squid_spawn_egg", "octopus_bomb_spawn_egg", "nightmare_spawn_egg", "bed_bug_spawn_egg", "lucid_spawn_egg", "scorpion_spawn_egg", "basilisk_spawn_egg", "emperor_scorpion_spawn_egg", "toreterror_spawn_egg", "creeping_horror_spawn_egg", "lurking_terror_spawn_egg" -> 90; @@ -2420,6 +2445,14 @@ public final class AntarchyFabricContent { BOMBER_WALK, BOMBER_KNOCK, BOMBER_EXPLODE, + STINKY_FLY_SOUND, + CREEPING_HORROR_GROWL, + CREEPING_HORROR_HURT, + CREEPING_HORROR_BITE, + LURKING_TERROR_SNARL, + LURKING_TERROR_HURT, + LURKING_TERROR_BITE, + LURKING_TERROR_FLY_LOOP, DUCT_TAPE_USE ); 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 04d4786e..ffa46565 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 @@ -24,6 +24,7 @@ import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.client.renderer.blockentity.CampfireRenderer; +import net.minecraft.client.renderer.entity.ArmorStandRenderer; import net.minecraft.client.renderer.entity.ThrownItemRenderer; import net.minecraft.client.renderer.item.ItemProperties; import net.minecraft.resources.ResourceLocation; @@ -96,6 +97,7 @@ public final class AntarchyFabricClientBootstrap { EntityRendererRegistry.register(AntarchyFabricContent.WASP.get(), WaspRenderer::new); EntityRendererRegistry.register(AntarchyFabricContent.BOMBER.get(), BomberRenderer::new); EntityRendererRegistry.register(AntarchyFabricContent.JUMPY_BUG.get(), JumpyBugRenderer::new); + EntityRendererRegistry.register(AntarchyFabricContent.SPIT_BUG.get(), SpitBugRenderer::new); EntityRendererRegistry.register(AntarchyFabricContent.BASILISK.get(), BasiliskRenderer::new); EntityRendererRegistry.register(AntarchyFabricContent.SHRINK_RAY_PROJECTILE.get(), SizeRayProjectileRenderer::new); EntityRendererRegistry.register(AntarchyFabricContent.GROWTH_RAY_PROJECTILE.get(), SizeRayProjectileRenderer::new); @@ -103,6 +105,7 @@ public final class AntarchyFabricClientBootstrap { EntityRendererRegistry.register(AntarchyFabricContent.LUCID_PEARL_PROJECTILE.get(), ThrownItemRenderer::new); EntityRendererRegistry.register(AntarchyFabricContent.HUSH_PROJECTILE.get(), HushProjectileRenderer::new); EntityRendererRegistry.register(AntarchyFabricContent.BRUTALFLY_ORB.get(), BrutalflyOrbRenderer::new); + EntityRendererRegistry.register(AntarchyFabricContent.SPIT_BUG_PROJECTILE.get(), SpitBugProjectileRenderer::new); EntityRendererRegistry.register(AntarchyFabricContent.UPWARD_FALLING_BLOCK.get(), UpwardFallingBlockRenderer::new); EntityRendererRegistry.register(AntarchyFabricContent.SCORPION.get(), ScorpionRenderer::new); EntityRendererRegistry.register(AntarchyFabricContent.EMPEROR_SCORPION.get(), EmperorScorpionRenderer::new); @@ -296,6 +299,10 @@ public final class AntarchyFabricClientBootstrap { } return; } + if (entityType == EntityType.ARMOR_STAND && renderer instanceof ArmorStandRenderer armorStandRenderer) { + registrationHelper.register(new FallenKingCrownArmorStandLayer((net.minecraft.client.renderer.entity.RenderLayerParent) armorStandRenderer)); + return; + } if (software.bernie.geckolib.renderer.GeoEntityRenderer.class.isAssignableFrom(renderer.getClass())) { software.bernie.geckolib.renderer.GeoEntityRenderer geoRenderer = (software.bernie.geckolib.renderer.GeoEntityRenderer) (Object) renderer; @@ -325,6 +332,7 @@ public final class AntarchyFabricClientBootstrap { ElythiaFireflyManager.register(); LucidSoundHandler.register(); MogglesClientRenderer.register(); + StinkySoundHandler.register(); ReverieTrailHandler.register(); HudRenderCallback.EVENT.register((guiGraphics, partialTick) -> { diff --git a/fabric/src/main/java/com/craisinlord/antarchy/fabric/client/FallenKingCrownArmorStandLayer.java b/fabric/src/main/java/com/craisinlord/antarchy/fabric/client/FallenKingCrownArmorStandLayer.java new file mode 100644 index 00000000..4d36e49e --- /dev/null +++ b/fabric/src/main/java/com/craisinlord/antarchy/fabric/client/FallenKingCrownArmorStandLayer.java @@ -0,0 +1,45 @@ +package com.craisinlord.antarchy.fabric.client; + +import com.craisinlord.antarchy.fabric.AntarchyFabricContent; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Axis; +import net.minecraft.client.Minecraft; +import net.minecraft.client.model.ArmorStandModel; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.block.BlockRenderDispatcher; +import net.minecraft.client.renderer.entity.LivingEntityRenderer; +import net.minecraft.client.renderer.entity.RenderLayerParent; +import net.minecraft.client.renderer.entity.layers.RenderLayer; +import net.minecraft.world.entity.decoration.ArmorStand; +import net.minecraft.world.item.ItemStack; + +public final class FallenKingCrownArmorStandLayer extends RenderLayer { + private final BlockRenderDispatcher blockRenderer; + + public FallenKingCrownArmorStandLayer(RenderLayerParent renderer) { + super(renderer); + this.blockRenderer = Minecraft.getInstance().getBlockRenderer(); + } + + @Override + public void render(PoseStack poseStack, MultiBufferSource buffer, int packedLight, ArmorStand armorStand, float limbSwing, float limbSwingAmount, float partialTick, float ageInTicks, float netHeadYaw, float headPitch) { + ItemStack headStack = armorStand.getItemBySlot(net.minecraft.world.entity.EquipmentSlot.HEAD); + if (!headStack.is(AntarchyFabricContent.FALLEN_KING_CROWN.get()) || armorStand.isInvisible()) { + return; + } + + poseStack.pushPose(); + this.getParentModel().head.translateAndRotate(poseStack); + poseStack.translate(0.5D, -0.125D, -0.5D); + poseStack.mulPose(Axis.XP.rotationDegrees(180.0F)); + poseStack.mulPose(Axis.YP.rotationDegrees(180.0F)); + this.blockRenderer.renderSingleBlock( + AntarchyFabricContent.FALLEN_KING_CROWN_BLOCK.get().defaultBlockState(), + poseStack, + buffer, + packedLight, + LivingEntityRenderer.getOverlayCoords(armorStand, 0.0F) + ); + poseStack.popPose(); + } +} diff --git a/fabric/src/main/java/com/craisinlord/antarchy/fabric/client/StinkySoundHandler.java b/fabric/src/main/java/com/craisinlord/antarchy/fabric/client/StinkySoundHandler.java new file mode 100644 index 00000000..e279fb2f --- /dev/null +++ b/fabric/src/main/java/com/craisinlord/antarchy/fabric/client/StinkySoundHandler.java @@ -0,0 +1,48 @@ +package com.craisinlord.antarchy.fabric.client; + +import com.craisinlord.antarchy.content.AntarchySoundEvents; +import com.craisinlord.antarchy.content.AntarchyObjects; +import com.craisinlord.antarchy.fabric.AntarchyFabricContent; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +import net.minecraft.client.Minecraft; +import net.minecraft.sounds.SoundSource; + +public final class StinkySoundHandler { + private static final int FIRST_SOUND_DELAY = 20; + private static final int MIN_INTERVAL = 60; + private static final int MAX_INTERVAL = 120; + + private static int nextSoundTick = FIRST_SOUND_DELAY; + + private StinkySoundHandler() { + } + + public static void register() { + ClientTickEvents.END_CLIENT_TICK.register(client -> { + if (client.level == null || client.player == null || client.isPaused()) { + nextSoundTick = FIRST_SOUND_DELAY; + return; + } + + if (!client.player.hasEffect(AntarchyObjects.STINKY_EFFECT.get())) { + nextSoundTick = FIRST_SOUND_DELAY; + return; + } + + nextSoundTick--; + if (nextSoundTick > 0) { + return; + } + + client.level.playSound( + null, + client.player.blockPosition(), + AntarchySoundEvents.STINKY_FLY.get(), + SoundSource.AMBIENT, + 0.14F + client.level.random.nextFloat() * 0.06F, + 0.92F + client.level.random.nextFloat() * 0.16F + ); + nextSoundTick = MIN_INTERVAL + client.level.random.nextInt(MAX_INTERVAL - MIN_INTERVAL + 1); + }); + } +} diff --git a/fabric/src/main/resources/data/minecraft/tags/fluid/water.json b/fabric/src/main/resources/data/minecraft/tags/fluid/water.json new file mode 100644 index 00000000..6d00bd9c --- /dev/null +++ b/fabric/src/main/resources/data/minecraft/tags/fluid/water.json @@ -0,0 +1,6 @@ +{ + "values": [ + "antarchy:ichor", + "antarchy:flowing_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 a870ec80..b9cde459 100644 --- a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyNeoforge.java +++ b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/AntarchyNeoforge.java @@ -137,6 +137,14 @@ public class AntarchyNeoforge { AntarchyNeoforgeSounds.BOMBER_WALK, AntarchyNeoforgeSounds.BOMBER_KNOCK, AntarchyNeoforgeSounds.BOMBER_EXPLODE, + AntarchyNeoforgeSounds.STINKY_FLY, + AntarchyNeoforgeSounds.CREEPING_HORROR_GROWL, + AntarchyNeoforgeSounds.CREEPING_HORROR_HURT, + AntarchyNeoforgeSounds.CREEPING_HORROR_BITE, + AntarchyNeoforgeSounds.LURKING_TERROR_SNARL, + AntarchyNeoforgeSounds.LURKING_TERROR_HURT, + AntarchyNeoforgeSounds.LURKING_TERROR_BITE, + AntarchyNeoforgeSounds.LURKING_TERROR_FLY_LOOP, AntarchyNeoforgeSounds.DUCT_TAPE_USE ); bindCommonObjects(); 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 5b85ef4c..91ae15fc 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 @@ -15,6 +15,7 @@ import com.mojang.blaze3d.shaders.FogShape; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.VertexConsumer; import net.minecraft.client.model.BoatModel; +import net.minecraft.client.model.ArmorStandModel; import net.minecraft.client.model.ChestBoatModel; import net.minecraft.client.model.PlayerModel; import net.minecraft.client.model.HumanoidModel; @@ -33,6 +34,7 @@ import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer; import net.minecraft.client.renderer.ItemBlockRenderTypes; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.blockentity.CampfireRenderer; +import net.minecraft.client.renderer.entity.ArmorStandRenderer; import net.minecraft.client.renderer.entity.LivingEntityRenderer; import net.minecraft.client.renderer.item.ItemProperties; import net.minecraft.resources.ResourceLocation; @@ -112,6 +114,7 @@ public final class AntarchyNeoForgeClient { event.registerEntityRenderer(AntarchyNeoforgeEntites.WASP.get(), context -> withParalyzedGeoLayer(new WaspRenderer(context))); event.registerEntityRenderer(AntarchyNeoforgeEntites.BOMBER.get(), context -> withParalyzedGeoLayer(new BomberRenderer(context))); event.registerEntityRenderer(AntarchyNeoforgeEntites.JUMPY_BUG.get(), context -> withParalyzedGeoLayer(new JumpyBugRenderer(context))); + event.registerEntityRenderer(AntarchyNeoforgeEntites.SPIT_BUG.get(), context -> withParalyzedGeoLayer(new SpitBugRenderer(context))); event.registerEntityRenderer(AntarchyNeoforgeEntites.BASILISK.get(), context -> withParalyzedGeoLayer(new BasiliskRenderer(context))); event.registerEntityRenderer(AntarchyNeoforgeEntites.SHRINK_RAY_PROJECTILE.get(), SizeRayProjectileRenderer::new); event.registerEntityRenderer(AntarchyNeoforgeEntites.GROWTH_RAY_PROJECTILE.get(), SizeRayProjectileRenderer::new); @@ -119,6 +122,7 @@ public final class AntarchyNeoForgeClient { event.registerEntityRenderer(AntarchyNeoforgeEntites.LUCID_PEARL_PROJECTILE.get(), ThrownItemRenderer::new); event.registerEntityRenderer(AntarchyNeoforgeEntites.HUSH_PROJECTILE.get(), HushProjectileRenderer::new); event.registerEntityRenderer(AntarchyNeoforgeEntites.BRUTALFLY_ORB.get(), BrutalflyOrbRenderer::new); + event.registerEntityRenderer(AntarchyNeoforgeEntites.SPIT_BUG_PROJECTILE.get(), SpitBugProjectileRenderer::new); event.registerEntityRenderer(AntarchyNeoforgeEntites.UPWARD_FALLING_BLOCK.get(), com.craisinlord.antarchy.content.client.renderer.UpwardFallingBlockRenderer::new); event.registerEntityRenderer(AntarchyNeoforgeEntites.SCORPION.get(), context -> withParalyzedGeoLayer(new ScorpionRenderer(context))); event.registerEntityRenderer(AntarchyNeoforgeEntites.EMPEROR_SCORPION.get(), context -> withParalyzedGeoLayer(new EmperorScorpionRenderer(context))); @@ -140,6 +144,11 @@ public final class AntarchyNeoForgeClient { renderer.addLayer(new FallenKingCrownLayer(renderer)); } } + LivingEntityRenderer armorStandRenderer = + (LivingEntityRenderer) event.getRenderer(EntityType.ARMOR_STAND); + if (armorStandRenderer != null) { + armorStandRenderer.addLayer(new FallenKingCrownArmorStandLayer(armorStandRenderer)); + } BuiltInRegistries.ENTITY_TYPE.forEach(entityType -> addParalyzedLayerToEntity(event, entityType)); } diff --git a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/client/FallenKingCrownArmorStandLayer.java b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/client/FallenKingCrownArmorStandLayer.java new file mode 100644 index 00000000..ab2dfdd8 --- /dev/null +++ b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/client/FallenKingCrownArmorStandLayer.java @@ -0,0 +1,46 @@ +package com.craisinlord.antarchy.neoforge.client; + +import com.craisinlord.antarchy.neoforge.registry.AntarchyNeoforgeBlocks; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Axis; +import net.minecraft.client.Minecraft; +import net.minecraft.client.model.ArmorStandModel; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.block.BlockRenderDispatcher; +import net.minecraft.client.renderer.entity.LivingEntityRenderer; +import net.minecraft.client.renderer.entity.RenderLayerParent; +import net.minecraft.client.renderer.entity.layers.RenderLayer; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.decoration.ArmorStand; +import net.minecraft.world.item.ItemStack; + +public final class FallenKingCrownArmorStandLayer extends RenderLayer { + private final BlockRenderDispatcher blockRenderer; + + public FallenKingCrownArmorStandLayer(RenderLayerParent renderer) { + super(renderer); + this.blockRenderer = Minecraft.getInstance().getBlockRenderer(); + } + + @Override + public void render(PoseStack poseStack, MultiBufferSource buffer, int packedLight, ArmorStand armorStand, float limbSwing, float limbSwingAmount, float partialTick, float ageInTicks, float netHeadYaw, float headPitch) { + ItemStack headStack = armorStand.getItemBySlot(EquipmentSlot.HEAD); + if (!headStack.is(com.craisinlord.antarchy.neoforge.registry.AntarchyNeoforgeItems.FALLEN_KING_CROWN.get()) || armorStand.isInvisible()) { + return; + } + + poseStack.pushPose(); + this.getParentModel().head.translateAndRotate(poseStack); + poseStack.translate(0.5D, -0.125D, -0.5D); + poseStack.mulPose(Axis.XP.rotationDegrees(180.0F)); + poseStack.mulPose(Axis.YP.rotationDegrees(180.0F)); + this.blockRenderer.renderSingleBlock( + AntarchyNeoforgeBlocks.FALLEN_KING_CROWN.get().defaultBlockState(), + poseStack, + buffer, + packedLight, + LivingEntityRenderer.getOverlayCoords(armorStand, 0.0F) + ); + poseStack.popPose(); + } +} diff --git a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/client/StinkySoundHandler.java b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/client/StinkySoundHandler.java new file mode 100644 index 00000000..6df0b334 --- /dev/null +++ b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/client/StinkySoundHandler.java @@ -0,0 +1,52 @@ +package com.craisinlord.antarchy.neoforge.client; + +import com.craisinlord.antarchy.Antarchy; +import com.craisinlord.antarchy.content.AntarchyObjects; +import com.craisinlord.antarchy.content.AntarchySoundEvents; +import net.minecraft.client.Minecraft; +import net.minecraft.sounds.SoundSource; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.client.event.ClientTickEvent; + +@EventBusSubscriber(modid = Antarchy.MODID, value = Dist.CLIENT, bus = EventBusSubscriber.Bus.GAME) +public final class StinkySoundHandler { + private static final int FIRST_SOUND_DELAY = 20; + private static final int MIN_INTERVAL = 60; + private static final int MAX_INTERVAL = 120; + + private static int nextSoundTick = FIRST_SOUND_DELAY; + + private StinkySoundHandler() { + } + + @SubscribeEvent + public static void onClientTick(ClientTickEvent.Post event) { + Minecraft mc = Minecraft.getInstance(); + if (mc.level == null || mc.player == null || mc.isPaused()) { + nextSoundTick = FIRST_SOUND_DELAY; + return; + } + + if (!mc.player.hasEffect(AntarchyObjects.STINKY_EFFECT.get())) { + nextSoundTick = FIRST_SOUND_DELAY; + return; + } + + nextSoundTick--; + if (nextSoundTick > 0) { + return; + } + + mc.level.playSound( + null, + mc.player.blockPosition(), + AntarchySoundEvents.STINKY_FLY.get(), + SoundSource.AMBIENT, + 0.14F + mc.level.random.nextFloat() * 0.06F, + 0.92F + mc.level.random.nextFloat() * 0.16F + ); + nextSoundTick = MIN_INTERVAL + mc.level.random.nextInt(MAX_INTERVAL - MIN_INTERVAL + 1); + } +} 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 d51007f4..9a595827 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 @@ -69,6 +69,7 @@ public class AntarchyNeoforgeCreativeModeTabs { event.accept(AntarchyNeoforgeItems.WASP_SPAWN_EGG.get()); event.accept(AntarchyNeoforgeItems.BOMBER_SPAWN_EGG.get()); event.accept(AntarchyNeoforgeItems.JUMPY_BUG_SPAWN_EGG.get()); + event.accept(AntarchyNeoforgeItems.SPIT_BUG_SPAWN_EGG.get()); event.accept(AntarchyNeoforgeItems.STINK_BUG_SPAWN_EGG.get()); event.accept(AntarchyNeoforgeItems.CLOUD_SHARK_SPAWN_EGG.get()); event.accept(AntarchyNeoforgeItems.KRAKEN_SPAWN_EGG.get()); diff --git a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeEntites.java b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeEntites.java index 361b7693..81417ae0 100644 --- a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeEntites.java +++ b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeEntites.java @@ -26,6 +26,8 @@ import com.craisinlord.antarchy.content.entity.OuranwoodChestBoatEntity; import com.craisinlord.antarchy.content.entity.ReverieEntity; import com.craisinlord.antarchy.content.entity.ScorpionEntity; import com.craisinlord.antarchy.content.entity.SizeRayProjectileEntity; +import com.craisinlord.antarchy.content.entity.SpitBugEntity; +import com.craisinlord.antarchy.content.entity.SpitBugProjectileEntity; import com.craisinlord.antarchy.content.entity.StinkBugEntity; import com.craisinlord.antarchy.content.entity.TriffidEntity; import com.craisinlord.antarchy.content.entity.UpwardFallingBlockEntity; @@ -135,6 +137,17 @@ public final class AntarchyNeoforgeEntites { .sized(3.0F, 3.0F) .clientTrackingRange(8) .build("jumpy_bug")); + public static final DeferredHolder, EntityType> SPIT_BUG = ENTITY_TYPES.register("spit_bug", + () -> EntityType.Builder.of(SpitBugEntity::new, MobCategory.MONSTER) + .sized(2.5F, 3.0F) + .clientTrackingRange(10) + .build("spit_bug")); + public static final DeferredHolder, EntityType> SPIT_BUG_PROJECTILE = ENTITY_TYPES.register("spit_bug_projectile", + () -> EntityType.Builder.of(SpitBugProjectileEntity::new, MobCategory.MISC) + .sized(0.5F, 0.5F) + .clientTrackingRange(8) + .updateInterval(1) + .build("spit_bug_projectile")); public static final DeferredHolder, EntityType> SHRINK_RAY_PROJECTILE = ENTITY_TYPES.register("shrink_ray_projectile", () -> EntityType.Builder.of(SizeRayProjectileEntity::createShrink, MobCategory.MISC) .sized(0.5F, 0.5F) diff --git a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeEntityAttributes.java b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeEntityAttributes.java index 3cf6bf1e..f739c8dc 100644 --- a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeEntityAttributes.java +++ b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeEntityAttributes.java @@ -51,6 +51,7 @@ public class AntarchyNeoforgeEntityAttributes { event.put(AntarchyNeoforgeEntites.WASP.get(), WaspEntity.createAttributes().build()); event.put(AntarchyNeoforgeEntites.BOMBER.get(), BomberEntity.createAttributes().build()); event.put(AntarchyNeoforgeEntites.JUMPY_BUG.get(), JumpyBugEntity.createAttributes().build()); + event.put(AntarchyNeoforgeEntites.SPIT_BUG.get(), SpitBugEntity.createAttributes().build()); event.put(AntarchyNeoforgeEntites.MANTIS.get(), MantisEntity.createAttributes().build()); event.put(AntarchyNeoforgeEntites.TRIFFID.get(), TriffidEntity.createAttributes().build()); event.put(AntarchyNeoforgeEntites.LUCID.get(), LucidEntity.createAttributes().build()); 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 099e6c02..74c1ec69 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 @@ -531,6 +531,8 @@ public final class AntarchyNeoforgeItems { () -> new DeferredSpawnEggItem(AntarchyNeoforgeEntites.BOMBER, 0x7A7A7A, 0xB32020, new Item.Properties())); public static final DeferredItem JUMPY_BUG_SPAWN_EGG = ITEMS.register("jumpy_bug_spawn_egg", () -> new DeferredSpawnEggItem(AntarchyNeoforgeEntites.JUMPY_BUG, 0x0A1636, 0x8A3E00, new Item.Properties())); + public static final DeferredItem SPIT_BUG_SPAWN_EGG = ITEMS.register("spit_bug_spawn_egg", + () -> new DeferredSpawnEggItem(AntarchyNeoforgeEntites.SPIT_BUG, 0x6B4A2B, 0x7ED957, new Item.Properties())); public static final DeferredItem STINK_BUG_SPAWN_EGG = ITEMS.register("stink_bug_spawn_egg", () -> new DeferredSpawnEggItem(AntarchyNeoforgeEntites.STINK_BUG, 0x111111, 0xFF7A00, new Item.Properties())); public static final DeferredItem CLOUD_SHARK_SPAWN_EGG = ITEMS.register("cloud_shark_spawn_egg", 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 43f507fd..eae7bec6 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 @@ -30,8 +30,6 @@ import net.minecraft.core.particles.ParticleType; import net.minecraft.core.particles.SimpleParticleType; import net.minecraft.core.registries.Registries; import net.minecraft.network.codec.StreamCodec; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.damagesource.DamageType; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffects; @@ -43,7 +41,6 @@ import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.SimpleBlockConfiguration; import net.minecraft.world.level.material.Fluid; -import net.minecraft.tags.TagKey; import net.neoforged.bus.api.IEventBus; import net.neoforged.neoforge.common.SoundActions; import net.neoforged.neoforge.fluids.BaseFlowingFluid; @@ -67,7 +64,6 @@ public final class AntarchyNeoforgeMisc { private static final DeferredRegister> ENTITY_SUB_PREDICATES = DeferredRegister.create(Registries.ENTITY_SUB_PREDICATE_TYPE, Antarchy.MODID); private static final DeferredRegister ATTRIBUTES = DeferredRegister.create(Registries.ATTRIBUTE, Antarchy.MODID); - // Attributes public static final DeferredHolder DOUBLE_DAMAGE_CHANCE = ATTRIBUTES.register( "double_damage_chance", () -> new net.minecraft.world.entity.ai.attributes.RangedAttribute("attribute.antarchy.double_damage_chance", 0.0, 0.0, 1.0).setSyncable(true) diff --git a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeSounds.java b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeSounds.java index 9cb636a3..d2c1cb47 100644 --- a/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeSounds.java +++ b/neoforge/src/main/java/com/craisinlord/antarchy/neoforge/registry/AntarchyNeoforgeSounds.java @@ -124,6 +124,14 @@ public final class AntarchyNeoforgeSounds { public static final DeferredHolder BOMBER_WALK = registerSoundEvent("bomber_walk"); public static final DeferredHolder BOMBER_KNOCK = registerSoundEvent("bomber_knock"); public static final DeferredHolder BOMBER_EXPLODE = registerSoundEvent("bomber_explode"); + public static final DeferredHolder STINKY_FLY = registerSoundEvent("stinky_fly"); + public static final DeferredHolder CREEPING_HORROR_GROWL = registerSoundEvent("creeping_horror_growl"); + public static final DeferredHolder CREEPING_HORROR_HURT = registerSoundEvent("creeping_horror_hurt"); + public static final DeferredHolder CREEPING_HORROR_BITE = registerSoundEvent("creeping_horror_bite"); + public static final DeferredHolder LURKING_TERROR_SNARL = registerSoundEvent("lurking_terror_snarl"); + public static final DeferredHolder LURKING_TERROR_HURT = registerSoundEvent("lurking_terror_hurt"); + public static final DeferredHolder LURKING_TERROR_BITE = registerSoundEvent("lurking_terror_bite"); + public static final DeferredHolder LURKING_TERROR_FLY_LOOP = registerSoundEvent("lurking_terror_fly_loop"); public static final DeferredHolder DUCT_TAPE_USE = registerSoundEvent("duct_tape_use"); public static final DeferredHolder POTENT_NYXITE_HYPNOTIC_GAS = registerSoundEvent("potent_nyxite_hypnotic_gas"); public static final DeferredHolder POTENT_NYXITE_GEYSER_ERUPTION_START = registerSoundEvent("potent_nyxite_geyser_eruption_start"); 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 8f4acca4..d6ade634 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 @@ -34,6 +34,7 @@ public class AntarchyNeoforgeSpawnPlacements { event.register(AntarchyNeoforgeEntites.WASP.get(), SpawnPlacementTypes.NO_RESTRICTIONS, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, WaspEntity::canSpawn, RegisterSpawnPlacementsEvent.Operation.OR); event.register(AntarchyNeoforgeEntites.BOMBER.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, BomberEntity::canSpawn, RegisterSpawnPlacementsEvent.Operation.OR); event.register(AntarchyNeoforgeEntites.JUMPY_BUG.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, JumpyBugEntity::canSpawn, RegisterSpawnPlacementsEvent.Operation.OR); + event.register(AntarchyNeoforgeEntites.SPIT_BUG.get(), SpawnPlacementTypes.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, SpitBugEntity::canSpawn, RegisterSpawnPlacementsEvent.Operation.OR); event.register(AntarchyNeoforgeEntites.KRAKEN.get(), SpawnPlacementTypes.IN_WATER, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, KrakenEntity::canSpawn, RegisterSpawnPlacementsEvent.Operation.OR); event.register(AntarchyNeoforgeEntites.MISSILE_SQUID.get(), SpawnPlacementTypes.IN_WATER, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, MissileSquidEntity::canSpawn, RegisterSpawnPlacementsEvent.Operation.OR); event.register(AntarchyNeoforgeEntites.OCTOPUS_BOMB.get(), SpawnPlacementTypes.IN_WATER, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, OctopusBombEntity::canSpawn, RegisterSpawnPlacementsEvent.Operation.OR); diff --git a/neoforge/src/main/resources/data/antarchy/neoforge/biome_modifier/ant_nests_in_forests.json b/neoforge/src/main/resources/data/antarchy/neoforge/biome_modifier/ant_nests_in_forests.json index 45283482..684bd2ee 100644 --- a/neoforge/src/main/resources/data/antarchy/neoforge/biome_modifier/ant_nests_in_forests.json +++ b/neoforge/src/main/resources/data/antarchy/neoforge/biome_modifier/ant_nests_in_forests.json @@ -3,7 +3,8 @@ "biomes": "#antarchy:overworld_ant_nest_spawn_biomes", "features": [ "antarchy:brown_ant_nest", - "antarchy:rainbow_ant_nest" + "antarchy:rainbow_ant_nest", + "antarchy:termite_nest" ], "step": "vegetal_decoration" }